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