Preload all Subnets in TunnelServer mode.
[tinc] / src / net_setup.c
index 2b177c1..cad84cc 100644 (file)
@@ -1,7 +1,8 @@
 /*
     net_setup.c -- Setup.
     Copyright (C) 1998-2005 Ivo Timmermans,
-                  2000-2009 Guus Sliepen <guus@tinc-vpn.org>
+                  2000-2010 Guus Sliepen <guus@tinc-vpn.org>
+                  2006      Scott Lamb <slamb@slamb.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -200,6 +201,65 @@ bool read_rsa_private_key(void) {
        return true;
 }
 
+/*
+  Read Subnets from all host config files
+*/
+static void load_all_subnets(void) {
+       DIR *dir;
+       struct dirent *ent;
+       char *dname;
+       char *fname;
+       avl_tree_t *config_tree;
+       config_t *cfg;
+       subnet_t *s;
+       node_t *n;
+       bool result;
+
+       xasprintf(&dname, "%s/hosts", confbase);
+       dir = opendir(dname);
+       if(!dir) {
+               logger(LOG_ERR, "Could not open %s: %s", dname, strerror(errno));
+               free(dname);
+               return;
+       }
+
+       while((ent = readdir(dir))) {
+               if(!check_id(ent->d_name))
+                       continue;
+
+               n = lookup_node(ent->d_name);
+               if(n)
+                       continue;
+
+               #ifdef _DIRENT_HAVE_D_TYPE
+               //if(ent->d_type != DT_REG)
+               //      continue;
+               #endif
+
+               xasprintf(&fname, "%s/hosts/%s", confbase, ent->d_name);
+               init_configuration(&config_tree);
+               result = read_config_file(config_tree, fname);
+               free(fname);
+               if(!result)
+                       continue;
+
+               n = new_node();
+               n->name = xstrdup(ent->d_name);
+               node_add(n);
+
+               for(cfg = lookup_config(config_tree, "Subnet"); cfg; cfg = lookup_config_next(config_tree, cfg)) {
+                       if(!get_config_subnet(cfg, &s))
+                               continue;
+
+                       subnet_add(n, s);
+               }
+
+               exit_configuration(&config_tree);
+       }
+
+       closedir(dir);
+}
+
 /*
   Configure node_t myself and set up the local sockets (listen only)
 */
@@ -217,8 +277,8 @@ bool setup_myself(void) {
        myself->connection = new_connection();
        init_configuration(&myself->connection->config_tree);
 
-       xasprintf(&myself->hostname, "MYSELF");
-       xasprintf(&myself->connection->hostname, "MYSELF");
+       myself->hostname = xstrdup("MYSELF");
+       myself->connection->hostname = xstrdup("MYSELF");
 
        myself->connection->options = 0;
        myself->connection->protocol_version = PROT_CURRENT;
@@ -245,8 +305,9 @@ bool setup_myself(void) {
        if(!read_rsa_private_key())
                return false;
 
-       if(!get_config_string(lookup_config(myself->connection->config_tree, "Port"), &myport))
-               xasprintf(&myport, "655");
+       if(!get_config_string(lookup_config(config_tree, "Port"), &myport)
+                       && !get_config_string(lookup_config(myself->connection->config_tree, "Port"), &myport))
+               myport = xstrdup("655");
 
        /* Read in all the subnets specified in the host configuration file */
 
@@ -295,13 +356,18 @@ bool setup_myself(void) {
        } else
                routing_mode = RMODE_ROUTER;
 
-       // Enable PMTUDiscovery by default if we are in router mode.
-
-       choice = routing_mode == RMODE_ROUTER;
+       choice = true;
        get_config_bool(lookup_config(myself->connection->config_tree, "PMTUDiscovery"), &choice);
-       if(choice)      
+       get_config_bool(lookup_config(config_tree, "PMTUDiscovery"), &choice);
+       if(choice)
                myself->options |= OPTION_PMTU_DISCOVERY;
 
+       choice = true;
+       get_config_bool(lookup_config(config_tree, "ClampMSS"), &choice);
+       get_config_bool(lookup_config(myself->connection->config_tree, "ClampMSS"), &choice);
+       if(choice)
+               myself->options |= OPTION_CLAMP_MSS;
+
        get_config_bool(lookup_config(config_tree, "PriorityInheritance"), &priorityinheritance);
 
 #if !defined(SOL_IP) || !defined(IP_TOS)
@@ -351,14 +417,14 @@ bool setup_myself(void) {
                        }
                }
        } else
-               myself->incipher = EVP_aes_256_cbc();
+               myself->incipher = EVP_bf_cbc();
 
        if(myself->incipher)
                myself->inkeylength = myself->incipher->key_len + myself->incipher->iv_len;
        else
                myself->inkeylength = 1;
 
-       myself->connection->outcipher = EVP_aes_256_ofb();
+       myself->connection->outcipher = EVP_bf_ofb();
 
        if(!get_config_int(lookup_config(config_tree, "KeyExpire"), &keylifetime))
                keylifetime = 3600;
@@ -379,9 +445,9 @@ bool setup_myself(void) {
                        }
                }
        } else
-               myself->indigest = EVP_sha256();
+               myself->indigest = EVP_sha1();
 
-       myself->connection->outdigest = EVP_sha256();
+       myself->connection->outdigest = EVP_sha1();
 
        if(get_config_int(lookup_config(myself->connection->config_tree, "MACLength"), &myself->inmaclength)) {
                if(myself->indigest) {
@@ -419,6 +485,9 @@ bool setup_myself(void) {
 
        graph();
 
+       if(tunnelserver)
+               load_all_subnets();
+
        /* Open device */
 
        if(!setup_device())
@@ -540,10 +609,17 @@ void close_network_connections(void) {
        for(node = connection_tree->head; node; node = next) {
                next = node->next;
                c = node->data;
-               c->outgoing = false;
+               c->outgoing = NULL;
                terminate_connection(c, false);
        }
 
+       for(list_node_t *node = outgoing_list->head; node; node = node->next) {
+               outgoing_t *outgoing = node->data;
+
+               if(outgoing->event)
+                       event_del(outgoing->event);
+       }
+
        list_delete_list(outgoing_list);
 
        if(myself && myself->connection) {