From: Guus Sliepen Date: Mon, 9 May 2011 19:35:14 +0000 (+0200) Subject: Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 X-Git-Tag: import-tinc-1.1~540 X-Git-Url: http://git.meshlink.io/?p=meshlink;a=commitdiff_plain;h=ce8775000ab38229a78ecf3dc26bab008ca0f332 Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1 Conflicts: NEWS README configure.in doc/tincd.8.in lib/pidfile.c src/bsd/device.c src/dropin.h src/net.c src/net_packet.c src/node.c src/process.c src/tincd.c --- ce8775000ab38229a78ecf3dc26bab008ca0f332 diff --cc NEWS index cee37ea8,792a71f1..c48a0e80 --- a/NEWS +++ b/NEWS @@@ -1,10 -1,4 +1,10 @@@ +Version 1.1-cvs Work in progress + + * Use libevent to handle I/O events and timeouts. + + * Use splay trees instead of AVL trees. + - Version 1.0.14 not released yet + Version 1.0.14 May 8 2011 * Fixed reading configuration files that do not end with a newline. Again. diff --cc README index 3f21f25d,bc8bea00..b1236fab --- a/README +++ b/README @@@ -1,7 -1,7 +1,7 @@@ -This is the README file for tinc version 1.0.14. Installation +This is the README file for tinc version 1.1-cvs. Installation instructions may be found in the INSTALL file. - tinc is Copyright (C) 1998-2010 by: + tinc is Copyright (C) 1998-2011 by: Ivo Timmermans, Guus Sliepen , @@@ -69,18 -69,13 +69,16 @@@ this library is not installed on you sy manual in doc/tinc.texi contains more detailed information on how to install this library. - Since 1.0pre6, the zlib library is used for optional compression. You need this - library whether or not you plan to enable the compression. You can find it at - http://www.gzip.org/zlib/. Because of a possible exploit in earlier versions we - recommand that you download version 1.1.4 or later. + Since 1.0pre6, the zlib library is used for optional compression. You can + find it at http://www.gzip.org/zlib/. Because of a possible exploit in + earlier versions we recommend that you download version 1.1.4 or later. - Since 1.0, the lzo library is also used for optional compression. You need this - library whether or not you plan to enable compression. You can find it at - http://www.oberhumer.com/opensource/lzo/. + Since 1.0, the lzo library is also used for optional compression. You can + find it at http://www.oberhumer.com/opensource/lzo/. +Since 1.1, the libevent library is used for the main event loop. You can find +it at http://monkey.org/~provos/libevent/. + In order to compile tinc, you will need a GNU C compiler environment. diff --cc configure.in index 5aacff6a,a6dd6d69..7c050139 --- a/configure.in +++ b/configure.in @@@ -98,8 -101,8 +100,8 @@@ dnl Checks for header files dnl We do this in multiple stages, because unlike Linux all the other operating systems really suck and don't include their own dependencies. AC_HEADER_STDC - AC_CHECK_HEADERS([stdbool.h syslog.h sys/file.h sys/ioctl.h sys/mman.h sys/param.h sys/socket.h sys/time.h sys/uio.h sys/un.h sys/wait.h netdb.h arpa/inet.h dirent.h]) - AC_CHECK_HEADERS([net/if.h net/if_types.h linux/if_tun.h net/if_tun.h net/if_tap.h net/ethernet.h net/if_arp.h netinet/in_systm.h netinet/in.h netinet/in6.h time.h], -AC_CHECK_HEADERS([stdbool.h syslog.h sys/file.h sys/ioctl.h sys/mman.h sys/param.h sys/resource.h sys/socket.h sys/time.h sys/uio.h sys/wait.h netdb.h arpa/inet.h dirent.h]) -AC_CHECK_HEADERS([net/if.h net/if_types.h linux/if_tun.h net/if_tun.h net/tun/if_tun.h net/if_tap.h net/tap/if_tap.h net/ethernet.h net/if_arp.h netinet/in_systm.h netinet/in.h netinet/in6.h], ++AC_CHECK_HEADERS([stdbool.h syslog.h sys/file.h sys/ioctl.h sys/mman.h sys/param.h sys/resource.h sys/socket.h sys/time.h sys/uio.h sys/un.h sys/wait.h netdb.h arpa/inet.h dirent.h]) ++AC_CHECK_HEADERS([net/if.h net/if_types.h linux/if_tun.h net/if_tun.h net/tun/if_tun.h net/if_tap.h net/tap/if_tap.h net/ethernet.h net/if_arp.h netinet/in_systm.h netinet/in.h netinet/in6.h time.h], [], [], [#include "have.h"] ) AC_CHECK_HEADERS([netinet/if_ether.h netinet/ip.h netinet/ip6.h], @@@ -127,7 -130,7 +129,7 @@@ dnl Checks for library functions AC_FUNC_MEMCMP AC_FUNC_ALLOCA AC_TYPE_SIGNAL - AC_CHECK_FUNCS([asprintf daemon fchmod flock ftime fork get_current_dir_name gettimeofday mlockall putenv random select strdup strerror strsignal strtol system time unsetenv vsyslog writev], -AC_CHECK_FUNCS([asprintf daemon fchmod flock ftime fork get_current_dir_name gettimeofday mlockall putenv random select strdup strerror strsignal strtol system unsetenv usleep vsyslog writev], ++AC_CHECK_FUNCS([asprintf daemon fchmod flock ftime fork get_current_dir_name gettimeofday mlockall putenv random select strdup strerror strsignal strtol system time usleep unsetenv vsyslog writev], [], [], [#include "have.h"] ) AC_FUNC_MALLOC diff --cc doc/tinc.texi index 3dc9eca4,6bbc2e24..7fc8909f --- a/doc/tinc.texi +++ b/doc/tinc.texi @@@ -37,10 -37,9 +37,10 @@@ permission notice identical to this one @page @vskip 0pt plus 1filll +@cindex copyright This is the info manual for @value{PACKAGE} version @value{VERSION}, a Virtual Private Network daemon. - Copyright @copyright{} 1998-2010 Ivo Timmermans, + Copyright @copyright{} 1998-2011 Ivo Timmermans, Guus Sliepen and Wessel Dankers . @@@ -1552,12 -1558,24 +1574,16 @@@ This will also disable the automatic re Set debug level to @var{level}. The higher the debug level, the more gets logged. Everything goes via syslog. -@item -k, --kill[=@var{signal}] -Attempt to kill a running tincd (optionally with the specified @var{signal} instead of SIGTERM) and exit. -Use it in conjunction with the -n option to make sure you kill the right tinc daemon. -Under native Windows the optional argument is ignored, -the service will always be stopped and removed. - @item -n, --net=@var{netname} - Use configuration for net @var{netname}. @xref{Multiple networks}. + Use configuration for net @var{netname}. + This will let tinc read all configuration files from + @file{@value{sysconfdir}/tinc/@var{netname}/}. + Specifying . for @var{netname} is the same as not specifying any @var{netname}. + @xref{Multiple networks}. -@item -K, --generate-keys[=@var{bits}] -Generate public/private keypair of @var{bits} length. If @var{bits} is not specified, -2048 is the default. tinc will ask where you want to store the files, -but will default to the configuration directory (you can use the -c or -n option -in combination with -K). After that, tinc will quit. +@item --controlsocket=@var{filename} +Open control socket at @var{filename}. If unspecified, the default is +@file{@value{localstatedir}/run/tinc.@var{netname}.control}. @item -L, --mlock Lock tinc into main memory. diff --cc doc/tincd.8.in index df6af144,a8ef2fb8..a210979e --- a/doc/tincd.8.in +++ b/doc/tincd.8.in @@@ -53,6 -56,29 +53,14 @@@ Increase debug level or set it t .It Fl n, -net Ns = Ns Ar NETNAME Connect to net .Ar NETNAME . + This will let tinc read all configuration files from + .Pa @sysconfdir@/tinc/ Ar NETNAME . + Specifying + .Li . + for + .Ar NETNAME + is the same as not specifying any + .Ar NETNAME . -.It Fl K, -generate-keys Ns Op = Ns Ar BITS -Generate public/private RSA keypair and exit. -If -.Ar BITS -is omitted, the default length will be 2048 bits. -When saving keys to existing files, tinc will not delete the old keys, -you have to remove them manually. .It Fl L, -mlock Lock tinc into main memory. This will prevent sensitive data like shared private keys to be written to the system swap files/partitions. diff --cc src/bsd/device.c index 993b9825,d6ef0e82..d647734e --- a/src/bsd/device.c +++ b/src/bsd/device.c @@@ -197,13 -197,12 +197,12 @@@ bool read_packet(vpn_packet_t *packet) #ifdef HAVE_TUNEMU case DEVICE_TYPE_TUNEMU: if(device_type == DEVICE_TYPE_TUNEMU) - lenin = tunemu_read(device_fd, packet->data + 14, MTU - 14); + inlen = tunemu_read(device_fd, packet->data + 14, MTU - 14); else - #else - inlen = read(device_fd, packet->data + 14, MTU - 14); #endif - lenin = read(device_fd, packet->data + 14, MTU - 14); ++ inlen = read(device_fd, packet->data + 14, MTU - 14); - if(lenin <= 0) { + if(inlen <= 0) { logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); return false; diff --cc src/dropin.c index 52fb5b86,00000000..4aed74e9 mode 100644,000000..100644 --- a/src/dropin.c +++ b/src/dropin.c @@@ -1,172 -1,0 +1,173 @@@ +/* + dropin.c -- a set of drop-in replacements for libc functions + Copyright (C) 2000-2005 Ivo Timmermans, - 2000-2009 Guus Sliepen ++ 2000-2011 Guus Sliepen + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" + +#include "xalloc.h" + +#ifndef HAVE_DAEMON +/* + Replacement for the daemon() function. + + The daemon() function is for programs wishing to detach themselves + from the controlling terminal and run in the background as system + daemons. + + Unless the argument nochdir is non-zero, daemon() changes the + current working directory to the root (``/''). + + Unless the argument noclose is non-zero, daemon() will redirect + standard input, standard output and standard error to /dev/null. +*/ +int daemon(int nochdir, int noclose) { +#ifdef HAVE_FORK + pid_t pid; + int fd; + + pid = fork(); + + /* Check if forking failed */ + if(pid < 0) { + perror("fork"); + exit(-1); + } + + /* If we are the parent, terminate */ + if(pid) + exit(0); + + /* Detach by becoming the new process group leader */ + if(setsid() < 0) { + perror("setsid"); + return -1; + } + + /* Change working directory to the root (to avoid keeping mount + points busy) */ + if(!nochdir) { + chdir("/"); + } + + /* Redirect stdin/out/err to /dev/null */ + if(!noclose) { + fd = open("/dev/null", O_RDWR); + + if(fd < 0) { + perror("opening /dev/null"); + return -1; + } else { + dup2(fd, 0); + dup2(fd, 1); + dup2(fd, 2); + } + } + + return 0; +#else + return -1; +#endif +} +#endif + +#ifndef HAVE_GET_CURRENT_DIR_NAME +/* + Replacement for the GNU get_current_dir_name function: + + get_current_dir_name will malloc(3) an array big enough to hold the + current directory name. If the environment variable PWD is set, and + its value is correct, then that value will be returned. +*/ +char *get_current_dir_name(void) { + size_t size; + char *buf; + char *r; + + /* Start with 100 bytes. If this turns out to be insufficient to + contain the working directory, double the size. */ + size = 100; + buf = xmalloc(size); + + errno = 0; /* Success */ + r = getcwd(buf, size); + + /* getcwd returns NULL and sets errno to ERANGE if the bufferspace + is insufficient to contain the entire working directory. */ + while(r == NULL && errno == ERANGE) { + free(buf); + size <<= 1; /* double the size */ + buf = xmalloc(size); + r = getcwd(buf, size); + } + + return buf; +} +#endif + +#ifndef HAVE_ASPRINTF +int asprintf(char **buf, const char *fmt, ...) { + int result; + va_list ap; + va_start(ap, fmt); + result = vasprintf(buf, fmt, ap); + va_end(ap); + return result; +} + +int vasprintf(char **buf, const char *fmt, va_list ap) { + int status; + va_list aq; + int len; + + len = 4096; + *buf = xmalloc(len); + + va_copy(aq, ap); + status = vsnprintf(*buf, len, fmt, aq); + va_end(aq); + + if(status >= 0) + *buf = xrealloc(*buf, status + 1); + + if(status > len - 1) { + len = status; + va_copy(aq, ap); + status = vsnprintf(*buf, len, fmt, aq); + va_end(aq); + } + + return status; +} +#endif + +#ifndef HAVE_GETTIMEOFDAY +int gettimeofday(struct timeval *tv, void *tz) { + tv->tv_sec = time(NULL); + tv->tv_usec = 0; + return 0; +} +#endif + - #ifdef HAVE_MINGW ++#ifndef HAVE_USLEEP +int usleep(long usec) { - Sleep(usec / 1000); ++ struct timeval tv = {usec / 1000000, (usec / 1000) % 1000}; ++ select(0, NULL, NULL, NULL, &tv); + return 0; +} +#endif diff --cc src/dropin.h index e9d13535,00000000..a3a22e3f mode 100644,000000..100644 --- a/src/dropin.h +++ b/src/dropin.h @@@ -1,44 -1,0 +1,44 @@@ +/* + dropin.h -- header file for dropin.c + Copyright (C) 2000-2005 Ivo Timmermans, - 2000-2009 Guus Sliepen ++ 2000-2011 Guus Sliepen + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef __DROPIN_H__ +#define __DROPIN_H__ + +#include "fake-getaddrinfo.h" +#include "fake-getnameinfo.h" + +#ifndef HAVE_DAEMON +extern int daemon(int, int); +#endif + +#ifndef HAVE_GET_CURRENT_DIR_NAME +extern char *get_current_dir_name(void); +#endif + +#ifndef HAVE_ASPRINTF +extern int asprintf(char **, const char *, ...); +extern int vasprintf(char **, const char *, va_list ap); +#endif + +#ifndef HAVE_GETTIMEOFDAY +extern int gettimeofday(struct timeval *, void *); +#endif + +#endif /* __DROPIN_H__ */ diff --cc src/memcmp.c index 8103e1a7,00000000..91049948 mode 100644,000000..100644 --- a/src/memcmp.c +++ b/src/memcmp.c @@@ -1,391 -1,0 +1,395 @@@ +/* Copyright (C) 1991, 1993, 1995, 1997, 1998 Free Software Foundation, Inc. + Contributed by Torbjorn Granlund (tege@sics.se). + + NOTE: The canonical source of this file is maintained with the GNU C Library. + Bugs can be reported to bug-glibc@prep.ai.mit.edu. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + ++#ifdef HAVE_INTTYPES_H ++#include ++#endif ++ +#undef __ptr_t +#if defined __cplusplus || (defined __STDC__ && __STDC__) +# define __ptr_t void * +#else /* Not C++ or ANSI C. */ +# undef const +# define const +# define __ptr_t char * +#endif /* C++ or ANSI C. */ + +#ifndef __P +# if defined __GNUC__ || (defined __STDC__ && __STDC__) +# define __P(args) args +# else +# define __P(args) () +# endif /* GCC. */ +#endif /* Not __P. */ + +#if defined HAVE_STRING_H || defined _LIBC +# include +#endif + +#undef memcmp + +#ifdef _LIBC + +# include + +#else /* Not in the GNU C library. */ + +# include + +/* Type to use for aligned memory operations. + This should normally be the biggest type supported by a single load + and store. Must be an unsigned type. */ +# define op_t unsigned long int +# define OPSIZ (sizeof(op_t)) + +/* Threshold value for when to enter the unrolled loops. */ +# define OP_T_THRES 16 + +/* Type to use for unaligned operations. */ +typedef unsigned char byte; + +# ifndef WORDS_BIGENDIAN +# define MERGE(w0, sh_1, w1, sh_2) (((w0) >> (sh_1)) | ((w1) << (sh_2))) +# else +# define MERGE(w0, sh_1, w1, sh_2) (((w0) << (sh_1)) | ((w1) >> (sh_2))) +# endif + +#endif /* In the GNU C library. */ + +#ifdef WORDS_BIGENDIAN +# define CMP_LT_OR_GT(a, b) ((a) > (b) ? 1 : -1) +#else +# define CMP_LT_OR_GT(a, b) memcmp_bytes ((a), (b)) +#endif + +/* BE VERY CAREFUL IF YOU CHANGE THIS CODE! */ + +/* The strategy of this memcmp is: + + 1. Compare bytes until one of the block pointers is aligned. + + 2. Compare using memcmp_common_alignment or + memcmp_not_common_alignment, regarding the alignment of the other + block after the initial byte operations. The maximum number of + full words (of type op_t) are compared in this way. + + 3. Compare the few remaining bytes. */ + +#ifndef WORDS_BIGENDIAN +/* memcmp_bytes -- Compare A and B bytewise in the byte order of the machine. + A and B are known to be different. + This is needed only on little-endian machines. */ + +static int memcmp_bytes __P((op_t, op_t)); + +# ifdef __GNUC__ +__inline +# endif +static int +memcmp_bytes (a, b) + op_t a, b; +{ + intptr_t srcp1 = (intptr_t) &a; + intptr_t srcp2 = (intptr_t) &b; + op_t a0, b0; + + do + { + a0 = ((byte *) srcp1)[0]; + b0 = ((byte *) srcp2)[0]; + srcp1 += 1; + srcp2 += 1; + } + while (a0 == b0); + return a0 - b0; +} +#endif + +static int memcmp_common_alignment __P((intptr_t, intptr_t, size_t)); + +/* memcmp_common_alignment -- Compare blocks at SRCP1 and SRCP2 with LEN `op_t' + objects (not LEN bytes!). Both SRCP1 and SRCP2 should be aligned for + memory operations on `op_t's. */ +#ifdef __GNUC__ +__inline +#endif +static int +memcmp_common_alignment (srcp1, srcp2, len) + intptr_t srcp1; + intptr_t srcp2; + size_t len; +{ + op_t a0, a1; + op_t b0, b1; + + switch (len % 4) + { + default: /* Avoid warning about uninitialized local variables. */ + case 2: + a0 = ((op_t *) srcp1)[0]; + b0 = ((op_t *) srcp2)[0]; + srcp1 -= 2 * OPSIZ; + srcp2 -= 2 * OPSIZ; + len += 2; + goto do1; + case 3: + a1 = ((op_t *) srcp1)[0]; + b1 = ((op_t *) srcp2)[0]; + srcp1 -= OPSIZ; + srcp2 -= OPSIZ; + len += 1; + goto do2; + case 0: + if (OP_T_THRES <= 3 * OPSIZ && len == 0) + return 0; + a0 = ((op_t *) srcp1)[0]; + b0 = ((op_t *) srcp2)[0]; + goto do3; + case 1: + a1 = ((op_t *) srcp1)[0]; + b1 = ((op_t *) srcp2)[0]; + srcp1 += OPSIZ; + srcp2 += OPSIZ; + len -= 1; + if (OP_T_THRES <= 3 * OPSIZ && len == 0) + goto do0; + /* Fall through. */ + } + + do + { + a0 = ((op_t *) srcp1)[0]; + b0 = ((op_t *) srcp2)[0]; + if (a1 != b1) + return CMP_LT_OR_GT (a1, b1); + + do3: + a1 = ((op_t *) srcp1)[1]; + b1 = ((op_t *) srcp2)[1]; + if (a0 != b0) + return CMP_LT_OR_GT (a0, b0); + + do2: + a0 = ((op_t *) srcp1)[2]; + b0 = ((op_t *) srcp2)[2]; + if (a1 != b1) + return CMP_LT_OR_GT (a1, b1); + + do1: + a1 = ((op_t *) srcp1)[3]; + b1 = ((op_t *) srcp2)[3]; + if (a0 != b0) + return CMP_LT_OR_GT (a0, b0); + + srcp1 += 4 * OPSIZ; + srcp2 += 4 * OPSIZ; + len -= 4; + } + while (len != 0); + + /* This is the right position for do0. Please don't move + it into the loop. */ + do0: + if (a1 != b1) + return CMP_LT_OR_GT (a1, b1); + return 0; +} + +static int memcmp_not_common_alignment __P((intptr_t, intptr_t, size_t)); + +/* memcmp_not_common_alignment -- Compare blocks at SRCP1 and SRCP2 with LEN + `op_t' objects (not LEN bytes!). SRCP2 should be aligned for memory + operations on `op_t', but SRCP1 *should be unaligned*. */ +#ifdef __GNUC__ +__inline +#endif +static int +memcmp_not_common_alignment (srcp1, srcp2, len) + intptr_t srcp1; + intptr_t srcp2; + size_t len; +{ + op_t a0, a1, a2, a3; + op_t b0, b1, b2, b3; + op_t x; + int shl, shr; + + /* Calculate how to shift a word read at the memory operation + aligned srcp1 to make it aligned for comparison. */ + + shl = 8 * (srcp1 % OPSIZ); + shr = 8 * OPSIZ - shl; + + /* Make SRCP1 aligned by rounding it down to the beginning of the `op_t' + it points in the middle of. */ + srcp1 &= -OPSIZ; + + switch (len % 4) + { + default: /* Avoid warning about uninitialized local variables. */ + case 2: + a1 = ((op_t *) srcp1)[0]; + a2 = ((op_t *) srcp1)[1]; + b2 = ((op_t *) srcp2)[0]; + srcp1 -= 1 * OPSIZ; + srcp2 -= 2 * OPSIZ; + len += 2; + goto do1; + case 3: + a0 = ((op_t *) srcp1)[0]; + a1 = ((op_t *) srcp1)[1]; + b1 = ((op_t *) srcp2)[0]; + srcp2 -= 1 * OPSIZ; + len += 1; + goto do2; + case 0: + if (OP_T_THRES <= 3 * OPSIZ && len == 0) + return 0; + a3 = ((op_t *) srcp1)[0]; + a0 = ((op_t *) srcp1)[1]; + b0 = ((op_t *) srcp2)[0]; + srcp1 += 1 * OPSIZ; + goto do3; + case 1: + a2 = ((op_t *) srcp1)[0]; + a3 = ((op_t *) srcp1)[1]; + b3 = ((op_t *) srcp2)[0]; + srcp1 += 2 * OPSIZ; + srcp2 += 1 * OPSIZ; + len -= 1; + if (OP_T_THRES <= 3 * OPSIZ && len == 0) + goto do0; + /* Fall through. */ + } + + do + { + a0 = ((op_t *) srcp1)[0]; + b0 = ((op_t *) srcp2)[0]; + x = MERGE(a2, shl, a3, shr); + if (x != b3) + return CMP_LT_OR_GT (x, b3); + + do3: + a1 = ((op_t *) srcp1)[1]; + b1 = ((op_t *) srcp2)[1]; + x = MERGE(a3, shl, a0, shr); + if (x != b0) + return CMP_LT_OR_GT (x, b0); + + do2: + a2 = ((op_t *) srcp1)[2]; + b2 = ((op_t *) srcp2)[2]; + x = MERGE(a0, shl, a1, shr); + if (x != b1) + return CMP_LT_OR_GT (x, b1); + + do1: + a3 = ((op_t *) srcp1)[3]; + b3 = ((op_t *) srcp2)[3]; + x = MERGE(a1, shl, a2, shr); + if (x != b2) + return CMP_LT_OR_GT (x, b2); + + srcp1 += 4 * OPSIZ; + srcp2 += 4 * OPSIZ; + len -= 4; + } + while (len != 0); + + /* This is the right position for do0. Please don't move + it into the loop. */ + do0: + x = MERGE(a2, shl, a3, shr); + if (x != b3) + return CMP_LT_OR_GT (x, b3); + return 0; +} + +int +rpl_memcmp (s1, s2, len) + const __ptr_t s1; + const __ptr_t s2; + size_t len; +{ + op_t a0; + op_t b0; + intptr_t srcp1 = (intptr_t) s1; + intptr_t srcp2 = (intptr_t) s2; + op_t res; + + if (len >= OP_T_THRES) + { + /* There are at least some bytes to compare. No need to test + for LEN == 0 in this alignment loop. */ + while (srcp2 % OPSIZ != 0) + { + a0 = ((byte *) srcp1)[0]; + b0 = ((byte *) srcp2)[0]; + srcp1 += 1; + srcp2 += 1; + res = a0 - b0; + if (res != 0) + return res; + len -= 1; + } + + /* SRCP2 is now aligned for memory operations on `op_t'. + SRCP1 alignment determines if we can do a simple, + aligned compare or need to shuffle bits. */ + + if (srcp1 % OPSIZ == 0) + res = memcmp_common_alignment (srcp1, srcp2, len / OPSIZ); + else + res = memcmp_not_common_alignment (srcp1, srcp2, len / OPSIZ); + if (res != 0) + return res; + + /* Number of bytes remaining in the interval [0..OPSIZ-1]. */ + srcp1 += len & -OPSIZ; + srcp2 += len & -OPSIZ; + len %= OPSIZ; + } + + /* There are just a few bytes to compare. Use byte memory operations. */ + while (len != 0) + { + a0 = ((byte *) srcp1)[0]; + b0 = ((byte *) srcp2)[0]; + srcp1 += 1; + srcp2 += 1; + res = a0 - b0; + if (res != 0) + return res; + len -= 1; + } + + return 0; +} + +#ifdef weak_alias +# undef bcmp +weak_alias (memcmp, bcmp) +#endif diff --cc src/net_packet.c index 7be46620,c7efa886..ded80a2f --- a/src/net_packet.c +++ b/src/net_packet.c @@@ -551,32 -572,38 +561,44 @@@ void broadcast_packet(const node_t *fro } static node_t *try_harder(const sockaddr_t *from, const vpn_packet_t *pkt) { - avl_node_t *node; + splay_node_t *node; - node_t *n, *found = NULL; + edge_t *e; + node_t *n = NULL; + bool hard = false; static time_t last_hard_try = 0; + time_t now = time(NULL); + + if(last_hard_try == now) + return NULL; + else + last_hard_try = now; - for(node = node_tree->head; node; node = node->next) { - n = node->data; + for(node = edge_weight_tree->head; node; node = node->next) { + e = node->data; - if(n == myself || !n->status.reachable || !digest_active(&n->indigest)) + if(e->to == myself) continue; - if(try_mac(n, pkt)) { - found = n; - break; + if(sockaddrcmp_noport(from, &e->address)) { + if(last_hard_try == now) + continue; + hard = true; } + + if(!try_mac(e->to, pkt)) + continue; + + n = e->to; + break; } - return found; + if(hard) + last_hard_try = now; + + return n; } -void handle_incoming_vpn_data(int sock) { +void handle_incoming_vpn_data(int sock, short events, void *data) { vpn_packet_t pkt; char *hostname; sockaddr_t from; diff --cc src/node.c index 862bd696,36979ef3..9281178b --- a/src/node.c +++ b/src/node.c @@@ -142,7 -141,12 +142,12 @@@ node_t *lookup_node_udp(const sockaddr_ } void update_node_udp(node_t *n, const sockaddr_t *sa) { + if(n == myself) { + logger(LOG_WARNING, "Trying to update UDP address of myself!\n"); + return; + } + - avl_delete(node_udp_tree, n); + splay_delete(node_udp_tree, n); if(n->hostname) free(n->hostname); diff --cc src/process.c index d588a3fd,e74c1d9a..737a75e2 --- a/src/process.c +++ b/src/process.c @@@ -386,7 -540,13 +386,8 @@@ static struct {SIGBUS, fatal_signal_handler}, {SIGILL, fatal_signal_handler}, {SIGPIPE, ignore_signal_handler}, - {SIGINT, sigint_handler}, - {SIGUSR1, sigusr1_handler}, - {SIGUSR2, sigusr2_handler}, {SIGCHLD, ignore_signal_handler}, - {SIGALRM, sigalrm_handler}, - {SIGWINCH, sigwinch_handler}, + {SIGABRT, SIG_DFL}, {0, NULL} }; #endif