.Va Device .
The info pages of the tinc package contain more information
about configuring the virtual network device.
+.It Va DeviceStandby Li = yes | no Po no Pc
+When disabled,
+.Nm tinc
+calls tinc-up on startup, and tinc-down on shutdown. When enabled,
+.Nm tinc
+will only call tinc-up when at least one node is reachable, and will call tinc-down as soon as no nodes are reachable.
.It Va DeviceType Li = Ar type Pq platform dependent
The type of the virtual network device.
Tinc will normally automatically select the right type of tun/tap interface, and this option should not be used.
.Bl -tag -width indent
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-up
This is the most important script.
-If it is present it will be executed right after the tinc daemon has been started and has connected to the virtual network device.
+If it is present it will be executed right after the tinc daemon has been started and has connected to the virtual network device (or when the first node becomes reachable if
+.Va DeviceStandby
+is used).
It should be used to set up the corresponding network interface,
but can also be used to start other things.
Under Windows you can use the Network Connections control panel instead of creating this script.
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-down
-This script is started right before the tinc daemon quits.
+This script is started right before the tinc daemon quits (or when the last node becomes unreachable if
+.Va DeviceStandby
+is used).
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/ Ns Ar HOST Ns Pa -up
This script is started when the tinc daemon with name
.Ar HOST
static void check_reachability(void) {
/* Check reachability status. */
+ int reachable_count = 0;
+ int became_reachable_count = 0;
+ int became_unreachable_count = 0;
for splay_each(node_t, n, node_tree) {
if(n->status.visited != n->status.reachable) {
n->status.reachable = !n->status.reachable;
if(n->status.reachable) {
logger(DEBUG_TRAFFIC, LOG_DEBUG, "Node %s (%s) became reachable",
n->name, n->hostname);
+ if (n != myself)
+ became_reachable_count++;
} else {
logger(DEBUG_TRAFFIC, LOG_DEBUG, "Node %s (%s) became unreachable",
n->name, n->hostname);
+ if (n != myself)
+ became_unreachable_count++;
}
if(experimental && OPTION_VERSION(n->options) >= 2)
}
}
}
+
+ if(n->status.reachable && n != myself)
+ reachable_count++;
+ }
+
+ if (device_standby) {
+ if (reachable_count == 0 && became_unreachable_count > 0)
+ device_disable();
+ else if (reachable_count == became_reachable_count)
+ device_enable();
}
}
extern int max_connection_burst;
extern bool do_prune;
extern char *myport;
+extern bool device_standby;
extern bool autoconnect;
extern bool disablebuggypeers;
extern int contradicting_add_edge;
extern void receive_tcppacket(struct connection_t *, const char *, int);
extern void broadcast_packet(const struct node_t *, vpn_packet_t *);
extern char *get_name(void);
+extern void device_enable(void);
+extern void device_disable(void);
extern bool setup_myself_reloadable(void);
extern bool setup_network(void);
extern void setup_outgoing_connection(struct outgoing_t *);
char *myport;
static io_t device_io;
devops_t devops;
+bool device_standby = false;
char *proxyhost;
char *proxyport;
return true;
}
+void device_enable(void) {
+ /* 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]);
+}
+
/*
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;
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();