commit - ecd6b12a1f94fa609c3f7484f12d4cc8bc5a46f1
commit + cfe57149140baac9bfd1f900a6e6e425e41b6900
blob - e12a0cfb06988605fc631ae39271ed44a52e41d2
blob + ca4a7aa15578c1b5edae7540faa824038de59c42
--- Makefile
+++ Makefile
PROG = lstun
DISTNAME = ${PROG}-${VERSION}
-HEADERS = log.h
+HEADERS = log.h \
+ lstun.h
SOURCES = compats.c \
log.c \
lstun.c \
+ splice.c \
+ splice_bev.c \
tests.c
OBJS = ${SOURCES:.c=.o}
blob - aa7a9534a58d2c80e103a87a08936d9cfc8eca26
blob + 0adf97437ca6d672a99314a848d308eae7039d08
--- configure
+++ configure
HAVE_PLEDGE=
HAVE_PROGRAM_INVOCATION_SHORT_NAME=
HAVE_PR_SET_NAME=
+HAVE_SO_SPLICE=
HAVE_STRLCAT=
HAVE_STRLCPY=
HAVE_STRTONUM=
runtest pledge PLEDGE || true
runtest program_invocation_short_name PROGRAM_INVOCATION_SHORT_NAME || true
runtest PR_SET_NAME PR_SET_NAME || true
+runtest SO_SPLICE SO_SPLICE || true
runtest static STATIC "" "-static" || true
runtest strlcat STRLCAT || true
runtest strlcpy STRLCPY || true
#define HAVE_PLEDGE ${HAVE_PLEDGE}
#define HAVE_PROGRAM_INVOCATION_SHORT_NAME ${HAVE_PROGRAM_INVOCATION_SHORT_NAME}
#define HAVE_PR_SET_NAME ${HAVE_PR_SET_NAME}
+#define HAVE_SO_SPLICE ${HAVE_SO_SPLICE}
#define HAVE_STRLCAT ${HAVE_STRLCAT}
#define HAVE_STRLCPY ${HAVE_STRLCPY}
#define HAVE_STRTONUM ${HAVE_STRTONUM}
blob - 50e49b42d189dc64abe213706e0286c48e7ec44e
blob + f90988dfb32aaa18e6e06ab124a5d6ac0f10c5a0
--- lstun.c
+++ lstun.c
#include <unistd.h>
#include "log.h"
+#include "lstun.h"
#define MAXSOCK 32
#define BACKOFF 1
int conn;
-struct conn {
- int ntentative;
- struct timeval retry;
- struct event waitev;
- int source;
- struct bufferevent *sourcebev;
- int to;
- struct bufferevent *tobev;
-};
-
static void
sig_handler(int sig, short event, void *data)
{
}
static void
+killing_time(int fd, short event, void *data)
+{
+ if (ssh_pid == -1)
+ return;
+
+ log_debug("timeout expired, killing ssh (%d)", ssh_pid);
+ kill(ssh_pid, SIGTERM);
+ ssh_pid = -1;
+}
+
+void
conn_free(struct conn *c)
{
if (c->sourcebev != NULL)
close(c->to);
free(c);
-}
-static void
-killing_time(int fd, short event, void *data)
-{
- if (ssh_pid == -1)
- return;
-
- log_debug("timeout expired, killing ssh (%d)", ssh_pid);
- kill(ssh_pid, SIGTERM);
- ssh_pid = -1;
-}
-
-static void
-nopcb(struct bufferevent *bev, void *d)
-{
- return;
-}
-
-static void
-sreadcb(struct bufferevent *bev, void *d)
-{
- struct conn *c = d;
-
- bufferevent_write_buffer(c->tobev, EVBUFFER_INPUT(bev));
-}
-
-static void
-treadcb(struct bufferevent *bev, void *d)
-{
- struct conn *c = d;
-
- bufferevent_write_buffer(c->sourcebev, EVBUFFER_INPUT(bev));
-}
-
-static void
-errcb(struct bufferevent *bev, short event, void *d)
-{
- struct conn *c = d;
-
- log_info("closing connection (event=%x)", event);
-
- conn_free(c);
-
if (--conn == 0) {
log_debug("scheduling ssh termination (%llds)",
(long long)timeout.tv_sec);
log_info("connected!");
- c->sourcebev = bufferevent_new(c->source, sreadcb, nopcb, errcb, c);
- c->tobev = bufferevent_new(c->to, treadcb, nopcb, errcb, c);
- if (c->sourcebev == NULL || c->tobev == NULL) {
- log_warn("bufferevent_new");
+ if (conn_splice(c) == -1)
conn_free(c);
- return;
- }
-
- bufferevent_enable(c->sourcebev, EV_READ|EV_WRITE);
- bufferevent_enable(c->tobev, EV_READ|EV_WRITE);
}
static void
blob - 3ac5d07899463dd2f7686bdb4d644b9b756021fd
blob + 4a4aeb61dc59fbbf52851f5fad6d3a12dc91ab45
--- tests.c
+++ tests.c
return 0;
}
#endif /* TEST_PR_SET_NAME */
+#if TEST_SO_SPLICE
+#include <sys/socket.h>
+
+int
+main(void)
+{
+ int src = 0, dst = 1;
+
+ /*
+ * invalid usage, i'm only interested in checking if it
+ * compiles
+ */
+ setsockopt(src, SOL_SOCKET, SO_SPLICE, &dst, sizeof(int));
+ return 0;
+}
+#endif /* TEST_SO_SPLICE */
#if TEST_STATIC
int
main(void)
blob - /dev/null
blob + c57c79c233526cdcfb89e7f7761c0b94b4b75dad (mode 644)
--- /dev/null
+++ lstun.h
+/*
+ * Copyright (c) 2022 Omar Polo <op@omarpolo.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+struct conn {
+ int ntentative;
+ struct timeval retry;
+ struct event waitev;
+ int source;
+ struct bufferevent *sourcebev;
+ int to;
+ struct bufferevent *tobev;
+};
+
+int conn_splice(struct conn *);
+void conn_free(struct conn *);
blob - /dev/null
blob + ad33ac746ebe2a3cb533e1c25e26f9742c81277f (mode 644)
--- /dev/null
+++ splice.c
+/*
+ * Copyright (c) 2022 Omar Polo <op@omarpolo.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "config.h"
+
+#if HAVE_SO_SPLICE
+
+#include <sys/socket.h>
+
+#include "log.h"
+#include "lstun.h"
+
+static void
+splice_done(int fd, short ev, void *data)
+{
+ struct conn *c = data;
+
+ log_info("closing connection (event=%x)", ev);
+ conn_free(c);
+}
+
+int
+conn_splice(struct conn *c)
+{
+ if (setsockopt(c->source, SOL_SOCKET, SO_SPLICE, &c->to, sizeof(int))
+ == -1)
+ return -1;
+ if (setsockopt(c->to, SOL_SOCKET, SO_SPLICE, &c->source, sizeof(int))
+ == -1)
+ return -1;
+
+ event_once(c->source, EV_READ, splice_done, c, NULL);
+ return 0;
+}
+
+#endif /* HAVE_SO_SPLICE */
blob - /dev/null
blob + 63498c504deb7aaca4573c0a1afcf27dfd0c093b (mode 644)
--- /dev/null
+++ splice_bev.c
+/*
+ * Copyright (c) 2022 Omar Polo <op@omarpolo.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "config.h"
+
+#if !HAVE_SO_SPLICE
+
+#include <sys/socket.h>
+
+#include "log.h"
+#include "lstun.h"
+
+static void
+nopcb(struct bufferevent *bev, void *d)
+{
+ return;
+}
+
+static void
+sreadcb(struct bufferevent *bev, void *d)
+{
+ struct conn *c = d;
+
+ bufferevent_write_buffer(c->tobev, EVBUFFER_INPUT(bev));
+}
+
+static void
+treadcb(struct bufferevent *bev, void *d)
+{
+ struct conn *c = d;
+
+ bufferevent_write_buffer(c->sourcebev, EVBUFFER_INPUT(bev));
+}
+
+static void
+errcb(struct bufferevent *bev, short event, void *d)
+{
+ struct conn *c = d;
+
+ log_info("closing connection (event=%x)", event);
+ conn_free(c);
+}
+
+int
+conn_splice(struct conn *c)
+{
+ c->sourcebev = bufferevent_new(c->source, sreadcb, nopcb, errcb, c);
+ c->tobev = bufferevent_new(c->to, treadcb, nopcb, errcb, c);
+
+ if (c->sourcebev == NULL || c->tobev == NULL) {
+ log_warn("bufferevent_new");
+ return -1;
+ }
+
+ bufferevent_enable(c->sourcebev, EV_READ|EV_WRITE);
+ bufferevent_enable(c->tobev, EV_READ|EV_WRITE);
+ return 0;
+}
+
+#endif /* !HAVE_SO_SPLICE */