Module Name:    src
Committed By:   pooka
Date:           Sun Jan  9 19:56:34 UTC 2011

Modified Files:
        src/lib/librumphijack: hijack.c

Log Message:
Networked X11 clients have the annoying property that they need to
contact the X server.  Since most of the useful cases these days
are local, add a toggle which forwards PF_LOCAL sockets to the host
and all other protocol families to the rump kernel.

This makes an unmodified firefox work with a rump TCP/IP stack.
I'm sure someone will find applications for being able to run
multiple web browser profiles on one OS with each browser having
a different IP address in the same subnet ...


To generate a diff of this commit:
cvs rdiff -u -r1.6 -r1.7 src/lib/librumphijack/hijack.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/librumphijack/hijack.c
diff -u src/lib/librumphijack/hijack.c:1.6 src/lib/librumphijack/hijack.c:1.7
--- src/lib/librumphijack/hijack.c:1.6	Sun Jan  9 14:15:06 2011
+++ src/lib/librumphijack/hijack.c	Sun Jan  9 19:56:33 2011
@@ -1,4 +1,4 @@
-/*      $NetBSD: hijack.c,v 1.6 2011/01/09 14:15:06 pooka Exp $	*/
+/*      $NetBSD: hijack.c,v 1.7 2011/01/09 19:56:33 pooka Exp $	*/
 
 /*-
  * Copyright (c) 2011 Antti Kantee.  All Rights Reserved.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: hijack.c,v 1.6 2011/01/09 14:15:06 pooka Exp $");
+__RCSID("$NetBSD: hijack.c,v 1.7 2011/01/09 19:56:33 pooka Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -91,6 +91,15 @@
 	"__pollts50",
 };
 
+static int	(*host_socket)(int, int, int);
+static int	(*host_connect)(int, const struct sockaddr *, socklen_t);
+static int	(*host_bind)(int, const struct sockaddr *, socklen_t);
+static int	(*host_listen)(int, int);
+static int	(*host_accept)(int, struct sockaddr *, socklen_t *);
+static int	(*host_getpeername)(int, struct sockaddr *, socklen_t *);
+static int	(*host_getsockname)(int, struct sockaddr *, socklen_t *);
+static int	(*host_setsockopt)(int, int, int, const void *, socklen_t);
+
 static ssize_t	(*host_read)(int, void *, size_t);
 static ssize_t	(*host_readv)(int, const struct iovec *, int);
 static ssize_t	(*host_write)(int, const void *, size_t);
@@ -116,6 +125,9 @@
 	return dlsym(handle, symbol);
 }
 
+/* low calorie sockets? */
+static bool hostlocalsockets = false;
+
 static void __attribute__((constructor))
 rcinit(void)
 {
@@ -133,6 +145,15 @@
 	rumpcdlsym = dlsym(hand, "rumpclient_dlsym");
 	*rumpcdlsym = hijackdlsym;
 
+	host_socket = dlsym(RTLD_NEXT, "__socket30");
+	host_listen = dlsym(RTLD_NEXT, "listen");
+	host_connect = dlsym(RTLD_NEXT, "connect");
+	host_bind = dlsym(RTLD_NEXT, "bind");
+	host_accept = dlsym(RTLD_NEXT, "accept");
+	host_getpeername = dlsym(RTLD_NEXT, "getpeername");
+	host_getsockname = dlsym(RTLD_NEXT, "getsockname");
+	host_setsockopt = dlsym(RTLD_NEXT, "setsockopt");
+
 	host_read = dlsym(RTLD_NEXT, "read");
 	host_readv = dlsym(RTLD_NEXT, "readv");
 	host_write = dlsym(RTLD_NEXT, "write");
@@ -228,13 +249,21 @@
 {
 	int (*rc_socket)(int, int, int);
 	int fd;
+	bool dohost;
+
+	dohost = hostlocalsockets && (domain == AF_LOCAL);
 
-	rc_socket = rumpcalls[RUMPCALL_SOCKET];
+	if (dohost)
+		rc_socket = host_socket;
+	else
+		rc_socket = rumpcalls[RUMPCALL_SOCKET];
 	fd = rc_socket(domain, type, protocol);
 
-	DPRINTF(("socket <- %d\n", fd_rump2host(fd)));
+	if (!dohost)
+		fd = fd_rump2host(fd);
+	DPRINTF(("socket <- %d\n", fd));
 
-	return fd_rump2host(fd);
+	return fd;
 }
 
 int
@@ -242,14 +271,24 @@
 {
 	int (*rc_accept)(int, struct sockaddr *, socklen_t *);
 	int fd;
+	bool isrump;
+
+	isrump = fd_isrump(s);
 
 	DPRINTF(("accept -> %d", s));
-	assertfd(s);
-	rc_accept = rumpcalls[RUMPCALL_ACCEPT];
-	fd = rc_accept(fd_host2rump(s), addr, addrlen);
-	DPRINTF((" <- %d\n", fd_rump2host(fd)));
+	if (isrump) {
+		rc_accept = rumpcalls[RUMPCALL_ACCEPT];
+		s = fd_host2rump(s);
+	} else {
+		rc_accept = host_accept;
+	}
+	fd = rc_accept(s, addr, addrlen);
+	if (fd != -1 && isrump)
+		fd = fd_rump2host(fd);
+
+	DPRINTF((" <- %d\n", fd));
 
-	return fd_rump2host(fd);
+	return fd;
 }
 
 int
@@ -258,10 +297,13 @@
 	int (*rc_bind)(int, const struct sockaddr *, socklen_t);
 
 	DPRINTF(("bind -> %d\n", s));
-	assertfd(s);
-	rc_bind = rumpcalls[RUMPCALL_BIND];
-
-	return rc_bind(fd_host2rump(s), name, namelen);
+	if (fd_isrump(s)) {
+		rc_bind = rumpcalls[RUMPCALL_BIND];
+		s = fd_host2rump(s);
+	} else {
+		rc_bind = host_bind;
+	}
+	return rc_bind(s, name, namelen);
 }
 
 int
@@ -270,10 +312,14 @@
 	int (*rc_connect)(int, const struct sockaddr *, socklen_t);
 
 	DPRINTF(("connect -> %d\n", s));
-	assertfd(s);
-	rc_connect = rumpcalls[RUMPCALL_CONNECT];
+	if (fd_isrump(s)) {
+		rc_connect = rumpcalls[RUMPCALL_CONNECT];
+		s = fd_host2rump(s);
+	} else {
+		rc_connect = host_connect;
+	}
 
-	return rc_connect(fd_host2rump(s), name, namelen);
+	return rc_connect(s, name, namelen);
 }
 
 int
@@ -282,9 +328,13 @@
 	int (*rc_getpeername)(int, struct sockaddr *, socklen_t *);
 
 	DPRINTF(("getpeername -> %d\n", s));
-	assertfd(s);
-	rc_getpeername = rumpcalls[RUMPCALL_GETPEERNAME];
-	return rc_getpeername(fd_host2rump(s), name, namelen);
+	if (fd_isrump(s)) {
+		rc_getpeername = rumpcalls[RUMPCALL_GETPEERNAME];
+		s = fd_host2rump(s);
+	} else {
+		rc_getpeername = host_getpeername;
+	}
+	return rc_getpeername(s, name, namelen);
 }
 
 int
@@ -293,9 +343,13 @@
 	int (*rc_getsockname)(int, struct sockaddr *, socklen_t *);
 
 	DPRINTF(("getsockname -> %d\n", s));
-	assertfd(s);
-	rc_getsockname = rumpcalls[RUMPCALL_GETSOCKNAME];
-	return rc_getsockname(fd_host2rump(s), name, namelen);
+	if (fd_isrump(s)) {
+		rc_getsockname = rumpcalls[RUMPCALL_GETSOCKNAME];
+		s = fd_host2rump(s);
+	} else {
+		rc_getsockname = host_getsockname;
+	}
+	return rc_getsockname(s, name, namelen);
 }
 
 int
@@ -304,9 +358,13 @@
 	int (*rc_listen)(int, int);
 
 	DPRINTF(("listen -> %d\n", s));
-	assertfd(s);
-	rc_listen = rumpcalls[RUMPCALL_LISTEN];
-	return rc_listen(fd_host2rump(s), backlog);
+	if (fd_isrump(s)) {
+		rc_listen = rumpcalls[RUMPCALL_LISTEN];
+		s = fd_host2rump(s);
+	} else {
+		rc_listen = host_listen;
+	}
+	return rc_listen(s, backlog);
 }
 
 ssize_t
@@ -379,7 +437,7 @@
 {
 	int (*rc_getsockopt)(int, int, int, void *, socklen_t *);
 
-	DPRINTF(("getsockopt\n"));
+	DPRINTF(("getsockopt -> %d\n", s));
 	assertfd(s);
 	rc_getsockopt = rumpcalls[RUMPCALL_GETSOCKOPT];
 	return rc_getsockopt(fd_host2rump(s), level, optname, optval, optlen);
@@ -390,10 +448,14 @@
 {
 	int (*rc_setsockopt)(int, int, int, const void *, socklen_t);
 
-	DPRINTF(("setsockopt\n"));
-	assertfd(s);
-	rc_setsockopt = rumpcalls[RUMPCALL_SETSOCKOPT];
-	return rc_setsockopt(fd_host2rump(s), level, optname, optval, optlen);
+	DPRINTF(("setsockopt -> %d\n", s));
+	if (fd_isrump(s)) {
+		rc_setsockopt = rumpcalls[RUMPCALL_SETSOCKOPT];
+		s = fd_host2rump(s);
+	} else {
+		rc_setsockopt = host_setsockopt;
+	}
+	return rc_setsockopt(s, level, optname, optval, optlen);
 }
 
 int
@@ -401,7 +463,7 @@
 {
 	int (*rc_shutdown)(int, int);
 
-	DPRINTF(("shutdown\n"));
+	DPRINTF(("shutdown -> %d\n", s));
 	assertfd(s);
 	rc_shutdown = rumpcalls[RUMPCALL_SHUTDOWN];
 	return rc_shutdown(fd_host2rump(s), how);
@@ -496,6 +558,7 @@
 {
 	int (*op_readv)(int, const struct iovec *, int);
 
+	DPRINTF(("readv %d\n", fd));
 	if (fd_isrump(fd)) {
 		fd = fd_host2rump(fd);
 		op_readv = rumpcalls[RUMPCALL_READV];
@@ -503,7 +566,6 @@
 		op_readv = host_readv;
 	}
 
-	DPRINTF(("readv\n"));
 	return op_readv(fd, iov, iovcnt);
 }
 
@@ -527,6 +589,7 @@
 {
 	int (*op_writev)(int, const struct iovec *, int);
 
+	DPRINTF(("writev %d\n", fd));
 	if (fd_isrump(fd)) {
 		fd = fd_host2rump(fd);
 		op_writev = rumpcalls[RUMPCALL_WRITEV];
@@ -604,6 +667,8 @@
 	nfds_t i, j, realnfds;
 	int rv, incr;
 
+	DPRINTF(("select\n"));
+
 	/*
 	 * Well, first we must scan the fds to figure out how many
 	 * fds there really are.  This is because up to and including

Reply via email to