X-Git-Url: https://git.librecmc.org/?p=oweals%2Ftinc.git;a=blobdiff_plain;f=src%2Fprotocol_key.c;h=fbd7cabb8babafdd89fd09ac16a4fa46254bc8f8;hp=ad393d38668a52d8b6feb261b10d22bc1b2d5531;hb=23acc19bc090051156ad895caed61848f5afb144;hpb=d15099e0029578bfd24d6b464b941f4693280001 diff --git a/src/protocol_key.c b/src/protocol_key.c index ad393d3..fbd7cab 100644 --- a/src/protocol_key.c +++ b/src/protocol_key.c @@ -1,7 +1,7 @@ /* protocol_key.c -- handle the meta-protocol, key exchange Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2009 Guus Sliepen + 2000-2010 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 @@ -36,15 +36,19 @@ bool mykeyused = false; -bool send_key_changed() { - /* Only send this message if some other daemon requested our key previously. - This reduces unnecessary key_changed broadcasts. - */ +void send_key_changed() { + avl_node_t *node; + connection_t *c; - if(!mykeyused) - return true; + send_request(broadcast, "%d %x %s", KEY_CHANGED, rand(), myself->name); + + /* Immediately send new keys to directly connected nodes to keep UDP mappings alive */ - return send_request(broadcast, "%d %x %s", KEY_CHANGED, rand(), myself->name); + for(node = connection_tree->head; node; node = node->next) { + c = node->data; + if(c->status.active && c->node && c->node->status.reachable) + send_ans_key(c->node); + } } bool key_changed_h(connection_t *c) { @@ -141,8 +145,6 @@ bool req_key_h(connection_t *c) { } bool send_ans_key(node_t *to) { - char *key; - // Set key parameters to->incipher = myself->incipher; to->inkeylength = myself->inkeylength; @@ -161,10 +163,10 @@ 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 - key = alloca(2 * to->inkeylength + 1); + char key[2 * to->inkeylength + 1]; bin2hex(to->inkey, key, to->inkeylength); key[to->inkeylength * 2] = '\0'; @@ -179,12 +181,14 @@ bool ans_key_h(connection_t *c) { char from_name[MAX_STRING_SIZE]; char to_name[MAX_STRING_SIZE]; char key[MAX_STRING_SIZE]; + char address[MAX_STRING_SIZE] = ""; + char port[MAX_STRING_SIZE] = ""; int cipher, digest, maclength, compression; node_t *from, *to; - if(sscanf(c->buffer, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %d %d %d %d", + if(sscanf(c->buffer, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %d %d %d %d "MAX_STRING" "MAX_STRING, from_name, to_name, key, &cipher, &digest, &maclength, - &compression) != 7) { + &compression, address, port) < 7) { logger(LOG_ERR, "Got bad %s from %s (%s)", "ANS_KEY", c->name, c->hostname); return false; @@ -223,6 +227,16 @@ bool ans_key_h(connection_t *c) { return true; } + if(!*address && from->address.sa.sa_family != AF_UNSPEC) { + char *address, *port; + ifdebug(PROTOCOL) logger(LOG_DEBUG, "Appending reflexive UDP address to ANS_KEY from %s to %s", from->name, to->name); + sockaddr2str(&from->address, &address, &port); + send_request(to->nexthop->connection, "%s %s %s", c->buffer, address, port); + free(address); + free(port); + return true; + } + return send_request(to->nexthop->connection, "%s", c->buffer); } @@ -290,6 +304,12 @@ bool ans_key_h(connection_t *c) { from->status.validkey = true; from->sent_seqno = 0; + if(*address && *port) { + ifdebug(PROTOCOL) logger(LOG_DEBUG, "Using reflexive UDP address from %s: %s port %s", from->name, address, port); + sockaddr_t sa = str2sockaddr(address, port); + update_node_udp(from, &sa); + } + if(from->options & OPTION_PMTU_DISCOVERY && !from->mtuprobes) send_mtu_probe(from);