+ 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 */
+
+ if(get_config_string(lookup_config(myself->connection->config_tree, "Cipher"), &cipher))
+ {
+ if(!strcasecmp(cipher, "none"))
+ {
+ myself->cipher = NULL;
+ }
+ else
+ {
+ if(!(myself->cipher = EVP_get_cipherbyname(cipher)))
+ {
+ syslog(LOG_ERR, _("Unrecognized cipher type!"));
+ return -1;
+ }
+ }
+ }
+ else
+ myself->cipher = EVP_bf_cbc();
+
+ if(myself->cipher)
+ myself->keylength = myself->cipher->key_len + myself->cipher->iv_len;
+ else
+ myself->keylength = 1;
+
+ 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;
+
+ /* Check if we want to use message authentication codes... */
+
+ if(get_config_string(lookup_config(myself->connection->config_tree, "Digest"), &digest))
+ {
+ if(!strcasecmp(digest, "none"))
+ {
+ myself->digest = NULL;
+ }
+ else
+ {
+ if(!(myself->digest = EVP_get_digestbyname(digest)))
+ {
+ syslog(LOG_ERR, _("Unrecognized digest type!"));
+ return -1;
+ }
+ }
+ }
+ else
+ myself->digest = EVP_sha1();
+
+ if(get_config_int(lookup_config(myself->connection->config_tree, "MACLength"), &myself->maclength))
+ {
+ if(myself->digest)
+ {
+ if(myself->maclength > myself->digest->md_size)
+ {
+ syslog(LOG_ERR, _("MAC length exceeds size of digest!"));
+ return -1;
+ }
+ else if (myself->maclength < 0)
+ {
+ syslog(LOG_ERR, _("Bogus MAC length!"));
+ return -1;
+ }
+ }
+ }
+ else
+ myself->maclength = 4;
+cp
+ /* Done */
+
+ myself->nexthop = myself;
+ myself->via = myself;
+ myself->status.active = 1;
+ node_add(myself);
+
+ graph();
+
+ syslog(LOG_NOTICE, _("Ready: listening on port %hd"), myself->port);
+cp
+ return 0;
+}
+
+/*
+ setup all initial network connections
+*/
+int setup_network_connections(void)
+{
+cp
+ init_connections();
+ init_subnets();
+ init_nodes();
+ init_edges();
+ init_events();
+
+ if(get_config_int(lookup_config(config_tree, "PingTimeout"), &pingtimeout))
+ {
+ if(pingtimeout < 1)
+ {
+ pingtimeout = 86400;
+ }
+ }
+ else
+ pingtimeout = 60;
+
+ if(setup_device() < 0)
+ return -1;
+
+ /* Run tinc-up script to further initialize the tap interface */
+ execute_script("tinc-up");
+
+ if(setup_myself() < 0)
+ return -1;
+
+ try_outgoing_connections();