If no Port is specified, set myport to actual port of first listening socket.
[tinc] / src / net_setup.c
index ee8296c..0085598 100644 (file)
@@ -38,6 +38,7 @@
 #include "protocol.h"
 #include "route.h"
 #include "rsa.h"
+#include "script.h"
 #include "subnet.h"
 #include "utils.h"
 #include "xalloc.h"
@@ -410,17 +411,18 @@ char *get_name(void) {
 
        if(*name == '$') {
                char *envname = getenv(name + 1);
+               char hostname[32] = "";
                if(!envname) {
                        if(strcmp(name + 1, "HOST")) {
                                logger(DEBUG_ALWAYS, LOG_ERR, "Invalid Name: environment variable %s does not exist\n", name + 1);
                                return false;
                        }
-                       char envname[32];
-                       if(gethostname(envname, 32)) {
+                       if(gethostname(hostname, sizeof hostname) || !*hostname) {
                                logger(DEBUG_ALWAYS, LOG_ERR, "Could not get hostname: %s\n", strerror(errno));
                                return false;
                        }
-                       envname[31] = 0;
+                       hostname[31] = 0;
+                       envname = hostname;
                }
                free(name);
                name = xstrdup(envname);
@@ -455,11 +457,7 @@ bool setup_myself_reloadable(void) {
 
        free(scriptextension);
        if(!get_config_string(lookup_config(config_tree, "ScriptsExtension"), &scriptextension))
-#ifdef HAVE_MINGW
-               scriptextension = xstrdup(".bat");
-#else
                scriptextension = xstrdup("");
-#endif
 
        get_config_string(lookup_config(config_tree, "Proxy"), &proxy);
        if(proxy) {
@@ -635,6 +633,8 @@ bool setup_myself_reloadable(void) {
                keylifetime = 3600;
 
        get_config_int(lookup_config(config_tree, "AutoConnect"), &autoconnect);
+       if(autoconnect < 0)
+               autoconnect = 0;
 
        get_config_bool(lookup_config(config_tree, "DisableBuggyPeers"), &disablebuggypeers);
 
@@ -649,6 +649,7 @@ bool setup_myself_reloadable(void) {
 static bool setup_myself(void) {
        char *name, *hostname, *cipher, *digest, *type;
        char *address = NULL;
+       bool port_specified = false;
 
        if(!(name = get_name())) {
                logger(DEBUG_ALWAYS, LOG_ERR, "Name for tinc daemon required!");
@@ -663,9 +664,8 @@ static bool setup_myself(void) {
 
        if(!get_config_string(lookup_config(config_tree, "Port"), &myport))
                myport = xstrdup("655");
-
-       xasprintf(&myself->hostname, "MYSELF port %s", myport);
-       myself->connection->hostname = xstrdup(myself->hostname);
+       else
+               port_specified = true;
 
        myself->connection->options = 0;
        myself->connection->protocol_major = PROT_MAJOR;
@@ -681,6 +681,8 @@ static bool setup_myself(void) {
        if(!read_rsa_private_key())
                return false;
 
+       /* Ensure myport is numeric */
+
        if(!atoi(myport)) {
                struct addrinfo *ai = str2addrinfo("localhost", myport, SOCK_DGRAM);
                sockaddr_t sa;
@@ -711,7 +713,12 @@ static bool setup_myself(void) {
        get_config_bool(lookup_config(config_tree, "TunnelServer"), &tunnelserver);
        strictsubnets |= tunnelserver;
 
-
+       if(get_config_int(lookup_config(config_tree, "MaxConnectionBurst"), &max_connection_burst)) {
+               if(max_connection_burst <= 0) {
+                       logger(DEBUG_ALWAYS, LOG_ERR, "MaxConnectionBurst cannot be negative!");
+                       return false;
+               }
+       }
 
        if(get_config_int(lookup_config(config_tree, "UDPRcvBuf"), &udp_rcvbuf)) {
                if(udp_rcvbuf <= 0) {
@@ -742,14 +749,15 @@ static bool setup_myself(void) {
        if(!get_config_string(lookup_config(config_tree, "Cipher"), &cipher))
                cipher = xstrdup("blowfish");
 
-       if(!(myself->incipher = cipher_open_by_name(cipher))) {
+       if(!strcasecmp(cipher, "none")) {
+               myself->incipher = NULL;
+       } else if(!(myself->incipher = cipher_open_by_name(cipher))) {
                logger(DEBUG_ALWAYS, LOG_ERR, "Unrecognized cipher type!");
                return false;
        }
 
        free(cipher);
 
-       send_key_changed();
        timeout_add(&keyexpire_timeout, keyexpire_handler, &keyexpire_timeout, &(struct timeval){keylifetime, rand() % 100000});
 
        /* Check if we want to use message authentication codes... */
@@ -765,7 +773,9 @@ static bool setup_myself(void) {
        if(!get_config_string(lookup_config(config_tree, "Digest"), &digest))
                digest = xstrdup("sha1");
 
-       if(!(myself->indigest = digest_open_by_name(digest, maclength))) {
+       if(!strcasecmp(digest, "none")) {
+               myself->indigest = NULL;
+       } else if(!(myself->indigest = digest_open_by_name(digest, maclength))) {
                logger(DEBUG_ALWAYS, LOG_ERR, "Unrecognized digest type!");
                return false;
        }
@@ -827,56 +837,8 @@ static bool setup_myself(void) {
        if(device_fd >= 0)
                io_add(&device_io, handle_device_data, NULL, device_fd, IO_READ);
 
-       /* Run tinc-up script to further initialize the tap interface */
-       char *envp[5];
-       xasprintf(&envp[0], "NETNAME=%s", netname ? : "");
-       xasprintf(&envp[1], "DEVICE=%s", device ? : "");
-       xasprintf(&envp[2], "INTERFACE=%s", iface ? : "");
-       xasprintf(&envp[3], "NAME=%s", myself->name);
-       envp[4] = NULL;
-
-       execute_script("tinc-up", envp);
-
-       for(int i = 0; i < 4; i++)
-               free(envp[i]);
-
-       /* Run subnet-up scripts for our own subnets */
-
-       subnet_update(myself, NULL, true);
-
        /* Open sockets */
 
-#ifndef HAVE_MINGW
-       int unix_fd = socket(AF_UNIX, SOCK_STREAM, 0);
-       if(unix_fd < 0) {
-               logger(DEBUG_ALWAYS, LOG_ERR, "Could not create UNIX socket: %s", sockstrerror(errno));
-               return false;
-       }
-
-       struct sockaddr_un sa;
-       sa.sun_family = AF_UNIX;
-       strncpy(sa.sun_path, unixsocketname, sizeof sa.sun_path);
-
-       if(connect(unix_fd, (struct sockaddr *)&sa, sizeof sa) >= 0) {
-               logger(DEBUG_ALWAYS, LOG_ERR, "UNIX socket %s is still in use!", unixsocketname);
-               return false;
-       }
-
-       unlink(unixsocketname);
-
-       if(bind(unix_fd, (struct sockaddr *)&sa, sizeof sa) < 0) {
-               logger(DEBUG_ALWAYS, LOG_ERR, "Could not bind UNIX socket to %s: %s", unixsocketname, sockstrerror(errno));
-               return false;
-       }
-
-       if(listen(unix_fd, 3) < 0) {
-               logger(DEBUG_ALWAYS, LOG_ERR, "Could not listen on UNIX socket %s: %s", unixsocketname, sockstrerror(errno));
-               return false;
-       }
-
-       io_add(&unix_socket, handle_new_unix_connection, &unix_socket, unix_fd, IO_READ);
-#endif
-
        if(!do_detach && getenv("LISTEN_FDS")) {
                sockaddr_t sa;
                socklen_t salen;
@@ -988,13 +950,29 @@ static bool setup_myself(void) {
                } while(cfg);
        }
 
-       if(listen_sockets)
-               logger(DEBUG_ALWAYS, LOG_NOTICE, "Ready");
-       else {
+       if(!listen_sockets) {
                logger(DEBUG_ALWAYS, LOG_ERR, "Unable to create any listening socket!");
                return false;
        }
 
+       /* If no Port option was specified, set myport to the port used by the first listening socket. */
+
+       if(!port_specified) {
+               sockaddr_t sa;
+               socklen_t salen = sizeof sa;
+               if(!getsockname(listen_socket[0].udp.fd, &sa.sa, &salen)) {
+                       free(myport);
+                       sockaddr2str(&sa, NULL, &myport);
+                       if(!myport)
+                               myport = xstrdup("655");
+               }
+       }
+
+       xasprintf(&myself->hostname, "MYSELF port %s", myport);
+       myself->connection->hostname = xstrdup(myself->hostname);
+
+       /* Done. */
+
        last_config_check = now.tv_sec;
 
        return true;
@@ -1028,6 +1006,26 @@ bool setup_network(void) {
        if(!setup_myself())
                return false;
 
+       if(!init_control())
+               return false;
+
+       /* Run tinc-up script to further initialize the tap interface */
+
+       char *envp[5] = {NULL};
+       xasprintf(&envp[0], "NETNAME=%s", netname ? : "");
+       xasprintf(&envp[1], "DEVICE=%s", device ? : "");
+       xasprintf(&envp[2], "INTERFACE=%s", iface ? : "");
+       xasprintf(&envp[3], "NAME=%s", myself->name);
+
+       execute_script("tinc-up", envp);
+
+       for(int i = 0; i < 4; i++)
+               free(envp[i]);
+
+       /* Run subnet-up scripts for our own subnets */
+
+       subnet_update(myself, NULL, true);
+
        return true;
 }
 
@@ -1060,17 +1058,11 @@ void close_network_connections(void) {
                close(listen_socket[i].udp.fd);
        }
 
-#ifndef HAVE_MINGW
-       io_del(&unix_socket);
-       close(unix_socket.fd);
-#endif
-
-       char *envp[5];
+       char *envp[5] = {NULL};
        xasprintf(&envp[0], "NETNAME=%s", netname ? : "");
        xasprintf(&envp[1], "DEVICE=%s", device ? : "");
        xasprintf(&envp[2], "INTERFACE=%s", iface ? : "");
        xasprintf(&envp[3], "NAME=%s", myself->name);
-       envp[4] = NULL;
 
        exit_requests();
        exit_edges();
@@ -1087,5 +1079,7 @@ void close_network_connections(void) {
 
        devops.close();
 
+       exit_control();
+
        return;
 }