/*
net_setup.c -- Setup.
Copyright (C) 1998-2005 Ivo Timmermans,
- 2000-2010 Guus Sliepen <guus@tinc-vpn.org>
+ 2000-2012 Guus Sliepen <guus@tinc-vpn.org>
2006 Scott Lamb <slamb@slamb.org>
+ 2010 Brandon Black <blblack@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include "xalloc.h"
char *myport;
+devops_t devops;
bool read_rsa_public_key(connection_t *c) {
FILE *fp;
xasprintf(&fname, "%s/hosts/%s", confbase, c->name);
fp = fopen(fname, "r");
- if(fp) {
- c->rsa_key = PEM_read_RSAPublicKey(fp, &c->rsa_key, NULL, NULL);
- fclose(fp);
+ if(!fp) {
+ logger(LOG_ERR, "Error reading RSA public key file `%s': %s", fname, strerror(errno));
+ free(fname);
+ return false;
}
+ c->rsa_key = PEM_read_RSAPublicKey(fp, &c->rsa_key, NULL, NULL);
+ fclose(fp);
free(fname);
if(c->rsa_key)
xasprintf(&fname, "%s/hosts/%s", confbase, c->name);
fp = fopen(fname, "r");
- if(fp) {
- c->rsa_key = PEM_read_RSA_PUBKEY(fp, &c->rsa_key, NULL, NULL);
-// RSA_blinding_on(c->rsa_key, NULL);
- fclose(fp);
+ if(!fp) {
+ logger(LOG_ERR, "Error reading RSA public key file `%s': %s", fname, strerror(errno));
+ free(fname);
+ return false;
}
+ c->rsa_key = PEM_read_RSA_PUBKEY(fp, &c->rsa_key, NULL, NULL);
+// RSA_blinding_on(c->rsa_key, NULL);
+ fclose(fp);
free(fname);
if(c->rsa_key)
return false;
}
-bool read_rsa_private_key(void) {
+static bool read_rsa_private_key(void) {
FILE *fp;
char *fname, *key, *pubkey;
struct stat s;
/*
Configure node_t myself and set up the local sockets (listen only)
*/
-bool setup_myself(void) {
+static bool setup_myself(void) {
config_t *cfg;
subnet_t *subnet;
- char *name, *hostname, *mode, *afname, *cipher, *digest;
+ char *name, *hostname, *mode, *afname, *cipher, *digest, *type;
char *fname = NULL;
char *address = NULL;
char *envp[5];
struct addrinfo *ai, *aip, hint = {0};
bool choice;
int i, err;
+ int replaywin_int;
myself = new_node();
myself->connection = new_connection();
myself->name = name;
myself->connection->name = xstrdup(name);
xasprintf(&fname, "%s/hosts/%s", confbase, name);
+ read_config_options(config_tree, name);
read_config_file(config_tree, fname);
free(fname);
} else
maxtimeout = 900;
+ if(get_config_int(lookup_config(config_tree, "UDPRcvBuf"), &udp_rcvbuf)) {
+ if(udp_rcvbuf <= 0) {
+ logger(LOG_ERR, "UDPRcvBuf cannot be negative!");
+ return false;
+ }
+ }
+
+ if(get_config_int(lookup_config(config_tree, "UDPSndBuf"), &udp_sndbuf)) {
+ if(udp_sndbuf <= 0) {
+ logger(LOG_ERR, "UDPSndBuf cannot be negative!");
+ return false;
+ }
+ }
+
+ if(get_config_int(lookup_config(config_tree, "ReplayWindow"), &replaywin_int)) {
+ if(replaywin_int < 0) {
+ logger(LOG_ERR, "ReplayWindow cannot be negative!");
+ return false;
+ }
+ replaywin = (unsigned)replaywin_int;
+ }
+
if(get_config_string(lookup_config(config_tree, "AddressFamily"), &afname)) {
if(!strcasecmp(afname, "IPv4"))
addressfamily = AF_INET;
/* Open device */
- if(!setup_device())
+ devops = os_devops;
+
+ if(get_config_string(lookup_config(config_tree, "DeviceType"), &type)) {
+ if(!strcasecmp(type, "dummy"))
+ devops = dummy_devops;
+ else if(!strcasecmp(type, "raw_socket"))
+ devops = raw_socket_devops;
+#ifdef ENABLE_UML
+ else if(!strcasecmp(type, "uml"))
+ devops = uml_devops;
+#endif
+#ifdef ENABLE_VDE
+ else if(!strcasecmp(type, "vde"))
+ devops = vde_devops;
+#endif
+ }
+
+ if(!devops.setup())
return false;
/* Run tinc-up script to further initialize the tap interface */
/* Open sockets */
- get_config_string(lookup_config(config_tree, "BindToAddress"), &address);
+ cfg = lookup_config(config_tree, "BindToAddress");
- hint.ai_family = addressfamily;
- hint.ai_socktype = SOCK_STREAM;
- hint.ai_protocol = IPPROTO_TCP;
- hint.ai_flags = AI_PASSIVE;
+ do {
+ get_config_string(cfg, &address);
+ if(cfg)
+ cfg = lookup_config_next(config_tree, cfg);
- err = getaddrinfo(address, myport, &hint, &ai);
+ hint.ai_family = addressfamily;
+ hint.ai_socktype = SOCK_STREAM;
+ hint.ai_protocol = IPPROTO_TCP;
+ hint.ai_flags = AI_PASSIVE;
- if(err || !ai) {
- logger(LOG_ERR, "System call `%s' failed: %s", "getaddrinfo",
- gai_strerror(err));
- return false;
- }
+ err = getaddrinfo(address, myport, &hint, &ai);
+ free(address);
- listen_sockets = 0;
+ if(err || !ai) {
+ logger(LOG_ERR, "System call `%s' failed: %s", "getaddrinfo",
+ gai_strerror(err));
+ return false;
+ }
- for(aip = ai; aip; aip = aip->ai_next) {
- listen_socket[listen_sockets].tcp =
- setup_listen_socket((sockaddr_t *) aip->ai_addr);
+ listen_sockets = 0;
- if(listen_socket[listen_sockets].tcp < 0)
- continue;
+ for(aip = ai; aip; aip = aip->ai_next) {
+ listen_socket[listen_sockets].tcp =
+ setup_listen_socket((sockaddr_t *) aip->ai_addr);
- listen_socket[listen_sockets].udp =
- setup_vpn_in_socket((sockaddr_t *) aip->ai_addr);
+ if(listen_socket[listen_sockets].tcp < 0)
+ continue;
- if(listen_socket[listen_sockets].udp < 0)
- continue;
+ listen_socket[listen_sockets].udp =
+ setup_vpn_in_socket((sockaddr_t *) aip->ai_addr);
- ifdebug(CONNECTIONS) {
- hostname = sockaddr2hostname((sockaddr_t *) aip->ai_addr);
- logger(LOG_NOTICE, "Listening on %s", hostname);
- free(hostname);
- }
+ if(listen_socket[listen_sockets].udp < 0)
+ continue;
- memcpy(&listen_socket[listen_sockets].sa, aip->ai_addr, aip->ai_addrlen);
- listen_sockets++;
- }
+ ifdebug(CONNECTIONS) {
+ hostname = sockaddr2hostname((sockaddr_t *) aip->ai_addr);
+ logger(LOG_NOTICE, "Listening on %s", hostname);
+ free(hostname);
+ }
+
+ memcpy(&listen_socket[listen_sockets].sa, aip->ai_addr, aip->ai_addrlen);
+ listen_sockets++;
+ }
- freeaddrinfo(ai);
+ freeaddrinfo(ai);
+ } while(cfg);
if(listen_sockets)
logger(LOG_NOTICE, "Ready");
for(i = 0; i < 4; i++)
free(envp[i]);
- close_device();
+ devops.close();
return;
}