This diff implements socket splicing for relayd.  Instead of copying
data in userland from one TCP socket into another, the kernel is
told to move the data himself.

The environment variable RELAY_NOSPLICE works like EVENT_NOKQUEUE
from libevent.  It can be used to easily turn it on and off for
testing.

At the moment, I have only implemented plain TCP connections in
relayd.  HTTP can be done later.

If you are using relayd with OpenBSD 4.9 to relay TCP connections,
please test this.

ok?

bluhm


Index: usr.sbin/relayd/parse.y
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/relayd/parse.y,v
retrieving revision 1.149
diff -u -p -r1.149 parse.y
--- usr.sbin/relayd/parse.y     26 Oct 2010 15:04:37 -0000      1.149
+++ usr.sbin/relayd/parse.y     31 Jan 2011 23:34:13 -0000
@@ -796,6 +796,9 @@ proto               : relay_proto PROTO STRING      {
                        free($3);
                        p->id = ++last_proto_id;
                        p->type = $1;
+                       if (p->type == RELAY_PROTO_TCP &&
+                           !getenv("RELAY_NOSPLICE"))
+                               p->flags |= F_SPLICE;
                        p->cache = RELAY_CACHESIZE;
                        p->tcpflags = TCPFLAG_DEFAULT;
                        p->sslflags = SSLFLAG_DEFAULT;
@@ -2170,6 +2173,8 @@ parse_config(const char *filename, int o
        (void)strlcpy(conf->sc_proto_default.sslciphers, SSLCIPHERS_DEFAULT,
            sizeof(conf->sc_proto_default.sslciphers));
        conf->sc_proto_default.type = RELAY_PROTO_TCP;
+       if (!getenv("RELAY_NOSPLICE"))
+               conf->sc_proto_default.flags |= F_SPLICE;
        (void)strlcpy(conf->sc_proto_default.name, "default",
            sizeof(conf->sc_proto_default.name));
        RB_INIT(&conf->sc_proto_default.request_tree);
Index: usr.sbin/relayd/relay.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/relayd/relay.c,v
retrieving revision 1.128
diff -u -p -r1.128 relay.c
--- usr.sbin/relayd/relay.c     20 Dec 2010 12:38:06 -0000      1.128
+++ usr.sbin/relayd/relay.c     31 Jan 2011 23:19:59 -0000
@@ -2328,6 +2328,21 @@ relay_connect(struct rsession *con)
                return (-1);
        }
 
+       if (rlay->rl_proto->flags & F_SPLICE) {
+               if (setsockopt(con->se_in.s, SOL_SOCKET, SO_SPLICE,
+                   &con->se_out.s, sizeof(int)) == -1) {
+                       log_debug("relay_connect: session %d: splice forward "
+                           "failed: %s", con->se_id, strerror(errno));
+                       return (-1);
+               }
+               if (setsockopt(con->se_out.s, SOL_SOCKET, SO_SPLICE,
+                   &con->se_in.s, sizeof(int)) == -1) {
+                       log_debug("relay_connect: session %d: splice backward "
+                           "failed: %s", con->se_id, strerror(errno));
+                       return (-1);
+               }
+       }
+
        if (errno == EINPROGRESS)
                event_again(&con->se_ev, con->se_out.s, EV_WRITE|EV_TIMEOUT,
                    relay_connected, &con->se_tv_start, &env->sc_timeout, con);
Index: usr.sbin/relayd/relayd.8
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/relayd/relayd.8,v
retrieving revision 1.23
diff -u -p -r1.23 relayd.8
--- usr.sbin/relayd/relayd.8    24 May 2010 19:44:23 -0000      1.23
+++ usr.sbin/relayd/relayd.8    1 Feb 2011 00:10:22 -0000
@@ -121,6 +121,10 @@ Only check the configuration file for va
 .It Fl v
 Produce more verbose output.
 .El
+.Sh ENVIRONMENT
+It is possible to disable support for socket splicing by setting
+the environment variable
+.Ev RELAY_NOSPLICE .
 .Sh FILES
 .Bl -tag -width "/var/run/relayd.sockXX" -compact
 .It /etc/relayd.conf
Index: usr.sbin/relayd/relayd.h
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/relayd/relayd.h,v
retrieving revision 1.140
diff -u -p -r1.140 relayd.h
--- usr.sbin/relayd/relayd.h    31 Dec 2010 21:22:42 -0000      1.140
+++ usr.sbin/relayd/relayd.h    31 Jan 2011 23:18:49 -0000
@@ -249,6 +249,7 @@ TAILQ_HEAD(addresslist, address);
 #define F_SSLCLIENT            0x00200000
 #define F_NEEDRT               0x00400000
 #define F_MATCH                        0x00800000
+#define F_SPLICE               0x01000000
 
 enum forwardmode {
        FWD_NORMAL              = 0,

Reply via email to