X-Git-Url: https://www.tinc-vpn.org/git/browse?p=tinc;a=blobdiff_plain;f=src%2Fnet.c;h=fecf7e6ecf8b00241c0d9a21fa2f39ae0e2f834f;hp=2efd34087c8883de855092be982b9d0dcda74d8a;hb=e5130495d7d4083d58ab76c26001aa27f5fc13db;hpb=950fb8e916b0e248dcaa72c96859acd6046683aa diff --git a/src/net.c b/src/net.c index 2efd3408..fecf7e6e 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.33 2000/10/11 10:35:16 guus Exp $ + $Id: net.c,v 1.35.4.37 2000/10/15 19:53:15 zarq Exp $ */ #include "config.h" @@ -37,6 +37,13 @@ #include #include +/* Next two includes are for tun/tap support */ +#include + +#ifdef HAVE_LINUX_IF_TUN_H +#include +#endif + #include #include @@ -59,9 +66,7 @@ int total_socket_out = 0; int upstreamindex = 0; static int seconds_till_retry; -/* The global list of existing connections */ -conn_list_t *conn_list = NULL; -conn_list_t *myself = NULL; +char *unknown = NULL; /* strip off the MAC adresses of an ethernet frame @@ -84,7 +89,7 @@ cp p->data[0] = p->data[6] = 0xfe; p->data[1] = p->data[7] = 0xfd; /* Really evil pointer stuff just below! */ - *((ip_t*)(&p->data[2])) = (ip_t)(htonl(myself->real_ip)); + *((ip_t*)(&p->data[2])) = (ip_t)(htonl(myself->address)); *((ip_t*)(&p->data[8])) = *((ip_t*)(&p->data[26])); cp } @@ -95,7 +100,7 @@ int xsend(conn_list_t *cl, vpn_packet_t *inpkt) int outlen, outpad; cp outpkt.len = inpkt->len; - EVP_EncryptInit(cl->cipher_pktctx, cl->cipher_pkttype, cl->cipher_pktkey, cl->cipher_pktiv); + EVP_EncryptInit(cl->cipher_pktctx, cl->cipher_pkttype, cl->cipher_pktkey, NULL); EVP_EncryptUpdate(cl->cipher_pktctx, outpkt.data, &outlen, inpkt->data, inpkt->len); EVP_EncryptFinal(cl->cipher_pktctx, outpkt.data + outlen, &outpad); outlen += outpad; @@ -128,7 +133,7 @@ cp inpkt->len); outpkt.len = inpkt->len; - EVP_DecryptInit(myself->cipher_pktctx, myself->cipher_pkttype, myself->cipher_pktkey, myself->cipher_pktiv); + EVP_DecryptInit(myself->cipher_pktctx, myself->cipher_pkttype, myself->cipher_pktkey, NULL); EVP_DecryptUpdate(myself->cipher_pktctx, outpkt.data, &outlen, inpkt->data, inpkt->len); /* FIXME: grok DecryptFinal EVP_DecryptFinal(myself->cipher_pktctx, outpkt.data + outlen, &outpad); @@ -274,7 +279,7 @@ int send_packet(ip_t to, vpn_packet_t *packet) { conn_list_t *cl; cp - if((cl = lookup_conn(to)) == NULL) + if((cl = lookup_conn_list_ipv4(to)) == NULL) { if(debug_lvl > 3) { @@ -286,53 +291,9 @@ cp } /* If we ourselves have indirectdata flag set, we should send only to our uplink! */ - - /* The next few lines will be obsoleted, if we are going indirect, matching subnet_t - should point to only our uplink as the recepient - */ - - if(myself->flags & EXPORTINDIRECTDATA) - { - for(cl = conn_list; cl != NULL && !cl->status.outgoing; cl = cl->next); - if(!cl) - { /* No open outgoing connection has been found. */ - if(debug_lvl > 3) - syslog(LOG_NOTICE, _("There is no remote host I can send this packet to!")); - return -1; - } - } - else - - /* If indirectdata flag is set for the destination we just looked up, - * then real_ip is actually the vpn_ip of the gateway tincd - * it is behind. - */ - - if(cl->flags & INDIRECTDATA) - { - if(debug_lvl > 3) - syslog(LOG_NOTICE, _("Indirect packet to %s via %s"), - cl->name, cl->hostname); - if((cl = lookup_conn(cl->real_ip)) == NULL) - { - if(debug_lvl > 3) - syslog(LOG_NOTICE, _("Indirect look up %d.%d.%d.%d in connection list failed!"), IP_ADDR_V(to)); - - /* Gateway tincd dead? Should we kill it? (GS) */ - - return -1; - } - if(cl->flags & INDIRECTDATA) /* This should not happen */ - { - if(debug_lvl > 3) - syslog(LOG_NOTICE, _("Double indirection for %d.%d.%d.%d"), IP_ADDR_V(to)); - return -1; - } - } - - if(my_key_expiry <= time(NULL)) - regenerate_keys(); + /* FIXME - check for indirection and reprogram it The Right Way(tm) this time. */ + if(!cl->status.dataopen) if(setup_vpn_connection(cl) < 0) { @@ -374,19 +335,46 @@ int setup_tap_fd(void) int nfd; const char *tapfname; config_t const *cfg; + +#ifdef HAVE_TUNTAP + struct ifreq ifr; +#endif cp - if((cfg = get_config_val(tapdevice)) == NULL) - tapfname = "/dev/tap0"; - else + if((cfg = get_config_val(config, tapdevice))) tapfname = cfg->data.ptr; - + else +#ifdef HAVE_TUNTAP + tapfname = "/dev/misc/net/tun"; +#else + tapfname = "/dev/tap0"; +#endif +cp if((nfd = open(tapfname, O_RDWR | O_NONBLOCK)) < 0) { syslog(LOG_ERR, _("Could not open %s: %m"), tapfname); return -1; } - +cp tap_fd = nfd; + +#ifdef HAVE_TUNTAP + /* Ok now check if this is an old ethertap or a new tun/tap thingie */ + memset(&ifr, 0, sizeof(ifr)); +cp + ifr.ifr_flags = IFF_TAP; + if (netname) + strncpy(ifr.ifr_name, netname, IFNAMSIZ); +cp + if (!ioctl(tap_fd, TUNSETIFF, (void *) &ifr)) + { + syslog(LOG_INFO, _("%s is a new style tun/tap device"), tapfname); + if((cfg = get_config_val(config, tapsubnet)) == NULL) + syslog(LOG_INFO, _("tun/tap device will be left unconfigured")); + else + /* Setup inetaddr/netmask etc */; + } +#endif + cp return 0; } @@ -427,7 +415,7 @@ cp return -1; } - if((cfg = get_config_val(interface))) + if((cfg = get_config_val(config, interface))) { if(setsockopt(nfd, SOL_SOCKET, SO_KEEPALIVE, cfg->data.ptr, strlen(cfg->data.ptr))) { @@ -440,7 +428,7 @@ cp a.sin_family = AF_INET; a.sin_port = htons(port); - if((cfg = get_config_val(interfaceip))) + if((cfg = get_config_val(config, interfaceip))) a.sin_addr.s_addr = htonl(cfg->data.ip->ip); else a.sin_addr.s_addr = htonl(INADDR_ANY); @@ -515,7 +503,7 @@ cp if(debug_lvl > 0) syslog(LOG_INFO, _("Trying to connect to %s"), cl->hostname); - if((cfg = get_config_val(upstreamport)) == NULL) + if((cfg = get_config_val(cl->config, port)) == NULL) cl->port = 655; else cl->port = cfg->data.val; @@ -530,7 +518,7 @@ cp a.sin_family = AF_INET; a.sin_port = htons(cl->port); - a.sin_addr.s_addr = htonl(cl->real_ip); + a.sin_addr.s_addr = htonl(cl->address); if(connect(cl->meta_socket, (struct sockaddr *)&a, sizeof(a)) == -1) { @@ -572,14 +560,14 @@ cp } ncn = new_conn_list(); - ncn->real_ip = ntohl(*((ip_t*)(h->h_addr_list[0]))); - ncn->hostname = hostlookup(htonl(ncn->real_ip)); + ncn->address = ntohl(*((ip_t*)(h->h_addr_list[0]))); + ncn->hostname = hostlookup(htonl(ncn->address)); if(setup_outgoing_meta_socket(ncn) < 0) { syslog(LOG_ERR, _("Could not set up a meta connection to %s"), ncn->hostname); - free_conn_element(ncn); + free_conn_list(ncn); return -1; } @@ -600,39 +588,52 @@ int setup_myself(void) cp myself = new_conn_list(); - myself->hostname = "MYSELF"; /* FIXME? */ + asprintf(&myself->hostname, "MYSELF"); /* FIXME? Do hostlookup on ourselves? */ myself->flags = 0; + myself->protocol_version = PROT_CURRENT; - if(!(cfg = get_config_val(tincname))) /* Not acceptable */ + if(!(cfg = get_config_val(config, tincname))) /* Not acceptable */ { syslog(LOG_ERR, _("Name for tinc daemon required!")); return -1; } else myself->name = (char*)cfg->data.val; + + if(check_id(myself->name)) + { + syslog(LOG_ERR, _("Invalid name for myself!")); + return -1; + } + + if(read_host_config(myself)) + { + syslog(LOG_ERR, _("Cannot open host configuration file for myself!")); + return -1; + } - if(!(cfg = get_config_val(listenport))) + if(!(cfg = get_config_val(myself->config, port))) myself->port = 655; else myself->port = cfg->data.val; - if((cfg = get_config_val(indirectdata))) + if((cfg = get_config_val(myself->config, indirectdata))) if(cfg->data.val == stupid_true) myself->flags |= EXPORTINDIRECTDATA; - if((cfg = get_config_val(tcponly))) + if((cfg = get_config_val(myself->config, tcponly))) if(cfg->data.val == stupid_true) myself->flags |= TCPONLY; if((myself->meta_socket = setup_listen_meta_socket(myself->port)) < 0) { - syslog(LOG_ERR, _("Unable to set up a listening socket")); + syslog(LOG_ERR, _("Unable to set up a listening socket!")); return -1; } if((myself->socket = setup_vpn_in_socket(myself->port)) < 0) { - syslog(LOG_ERR, _("Unable to set up an incoming vpn data socket")); + syslog(LOG_ERR, _("Unable to set up an incoming vpn data socket!")); close(myself->meta_socket); return -1; } @@ -649,8 +650,9 @@ sigalrm_handler(int a) { config_t const *cfg; cp - cfg = get_next_config_val(upstreamip, upstreamindex++); - +/* FIXME! Use name instead of upstreamip. + cfg = get_next_config_val(config, upstreamip, upstreamindex++); +*/ while(cfg) { if(!setup_outgoing_connection(cfg->data.ptr)) /* function returns 0 when there are no problems */ @@ -658,7 +660,7 @@ cp signal(SIGALRM, SIG_IGN); return; } - cfg = get_next_config_val(upstreamip, upstreamindex++); /* Or else we try the next ConnectTo line */ +// cfg = get_next_config_val(config, upstreamip, upstreamindex++); /* Or else we try the next ConnectTo line */ } signal(SIGALRM, sigalrm_handler); @@ -679,7 +681,7 @@ int setup_network_connections(void) { config_t const *cfg; cp - if((cfg = get_config_val(pingtimeout)) == NULL) + if((cfg = get_config_val(config, pingtimeout)) == NULL) timeout = 5; else timeout = cfg->data.val; @@ -690,7 +692,7 @@ cp if(setup_myself() < 0) return -1; - if((cfg = get_next_config_val(upstreamip, upstreamindex++)) == NULL) +// if((cfg = get_next_config_val(config, upstreamip, upstreamindex++)) == NULL) /* No upstream IP given, we're listen only. */ return 0; @@ -698,7 +700,7 @@ cp { if(!setup_outgoing_connection(cfg->data.ptr)) /* function returns 0 when there are no problems */ return 0; - cfg = get_next_config_val(upstreamip, upstreamindex++); /* Or else we try the next ConnectTo line */ +// cfg = get_next_config_val(config, upstreamip, upstreamindex++); /* Or else we try the next ConnectTo line */ } signal(SIGALRM, sigalrm_handler); @@ -767,7 +769,7 @@ cp a.sin_family = AF_INET; a.sin_port = htons(cl->port); - a.sin_addr.s_addr = htonl(cl->real_ip); + a.sin_addr.s_addr = htonl(cl->address); if(connect(nfd, (struct sockaddr *)&a, sizeof(a)) == -1) { @@ -808,10 +810,12 @@ cp return NULL; } - p->real_ip = ntohl(ci.sin_addr.s_addr); + p->name = unknown; + p->address = ntohl(ci.sin_addr.s_addr); p->hostname = hostlookup(ci.sin_addr.s_addr); p->meta_socket = sfd; p->status.meta = 1; + p->buffer = xmalloc(MAXBUFSIZE); p->buflen = 0; p->last_ping_time = time(NULL); p->want_ping = 0; @@ -820,9 +824,9 @@ cp syslog(LOG_NOTICE, _("Connection from %s port %d"), p->hostname, htons(ci.sin_port)); - if(send_basic_info(p) < 0) + if(send_id(p) < 0) { - free_conn_element(p); + free_conn_list(p); return NULL; } cp @@ -900,12 +904,6 @@ cp if(debug_lvl > 0) syslog(LOG_NOTICE, _("Closing connection with %s (%s)"), cl->name, cl->hostname); - - if(cl->status.timeout) - send_timeout(cl); -/* else if(!cl->status.termreq) - send_termreq(cl); - */ if(cl->socket) close(cl->socket); @@ -915,8 +913,11 @@ cp cl->status.remove = 1; /* If this cl isn't active, don't send any DEL_HOSTs. */ + +/* FIXME: reprogram this. if(cl->status.active) notify_others(cl,NULL,send_del_host); +*/ cp /* Find all connections that were lost because they were behind cl @@ -927,7 +928,9 @@ cp if((p->nexthop == cl) && (p != cl)) { if(cl->status.active && p->status.active) +/* FIXME: reprogram this notify_others(p,cl,send_del_host); +*/; if(cl->socket) close(cl->socket); p->status.active = 0; @@ -1146,17 +1149,19 @@ cp if(sighup) { sighup = 0; +/* FIXME: reprogram this. if(debug_lvl > 1) syslog(LOG_INFO, _("Rereading configuration file")); close_network_connections(); clear_config(); - if(read_config_file(configfilename)) + if(read_config_file(&config, configfilename)) { syslog(LOG_ERR, _("Unable to reread configuration file, exiting")); exit(0); } sleep(5); setup_network_connections(); +*/ continue; }