PERFORCE change 164164 for review
Jonathan Anderson
jona at FreeBSD.org
Fri Jun 12 11:05:37 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=164164
Change 164164 by jona at 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 <sys/socket.h>
+#include <err.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sysexits.h>
+#include <unistd.h>
#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 <stdio.h> // 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 <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+#include <sys/types.h>
+#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);
More information about the p4-projects
mailing list