diff --git a/doc/tinc.texi b/doc/tinc.texi index f386b835..b489042d 100644 --- a/doc/tinc.texi +++ b/doc/tinc.texi @@ -15,7 +15,7 @@ This is the info manual for @value{PACKAGE} version @value{VERSION}, a Virtual Private Network daemon. -Copyright @copyright{} 1998-2014 Ivo Timmermans, +Copyright @copyright{} 1998-2015 Ivo Timmermans, Guus Sliepen and Wessel Dankers . @@ -43,7 +43,7 @@ permission notice identical to this one. @vskip 0pt plus 1filll This is the info manual for @value{PACKAGE} version @value{VERSION}, a Virtual Private Network daemon. -Copyright @copyright{} 1998-2014 Ivo Timmermans, +Copyright @copyright{} 1998-2015 Ivo Timmermans, Guus Sliepen and Wessel Dankers . diff --git a/src/invitation.c b/src/invitation.c index ed2df88a..415c2377 100644 --- a/src/invitation.c +++ b/src/invitation.c @@ -84,7 +84,7 @@ char *get_my_hostname() { char *port = NULL; char *hostport = NULL; char *name = get_my_name(false); - char filename[PATH_MAX]; + char filename[PATH_MAX] = {0}; // Use first Address statement in own host config file if(check_id(name)) { @@ -182,7 +182,7 @@ again: hostname = xstrdup(line); save: - if(filename) { + if(*filename) { FILE *f = fopen(filename, "a"); if(f) { fprintf(f, "\nAddress = %s\n", hostname); diff --git a/src/logger.c b/src/logger.c index 2defb239..ad7cef28 100644 --- a/src/logger.c +++ b/src/logger.c @@ -26,6 +26,7 @@ #include "logger.h" #include "connection.h" #include "control_common.h" +#include "process.h" #include "sptps.h" debug_t debug_level = DEBUG_NOTHING; @@ -37,7 +38,7 @@ static HANDLE loghandle = NULL; #endif static const char *logident = NULL; bool logcontrol = false; - +int umbilical = 0; static void real_logger(int level, int priority, const char *message) { char timestr[32] = ""; @@ -79,6 +80,11 @@ static void real_logger(int level, int priority, const char *message) { case LOGMODE_NULL: break; } + + if(umbilical && do_detach) { + write(umbilical, message, strlen(message)); + write(umbilical, "\n", 1); + } } if(logcontrol) { diff --git a/src/logger.h b/src/logger.h index 8f690290..252497bf 100644 --- a/src/logger.h +++ b/src/logger.h @@ -69,6 +69,7 @@ enum { extern debug_t debug_level; extern bool logcontrol; +extern int umbilical; extern void openlogger(const char *, logmode_t); extern void reopenlogger(void); extern void logger(int, int, const char *, ...) __attribute__ ((__format__(printf, 3, 4))); diff --git a/src/net_packet.c b/src/net_packet.c index e3b9d398..d8e9e47f 100644 --- a/src/net_packet.c +++ b/src/net_packet.c @@ -1196,7 +1196,7 @@ static void try_tx_sptps(node_t *n, bool mtu) { if(via != n) { if((via->options >> 24) < 4) return; - return try_tx_sptps(via, mtu); + return try_tx(via, mtu); } /* Otherwise, try to establish UDP connectivity. */ @@ -1209,7 +1209,7 @@ static void try_tx_sptps(node_t *n, bool mtu) { while we try to establish direct connectivity. */ if(!n->status.udp_confirmed && n != n->nexthop && (n->nexthop->options >> 24) >= 4) - try_tx_sptps(n->nexthop, mtu); + try_tx(n->nexthop, mtu); } static void try_tx_legacy(node_t *n, bool mtu) { @@ -1234,6 +1234,8 @@ static void try_tx_legacy(node_t *n, bool mtu) { } void try_tx(node_t *n, bool mtu) { + if(!n->status.reachable) + return; if(n->status.sptps) try_tx_sptps(n, mtu); else @@ -1270,7 +1272,7 @@ void send_packet(node_t *n, vpn_packet_t *packet) { if(n->status.sptps) { send_sptps_packet(n, packet); - try_tx_sptps(n, true); + try_tx(n, true); return; } @@ -1290,7 +1292,7 @@ void send_packet(node_t *n, vpn_packet_t *packet) { } send_udppacket(via, packet); - try_tx_legacy(via, true); + try_tx(via, true); } void broadcast_packet(const node_t *from, vpn_packet_t *packet) { @@ -1473,7 +1475,7 @@ skip_harder: if(to != myself) { send_sptps_data(to, from, 0, DATA(&pkt), pkt.len); - try_tx_sptps(to, true); + try_tx(to, true); return; } } else { diff --git a/src/net_socket.c b/src/net_socket.c index adea5454..8acd4b45 100644 --- a/src/net_socket.c +++ b/src/net_socket.c @@ -800,6 +800,11 @@ void try_outgoing_connections(void) { continue; } + if(!strcmp(name, myself->name)) { + free(name); + continue; + } + bool found = false; for list_each(outgoing_t, outgoing, outgoing_list) { diff --git a/src/sptps_speed.c b/src/sptps_speed.c index ab41e8d5..d03246c5 100644 --- a/src/sptps_speed.c +++ b/src/sptps_speed.c @@ -33,6 +33,7 @@ bool send_request(void *c, const char *msg, ...) { return false; } struct list_t *connection_list = NULL; bool send_meta(void *c, const char *msg , int len) { return false; } char *logfilename = NULL; +bool do_detach = false; struct timeval now; static bool send_data(void *handle, uint8_t type, const void *data, size_t len) { diff --git a/src/sptps_test.c b/src/sptps_test.c index 38c2c08e..f83307fe 100644 --- a/src/sptps_test.c +++ b/src/sptps_test.c @@ -35,6 +35,7 @@ bool send_request(void *c, const char *msg, ...) { return false; } struct list_t *connection_list = NULL; bool send_meta(void *c, const char *msg , int len) { return false; } char *logfilename = NULL; +bool do_detach = false; struct timeval now; static bool verbose; diff --git a/src/tincctl.c b/src/tincctl.c index 94f9e176..ed1f6acb 100644 --- a/src/tincctl.c +++ b/src/tincctl.c @@ -89,7 +89,7 @@ static struct option const long_options[] = { static void version(void) { printf("%s version %s (built %s %s, protocol %d.%d)\n", PACKAGE, BUILD_VERSION, BUILD_DATE, BUILD_TIME, PROT_MAJOR, PROT_MINOR); - printf("Copyright (C) 1998-2014 Ivo Timmermans, Guus Sliepen and others.\n" + printf("Copyright (C) 1998-2015 Ivo Timmermans, Guus Sliepen and others.\n" "See the AUTHORS file for a complete list.\n\n" "tinc comes with ABSOLUTELY NO WARRANTY. This is free software,\n" "and you are welcome to redistribute it under certain conditions;\n" @@ -853,6 +853,13 @@ static int cmd_start(int argc, char *argv[]) { } return status; #else + int pfd[2] = {-1, -1}; + if(socketpair(AF_UNIX, SOCK_STREAM, 0, pfd)) { + fprintf(stderr, "Could not create umbilical socket: %s\n", strerror(errno)); + free(nargv); + return 1; + } + pid_t pid = fork(); if(pid == -1) { fprintf(stderr, "Could not fork: %s\n", strerror(errno)); @@ -860,8 +867,15 @@ static int cmd_start(int argc, char *argv[]) { return 1; } - if(!pid) + if(!pid) { + close(pfd[0]); + char buf[100] = ""; + snprintf(buf, sizeof buf, "%d", pfd[1]); + setenv("TINC_UMBILICAL", buf, true); exit(execvp(c, nargv)); + } else { + close(pfd[1]); + } free(nargv); @@ -869,12 +883,33 @@ static int cmd_start(int argc, char *argv[]) { #ifdef SIGINT signal(SIGINT, SIG_IGN); #endif + + // Pass all log messages from the umbilical to stderr. + // A nul-byte right before closure means tincd started succesfully. + bool failure = true; + char buf[1024]; + ssize_t len; + + while((len = read(pfd[0], buf, sizeof buf)) > 0) { + failure = buf[len - 1]; + if(!failure) + len--; + write(2, buf, len); + } + + if(len) + failure = true; + + close(pfd[0]); + + // Make sure the child process is really gone. result = waitpid(pid, &status, 0); + #ifdef SIGINT signal(SIGINT, SIG_DFL); #endif - if(result != pid || !WIFEXITED(status) || WEXITSTATUS(status)) { + if(failure || result != pid || !WIFEXITED(status) || WEXITSTATUS(status)) { fprintf(stderr, "Error starting %s\n", c); return 1; } diff --git a/src/tincd.c b/src/tincd.c index fb2a1557..eb03165f 100644 --- a/src/tincd.c +++ b/src/tincd.c @@ -344,7 +344,7 @@ int main(int argc, char **argv) { if(show_version) { printf("%s version %s (built %s %s, protocol %d.%d)\n", PACKAGE, BUILD_VERSION, BUILD_DATE, BUILD_TIME, PROT_MAJOR, PROT_MINOR); - printf("Copyright (C) 1998-2014 Ivo Timmermans, Guus Sliepen and others.\n" + printf("Copyright (C) 1998-2015 Ivo Timmermans, Guus Sliepen and others.\n" "See the AUTHORS file for a complete list.\n\n" "tinc comes with ABSOLUTELY NO WARRANTY. This is free software,\n" "and you are welcome to redistribute it under certain conditions;\n" @@ -363,6 +363,18 @@ int main(int argc, char **argv) { logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "WSAStartup", winerror(GetLastError())); return 1; } +#else + // Check if we got an umbilical fd from the process that started us + char *umbstr = getenv("TINC_UMBILICAL"); + if(umbstr) { + umbilical = atoi(umbstr); + if(fcntl(umbilical, F_GETFL) < 0) + umbilical = 0; +#ifdef FD_CLOEXEC + if(umbilical) + fcntl(umbilical, F_SETFD, FD_CLOEXEC); +#endif + } #endif openlogger("tinc", use_logfile?LOGMODE_FILE:LOGMODE_STDERR); @@ -466,6 +478,12 @@ int main2(int argc, char **argv) { logger(DEBUG_ALWAYS, LOG_NOTICE, "Ready"); + if(umbilical) { // snip! + write(umbilical, "", 1); + close(umbilical); + umbilical = 0; + } + try_outgoing_connections(); status = main_loop();