char *myport;
static io_t device_io;
devops_t devops;
+bool device_standby = false;
char *proxyhost;
char *proxyport;
char *proxyuser;
char *proxypass;
proxytype_t proxytype;
-int autoconnect;
+bool autoconnect;
bool disablebuggypeers;
char *scriptinterpreter;
if(!read_host_config(config_tree, n->name))
goto exit;
- /* First, check for simple ECDSAPublicKey statement */
+ /* First, check for simple Ed25519PublicKey statement */
- if(get_config_string(lookup_config(config_tree, "ECDSAPublicKey"), &p)) {
+ if(get_config_string(lookup_config(config_tree, "Ed25519PublicKey"), &p)) {
n->ecdsa = ecdsa_set_base64_public_key(p);
free(p);
goto exit;
}
- /* Else, check for ECDSAPublicKeyFile statement and read it */
+ /* Else, check for Ed25519PublicKeyFile statement and read it */
- if(!get_config_string(lookup_config(config_tree, "ECDSAPublicKeyFile"), &pubname))
+ if(!get_config_string(lookup_config(config_tree, "Ed25519PublicKeyFile"), &pubname))
xasprintf(&pubname, "%s" SLASH "hosts" SLASH "%s", confbase, n->name);
fp = fopen(pubname, "r");
return false;
}
- /* First, check for simple ECDSAPublicKey statement */
+ /* First, check for simple Ed25519PublicKey statement */
- if(get_config_string(lookup_config(c->config_tree, "ECDSAPublicKey"), &p)) {
+ if(get_config_string(lookup_config(c->config_tree, "Ed25519PublicKey"), &p)) {
c->ecdsa = ecdsa_set_base64_public_key(p);
free(p);
return c->ecdsa;
}
- /* Else, check for ECDSAPublicKeyFile statement and read it */
+ /* Else, check for Ed25519PublicKeyFile statement and read it */
- if(!get_config_string(lookup_config(c->config_tree, "ECDSAPublicKeyFile"), &fname))
+ if(!get_config_string(lookup_config(c->config_tree, "Ed25519PublicKeyFile"), &fname))
xasprintf(&fname, "%s" SLASH "hosts" SLASH "%s", confbase, c->name);
fp = fopen(fname, "r");
if(!fp) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Error reading ECDSA public key file `%s': %s",
+ logger(DEBUG_ALWAYS, LOG_ERR, "Error reading Ed25519 public key file `%s': %s",
fname, strerror(errno));
free(fname);
return false;
fclose(fp);
if(!c->ecdsa)
- logger(DEBUG_ALWAYS, LOG_ERR, "Parsing ECDSA public key file `%s' failed.", fname);
+ logger(DEBUG_ALWAYS, LOG_ERR, "Parsing Ed25519 public key file `%s' failed.", fname);
free(fname);
return c->ecdsa;
}
/* Check for PrivateKeyFile statement and read it */
- if(!get_config_string(lookup_config(config_tree, "ECDSAPrivateKeyFile"), &fname))
- xasprintf(&fname, "%s" SLASH "ecdsa_key.priv", confbase);
+ if(!get_config_string(lookup_config(config_tree, "Ed25519PrivateKeyFile"), &fname))
+ xasprintf(&fname, "%s" SLASH "ed25519_key.priv", confbase);
fp = fopen(fname, "r");
if(!fp) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Error reading ECDSA private key file `%s': %s", fname, strerror(errno));
+ logger(DEBUG_ALWAYS, LOG_ERR, "Error reading Ed25519 private key file `%s': %s", fname, strerror(errno));
if(errno == ENOENT)
- logger(DEBUG_ALWAYS, LOG_INFO, "Create an ECDSA keypair with `tinc -n %s generate-ecdsa-keys'.", netname ?: ".");
+ logger(DEBUG_ALWAYS, LOG_INFO, "Create an Ed25519 keypair with `tinc -n %s generate-ed25519-keys'.", netname ?: ".");
free(fname);
return false;
}
struct stat s;
if(fstat(fileno(fp), &s)) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Could not stat ECDSA private key file `%s': %s'", fname, strerror(errno));
+ logger(DEBUG_ALWAYS, LOG_ERR, "Could not stat Ed25519 private key file `%s': %s'", fname, strerror(errno));
free(fname);
return false;
}
if(s.st_mode & ~0100700)
- logger(DEBUG_ALWAYS, LOG_WARNING, "Warning: insecure file permissions for ECDSA private key file `%s'!", fname);
+ logger(DEBUG_ALWAYS, LOG_WARNING, "Warning: insecure file permissions for Ed25519 private key file `%s'!", fname);
#endif
myself->connection->ecdsa = ecdsa_read_pem_private_key(fp);
fclose(fp);
if(!myself->connection->ecdsa)
- logger(DEBUG_ALWAYS, LOG_ERR, "Reading ECDSA private key file `%s' failed: %s", fname, strerror(errno));
+ logger(DEBUG_ALWAYS, LOG_ERR, "Reading Ed25519 private key file `%s' failed", fname);
free(fname);
return myself->connection->ecdsa;
}
invitation_key = NULL;
}
- xasprintf(&fname, "%s" SLASH "invitations" SLASH "ecdsa_key.priv", confbase);
+ xasprintf(&fname, "%s" SLASH "invitations" SLASH "ed25519_key.priv", confbase);
fp = fopen(fname, "r");
invitation_key = ecdsa_read_pem_private_key(fp);
fclose(fp);
if(!invitation_key)
- logger(DEBUG_ALWAYS, LOG_ERR, "Reading ECDSA private key file `%s' failed: %s", fname, strerror(errno));
+ logger(DEBUG_ALWAYS, LOG_ERR, "Reading Ed25519 private key file `%s' failed", fname);
}
free(fname);
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;
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;
free(bmode);
}
+ const char* const DEFAULT_BROADCAST_SUBNETS[] = { "ff:ff:ff:ff:ff:ff", "255.255.255.255", "224.0.0.0/4", "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");
if(!get_config_int(lookup_config(config_tree, "KeyExpire"), &keylifetime))
keylifetime = 3600;
- get_config_int(lookup_config(config_tree, "AutoConnect"), &autoconnect);
- if(autoconnect < 0)
- autoconnect = 0;
+ config_t *cfg = lookup_config(config_tree, "AutoConnect");
+ if(cfg) {
+ if(!get_config_bool(cfg, &autoconnect)) {
+ // Some backwards compatibility with when this option was an int
+ int val = 0;
+ get_config_int(cfg, &val);
+ autoconnect = val;
+ }
+ }
get_config_bool(lookup_config(config_tree, "DisableBuggyPeers"), &disablebuggypeers);
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)
*/
#endif
}
+ get_config_bool(lookup_config(config_tree, "DeviceStandby"), &device_standby);
+
if(!devops.setup())
return false;
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;
}
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 */
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();