-/*
- if(RSA_check_key(myself->rsa_key) != 1)
- {
- syslog(LOG_ERR, _("Invalid public/private keypair!"));
- return -1;
- }
-*/
- if(!(cfg = get_config_val(myself->config, config_port)))
- myself->port = 655;
- else
- myself->port = cfg->data.val;
-
-/* Read in all the subnets specified in the host configuration file */
-
- for(next = myself->config; (cfg = get_config_val(next, config_subnet)); next = cfg->next)
- {
- net = new_subnet();
- net->type = SUBNET_IPV4;
- net->net.ipv4.address = cfg->data.ip->address;
- net->net.ipv4.mask = cfg->data.ip->mask;
-
- /* Teach newbies what subnets are... */
-
- if((net->net.ipv4.address & net->net.ipv4.mask) != net->net.ipv4.address)
- {
- syslog(LOG_ERR, _("Network address and subnet mask do not match!"));
- return -1;
- }
-
- subnet_add(myself, net);
- }
-
-cp
- /* Check some options */
-
- if((cfg = get_config_val(config, config_indirectdata)))
- if(cfg->data.val == stupid_true)
- myself->options |= OPTION_INDIRECT;
-
- if((cfg = get_config_val(config, config_tcponly)))
- if(cfg->data.val == stupid_true)
- myself->options |= OPTION_TCPONLY;
-
- if((cfg = get_config_val(myself->config, config_indirectdata)))
- if(cfg->data.val == stupid_true)
- myself->options |= OPTION_INDIRECT;
-
- if((cfg = get_config_val(myself->config, config_tcponly)))
- if(cfg->data.val == stupid_true)
- myself->options |= OPTION_TCPONLY;
-
- if(myself->options & OPTION_TCPONLY)
- myself->options |= OPTION_INDIRECT;
-
- if((cfg = get_config_val(config, config_mode)))
- {
- if(!strcasecmp(cfg->data.ptr, "router"))
- routing_mode = RMODE_ROUTER;
- else if (!strcasecmp(cfg->data.ptr, "switch"))
- routing_mode = RMODE_SWITCH;
- else if (!strcasecmp(cfg->data.ptr, "hub"))
- routing_mode = RMODE_HUB;
- else
- {
- syslog(LOG_ERR, _("Invalid routing mode!"));
- return -1;
- }
- }
- else
- routing_mode = RMODE_ROUTER;
-
-cp
- /* Open sockets */
-
- if((myself->meta_socket = setup_listen_meta_socket(myself->port)) < 0)
- {
- syslog(LOG_ERR, _("Unable to set up a listening TCP socket!"));
- return -1;
- }
-
- if((myself->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_pkttype = EVP_bf_cbc();
-
- myself->cipher_pktkeylength = myself->cipher_pkttype->key_len + myself->cipher_pkttype->iv_len;
-
- myself->cipher_pktkey = (char *)xmalloc(myself->cipher_pktkeylength);
- RAND_pseudo_bytes(myself->cipher_pktkey, myself->cipher_pktkeylength);
-
- if(!(cfg = get_config_val(config, config_keyexpire)))
- keylifetime = 3600;
- else
- keylifetime = cfg->data.val;
-
- keyexpires = time(NULL) + keylifetime;
-cp
-
- /* Activate ourselves */
-
- myself->status.active = 1;
-
- syslog(LOG_NOTICE, _("Ready: listening on port %hd"), myself->port);
-cp
- return 0;
-}
-
-RETSIGTYPE
-sigalrm_handler(int a)
-{
- config_t const *cfg;
-cp
- cfg = get_config_val(upstreamcfg, config_connectto);
-
- if(!cfg)
- {
- if(upstreamcfg == config)
- {
- /* No upstream IP given, we're listen only. */
- signal(SIGALRM, SIG_IGN);
- return;
- }
- }
- else
- {
- /* We previously tried all the ConnectTo lines. Now wrap back to the first. */
- cfg = get_config_val(config, config_connectto);
- }
-
- while(cfg)
- {
- upstreamcfg = cfg->next;
- if(!setup_outgoing_connection(cfg->data.ptr)) /* function returns 0 when there are no problems */
- {
- signal(SIGALRM, SIG_IGN);
- return;
- }
- cfg = get_config_val(upstreamcfg, config_connectto); /* Or else we try the next ConnectTo line */
- }
-
- signal(SIGALRM, sigalrm_handler);
- upstreamcfg = config;
- seconds_till_retry += 5;
- if(seconds_till_retry > MAXTIMEOUT) /* Don't wait more than MAXTIMEOUT seconds. */
- seconds_till_retry = MAXTIMEOUT;
- syslog(LOG_ERR, _("Still failed to connect to other, will retry in %d seconds"),
- seconds_till_retry);
- alarm(seconds_till_retry);
-cp
-}
-
-/*
- setup all initial network connections
-*/
-int setup_network_connections(void)
-{
- config_t const *cfg;
-cp
- init_connections();
- init_subnets();
-
- if((cfg = get_config_val(config, config_pingtimeout)) == NULL)
- timeout = 60;
- else
- {
- timeout = cfg->data.val;
- if(timeout < 1)
- {
- timeout = 86400;
- }
- }
-
- if(setup_tap_fd() < 0)
- return -1;
-
- /* Run tinc-up script to further initialize the tap interface */
- execute_script("tinc-up");
-
- if(setup_myself() < 0)
- return -1;
-
- if(!(cfg = get_config_val(config, config_connectto)))
- /* No upstream IP given, we're listen only. */
- return 0;
-
- while(cfg)
- {
- upstreamcfg = cfg->next;
- if(!setup_outgoing_connection(cfg->data.ptr)) /* function returns 0 when there are no problems */
- return 0;
- cfg = get_config_val(upstreamcfg, config_connectto); /* Or else we try the next ConnectTo line */
- }
-
- if(do_detach)
- {
- signal(SIGALRM, sigalrm_handler);
- upstreamcfg = config;
- seconds_till_retry = MAXTIMEOUT;
- syslog(LOG_NOTICE, _("Trying to re-establish outgoing connection in %d seconds"), seconds_till_retry);
- alarm(seconds_till_retry);
- }
- else
- return -1;
-
-cp
- return 0;
-}
-
-/*
- close all open network connections
-*/
-void close_network_connections(void)
-{
- avl_node_t *node;
- connection_t *p;
-cp
- for(node = connection_tree->head; node; node = node->next)
- {
- p = (connection_t *)node->data;
- p->status.outgoing = 0;
- p->status.active = 0;
- terminate_connection(p);
- }
-
- if(myself)
- if(myself->status.active)
- {
- close(myself->meta_socket);
- free_connection(myself);
- myself = NULL;
- }
-
- close(tap_fd);
-
- /* Execute tinc-down script right after shutting down the interface */
- execute_script("tinc-down");
-
- destroy_connection_tree();
-cp
- return;
-}
-
-/*
- handle an incoming tcp connect call and open
- a connection to it.
-*/
-connection_t *create_new_connection(int sfd)
-{
- connection_t *p;
- struct sockaddr_in ci;
- int len = sizeof(ci);
-cp
- p = new_connection();
-
- if(getpeername(sfd, (struct sockaddr *) &ci, (socklen_t *) &len) < 0)
- {
- syslog(LOG_ERR, _("System call `%s' failed: %m"),
- "getpeername");
- close(sfd);
- return NULL;
- }
-
- asprintf(&p->name, _("UNKNOWN"));
- p->address = ntohl(ci.sin_addr.s_addr);
- p->hostname = hostlookup(ci.sin_addr.s_addr);
- p->port = htons(ci.sin_port); /* This one will be overwritten later */
- p->meta_socket = sfd;
- p->status.meta = 1;
- p->buffer = xmalloc(MAXBUFSIZE);
- p->buflen = 0;
- p->last_ping_time = time(NULL);
-
- if(debug_lvl >= DEBUG_CONNECTIONS)
- syslog(LOG_NOTICE, _("Connection from %s port %d"),
- p->hostname, htons(ci.sin_port));
-
- p->allow_request = ID;
-cp
- return p;
-}