everything (including myself).
- Use connection oriented UDP sockets for both incoming and outgoing
packets.
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- $Id: conf.c,v 1.9.4.20 2000/11/03 22:35:10 zarq Exp $
+ $Id: conf.c,v 1.9.4.21 2000/11/04 22:57:30 guus Exp $
*/
#include "config.h"
*/
static internal_config_t hazahaza[] = {
/* Main configuration file keywords */
- { "Name", tincname, TYPE_NAME },
- { "ConnectTo", connectto, TYPE_NAME },
- { "PingTimeout", pingtimeout, TYPE_INT },
- { "TapDevice", tapdevice, TYPE_NAME },
- { "PrivateKey", privatekey, TYPE_NAME },
- { "KeyExpire", keyexpire, TYPE_INT },
- { "Hostnames", resolve_dns, TYPE_BOOL },
- { "Interface", interface, TYPE_NAME },
- { "InterfaceIP", interfaceip, TYPE_IP },
+ { "Name", config_name, TYPE_NAME },
+ { "ConnectTo", config_connectto, TYPE_NAME },
+ { "PingTimeout", config_pingtimeout, TYPE_INT },
+ { "TapDevice", config_tapdevice, TYPE_NAME },
+ { "PrivateKey", config_privatekey, TYPE_NAME },
+ { "KeyExpire", config_keyexpire, TYPE_INT },
+ { "Hostnames", config_hostnames, TYPE_BOOL },
+ { "Interface", config_interface, TYPE_NAME },
+ { "InterfaceIP", config_interfaceip, TYPE_IP },
/* Host configuration file keywords */
- { "Address", address, TYPE_NAME },
- { "Port", port, TYPE_INT },
- { "PublicKey", publickey, TYPE_NAME },
- { "Subnet", subnet, TYPE_IP }, /* Use IPv4 subnets only for now */
- { "RestrictHosts", restricthosts, TYPE_BOOL },
- { "RestrictSubnets", restrictsubnets, TYPE_BOOL },
- { "RestrictAddress", restrictaddress, TYPE_BOOL },
- { "RestrictPort", restrictport, TYPE_BOOL },
- { "IndirectData", indirectdata, TYPE_BOOL },
- { "TCPonly", tcponly, TYPE_BOOL },
+ { "Address", config_address, TYPE_NAME },
+ { "Port", config_port, TYPE_INT },
+ { "PublicKey", config_publickey, TYPE_NAME },
+ { "Subnet", config_subnet, TYPE_IP }, /* Use IPv4 subnets only for now */
+ { "RestrictHosts", config_restricthosts, TYPE_BOOL },
+ { "RestrictSubnets", config_restrictsubnets, TYPE_BOOL },
+ { "RestrictAddress", config_restrictaddress, TYPE_BOOL },
+ { "RestrictPort", config_restrictport, TYPE_BOOL },
+ { "IndirectData", config_indirectdata, TYPE_BOOL },
+ { "TCPonly", config_tcponly, TYPE_BOOL },
{ NULL, 0, 0 }
};
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- $Id: conf.h,v 1.6.4.15 2000/10/29 00:24:31 guus Exp $
+ $Id: conf.h,v 1.6.4.16 2000/11/04 22:57:30 guus Exp $
*/
#ifndef __TINC_CONF_H__
} ip_mask_t;
typedef enum which_t {
- tincname = 1,
- connectto,
- pingtimeout,
- tapdevice,
- privatekey,
- keyexpire,
- resolve_dns,
- interface,
- interfaceip,
- address,
- port,
- publickey,
- subnet,
- restricthosts,
- restrictsubnets,
- restrictaddress,
- restrictport,
- indirectdata,
- tcponly,
+ config_name = 1,
+ config_connectto,
+ config_pingtimeout,
+ config_tapdevice,
+ config_privatekey,
+ config_keyexpire,
+ config_hostnames,
+ config_interface,
+ config_interfaceip,
+ config_address,
+ config_port,
+ config_publickey,
+ config_subnet,
+ config_restricthosts,
+ config_restrictsubnets,
+ config_restrictaddress,
+ config_restrictport,
+ config_indirectdata,
+ config_tcponly,
} which_t;
typedef struct config_t {
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- $Id: connlist.c,v 1.1.2.14 2000/11/04 15:34:07 guus Exp $
+ $Id: connlist.c,v 1.1.2.15 2000/11/04 22:57:30 guus Exp $
*/
#include "config.h"
void dump_conn_list(void)
{
conn_list_t *p;
- subnet_t *s;
- char *netstr;
cp
syslog(LOG_DEBUG, _("Connection list:"));
myself->name, myself->hostname, myself->port, myself->flags,
myself->socket, myself->meta_socket, myself->status);
- for(s = myself->subnets; s != NULL; s = s->next)
- {
- netstr = net2str(s);
- syslog(LOG_DEBUG, " %s", netstr);
- free(netstr);
- }
-
for(p = conn_list; p != NULL; p = p->next)
{
syslog(LOG_DEBUG, _(" %s at %s port %hd flags %d sockets %d, %d status %04x"),
p->name, p->hostname, p->port, p->flags,
p->socket, p->meta_socket, p->status);
-
- for(s = p->subnets; s != NULL; s = s->next)
- {
- netstr = net2str(s);
- syslog(LOG_DEBUG, " %s", netstr);
- free(netstr);
- }
}
syslog(LOG_DEBUG, _("End of connection list."));
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- $Id: net.c,v 1.35.4.66 2000/11/04 20:44:26 guus Exp $
+ $Id: net.c,v 1.35.4.67 2000/11/04 22:57:30 guus Exp $
*/
#include "config.h"
return 0;
}
-int xrecv(vpn_packet_t *inpkt)
+int xrecv(conn_list_t *cl, vpn_packet_t *inpkt)
{
vpn_packet_t outpkt;
int outlen, outpad;
returned a zero exit code
*/
void flush_queue(conn_list_t *cl, packet_queue_t **pq,
- int (*function)(conn_list_t*,void*))
+ int (*function)(conn_list_t*,vpn_packet_t*))
{
queue_element_t *p, *next = NULL;
cp
/* FIXME - check for indirection and reprogram it The Right Way(tm) this time. */
+ /* Connections are now opened beforehand...
+
if(!cl->status.dataopen)
if(setup_vpn_connection(cl) < 0)
{
cl->name, cl->hostname);
return -1;
}
+ */
if(!cl->status.validkey)
{
struct ifreq ifr;
cp
- if((cfg = get_config_val(config, tapdevice)))
+ if((cfg = get_config_val(config, config_tapdevice)))
tapfname = cfg->data.ptr;
else
#ifdef HAVE_TUNTAP
return -1;
}
- if((cfg = get_config_val(config, interface)))
+ if((cfg = get_config_val(config, config_interface)))
{
if(setsockopt(nfd, SOL_SOCKET, SO_KEEPALIVE, cfg->data.ptr, strlen(cfg->data.ptr)))
{
a.sin_family = AF_INET;
a.sin_port = htons(port);
- if((cfg = get_config_val(config, interfaceip)))
+ if((cfg = get_config_val(config, config_interfaceip)))
a.sin_addr.s_addr = htonl(cfg->data.ip->address);
else
a.sin_addr.s_addr = htonl(INADDR_ANY);
if(debug_lvl >= DEBUG_CONNECTIONS)
syslog(LOG_INFO, _("Trying to connect to %s"), cl->hostname);
- if((cfg = get_config_val(cl->config, port)) == NULL)
+ if((cfg = get_config_val(cl->config, config_port)) == NULL)
cl->port = 655;
else
cl->port = cfg->data.val;
return -1;
}
- if(!(cfg = get_config_val(ncn->config, address)))
+ if(!(cfg = get_config_val(ncn->config, config_address)))
{
syslog(LOG_ERR, _("No address specified for %s"));
free_conn_list(ncn);
int setup_myself(void)
{
config_t const *cfg;
+ config_t *next;
subnet_t *net;
cp
myself = new_conn_list();
myself->flags = 0;
myself->protocol_version = PROT_CURRENT;
- if(!(cfg = get_config_val(config, tincname))) /* Not acceptable */
+ if(!(cfg = get_config_val(config, config_name))) /* Not acceptable */
{
syslog(LOG_ERR, _("Name for tinc daemon required!"));
return -1;
return -1;
}
cp
- if(!(cfg = get_config_val(config, privatekey)))
+ if(!(cfg = get_config_val(config, config_privatekey)))
{
syslog(LOG_ERR, _("Private key for tinc daemon required!"));
return -1;
return -1;
}
cp
- if(!(cfg = get_config_val(myself->config, publickey)))
+ if(!(cfg = get_config_val(myself->config, config_publickey)))
{
syslog(LOG_ERR, _("Public key for tinc daemon required!"));
return -1;
return -1;
}
*/
- if(!(cfg = get_config_val(myself->config, port)))
+ if(!(cfg = get_config_val(myself->config, config_port)))
myself->port = 655;
else
myself->port = cfg->data.val;
- if((cfg = get_config_val(myself->config, indirectdata)))
+ if((cfg = get_config_val(myself->config, config_indirectdata)))
if(cfg->data.val == stupid_true)
myself->flags |= EXPORTINDIRECTDATA;
- if((cfg = get_config_val(myself->config, tcponly)))
+ if((cfg = get_config_val(myself->config, config_tcponly)))
if(cfg->data.val == stupid_true)
myself->flags |= TCPONLY;
/* Read in all the subnets specified in the host configuration file */
- for(cfg = myself->config; (cfg = get_config_val(cfg, subnet)); cfg = cfg->next)
+ for(next = myself->config; (cfg = get_config_val(next, config_subnet)); next = cfg->next)
{
net = new_subnet();
net->type = SUBNET_IPV4;
return -1;
}
- if((myself->socket = setup_vpn_in_socket(myself->port)) < 0)
- {
- syslog(LOG_ERR, _("Unable to set up an incoming vpn data socket!"));
- close(myself->meta_socket);
- return -1;
- }
-
/* Generate packet encryption key */
myself->cipher_pkttype = EVP_bf_cfb();
myself->cipher_pktkey = (char *)xmalloc(myself->cipher_pktkeylength);
RAND_bytes(myself->cipher_pktkey, myself->cipher_pktkeylength);
- if(!(cfg = get_config_val(config, keyexpire)))
+ if(!(cfg = get_config_val(config, config_keyexpire)))
keylifetime = 3600;
else
keylifetime = cfg->data.val;
{
config_t const *cfg;
cp
- cfg = get_config_val(upstreamcfg, connectto);
+ cfg = get_config_val(upstreamcfg, config_connectto);
if(!cfg && upstreamcfg == config)
/* No upstream IP given, we're listen only. */
signal(SIGALRM, SIG_IGN);
return;
}
- cfg = get_config_val(upstreamcfg, connectto); /* Or else we try the next ConnectTo line */
+ cfg = get_config_val(upstreamcfg, config_connectto); /* Or else we try the next ConnectTo line */
}
signal(SIGALRM, sigalrm_handler);
{
config_t const *cfg;
cp
- if((cfg = get_config_val(config, pingtimeout)) == NULL)
+ if((cfg = get_config_val(config, config_pingtimeout)) == NULL)
timeout = 60;
else
{
/* Run tinc-up script to further initialize the tap interface */
execute_script("tinc-up");
- if(!(cfg = get_config_val(config, connectto)))
+ if(!(cfg = get_config_val(config, config_connectto)))
/* No upstream IP given, we're listen only. */
return 0;
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, connectto); /* Or else we try the next ConnectTo line */
+ cfg = get_config_val(upstreamcfg, config_connectto); /* Or else we try the next ConnectTo line */
}
signal(SIGALRM, sigalrm_handler);
if(myself->status.active)
{
close(myself->meta_socket);
- close(myself->socket);
free_conn_list(myself);
myself = NULL;
}
{
int nfd, flags;
struct sockaddr_in a;
+ const int one = 1;
cp
if(debug_lvl >= DEBUG_TRAFFIC)
syslog(LOG_DEBUG, _("Opening UDP socket to %s"), cl->hostname);
return -1;
}
+ if(setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)))
+ {
+ syslog(LOG_ERR, _("System call `%s' failed: %m"),
+ "setsockopt");
+ return -1;
+ }
+
+ flags = fcntl(nfd, F_GETFL);
+ if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0)
+ {
+ syslog(LOG_ERR, _("System call `%s' failed: %m"),
+ "fcntl");
+ return -1;
+ }
+
+ memset(&a, 0, sizeof(a));
+ a.sin_family = AF_INET;
+ a.sin_port = htons(myself->port);
+ a.sin_addr.s_addr = htonl(INADDR_ANY);
+
+ if(bind(nfd, (struct sockaddr *)&a, sizeof(struct sockaddr)))
+ {
+ syslog(LOG_ERR, _("Can't bind to port %hd/udp: %m"), myself->port);
+ return -1;
+ }
+
a.sin_family = AF_INET;
a.sin_port = htons(cl->port);
a.sin_addr.s_addr = htonl(cl->address);
}
FD_SET(myself->meta_socket, fs);
- FD_SET(myself->socket, fs);
FD_SET(tap_fd, fs);
cp
}
udp socket and write it to the ethertap
device after being decrypted
*/
-int handle_incoming_vpn_data()
+int handle_incoming_vpn_data(conn_list_t *cl)
{
vpn_packet_t pkt;
int x, l = sizeof(x);
- struct sockaddr from;
int lenin;
- socklen_t fromlen = sizeof(from);
cp
- if(getsockopt(myself->socket, SOL_SOCKET, SO_ERROR, &x, &l) < 0)
+ if(getsockopt(cl->socket, SOL_SOCKET, SO_ERROR, &x, &l) < 0)
{
syslog(LOG_ERR, _("This is a bug: %s:%d: %d:%m"),
- __FILE__, __LINE__, myself->socket);
+ __FILE__, __LINE__, cl->socket);
return -1;
}
if(x)
return -1;
}
- if((lenin = recvfrom(myself->socket, (char *) &(pkt.len), MTU, 0, &from, &fromlen)) <= 0)
+ if((lenin = recv(cl->socket, (char *) &(pkt.len), MTU, 0)) <= 0)
{
syslog(LOG_ERR, _("Receiving packet failed: %m"));
return -1;
if(debug_lvl >= DEBUG_TRAFFIC)
{
- syslog(LOG_DEBUG, _("Received packet of %d bytes"), lenin);
- }
+ syslog(LOG_DEBUG, _("Received packet of %d bytes from %s (%s)"), lenin,
+ cl->name, cl->hostname);
+ }
cp
- return xrecv(&pkt);
+ return xrecv(cl, &pkt);
}
/*
void check_network_activity(fd_set *f)
{
conn_list_t *p;
- int x, l = sizeof(x);
cp
for(p = conn_list; p != NULL; p = p->next)
{
if(p->status.dataopen)
if(FD_ISSET(p->socket, f))
{
- /*
- The only thing that can happen to get us here is apparently an
- error on this outgoing(!) UDP socket that isn't immediate (i.e.
- something that will not trigger an error directly on send()).
- I've once got here when it said `No route to host'.
- */
+ handle_incoming_vpn_data(p);
+
+ /* Old error stuff (FIXME: copy this to handle_incoming_vpn_data()
+
getsockopt(p->socket, SOL_SOCKET, SO_ERROR, &x, &l);
syslog(LOG_ERR, _("Outgoing data socket error for %s (%s): %s"),
p->name, p->hostname, strerror(x));
terminate_connection(p);
+ */
return;
}
}
}
- if(FD_ISSET(myself->socket, f))
- handle_incoming_vpn_data();
-
if(FD_ISSET(myself->meta_socket, f))
handle_new_meta_connection();
cp
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- $Id: net.h,v 1.9.4.20 2000/10/29 09:19:25 guus Exp $
+ $Id: net.h,v 1.9.4.21 2000/11/04 22:57:31 guus Exp $
*/
#ifndef __TINC_NET_H__
extern int setup_vpn_connection(conn_list_t *);
extern void terminate_connection(conn_list_t *);
extern void flush_queues(conn_list_t *);
-extern int xrecv(vpn_packet_t *);
extern void add_queue(packet_queue_t **, void *, size_t);
#endif /* __TINC_NET_H__ */
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- $Id: netutl.c,v 1.12.4.14 2000/10/29 09:19:25 guus Exp $
+ $Id: netutl.c,v 1.12.4.15 2000/11/04 22:57:31 guus Exp $
*/
#include "config.h"
in.s_addr = addr;
lookup_hostname = 0;
- if((cfg = get_config_val(config, resolve_dns)) != NULL)
+ if((cfg = get_config_val(config, config_hostnames)) != NULL)
if(cfg->data.val == stupid_true)
lookup_hostname = 1;
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- $Id: protocol.c,v 1.28.4.57 2000/11/04 20:44:28 guus Exp $
+ $Id: protocol.c,v 1.28.4.58 2000/11/04 22:57:32 guus Exp $
*/
#include "config.h"
}
}
cp
- if((cfg = get_config_val(cl->config, publickey)))
+ if((cfg = get_config_val(cl->config, config_publickey)))
{
cl->rsa_key = RSA_new();
BN_hex2bn(&cl->rsa_key->n, cfg->data.ptr);
if(cl->status.outgoing)
cl->allow_request = ACK;
+ setup_vpn_connection(cl);
+
x = send_request(cl, "%d", ACK);
cl->status.encryptout = 1;
cp
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- $Id: route.c,v 1.1.2.1 2000/10/23 13:52:54 guus Exp $
+ $Id: route.c,v 1.1.2.2 2000/11/04 22:57:33 guus Exp $
*/
#include "config.h"
#include "system.h"
-int routing_mode = 0; /* Will be used to determine if we route by MAC or by payload's protocol */
+int routing_mode = 0; /* Will be used to determine if we route by MAC or by payload's protocol */
conn_list_t *route_packet(vpn_packet_t *packet)
{
cp
type = ntohs(*((unsigned short*)(&packet.data[12])))
+ if(routing_mode)
+ {
+ return route_mac(packet);
+ }
+
switch(type)
{
case 0x0800:
return route_arp(packet);
*/
default:
- /* TODO: try MAC as last resort? */
if(debug_lvl >= DEBUG_TRAFFIC)
{
syslog(LOG_WARNING, _("Cannot route packet: unknown type %hx"), type);
}
- return NULL;
+ return NULL;
}
}
+conn_list_t *route_mac(vpn_packet_t *packet)
+{
+ conn_list_t *cl;
+cp
+ cl = lookup_subnet_mac((mac_t *)(&packet.data[6]));
+ if(!cl)
+ if(debug_lvl >= DEBUG_TRAFFIC)
+ {
+ syslog(LOG_WARNING, _("Cannot route packet: unknown destination address %x:%x:%x:%x:%x:%x"),
+ packet.data[6],
+ packet.data[7],
+ packet.data[8],
+ packet.data[9],
+ packet.data[10],
+ packet.data[11]);
+ }
+cp
+ return cl;
+}
+
+
conn_list_t *route_ipv4(vpn_packet_t *packet)
{
ipv4_t dest;
cp
dest = ntohl(*((unsigned long*)(&packet.data[30]);
- cl = lookup_conn_list_ipv4(dest);
+ cl = lookup_subnet_ipv4(dest);
if(!cl)
if(debug_lvl >= DEBUG_TRAFFIC)
{
syslog(LOG_WARNING, _("Cannot route packet: unknown destination address %d.%d.%d.%d"),
packet.data[30], packet.data[31], packet.data[32], packet.data[33]);
}
-
- return cl;
cp
+ return cl;
}
conn_list_t *route_ipv6(vpn_packet_t *packet)
{
cp
syslog(LOG_WARNING, _("Cannot route packet: IPv6 routing not implemented yet"));
- return NULL;
cp
+ return NULL;
}
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- $Id: subnet.c,v 1.1.2.10 2000/11/04 11:49:58 guus Exp $
+ $Id: subnet.c,v 1.1.2.11 2000/11/04 22:57:33 guus Exp $
*/
#include "config.h"
for(subnet = subnet_list[SUBNET_IPV4]; subnet != NULL; subnet = subnet->global_next)
{
netstr = net2str(subnet);
- syslog(LOG_DEBUG, " %s owner %s", netstr, subnet->owner->name);
+ syslog(LOG_DEBUG, " %s owner %s", netstr, subnet->owner->name);
free(netstr);
}