From: Guus Sliepen Date: Sat, 25 Nov 2000 13:33:33 +0000 (+0000) Subject: - Use only one socket for all UDP traffic (for compatibility) X-Git-Tag: release-1.0pre4~125 X-Git-Url: https://www.tinc-vpn.org/git/browse?p=tinc;a=commitdiff_plain;h=1eedf54681d4556c6874f7baee8e810cab867756 - Use only one socket for all UDP traffic (for compatibility) - Write pidfile again after detaching - Check OS (for handling FreeBSD/Solaris tun/tap stuff) --- diff --git a/acconfig.h b/acconfig.h index 9861a745..7bb8efe1 100644 --- a/acconfig.h +++ b/acconfig.h @@ -44,6 +44,14 @@ # undef getopt #endif +/* Linux */ +#undef HAVE_LINUX + +/* FreeBSD */ +#undef HAVE_FREEBSD + +/* Solaris */ +#undef HAVE_SOLARIS /* Define to the location of the kernel sources */ #undef CONFIG_TINC_KERNELDIR diff --git a/autogen.sh b/autogen.sh index 344fbfa0..9e3c0452 100644 --- a/autogen.sh +++ b/autogen.sh @@ -70,6 +70,9 @@ if test "$DIE" -eq 1; then exit 1 fi +# Make sure configure doesn't complain about old configuration +rm -f config.status + if test -z "$*"; then echo "**Warning**: I am going to run \`configure' with no arguments." echo "If you wish to pass any to it, please specify them on the" diff --git a/configure.in b/configure.in index 7013b995..04bfd024 100644 --- a/configure.in +++ b/configure.in @@ -1,6 +1,6 @@ dnl Process this file with autoconf to produce a configure script. -dnl $Id: configure.in,v 1.13.2.24 2000/11/24 23:12:56 guus Exp $ +dnl $Id: configure.in,v 1.13.2.25 2000/11/25 13:33:30 guus Exp $ AC_INIT(src/tincd.c) AM_INIT_AUTOMAKE(tinc, 1.0pre4-cvs) @@ -29,6 +29,22 @@ jm_PERL AC_ISC_POSIX +dnl Check and set OS + +AC_CANONICAL_HOST + +case $host_os in + *linux*) + AC_DEFINE(HAVE_LINUX) + ;; + *freebsd*) + AC_DEFINE(HAVE_FREEBSD) + ;; + *solaris*) + AC_DEFINE(HAVE_SOLARIS) + ;; +esac + dnl Checks for libraries. dnl Checks for header files. @@ -58,7 +74,6 @@ AM_GNU_GETTEXT dnl Crypto stuff tinc_OPENSSL - dnl Support for SunOS AC_CHECK_FUNC(socket, [], [ diff --git a/src/net.c b/src/net.c index 5e8cfaff..893892c0 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) diff --git a/src/process.c b/src/process.c index 1319c0c0..5aaf573f 100644 --- a/src/process.c +++ b/src/process.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: process.c,v 1.1.2.14 2000/11/24 23:13:05 guus Exp $ + $Id: process.c,v 1.1.2.15 2000/11/25 13:33:33 guus Exp $ */ #include "config.h" @@ -150,12 +150,23 @@ int detach(void) cp setup_signals(); + /* First check if we can open a fresh new pidfile */ + if(write_pidfile()) return -1; + /* If we succeeded in doing that, detach */ + if(do_detach) - if(daemon(0, 0) < 0) - return -1; + { + if(daemon(0, 0) < 0) + return -1; + + /* Now UPDATE the pid in the pidfile, because we changed it... */ + + if(!write_pid(pidfilename)) + return 1; + } openlog(identname, LOG_CONS | LOG_PID, LOG_DAEMON); @@ -177,11 +188,8 @@ cp void _execute_script(const char *name) __attribute__ ((noreturn)); void _execute_script(const char *name) { - int error = 0; char *scriptname; char *s; - int fd; - cp if(netname) { diff --git a/src/protocol.c b/src/protocol.c index 11ce65f0..087589cd 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.66 2000/11/22 22:05:37 guus Exp $ + $Id: protocol.c,v 1.28.4.67 2000/11/25 13:33:33 guus Exp $ */ #include "config.h" @@ -575,8 +575,6 @@ cp if(cl->status.outgoing) cl->allow_request = ACK; - setup_vpn_connection(cl); - x = send_request(cl, "%d", ACK); cl->status.encryptout = 1; cp @@ -901,12 +899,6 @@ cp new->status.active = 1; new->cipher_pkttype = EVP_bf_cfb(); new->cipher_pktkeylength = cl->cipher_pkttype->key_len + cl->cipher_pkttype->iv_len; - - /* Okay this is a bit ugly... it would be better to setup UDP sockets dynamically, or - * perhaps just one UDP socket... but then again, this has benefits too... - */ - - setup_vpn_connection(new); cp return 0; }