From owner-p4-projects@FreeBSD.ORG Fri Jun 12 11:05:37 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id A75C61065672; Fri, 12 Jun 2009 11:05:36 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 67455106566C for ; Fri, 12 Jun 2009 11:05:36 +0000 (UTC) (envelope-from jona@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 547FD8FC14 for ; Fri, 12 Jun 2009 11:05:36 +0000 (UTC) (envelope-from jona@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n5CB5aEZ050897 for ; Fri, 12 Jun 2009 11:05:36 GMT (envelope-from jona@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n5CB5aXt050895 for perforce@freebsd.org; Fri, 12 Jun 2009 11:05:36 GMT (envelope-from jona@FreeBSD.org) Date: Fri, 12 Jun 2009 11:05:36 GMT Message-Id: <200906121105.n5CB5aXt050895@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to jona@FreeBSD.org using -f From: Jonathan Anderson To: Perforce Change Reviews Cc: Subject: PERFORCE change 164164 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 12 Jun 2009 11:05:37 -0000 http://perforce.freebsd.org/chv.cgi?CH=164164 Change 164164 by jona@jona-trustedbsd-belle-vm on 2009/06/12 11:04:55 Added some preliminary marshalling / send-with-file-descriptor code Affected files ... .. //depot/projects/trustedbsd/capabilities/src/tools/cap/user_angel/Makefile#4 edit .. //depot/projects/trustedbsd/capabilities/src/tools/cap/user_angel/fdtest.c#1 add .. //depot/projects/trustedbsd/capabilities/src/tools/cap/user_angel/protocol.c#4 edit .. //depot/projects/trustedbsd/capabilities/src/tools/cap/user_angel/protocol.h#4 edit Differences ... ==== //depot/projects/trustedbsd/capabilities/src/tools/cap/user_angel/Makefile#4 (text+ko) ==== @@ -1,6 +1,6 @@ -CFLAGS=-g -ggdb --std=c99 -Wall -Werror -pedantic-errors +CFLAGS=-g -ggdb --std=c99 -Wall -Werror #-pedantic-errors -BIN=user_angel test_client +BIN=user_angel test_client fdtest AGENT_OBJ = user_angel.o server.o cap.o protocol.o fdcomm.o powerbox.o CLIENT_OBJ = test_client.o protocol.o fdcomm.o @@ -13,9 +13,13 @@ test_client: ${CLIENT_OBJ} ${CC} -o $@ ${CLIENT_OBJ} +fdtest: fdtest.o fdcomm.o protocol.o + ${CC} -o $@ fdtest.o fdcomm.o protocol.o + cap.o: cap.c cap.h fdcomm.o: fdcomm.c fdcomm.h +fdtest.o: fdtest.c protocol.h powerbox.o: powerbox.c powerbox.h protocol.o: protocol.c protocol.h powerbox.h server.o: server.c protocol.h server.h ==== //depot/projects/trustedbsd/capabilities/src/tools/cap/user_angel/protocol.c#4 (text+ko) ==== @@ -33,15 +33,164 @@ #include +#include #include #include #include #include +#include +#include #include "protocol.h" +struct cap_wire_datum* cap_marshall_int(int32_t value) +{ + int size = sizeof(struct cap_wire_datum) + sizeof(int32_t); + struct cap_wire_datum *d = (struct cap_wire_datum*) malloc(size); + + d->type = INTEGER; + d->length = sizeof(int32_t); + ((int32_t*) d + sizeof(struct cap_wire_datum))[0] = value; + + return d; +} + + +struct cap_wire_datum* cap_marshall_string(char *value, int len) +{ + int size = sizeof(struct cap_wire_datum) + len; + struct cap_wire_datum *d = (struct cap_wire_datum*) malloc(size); + + d->type = STRING; + d->length = len; + memcpy(d + sizeof(struct cap_wire_datum), value, len); + + return d; +} +/* +int cap_send(int sock, struct cap_wire_datum* datum); +*/ + + + +#include // TODO: temporary +int cap_send_fd(int sock, const char *name, struct cap_wire_datum *d, + int32_t fd_array[], int32_t fdlen) +{ + printf("Sending datum + %i FD(s) over socket %i\n", fdlen, sock); + + // the datum is the I/O vector + struct iovec iov; + iov.iov_base = d; + iov.iov_len = sizeof(struct cap_wire_datum) + d->length; + + + // ancilliary data (file descriptors) + int cmsghdrlen = sizeof(struct cmsghdr) + fdlen * sizeof(int32_t); + struct cmsghdr *anc_hdr = (struct cmsghdr*) malloc(cmsghdrlen); + if(!anc_hdr) err(EX_OSERR, "Error creating ancilliary data header"); + + anc_hdr->cmsg_len = cmsghdrlen; + anc_hdr->cmsg_level = SOL_SOCKET; + anc_hdr->cmsg_type = SCM_RIGHTS; + memcpy(anc_hdr + sizeof(struct cmsghdr), fd_array, fdlen * sizeof(int32_t)); + + + // sendmsg header + struct msghdr header; + header.msg_name = (void*) name; + header.msg_namelen = strlen(name); + header.msg_iov = &iov; + header.msg_iovlen = 1; + header.msg_control = anc_hdr; + header.msg_controllen = anc_hdr->cmsg_len; + header.msg_flags = 0; + + + int bytes_sent = sendmsg(sock, &header, 0); +// int bytes_sent = send(sock, d, sizeof(struct cap_wire_datum), 0); + if(bytes_sent < 0) + { + perror("Error sending data and file descriptor(s)"); + sleep(200); + return -1; + } + + free(anc_hdr); + return bytes_sent; +} + + + +int cap_recv_fd(int sock, char **name, struct cap_wire_datum **d, + int32_t *fd_array, int32_t *fdlen) +{ + printf("cap_recv_fd(%i, char**, datum**, int[], %i)\n", sock, *fdlen); + + // how much data is there to receive? + struct cap_wire_datum peek; + printf("Peek at first %iB...\n", sizeof(struct cap_wire_datum)); + int bytes = recv(sock, &peek, sizeof(struct cap_wire_datum), MSG_PEEK); + int to_receive = sizeof(struct cap_wire_datum) + peek.length; + printf("Total to receive: %iB\n", to_receive); + + // make room for it + *d = (struct cap_wire_datum*) malloc(to_receive); + struct iovec iov; + iov.iov_base = d; + iov.iov_len = to_receive; + + // prepare to receive file descriptor(s) + int size = sizeof(struct cmsghdr) + *fdlen; + struct cmsghdr *anc_hdr = (struct cmsghdr*) malloc(size); + if(!anc_hdr) err(EX_OSERR, "Error creating ancilliary data header"); + anc_hdr->cmsg_len = size; + anc_hdr->cmsg_level = SOL_SOCKET; + anc_hdr->cmsg_type = SCM_RIGHTS; + memset(anc_hdr + sizeof(struct cmsghdr), 0, *fdlen * sizeof(int32_t)); + + // recvmsg() options + struct msghdr header; + header.msg_name = NULL; + header.msg_namelen = 0; + header.msg_iov = &iov; + header.msg_iovlen = 1; + header.msg_control = anc_hdr; + header.msg_controllen = anc_hdr->cmsg_len; + header.msg_flags = 0; + + + bytes = recvmsg(sock, &header, MSG_WAITALL); + if(bytes < 0) + { + perror("Error receiving message"); + return -1; + } + else if(bytes == 0) + { + fprintf(stderr, "Socket closed\n"); + return -1; + } + + size = sizeof(struct cmsghdr) + *fdlen * sizeof(int32_t); + printf("Received %iB cmsghdr\n", anc_hdr->cmsg_len); + + int recv_fdlen = + (anc_hdr->cmsg_len - sizeof(struct cmsghdr)) / sizeof(int32_t); + printf("Received %i FDs (room for %i)\n", recv_fdlen, *fdlen); + + if(recv_fdlen < *fdlen) *fdlen = recv_fdlen; + + int32_t* recv_fd_array = (int32_t*) anc_hdr + sizeof(anc_hdr); + memcpy(fd_array, recv_fd_array, *fdlen * sizeof(int32_t)); + + return 0; +} + + + int cap_send_int(int client, int value) { return send(client, &value, sizeof(int), 0); ==== //depot/projects/trustedbsd/capabilities/src/tools/cap/user_angel/protocol.h#4 (text+ko) ==== @@ -31,10 +31,24 @@ * SUCH DAMAGE. */ -#include -__FBSDID("$FreeBSD$"); +#include +#include "powerbox.h" + + +struct cap_wire_datum +{ + uint32_t type; + #define INTEGER 0x00000001 + #define FLOAT 0x00000002 + #define STRING 0x00000004 + #define LONG 0x00000100 + #define SHORT 0x00000200 + + uint32_t length; + + /* followed by data; */ +}; -#include "powerbox.h" /** Requests that clients can make */ @@ -46,6 +60,22 @@ +struct cap_wire_datum* cap_marshall_int(int32_t value); +struct cap_wire_datum* cap_marshall_string(char *value, int len); + +int cap_send(int sock, char *name, struct cap_wire_datum *d); +int cap_send_fd(int sock, const char *name, struct cap_wire_datum *d, + int32_t fd_array[], int32_t fdlen); + +int cap_recv(int sock, char **name, struct cap_wire_datum **d); + +/** You supply the FD array and say how big it is; I'll tell you how many FDs you actually received. */ +int cap_recv_fd(int sock, char **name, struct cap_wire_datum **d, + int32_t fd_array[], int32_t *fdlen); + + + + int cap_send_int(int client, int value); int cap_recv_int(int client, int *value);