Make broadcast addresses configurable.
[tinc] / src / net_setup.c
index 7c9f23a..0f8d31a 100644 (file)
@@ -46,6 +46,7 @@
 char *myport;
 static io_t device_io;
 devops_t devops;
+bool device_standby = false;
 
 char *proxyhost;
 char *proxyport;
@@ -416,7 +417,7 @@ char *get_name(void) {
                                return false;
                        }
                        if(gethostname(hostname, sizeof hostname) || !*hostname) {
-                               logger(DEBUG_ALWAYS, LOG_ERR, "Could not get hostname: %s\n", strerror(errno));
+                               logger(DEBUG_ALWAYS, LOG_ERR, "Could not get hostname: %s\n", sockstrerror(sockerrno));
                                return false;
                        }
                        hostname[31] = 0;
@@ -531,16 +532,6 @@ bool setup_myself_reloadable(void) {
        get_config_bool(lookup_config(config_tree, "DirectOnly"), &directonly);
        get_config_bool(lookup_config(config_tree, "LocalDiscovery"), &localdiscovery);
 
-       memset(&localdiscovery_address, 0, sizeof localdiscovery_address);
-       if(get_config_string(lookup_config(config_tree, "LocalDiscoveryAddress"), &address)) {
-               struct addrinfo *ai = str2addrinfo(address, myport, SOCK_DGRAM);
-               free(address);
-               if(!ai)
-                       return false;
-               memcpy(&localdiscovery_address, ai->ai_addr, ai->ai_addrlen);
-       }
-
-
        if(get_config_string(lookup_config(config_tree, "Mode"), &rmode)) {
                if(!strcasecmp(rmode, "router"))
                        routing_mode = RMODE_ROUTER;
@@ -595,6 +586,20 @@ bool setup_myself_reloadable(void) {
                free(bmode);
        }
 
+       const char* const DEFAULT_BROADCAST_SUBNETS[] = { "ff:ff:ff:ff:ff:ff", "255.255.255.255", "ff00::/8" };
+       for (size_t i = 0; i < sizeof(DEFAULT_BROADCAST_SUBNETS) / sizeof(*DEFAULT_BROADCAST_SUBNETS); i++) {
+               subnet_t *s = new_subnet();
+               if (!str2net(s, DEFAULT_BROADCAST_SUBNETS[i]))
+                       abort();
+               subnet_add(NULL, s);
+       }
+       for (config_t* cfg = lookup_config(config_tree, "BroadcastSubnet"); cfg; cfg = lookup_config_next(config_tree, cfg)) {
+               subnet_t *s;
+               if (!get_config_subnet(cfg, &s))
+                       continue;
+               subnet_add(NULL, s);
+       }
+
 #if !defined(SOL_IP) || !defined(IP_TOS)
        if(priorityinheritance)
                logger(DEBUG_ALWAYS, LOG_WARNING, "%s not supported on this platform", "PriorityInheritance");
@@ -726,6 +731,40 @@ static bool add_listen_address(char *address, bool bindto) {
        return true;
 }
 
+void device_enable(void) {
+       if (devops.enable)
+               devops.enable();
+
+       /* 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]);
+}
+
+void device_disable(void) {
+       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-down", envp);
+
+       for(int i = 0; i < 4; i++)
+               free(envp[i]);
+
+       if (devops.disable)
+               devops.disable();
+}
+
 /*
   Configure node_t myself and set up the local sockets (listen only)
 */
@@ -918,6 +957,8 @@ static bool setup_myself(void) {
 #endif
        }
 
+       get_config_bool(lookup_config(config_tree, "DeviceStandby"), &device_standby);
+
        if(!devops.setup())
                return false;
 
@@ -943,7 +984,7 @@ static bool setup_myself(void) {
                for(int 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));
+                               logger(DEBUG_ALWAYS, LOG_ERR, "Could not get address of listen fd %d: %s", i + 3, sockstrerror(sockerrno));
                                return false;
                        }
 
@@ -1048,18 +1089,8 @@ bool setup_network(void) {
        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]);
+       if (!device_standby)
+               device_enable();
 
        /* Run subnet-up scripts for our own subnets */
 
@@ -1098,25 +1129,19 @@ void close_network_connections(void) {
                close(listen_socket[i].udp.fd);
        }
 
-       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);
-
        exit_requests();
        exit_edges();
        exit_subnets();
        exit_nodes();
        exit_connections();
 
-       execute_script("tinc-down", envp);
+       if (!device_standby)
+               device_disable();
 
        if(myport) free(myport);
 
-       for(int i = 0; i < 4; i++)
-               free(envp[i]);
-
+       if (device_fd >= 0)
+               io_del(&device_io);
        devops.close();
 
        exit_control();