diff --git a/ChangeLog b/ChangeLog index c3f8d58..a834320 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,6 +15,7 @@ vNEXT: Added 'log_level' option to each protocol, which allows to turn off generation of log at each connection. + Added 'keepalive' option. v1.17: 09MAR2015 Support RFC5952-style IPv6 addresses, e.g. [::]:443. diff --git a/common.c b/common.c index 0814246..abf485c 100644 --- a/common.c +++ b/common.c @@ -155,7 +155,7 @@ int connect_addr(struct connection *cnx, int fd_from) struct addrinfo *a, from; struct sockaddr_storage ss; char buf[NI_MAXHOST]; - int fd, res; + int fd, res, one; memset(&from, 0, sizeof(from)); from.ai_addr = (struct sockaddr*)&ss; @@ -189,6 +189,12 @@ int connect_addr(struct connection *cnx, int fd_from) cnx->proto->description, strerror(errno)); close(fd); } else { + if (cnx->proto->keepalive) { + one = 1; + res = setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char*)&one, sizeof(one)); + CHECK_RES_RETURN(res, "setsockopt(SO_KEEPALIVE)"); + printf("set up keepalive\n"); + } return fd; } } diff --git a/probe.c b/probe.c index 9d025ac..9b4a63e 100644 --- a/probe.c +++ b/probe.c @@ -45,16 +45,16 @@ static int is_true(const char *p, int len, struct proto* proto) { return 1; } /* Table of protocols that have a built-in probe */ static struct proto builtins[] = { - /* description service saddr log_level probe */ - { "ssh", "sshd", NULL, 1, is_ssh_protocol}, - { "openvpn", NULL, NULL, 1, is_openvpn_protocol }, - { "tinc", NULL, NULL, 1, is_tinc_protocol }, - { "xmpp", NULL, NULL, 1, is_xmpp_protocol }, - { "http", NULL, NULL, 1, is_http_protocol }, - { "ssl", NULL, NULL, 1, is_tls_protocol }, - { "tls", NULL, NULL, 1, is_tls_protocol }, - { "adb", NULL, NULL, 1, is_adb_protocol }, - { "anyprot", NULL, NULL, 1, is_true } + /* description service saddr log_level keepalive probe */ + { "ssh", "sshd", NULL, 1, 0, is_ssh_protocol}, + { "openvpn", NULL, NULL, 1, 0, is_openvpn_protocol }, + { "tinc", NULL, NULL, 1, 0, is_tinc_protocol }, + { "xmpp", NULL, NULL, 1, 0, is_xmpp_protocol }, + { "http", NULL, NULL, 1, 0, is_http_protocol }, + { "ssl", NULL, NULL, 1, 0, is_tls_protocol }, + { "tls", NULL, NULL, 1, 0, is_tls_protocol }, + { "adb", NULL, NULL, 1, 0, is_adb_protocol }, + { "anyprot", NULL, NULL, 1, 0, is_true } }; static struct proto *protocols; diff --git a/probe.h b/probe.h index 4d9b473..8c576a2 100644 --- a/probe.h +++ b/probe.h @@ -23,6 +23,7 @@ struct proto { int log_level; /* 0: No logging of connection * 1: Log incoming connection */ + int keepalive; /* 0: No keepalive ; 1: Set Keepalive for this connection */ /* function to probe that protocol; parameters are buffer and length * containing the data to probe, and a pointer to the protocol structure */ diff --git a/sslh-main.c b/sslh-main.c index 220a867..81f937b 100644 --- a/sslh-main.c +++ b/sslh-main.c @@ -123,20 +123,21 @@ static void printsettings(void) for (p = get_first_protocol(); p; p = p->next) { fprintf(stderr, - "%s addr: %s. libwrap service: %s log_level: %d family %d %d\n", + "%s addr: %s. libwrap service: %s log_level: %d family %d %d [%s]\n", p->description, sprintaddr(buf, sizeof(buf), p->saddr), p->service, p->log_level, p->saddr->ai_family, - p->saddr->ai_addr->sa_family); + p->saddr->ai_addr->sa_family, + p->keepalive ? "keepalive" : ""); } fprintf(stderr, "listening on:\n"); for (a = addr_listen; a; a = a->ai_next) { fprintf(stderr, - "\t%s\t[keepalive: %d]\n", + "\t%s\t[%s]\n", sprintaddr(buf, sizeof(buf), a), - a->ai_flags & SO_KEEPALIVE ? 1 : 0); + a->ai_flags & SO_KEEPALIVE ? "keepalive" : ""); } fprintf(stderr, "timeout: %d\non-timeout: %s\n", probing_timeout, timeout_protocol()->description); @@ -299,6 +300,7 @@ static int config_protocols(config_t *config, struct proto **prots) )) { p->description = name; config_setting_lookup_string(prot, "service", &(p->service)); + config_setting_lookup_bool(prot, "keepalive", &p->keepalive); if (config_setting_lookup_int(prot, "log_level", &p->log_level) == CONFIG_FALSE) { p->log_level = 1;