diff --git a/Makefile b/Makefile index cc1587e4..4f615f6e 100644 --- a/Makefile +++ b/Makefile @@ -30,7 +30,7 @@ $(CONF): Linux*) \ echo "#define USE_IPTABLES" >$(CONF) \ ;; \ - OpenBSD) \ + OpenBSD|GNU/kFreeBSD) \ echo "#define USE_PF" >$(CONF) \ ;; \ *) \ diff --git a/base.c b/base.c index 210ddb5c..7f17127a 100644 --- a/base.c +++ b/base.c @@ -251,9 +251,11 @@ int apply_tcp_keepalive(int fd) { struct { int level, option, value; } opt[] = { { SOL_SOCKET, SO_KEEPALIVE, 1 }, +#if defined(TCP_KEEPIDLE) && defined(TCP_KEEPCNT) && defined(TCP_KEEPINTVL) { IPPROTO_TCP, TCP_KEEPIDLE, instance.tcp_keepalive_time }, { IPPROTO_TCP, TCP_KEEPCNT, instance.tcp_keepalive_probes }, { IPPROTO_TCP, TCP_KEEPINTVL, instance.tcp_keepalive_intvl }, +#endif }; for (int i = 0; i < SIZEOF_ARRAY(opt); ++i) { if (opt[i].value) { diff --git a/list.h b/list.h index 8200a160..ab8acc80 100644 --- a/list.h +++ b/list.h @@ -31,7 +31,7 @@ typedef struct list_head_t { #define LIST_HEAD_INIT(name) { &(name), &(name) } -#define LIST_HEAD(name) \ +#define RED_LIST_HEAD(name) \ struct list_head_t name = LIST_HEAD_INIT(name) static inline void INIT_LIST_HEAD(struct list_head_t *list) diff --git a/main.c b/main.c index 06585840..d41e93c8 100644 --- a/main.c +++ b/main.c @@ -85,6 +85,9 @@ int main(int argc, char **argv) " Headers: %8x\n" " Runtime: %8x\n", LIBEVENT_VERSION_NUMBER, event_get_version_number()); } +#ifdef USE_SPLICE + printf("Built with splice(2) support\n"); +#endif return EXIT_SUCCESS; default: printf( diff --git a/main.h b/main.h index 01a97de1..71cf044d 100644 --- a/main.h +++ b/main.h @@ -1,6 +1,7 @@ #ifndef MAIN_H_TUE_JAN_23_15_38_25_2007 #define MAIN_H_TUE_JAN_23_15_38_25_2007 +#include #include "parser.h" struct event_base; @@ -15,6 +16,9 @@ typedef struct app_subsys_t { #define FOREACH(ptr, array) for (ptr = array; ptr < array + SIZEOF_ARRAY(array); ptr++) #define FOREACH_REV(ptr, array) for (ptr = array + SIZEOF_ARRAY(array) - 1; ptr >= array; ptr--) +#ifdef SPLICE_F_MOVE +# define USE_SPLICE +#endif /* vim:set tabstop=4 softtabstop=4 shiftwidth=4: */ /* vim:set foldmethod=marker foldlevel=32 foldmarker={,}: */ diff --git a/redsocks.c b/redsocks.c index f08cdbc3..1bcc471f 100644 --- a/redsocks.c +++ b/redsocks.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include "list.h" #include "parser.h" @@ -48,7 +47,9 @@ enum pump_state_t { static const char *redsocks_event_str(unsigned short what); static int redsocks_start_bufferpump(redsocks_client *client); +#ifdef USE_SPLICE static int redsocks_start_splicepump(redsocks_client *client); +#endif static void redsocks_conn_list_del(redsocks_client *client); @@ -87,6 +88,7 @@ static parser_entry redsocks_entries[] = { } }; +#ifdef USE_SPLICE static bool is_splice_good() { struct utsname u; @@ -94,6 +96,11 @@ static bool is_splice_good() return false; } + /* splice(2) is Linux-specific */ + if (strcmp(u.sysname, "Linux") != 0) { + return false; + } + unsigned long int v[4] = { 0, 0, 0, 0 }; char *rel = u.release; for (int i = 0; i < SIZEOF_ARRAY(v); ++i) { @@ -108,6 +115,12 @@ static bool is_splice_good() (v[0] == 2 && v[1] == 6 && v[2] > 27) || (v[0] == 2 && v[1] == 6 && v[2] == 27 && v[3] >= 13); } +#else +static bool is_splice_good() +{ + return false; +} +#endif static int redsocks_onenter(parser_section *section) { @@ -336,7 +349,11 @@ void redsocks_start_relay(redsocks_client *client) client->state = pump_active; +#ifdef USE_SPLICE int error = ((client->instance->config.use_splice) ? redsocks_start_splicepump : redsocks_start_bufferpump)(client); +#else + int error = redsocks_start_bufferpump(client); +#endif if (!error) redsocks_log_error(client, LOG_DEBUG, "data relaying started"); else @@ -363,6 +380,7 @@ static int redsocks_start_bufferpump(redsocks_client *client) return error; } +#ifdef USE_SPLICE static int pipeprio(redsocks_pump *pump, int fd) { // client errors are logged with LOG_INFO, server errors with LOG_NOTICE @@ -657,6 +675,7 @@ static int redsocks_start_splicepump(redsocks_client *client) return 0; } +#endif /* USE_SPLICE */ static bool has_loopback_destination(redsocks_client *client) { @@ -1412,6 +1431,11 @@ static int redsocks_init_instance(redsocks_instance *instance) goto fail; } + if (instance->config.use_splice && !is_splice_good()) { + log_error(LOG_WARNING, "splice(2) support requested but unavailable or not built-in; ignoring"); + instance->config.use_splice = false; + } + if (instance->relay_ss->instance_init) instance->relay_ss->instance_init(instance); diff --git a/redsocks.conf.example b/redsocks.conf.example index 9d0bea9a..2c549c87 100644 --- a/redsocks.conf.example +++ b/redsocks.conf.example @@ -32,7 +32,7 @@ base { /* possible `redirector' values are: * iptables - for Linux * ipf - for FreeBSD - * pf - for OpenBSD + * pf - for OpenBSD and Debian GNU/kFreeBSD * generic - some generic redirector that MAY work */ redirector = iptables;