X-Git-Url: https://git.librecmc.org/?p=oweals%2Ftinc.git;a=blobdiff_plain;f=src%2Fnet.c;h=893892c033bedbb453453829ddd384a853ac45ed;hp=5e8cfaffaa8a103c819516a664fc4dda80469940;hb=1eedf54681d4556c6874f7baee8e810cab867756;hpb=0806605ce383b7e89fa26eda56f8a5f3bbed9dd3;ds=sidebyside diff --git a/src/net.c b/src/net.c index 5e8cfaf..893892c 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.81 2000/11/24 23:13:02 guus Exp $ + $Id: net.c,v 1.35.4.82 2000/11/25 13:33:30 guus Exp $ */ #include "config.h" @@ -100,6 +100,8 @@ int xsend(connection_t *cl, vpn_packet_t *inpkt) vpn_packet_t outpkt; int outlen, outpad; EVP_CIPHER_CTX ctx; + struct sockaddr_in to; + socklen_t tolen = sizeof(to); cp outpkt.len = inpkt->len; @@ -121,7 +123,11 @@ cp total_socket_out += outlen; - if((send(cl->socket, (char *) &(outpkt.len), outlen, 0)) < 0) + to.sin_family = AF_INET; + to.sin_addr.s_addr = htonl(cl->address); + to.sin_port = htons(cl->port); + + if((sendto(myself->socket, (char *) &(outpkt.len), outlen, 0, (const struct sockaddr *)&to, tolen)) < 0) { syslog(LOG_ERR, _("Error sending packet to %s (%s): %m"), cl->name, cl->hostname); @@ -336,17 +342,6 @@ 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) - { - syslog(LOG_ERR, _("Could not open UDP connection to %s (%s)"), - cl->name, cl->hostname); - return -1; - } - */ - if(!cl->status.validkey) { /* FIXME: Don't queue until everything else is fixed. @@ -384,19 +379,31 @@ int setup_tap_fd(void) int nfd; const char *tapfname; config_t const *cfg; -#ifdef HAVE_TUNTAP +#ifdef HAVE_LINUX + #ifdef HAVE_TUNTAP struct ifreq ifr; + #endif #endif cp if((cfg = get_config_val(config, config_tapdevice))) tapfname = cfg->data.ptr; else -#ifdef HAVE_TUNTAP - tapfname = "/dev/misc/net/tun"; -#else - tapfname = "/dev/tap0"; + { +#ifdef HAVE_LINUX + #ifdef HAVE_TUNTAP + tapfname = "/dev/misc/net/tun"; + #else + tapfname = "/dev/tap0"; + #endif +#endif +#ifdef HAVE_FREEBSD + tapfname = "/dev/tap0"; #endif +#ifdef HAVE_SOLARIS + tapfname = "/dev/tun"; +#endif + } cp if((nfd = open(tapfname, O_RDWR | O_NONBLOCK)) < 0) { @@ -406,9 +413,10 @@ cp cp tap_fd = nfd; + taptype = TAP_TYPE_ETHERTAP; + /* Set default MAC address for ethertap devices */ - taptype = TAP_TYPE_ETHERTAP; mymac.type = SUBNET_MAC; mymac.net.mac.address.x[0] = 0xfe; mymac.net.mac.address.x[1] = 0xfd; @@ -417,7 +425,8 @@ cp mymac.net.mac.address.x[4] = 0x00; mymac.net.mac.address.x[5] = 0x00; -#ifdef HAVE_TUNTAP +#ifdef HAVE_LINUX + #ifdef HAVE_TUNTAP /* Ok now check if this is an old ethertap or a new tun/tap thingie */ memset(&ifr, 0, sizeof(ifr)); cp @@ -430,6 +439,10 @@ cp syslog(LOG_INFO, _("%s is a new style tun/tap device"), tapfname); taptype = TAP_TYPE_TUNTAP; } + #endif +#endif +#ifdef HAVE_FREEBSD + taptype = TAP_TYPE_TUNTAP; #endif cp return 0; @@ -618,11 +631,7 @@ cp } /* - setup an outgoing connection. It's not - necessary to also open an udp socket as - well, because the other host will initiate - an authentication sequence during which - we will do just that. + Setup an outgoing meta connection. */ int setup_outgoing_connection(char *name) { @@ -781,7 +790,13 @@ cp 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 TCP socket!")); + return -1; + } + + if((myself->socket = setup_vpn_in_socket(myself->port)) < 0) + { + syslog(LOG_ERR, _("Unable to set up a listening UDP socket!")); return -1; } @@ -929,6 +944,7 @@ cp /* create a data (udp) socket + OBSOLETED: use only one listening socket for compatibility with non-Linux operating systems */ int setup_vpn_connection(connection_t *cl) { @@ -1049,13 +1065,13 @@ void build_fdset(fd_set *fs) cp FD_ZERO(fs); + FD_SET(myself->socket, fs); + RBL_FOREACH(connection_tree, rbl) { p = (connection_t *)rbl->data; if(p->status.meta) FD_SET(p->meta_socket, fs); - if(p->status.dataopen) - FD_SET(p->socket, fs); } FD_SET(myself->meta_socket, fs); @@ -1068,16 +1084,19 @@ cp udp socket and write it to the ethertap device after being decrypted */ -int handle_incoming_vpn_data(connection_t *cl) +int handle_incoming_vpn_data(void) { vpn_packet_t pkt; int x, l = sizeof(x); int lenin; + struct sockaddr_in from; + socklen_t fromlen = sizeof(from); + connection_t *cl; cp - if(getsockopt(cl->socket, SOL_SOCKET, SO_ERROR, &x, &l) < 0) + if(getsockopt(myself->socket, SOL_SOCKET, SO_ERROR, &x, &l) < 0) { syslog(LOG_ERR, _("This is a bug: %s:%d: %d:%m"), - __FILE__, __LINE__, cl->socket); + __FILE__, __LINE__, myself->socket); return -1; } if(x) @@ -1086,12 +1105,20 @@ cp return -1; } - if((lenin = recv(cl->socket, (char *) &(pkt.len), MTU, 0)) <= 0) + if((lenin = recvfrom(myself->socket, (char *) &(pkt.len), MTU, 0, (struct sockaddr *)&from, &fromlen)) <= 0) { syslog(LOG_ERR, _("Receiving packet failed: %m")); return -1; } + cl = lookup_connection(ntohl(from.sin_addr.s_addr), ntohs(from.sin_port)); + + if(!cl) + { + syslog(LOG_WARNING, _("Received UDP packets on port %d from unknown source %lx:%d"), ntohl(from.sin_addr.s_addr), ntohs(from.sin_port)); + return 0; + } + if(debug_lvl >= DEBUG_TRAFFIC) { syslog(LOG_DEBUG, _("Received packet of %d bytes from %s (%s)"), lenin, @@ -1250,6 +1277,9 @@ void check_network_activity(fd_set *f) connection_t *p; rbl_t *rbl; cp + if(FD_ISSET(myself->socket, f)) + handle_incoming_vpn_data(); + RBL_FOREACH(connection_tree, rbl) { p = (connection_t *)rbl->data; @@ -1257,21 +1287,6 @@ cp if(p->status.remove) return; - if(p->status.dataopen) - if(FD_ISSET(p->socket, f)) - { - 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(p->status.meta) if(FD_ISSET(p->meta_socket, f)) if(receive_meta(p) < 0)