From: Guus Sliepen Date: Mon, 26 Mar 2012 18:06:39 +0000 (+0100) Subject: Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 X-Git-Tag: import-tinc-1.1~384 X-Git-Url: http://git.meshlink.io/?p=meshlink;a=commitdiff_plain;h=1d9dacb1f26971e19463b5501c2410c57f780ecb;hp=86c2990327fdf7ec1197aa73cb2b9a926a734db4 Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 Conflicts: src/logger.c src/net_setup.c --- diff --git a/configure.in b/configure.in index 4d2bcbd6..bdac4bab 100644 --- a/configure.in +++ b/configure.in @@ -74,30 +74,44 @@ case $host_os in esac AC_ARG_ENABLE(uml, - AS_HELP_STRING([--enable-uml], [enable support for User Mode Linux]), - [ AC_DEFINE(ENABLE_UML, 1, [Support for UML]) - uml=true - ] + AS_HELP_STRING([--disable-uml], [enable support for User Mode Linux]), + [ AS_IF([test "x$enable_uml" = "xyes"], + [ AC_DEFINE(ENABLE_UML, 1, [Support for UML]) + uml=true + ], + [uml=false]) + ], + [uml=false] ) AC_ARG_ENABLE(vde, - AS_HELP_STRING([--enable-vde], [enable support for Virtual Distributed Ethernet]), - [ AC_CHECK_HEADERS(libvdeplug_dyn.h, [], [AC_MSG_ERROR([VDE plug header files not found.]); break]) - AC_DEFINE(ENABLE_VDE, 1, [Support for VDE]) - vde=true - ] + AS_HELP_STRING([--disable-vde], [enable support for Virtual Distributed Ethernet]), + [ AS_IF([test "x$enable_vde" = "xyes"], + [ AC_CHECK_HEADERS(libvdeplug_dyn.h, [], [AC_MSG_ERROR([VDE plug header files not found.]); break]) + AC_DEFINE(ENABLE_VDE, 1, [Support for VDE]) + vde=true + ], + [vde=false]) + ], + [vde=false] ) AC_ARG_ENABLE(tunemu, - AS_HELP_STRING([--enable-tunemu], [enable support for the tunemu driver]), - [ AC_DEFINE(ENABLE_TUNEMU, 1, [Support for tunemu]) - tunemu=true - ] + AS_HELP_STRING([--disable-tunemu], [enable support for the tunemu driver]), + [ AS_IF([test "x$enable_tunemu" = "xyes"], + [ AC_DEFINE(ENABLE_TUNEMU, 1, [Support for tunemu]) + tunemu=true + ], + [tunemu=false]) + ], + [tunemu=false] ) AC_ARG_WITH(windows2000, - AS_HELP_STRING([--with-windows2000], [compile with support for Windows 2000. This disables support for tunneling over existing IPv6 networks.]), - [AC_DEFINE(WITH_WINDOWS2000, 1, [Compile with support for Windows 2000])] + AS_HELP_STRING([--without-windows2000], [compile with support for Windows 2000. This disables support for tunneling over existing IPv6 networks.]), + [ AS_IF([test "x$with_windows2000" = "xyes"], + [AC_DEFINE(WITH_WINDOWS2000, 1, [Compile with support for Windows 2000])]) + ] ) AM_CONDITIONAL(UML, test "$uml" = true) @@ -183,8 +197,10 @@ fi dnl Check if support for jumbograms is requested AC_ARG_ENABLE(jumbograms, - AS_HELP_STRING([--enable-jumbograms], [enable support for jumbograms (packets up to 9000 bytes)]), - [ AC_DEFINE(ENABLE_JUMBOGRAMS, 1, [Support for jumbograms (packets up to 9000 bytes)]) ] + AS_HELP_STRING([--disable-jumbograms], [enable support for jumbograms (packets up to 9000 bytes)]), + [ AS_IF([test "x$enable_jumbograms" = "xyes"], + [ AC_DEFINE(ENABLE_JUMBOGRAMS, 1, [Support for jumbograms (packets up to 9000 bytes)]) ]) + ] ) AC_SUBST(INCLUDES) diff --git a/src/logger.c b/src/logger.c index 028cbaef..cc47a4a1 100644 --- a/src/logger.c +++ b/src/logger.c @@ -79,7 +79,7 @@ void reopenlogger() { fflush(logfile); FILE *newfile = fopen(logfilename, "a"); if(!newfile) { - logger(DEBUG_ALWAYS, LOG_ERR, "Unable to reopen log file %s: %s\n", logfilename, strerror(errno)); + logger(DEBUG_ALWAYS, LOG_ERR, "Unable to reopen log file %s: %s", logfilename, strerror(errno)); return; } fclose(logfile); diff --git a/src/net_setup.c b/src/net_setup.c index c181df94..0d21cc05 100644 --- a/src/net_setup.c +++ b/src/net_setup.c @@ -639,91 +639,144 @@ static bool setup_myself(void) { /* Open sockets */ - listen_sockets = 0; - cfg = lookup_config(config_tree, "BindToAddress"); - - do { - get_config_string(cfg, &address); - if(cfg) - cfg = lookup_config_next(config_tree, cfg); - - char *port = myport; - - if(address) { - char *space = strchr(address, ' '); - if(space) { - *space++ = 0; - port = space; - } - - if(!strcmp(address, "*")) - *address = 0; - } - - hint.ai_family = addressfamily; - hint.ai_socktype = SOCK_STREAM; - hint.ai_protocol = IPPROTO_TCP; - hint.ai_flags = AI_PASSIVE; + if(!do_detach && getenv("LISTEN_FDS")) { + sockaddr_t sa; + socklen_t salen; - err = getaddrinfo(address && *address ? address : NULL, port, &hint, &ai); - free(address); + listen_sockets = atoi(getenv("LISTEN_FDS")); +#ifdef HAVE_UNSETENV + unsetenv("LISTEN_FDS"); +#endif - if(err || !ai) { - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "getaddrinfo", - gai_strerror(err)); + if(listen_sockets > MAXSOCKETS) { + logger(DEBUG_ALWAYS, LOG_ERR, "Too many listening sockets"); return false; } - for(aip = ai; aip; aip = aip->ai_next) { - if(listen_sockets >= MAXSOCKETS) { - logger(DEBUG_ALWAYS, LOG_ERR, "Too many listening sockets"); + for(i = 0; i < listen_sockets; i++) { + salen = sizeof sa; + if(getsockname(i + 3, &sa.sa, &salen) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not get address of listen fd %d: %s", i + 3, sockstrerror(errno)); return false; } - listen_socket[listen_sockets].tcp = - setup_listen_socket((sockaddr_t *) aip->ai_addr); - - if(listen_socket[listen_sockets].tcp < 0) - continue; + listen_socket[i].tcp = i + 3; - listen_socket[listen_sockets].udp = - setup_vpn_in_socket((sockaddr_t *) aip->ai_addr); +#ifdef FD_CLOEXEC + fcntl(i + 3, F_SETFD, FD_CLOEXEC); +#endif - if(listen_socket[listen_sockets].udp < 0) { - close(listen_socket[listen_sockets].tcp); - continue; - } + listen_socket[i].udp = setup_vpn_in_socket(&sa); + if(listen_socket[i].udp < 0) + return false; - event_set(&listen_socket[listen_sockets].ev_tcp, - listen_socket[listen_sockets].tcp, - EV_READ|EV_PERSIST, - handle_new_meta_connection, NULL); - if(event_add(&listen_socket[listen_sockets].ev_tcp, NULL) < 0) { + event_set(&listen_socket[i].ev_tcp, listen_socket[i].tcp, EV_READ|EV_PERSIST, handle_new_meta_connection, NULL); + if(event_add(&listen_socket[i].ev_tcp, NULL) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "event_add failed: %s", strerror(errno)); abort(); } - event_set(&listen_socket[listen_sockets].ev_udp, - listen_socket[listen_sockets].udp, - EV_READ|EV_PERSIST, - handle_incoming_vpn_data, (void *)(intptr_t)listen_sockets); + event_set(&listen_socket[i].ev_udp, listen_socket[i].udp, EV_READ|EV_PERSIST, handle_incoming_vpn_data, (void *)(intptr_t)listen_sockets); if(event_add(&listen_socket[listen_sockets].ev_udp, NULL) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "event_add failed: %s", strerror(errno)); abort(); } if(debug_level >= DEBUG_CONNECTIONS) { - hostname = sockaddr2hostname((sockaddr_t *) aip->ai_addr); + hostname = sockaddr2hostname(&sa); logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Listening on %s", hostname); free(hostname); } - memcpy(&listen_socket[listen_sockets].sa, aip->ai_addr, aip->ai_addrlen); - listen_sockets++; + memcpy(&listen_socket[i].sa, &sa, salen); } + } else { + listen_sockets = 0; + cfg = lookup_config(config_tree, "BindToAddress"); + + do { + get_config_string(cfg, &address); + if(cfg) + cfg = lookup_config_next(config_tree, cfg); + + char *port = myport; + + if(address) { + char *space = strchr(address, ' '); + if(space) { + *space++ = 0; + port = space; + } + + if(!strcmp(address, "*")) + *address = 0; + } + + hint.ai_family = addressfamily; + hint.ai_socktype = SOCK_STREAM; + hint.ai_protocol = IPPROTO_TCP; + hint.ai_flags = AI_PASSIVE; - freeaddrinfo(ai); - } while(cfg); + err = getaddrinfo(address && *address ? address : NULL, port, &hint, &ai); + free(address); + + if(err || !ai) { + logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "getaddrinfo", + gai_strerror(err)); + return false; + } + + for(aip = ai; aip; aip = aip->ai_next) { + if(listen_sockets >= MAXSOCKETS) { + logger(DEBUG_ALWAYS, LOG_ERR, "Too many listening sockets"); + return false; + } + + listen_socket[listen_sockets].tcp = + setup_listen_socket((sockaddr_t *) aip->ai_addr); + + if(listen_socket[listen_sockets].tcp < 0) + continue; + + listen_socket[listen_sockets].udp = + setup_vpn_in_socket((sockaddr_t *) aip->ai_addr); + + if(listen_socket[listen_sockets].udp < 0) { + close(listen_socket[listen_sockets].tcp); + continue; + } + + event_set(&listen_socket[listen_sockets].ev_tcp, + listen_socket[listen_sockets].tcp, + EV_READ|EV_PERSIST, + handle_new_meta_connection, NULL); + if(event_add(&listen_socket[listen_sockets].ev_tcp, NULL) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "event_add failed: %s", strerror(errno)); + abort(); + } + + event_set(&listen_socket[listen_sockets].ev_udp, + listen_socket[listen_sockets].udp, + EV_READ|EV_PERSIST, + handle_incoming_vpn_data, (void *)(intptr_t)listen_sockets); + if(event_add(&listen_socket[listen_sockets].ev_udp, NULL) < 0) { + logger(DEBUG_ALWAYS, LOG_ERR, "event_add failed: %s", strerror(errno)); + abort(); + } + + if(debug_level >= DEBUG_CONNECTIONS) { + hostname = sockaddr2hostname((sockaddr_t *) aip->ai_addr); + logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Listening on %s", hostname); + free(hostname); + } + + memcpy(&listen_socket[listen_sockets].sa, aip->ai_addr, aip->ai_addrlen); + listen_sockets++; + } + + freeaddrinfo(ai); + } while(cfg); + } if(listen_sockets) logger(DEBUG_ALWAYS, LOG_NOTICE, "Ready"); diff --git a/src/tincd.c b/src/tincd.c index 1008f88a..3cbac4ba 100644 --- a/src/tincd.c +++ b/src/tincd.c @@ -389,6 +389,12 @@ int main(int argc, char **argv) { g_argv = argv; + if(getenv("LISTEN_PID") && atoi(getenv("LISTEN_PID")) == getpid()) + do_detach = false; +#ifdef HAVE_UNSETENV + unsetenv("LISTEN_PID"); +#endif + init_configuration(&config_tree); /* Slllluuuuuuurrrrp! */