/*
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
fp = fopen(fname, "r");
if(!fp) {
- logger(LOG_ERR, _("Error reading RSA public key file `%s': %s"),
+ logger(LOG_ERR, "Error reading RSA public key file `%s': %s",
fname, strerror(errno));
free(fname);
return false;
fp = fopen(fname, "r");
if(!fp) {
- logger(LOG_ERR, _("Error reading RSA public key file `%s': %s"),
+ logger(LOG_ERR, "Error reading RSA public key file `%s': %s",
fname, strerror(errno));
free(fname);
return false;
return true;
}
- logger(LOG_ERR, _("Reading RSA public key file `%s' failed: %s"),
+ logger(LOG_ERR, "Reading RSA public key file `%s' failed: %s",
fname, strerror(errno));
return false;
}
if(c->rsa_key)
return true;
- logger(LOG_ERR, _("No public key for %s specified!"), c->name);
+ logger(LOG_ERR, "No public key for %s specified!", c->name);
return false;
}
if(get_config_string(lookup_config(config_tree, "PrivateKey"), &key)) {
if(!get_config_string(lookup_config(myself->connection->config_tree, "PublicKey"), &pubkey)) {
- logger(LOG_ERR, _("PrivateKey used but no PublicKey found!"));
+ logger(LOG_ERR, "PrivateKey used but no PublicKey found!");
return false;
}
myself->connection->rsa_key = RSA_new();
fp = fopen(fname, "r");
if(!fp) {
- logger(LOG_ERR, _("Error reading RSA private key file `%s': %s"),
+ logger(LOG_ERR, "Error reading RSA private key file `%s': %s",
fname, strerror(errno));
free(fname);
return false;
#if !defined(HAVE_MINGW) && !defined(HAVE_CYGWIN)
if(fstat(fileno(fp), &s)) {
- logger(LOG_ERR, _("Could not stat RSA private key file `%s': %s'"),
+ logger(LOG_ERR, "Could not stat RSA private key file `%s': %s'",
fname, strerror(errno));
free(fname);
return false;
}
if(s.st_mode & ~0100700)
- logger(LOG_WARNING, _("Warning: insecure file permissions for RSA private key file `%s'!"), fname);
+ logger(LOG_WARNING, "Warning: insecure file permissions for RSA private key file `%s'!", fname);
#endif
myself->connection->rsa_key = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL);
fclose(fp);
if(!myself->connection->rsa_key) {
- logger(LOG_ERR, _("Reading RSA private key file `%s' failed: %s"),
+ logger(LOG_ERR, "Reading RSA private key file `%s' failed: %s",
fname, strerror(errno));
free(fname);
return false;
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)
*/
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;
if(!get_config_string(lookup_config(config_tree, "Name"), &name)) { /* Not acceptable */
- logger(LOG_ERR, _("Name for tinc daemon required!"));
+ logger(LOG_ERR, "Name for tinc daemon required!");
return false;
}
if(!check_id(name)) {
- logger(LOG_ERR, _("Invalid name for myself!"));
+ logger(LOG_ERR, "Invalid name for myself!");
free(name);
return false;
}
myself->connection->name = xstrdup(name);
if(!read_connection_config(myself->connection)) {
- logger(LOG_ERR, _("Cannot open host configuration file for myself!"));
+ logger(LOG_ERR, "Cannot open host configuration file for myself!");
return false;
}
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 */
if(myself->options & OPTION_TCPONLY)
myself->options |= OPTION_INDIRECT;
+ get_config_bool(lookup_config(config_tree, "DirectOnly"), &directonly);
+ get_config_bool(lookup_config(config_tree, "StrictSubnets"), &strictsubnets);
get_config_bool(lookup_config(config_tree, "TunnelServer"), &tunnelserver);
+ strictsubnets |= tunnelserver;
if(get_config_string(lookup_config(config_tree, "Mode"), &mode)) {
if(!strcasecmp(mode, "router"))
else if(!strcasecmp(mode, "hub"))
routing_mode = RMODE_HUB;
else {
- logger(LOG_ERR, _("Invalid routing mode!"));
+ logger(LOG_ERR, "Invalid routing mode!");
return false;
}
free(mode);
- } else
- routing_mode = RMODE_ROUTER;
+ }
- // Enable PMTUDiscovery by default if we are in router mode.
+ if(get_config_string(lookup_config(config_tree, "Forwarding"), &mode)) {
+ if(!strcasecmp(mode, "off"))
+ forwarding_mode = FMODE_OFF;
+ else if(!strcasecmp(mode, "internal"))
+ forwarding_mode = FMODE_INTERNAL;
+ else if(!strcasecmp(mode, "kernel"))
+ forwarding_mode = FMODE_KERNEL;
+ else {
+ logger(LOG_ERR, "Invalid forwarding mode!");
+ return false;
+ }
+ free(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)
if(priorityinheritance)
- logger(LOG_WARNING, _("%s not supported on this platform"), "PriorityInheritance");
+ logger(LOG_WARNING, "%s not supported on this platform", "PriorityInheritance");
#endif
if(!get_config_int(lookup_config(config_tree, "MACExpire"), &macexpire))
if(get_config_int(lookup_config(config_tree, "MaxTimeout"), &maxtimeout)) {
if(maxtimeout <= 0) {
- logger(LOG_ERR, _("Bogus maximum timeout!"));
+ logger(LOG_ERR, "Bogus maximum timeout!");
return false;
}
} else
else if(!strcasecmp(afname, "any"))
addressfamily = AF_UNSPEC;
else {
- logger(LOG_ERR, _("Invalid address family!"));
+ logger(LOG_ERR, "Invalid address family!");
return false;
}
free(afname);
myself->incipher = EVP_get_cipherbyname(cipher);
if(!myself->incipher) {
- logger(LOG_ERR, _("Unrecognized cipher type!"));
+ logger(LOG_ERR, "Unrecognized cipher type!");
return false;
}
}
} 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;
myself->indigest = EVP_get_digestbyname(digest);
if(!myself->indigest) {
- logger(LOG_ERR, _("Unrecognized digest type!"));
+ logger(LOG_ERR, "Unrecognized digest type!");
return false;
}
}
} 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) {
if(myself->inmaclength > myself->indigest->md_size) {
- logger(LOG_ERR, _("MAC length exceeds size of digest!"));
+ logger(LOG_ERR, "MAC length exceeds size of digest!");
return false;
} else if(myself->inmaclength < 0) {
- logger(LOG_ERR, _("Bogus MAC length!"));
+ logger(LOG_ERR, "Bogus MAC length!");
return false;
}
}
if(get_config_int(lookup_config(myself->connection->config_tree, "Compression"), &myself->incompression)) {
if(myself->incompression < 0 || myself->incompression > 11) {
- logger(LOG_ERR, _("Bogus compression level!"));
+ logger(LOG_ERR, "Bogus compression level!");
return false;
}
} else
graph();
+ if(strictsubnets)
+ load_all_subnets();
+
/* Open device */
if(!setup_device())
err = getaddrinfo(address, myport, &hint, &ai);
if(err || !ai) {
- logger(LOG_ERR, _("System call `%s' failed: %s"), "getaddrinfo",
+ logger(LOG_ERR, "System call `%s' failed: %s", "getaddrinfo",
gai_strerror(err));
return false;
}
ifdebug(CONNECTIONS) {
hostname = sockaddr2hostname((sockaddr_t *) aip->ai_addr);
- logger(LOG_NOTICE, _("Listening on %s"), hostname);
+ logger(LOG_NOTICE, "Listening on %s", hostname);
free(hostname);
}
freeaddrinfo(ai);
if(listen_sockets)
- logger(LOG_NOTICE, _("Ready"));
+ logger(LOG_NOTICE, "Ready");
else {
- logger(LOG_ERR, _("Unable to create any listening socket!"));
+ logger(LOG_ERR, "Unable to create any listening socket!");
return false;
}
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) {