From 698191fd2f512f3618e2d60592fcd57cd750b965 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Sat, 4 Nov 2000 22:57:33 +0000 Subject: [PATCH] - Prepended config_ to all configuration option names, because it confused everything (including myself). - Use connection oriented UDP sockets for both incoming and outgoing packets. --- src/conf.c | 40 ++++++++--------- src/conf.h | 40 ++++++++--------- src/connlist.c | 18 +------- src/net.c | 114 ++++++++++++++++++++++++++++--------------------- src/net.h | 3 +- src/netutl.c | 4 +- src/protocol.c | 6 ++- src/route.c | 40 +++++++++++++---- src/subnet.c | 4 +- 9 files changed, 147 insertions(+), 122 deletions(-) diff --git a/src/conf.c b/src/conf.c index 477d0fd8..0a65e32d 100644 --- a/src/conf.c +++ b/src/conf.c @@ -19,7 +19,7 @@ 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" @@ -56,26 +56,26 @@ int sighup = 0; */ 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 } }; diff --git a/src/conf.h b/src/conf.h index c4c030ad..9ab0add6 100644 --- a/src/conf.h +++ b/src/conf.h @@ -17,7 +17,7 @@ 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__ @@ -33,25 +33,25 @@ typedef struct ip_mask_t { } 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 { diff --git a/src/connlist.c b/src/connlist.c index 63f9e6c5..5d41dcb6 100644 --- a/src/connlist.c +++ b/src/connlist.c @@ -17,7 +17,7 @@ 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" @@ -162,8 +162,6 @@ cp void dump_conn_list(void) { conn_list_t *p; - subnet_t *s; - char *netstr; cp syslog(LOG_DEBUG, _("Connection list:")); @@ -171,25 +169,11 @@ cp 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.")); diff --git a/src/net.c b/src/net.c index dd692e8e..a4324a47 100644 --- a/src/net.c +++ b/src/net.c @@ -17,7 +17,7 @@ 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" @@ -170,7 +170,7 @@ cp 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; @@ -294,7 +294,7 @@ cp 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 @@ -375,6 +375,8 @@ 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) { @@ -382,6 +384,7 @@ cp cl->name, cl->hostname); return -1; } + */ if(!cl->status.validkey) { @@ -423,7 +426,7 @@ int setup_tap_fd(void) 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 @@ -515,7 +518,7 @@ cp 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))) { @@ -528,7 +531,7 @@ cp 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); @@ -606,7 +609,7 @@ cp 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; @@ -675,7 +678,7 @@ cp 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); @@ -718,6 +721,7 @@ cp int setup_myself(void) { config_t const *cfg; + config_t *next; subnet_t *net; cp myself = new_conn_list(); @@ -726,7 +730,7 @@ cp 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; @@ -740,7 +744,7 @@ cp 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; @@ -758,7 +762,7 @@ cp 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; @@ -774,22 +778,22 @@ cp 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; @@ -813,13 +817,6 @@ cp 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(); @@ -829,7 +826,7 @@ cp 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; @@ -850,7 +847,7 @@ sigalrm_handler(int a) { 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. */ @@ -864,7 +861,7 @@ cp 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); @@ -885,7 +882,7 @@ int setup_network_connections(void) { 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 { @@ -905,7 +902,7 @@ cp /* 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; @@ -914,7 +911,7 @@ cp 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); @@ -943,7 +940,6 @@ cp if(myself->status.active) { close(myself->meta_socket); - close(myself->socket); free_conn_list(myself); myself = NULL; } @@ -967,6 +963,7 @@ int setup_vpn_connection(conn_list_t *cl) { 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); @@ -978,6 +975,32 @@ cp 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); @@ -1058,7 +1081,6 @@ cp } FD_SET(myself->meta_socket, fs); - FD_SET(myself->socket, fs); FD_SET(tap_fd, fs); cp } @@ -1068,18 +1090,16 @@ 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) @@ -1088,7 +1108,7 @@ cp 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; @@ -1096,11 +1116,12 @@ cp 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); } /* @@ -1238,7 +1259,6 @@ cp 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) { @@ -1248,16 +1268,15 @@ cp 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; } @@ -1270,9 +1289,6 @@ cp } } - if(FD_ISSET(myself->socket, f)) - handle_incoming_vpn_data(); - if(FD_ISSET(myself->meta_socket, f)) handle_new_meta_connection(); cp diff --git a/src/net.h b/src/net.h index 98366349..e3d974ed 100644 --- a/src/net.h +++ b/src/net.h @@ -16,7 +16,7 @@ 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__ @@ -118,7 +118,6 @@ extern void main_loop(void); 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__ */ diff --git a/src/netutl.c b/src/netutl.c index b80473b1..d92d3ee5 100644 --- a/src/netutl.c +++ b/src/netutl.c @@ -16,7 +16,7 @@ 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" @@ -72,7 +72,7 @@ cp 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; diff --git a/src/protocol.c b/src/protocol.c index 0728ea1a..879e06f1 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -17,7 +17,7 @@ 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" @@ -225,7 +225,7 @@ cp } } 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); @@ -561,6 +561,8 @@ cp if(cl->status.outgoing) cl->allow_request = ACK; + setup_vpn_connection(cl); + x = send_request(cl, "%d", ACK); cl->status.encryptout = 1; cp diff --git a/src/route.c b/src/route.c index a958e1a7..0509b962 100644 --- a/src/route.c +++ b/src/route.c @@ -17,7 +17,7 @@ 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" @@ -30,7 +30,7 @@ #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) { @@ -38,6 +38,11 @@ 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: @@ -51,15 +56,35 @@ cp 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; @@ -67,22 +92,21 @@ conn_list_t *route_ipv4(vpn_packet_t *packet) 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; } diff --git a/src/subnet.c b/src/subnet.c index 15ae528e..6ca3feef 100644 --- a/src/subnet.c +++ b/src/subnet.c @@ -17,7 +17,7 @@ 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" @@ -301,7 +301,7 @@ cp 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); } -- 2.39.5