- config_t *cfg;
- subnet_t *subnet;
- char *name, *mode;
- int choice;
-cp
- myself = new_node();
- myself->connection = new_connection();
- init_configuration(&myself->connection->config_tree);
-
- asprintf(&myself->hostname, _("MYSELF"));
- asprintf(&myself->connection->hostname, _("MYSELF"));
-
- myself->connection->options = 0;
- myself->connection->protocol_version = PROT_CURRENT;
-
- if(!get_config_string(lookup_config(config_tree, "Name"), &name)) /* Not acceptable */
- {
- syslog(LOG_ERR, _("Name for tinc daemon required!"));
- return -1;
- }
-
- if(check_id(name))
- {
- syslog(LOG_ERR, _("Invalid name for myself!"));
- free(name);
- return -1;
- }
-
- myself->name = name;
- myself->connection->name = xstrdup(name);
-
-cp
- if(read_rsa_private_key())
- return -1;
-
- if(read_connection_config(myself->connection))
- {
- syslog(LOG_ERR, _("Cannot open host configuration file for myself!"));
- return -1;
- }
-
- if(read_rsa_public_key(myself->connection))
- return -1;
-cp
-
-/*
- if(RSA_check_key(rsa_key) != 1)
- {
- syslog(LOG_ERR, _("Invalid public/private keypair!"));
- return -1;
- }
-*/
- if(!get_config_port(lookup_config(myself->connection->config_tree, "Port"), &myself->port))
- myself->port = 655;
-
- myself->connection->port = myself->port;
-
-/* Read in all the subnets specified in the host configuration file */
-
- cfg = lookup_config(myself->connection->config_tree, "Subnet");
-
- while(cfg)
- {
- if(!get_config_subnet(cfg, &subnet))
- return -1;
-
- subnet_add(myself, subnet);
-
- cfg = lookup_config_next(myself->connection->config_tree, cfg);
- }
-
-cp
- /* Check some options */
-
- if(get_config_bool(lookup_config(config_tree, "IndirectData"), &choice))
- if(choice)
- myself->options |= OPTION_INDIRECT;
-
- if(get_config_bool(lookup_config(config_tree, "TCPOnly"), &choice))
- if(choice)
- myself->options |= OPTION_TCPONLY;
-
- if(get_config_bool(lookup_config(myself->connection->config_tree, "IndirectData"), &choice))
- if(choice)
- myself->options |= OPTION_INDIRECT;
-
- if(get_config_bool(lookup_config(myself->connection->config_tree, "TCPOnly"), &choice))
- if(choice)
- myself->options |= OPTION_TCPONLY;
-
- if(myself->options & OPTION_TCPONLY)
- myself->options |= OPTION_INDIRECT;
-
- if(get_config_string(lookup_config(config_tree, "Mode"), &mode))
- {
- if(!strcasecmp(mode, "router"))
- routing_mode = RMODE_ROUTER;
- else if (!strcasecmp(mode, "switch"))
- routing_mode = RMODE_SWITCH;
- else if (!strcasecmp(mode, "hub"))
- routing_mode = RMODE_HUB;
- else
- {
- syslog(LOG_ERR, _("Invalid routing mode!"));
- return -1;
- }
- }
- else
- routing_mode = RMODE_ROUTER;
-
-cp
- /* Open sockets */
-
- if((tcp_socket = setup_listen_socket(myself->port)) < 0)
- {
- syslog(LOG_ERR, _("Unable to set up a listening TCP socket!"));
- return -1;
- }
-
- if((udp_socket = setup_vpn_in_socket(myself->port)) < 0)
- {
- syslog(LOG_ERR, _("Unable to set up a listening UDP socket!"));
- return -1;
- }
-cp
- /* Generate packet encryption key */
-
- myself->cipher = EVP_bf_cbc();
-
- myself->keylength = myself->cipher->key_len + myself->cipher->iv_len;
-
- myself->key = (char *)xmalloc(myself->keylength);
- RAND_pseudo_bytes(myself->key, myself->keylength);
-
- if(!get_config_int(lookup_config(config_tree, "KeyExpire"), &keylifetime))
- keylifetime = 3600;
-
- keyexpires = time(NULL) + keylifetime;
-cp
- /* Done */
-
- myself->nexthop = myself;
- myself->via = myself;
- myself->status.active = 1;
- node_add(myself);
-
- syslog(LOG_NOTICE, _("Ready: listening on port %hd"), myself->port);
-cp
- return 0;
+ avl_node_t *node, *next;
+ connection_t *c;
+
+ cp();
+
+ for(node = connection_tree->head; node; node = next) {
+ next = node->next;
+ c = node->data;
+
+ if(c->last_ping_time + pingtimeout < now) {
+ if(c->status.active) {
+ if(c->status.pinged) {
+ ifdebug(CONNECTIONS) logger(LOG_INFO, _("%s (%s) didn't respond to PING in %ld seconds"),
+ c->name, c->hostname, now - c->last_ping_time);
+ c->status.timeout = true;
+ terminate_connection(c, true);
+ } else if(c->last_ping_time + pinginterval < now) {
+ send_ping(c);
+ }
+ } else {
+ if(c->status.remove) {
+ logger(LOG_WARNING, _("Old connection_t for %s (%s) status %04x still lingering, deleting..."),
+ c->name, c->hostname, bitfield_to_int(&c->status, sizeof c->status));
+ connection_del(c);
+ continue;
+ }
+ ifdebug(CONNECTIONS) logger(LOG_WARNING, _("Timeout from %s (%s) during authentication"),
+ c->name, c->hostname);
+ if(c->status.connecting) {
+ c->status.connecting = false;
+ closesocket(c->socket);
+ do_outgoing_connection(c);
+ } else {
+ terminate_connection(c, false);
+ }
+ }
+ }
+
+ if(c->outbuflen > 0 && c->last_flushed_time + pingtimeout < now) {
+ if(c->status.active) {
+ ifdebug(CONNECTIONS) logger(LOG_INFO,
+ _("%s (%s) could not flush for %ld seconds (%d bytes remaining)"),
+ c->name, c->hostname, now - c->last_flushed_time, c->outbuflen);
+ c->status.timeout = true;
+ terminate_connection(c, true);
+ }
+ }
+ }