From: Guus Sliepen Date: Fri, 19 Nov 2010 12:22:48 +0000 (+0000) Subject: Merge branch 'master' into 1.1 X-Git-Tag: import-tinc-1.1~542 X-Git-Url: http://git.meshlink.io/?a=commitdiff_plain;ds=sidebyside;h=886a6f61a1f4cc48a77b42d10f34f9126377d904;hp=--cc;p=meshlink Merge branch 'master' into 1.1 Conflicts: src/net_packet.c src/openssl/rsagen.h src/protocol_auth.c src/protocol_key.c --- 886a6f61a1f4cc48a77b42d10f34f9126377d904 diff --cc src/dropin.c index 89039da3,00000000..52fb5b86 mode 100644,000000..100644 --- a/src/dropin.c +++ b/src/dropin.c @@@ -1,165 -1,0 +1,172 @@@ +/* + dropin.c -- a set of drop-in replacements for libc functions + Copyright (C) 2000-2005 Ivo Timmermans, + 2000-2009 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 ++int usleep(long usec) { ++ Sleep(usec / 1000); ++ return 0; ++} ++#endif diff --cc src/net.h index f53c27a4,55856e2b..9b625a0d --- a/src/net.h +++ b/src/net.h @@@ -111,9 -110,14 +112,11 @@@ extern unsigned replaywin extern listen_socket_t listen_socket[MAXSOCKETS]; extern int listen_sockets; -extern int keyexpires; extern int keylifetime; + extern int udp_rcvbuf; + extern int udp_sndbuf; extern bool do_prune; -extern bool do_purge; extern char *myport; -extern time_t now; extern int contradicting_add_edge; extern int contradicting_del_edge; diff --cc src/net_packet.c index b444bc93,9e5ef465..7be46620 --- a/src/net_packet.c +++ b/src/net_packet.c @@@ -281,28 -293,35 +284,35 @@@ static void receive_udppacket(node_t *n /* Check the sequence number */ - inpkt->len -= sizeof(inpkt->seqno); + inpkt->len -= sizeof inpkt->seqno; inpkt->seqno = ntohl(inpkt->seqno); - if(inpkt->seqno != n->received_seqno + 1) { - if(inpkt->seqno >= n->received_seqno + sizeof n->late * 8) { - logger(LOG_WARNING, "Lost %d packets from %s (%s)", - inpkt->seqno - n->received_seqno - 1, n->name, n->hostname); - - memset(n->late, 0, sizeof n->late); - } else if (inpkt->seqno <= n->received_seqno) { - if((n->received_seqno >= sizeof n->late * 8 && inpkt->seqno <= n->received_seqno - sizeof n->late * 8) || !(n->late[(inpkt->seqno / 8) % sizeof n->late] & (1 << inpkt->seqno % 8))) { - logger(LOG_WARNING, "Got late or replayed packet from %s (%s), seqno %d, last received %d", - n->name, n->hostname, inpkt->seqno, n->received_seqno); - return; + if(replaywin) { + if(inpkt->seqno != n->received_seqno + 1) { + if(inpkt->seqno >= n->received_seqno + replaywin * 8) { + if(n->farfuture++ < replaywin >> 2) { + logger(LOG_WARNING, "Packet from %s (%s) is %d seqs in the future, dropped (%u)", + n->name, n->hostname, inpkt->seqno - n->received_seqno - 1, n->farfuture); + return; + } + logger(LOG_WARNING, "Lost %d packets from %s (%s)", + inpkt->seqno - n->received_seqno - 1, n->name, n->hostname); + memset(n->late, 0, replaywin); + } else if (inpkt->seqno <= n->received_seqno) { + if((n->received_seqno >= replaywin * 8 && inpkt->seqno <= n->received_seqno - replaywin * 8) || !(n->late[(inpkt->seqno / 8) % replaywin] & (1 << inpkt->seqno % 8))) { + logger(LOG_WARNING, "Got late or replayed packet from %s (%s), seqno %d, last received %d", + n->name, n->hostname, inpkt->seqno, n->received_seqno); + return; + } + } else { + for(i = n->received_seqno + 1; i < inpkt->seqno; i++) + n->late[(i / 8) % replaywin] |= 1 << i % 8; } - } else { - for(i = n->received_seqno + 1; i < inpkt->seqno; i++) - n->late[(i / 8) % sizeof n->late] |= 1 << i % 8; } + + n->farfuture = 0; + n->late[(inpkt->seqno / 8) % replaywin] &= ~(1 << inpkt->seqno % 8); } - - n->late[(inpkt->seqno / 8) % sizeof n->late] &= ~(1 << inpkt->seqno % 8); if(inpkt->seqno > n->received_seqno) n->received_seqno = inpkt->seqno; diff --cc src/net_socket.c index 44d7f771,2e6b0685..e20076fb --- a/src/net_socket.c +++ b/src/net_socket.c @@@ -258,8 -261,14 +260,14 @@@ int setup_vpn_in_socket(const sockaddr_ #endif option = 1; - setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (void *)&option, sizeof(option)); + setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (void *)&option, sizeof option); + if(udp_rcvbuf && setsockopt(nfd, SOL_SOCKET, SO_RCVBUF, (void *)&udp_rcvbuf, sizeof(udp_rcvbuf))) + logger(LOG_WARNING, "Can't set UDP SO_RCVBUF to %i: %s", udp_rcvbuf, strerror(errno)); + + if(udp_sndbuf && setsockopt(nfd, SOL_SOCKET, SO_SNDBUF, (void *)&udp_sndbuf, sizeof(udp_sndbuf))) + logger(LOG_WARNING, "Can't set UDP SO_SNDBUF to %i: %s", udp_sndbuf, strerror(errno)); + #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) if(sa->sa.sa_family == AF_INET6) setsockopt(nfd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&option, sizeof option); diff --cc src/node.c index 0159f9dd,7bcad892..862bd696 --- a/src/node.c +++ b/src/node.c @@@ -60,10 -52,13 +60,11 @@@ void exit_nodes(void) } node_t *new_node(void) { - node_t *n = xmalloc_and_zero(sizeof(*n)); + node_t *n = xmalloc_and_zero(sizeof *n); + if(replaywin) n->late = xmalloc_and_zero(replaywin); n->subnet_tree = new_subnet_tree(); n->edge_tree = new_edge_tree(); - EVP_CIPHER_CTX_init(&n->inctx); - EVP_CIPHER_CTX_init(&n->outctx); n->mtu = MTU; n->maxmtu = MTU; diff --cc src/protocol_key.c index f57dc2ea,fbd7cabb..ec5a690f --- a/src/protocol_key.c +++ b/src/protocol_key.c @@@ -156,17 -163,21 +156,17 @@@ bool send_ans_key(node_t *to) // Reset sequence number and late packet window mykeyused = true; to->received_seqno = 0; - memset(to->late, 0, sizeof(to->late)); + if(replaywin) memset(to->late, 0, replaywin); - // Convert to hexadecimal and send - char key[2 * to->inkeylength + 1]; - bin2hex(to->inkey, key, to->inkeylength); - key[to->inkeylength * 2] = '\0'; - - return send_request(to->nexthop->connection, "%d %s %s %s %d %d %d %d", ANS_KEY, - myself->name, to->name, key, - to->incipher ? to->incipher->nid : 0, - to->indigest ? to->indigest->type : 0, to->inmaclength, - to->incompression); + return send_request(to->nexthop->connection, "%d %s %s %s %d %d %zu %d", ANS_KEY, + myself->name, to->name, key, + cipher_get_nid(&to->incipher), + digest_get_nid(&to->indigest), + digest_length(&to->indigest), + to->incompression); } -bool ans_key_h(connection_t *c) { +bool ans_key_h(connection_t *c, char *request) { char from_name[MAX_STRING_SIZE]; char to_name[MAX_STRING_SIZE]; char key[MAX_STRING_SIZE];