Determine peer's reflexive address and port when exchanging keys.
To help peers that are behind NAT connect to each other directly via UDP, they need to know the exact external address and port that they use. Keys exchanged between NATted peers necessarily go via a third node, which knows this address and port, and can append this information to the keys, which is in turned used by the peers. Since PMTU discovery will immediately trigger UDP communication from both sides to each other, this should allow direct communication between peers behind full, address-restricted and port-restricted cone NAT.
This commit is contained in:
parent
d15099e002
commit
4a0b998151
1 changed files with 20 additions and 2 deletions
|
@ -179,12 +179,14 @@ bool ans_key_h(connection_t *c) {
|
||||||
char from_name[MAX_STRING_SIZE];
|
char from_name[MAX_STRING_SIZE];
|
||||||
char to_name[MAX_STRING_SIZE];
|
char to_name[MAX_STRING_SIZE];
|
||||||
char key[MAX_STRING_SIZE];
|
char key[MAX_STRING_SIZE];
|
||||||
|
char address[MAX_STRING_SIZE] = "";
|
||||||
|
char port[MAX_STRING_SIZE] = "";
|
||||||
int cipher, digest, maclength, compression;
|
int cipher, digest, maclength, compression;
|
||||||
node_t *from, *to;
|
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,
|
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,
|
logger(LOG_ERR, "Got bad %s from %s (%s)", "ANS_KEY", c->name,
|
||||||
c->hostname);
|
c->hostname);
|
||||||
return false;
|
return false;
|
||||||
|
@ -223,6 +225,16 @@ bool ans_key_h(connection_t *c) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!*address) {
|
||||||
|
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);
|
return send_request(to->nexthop->connection, "%s", c->buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,6 +302,12 @@ bool ans_key_h(connection_t *c) {
|
||||||
from->status.validkey = true;
|
from->status.validkey = true;
|
||||||
from->sent_seqno = 0;
|
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)
|
if(from->options & OPTION_PMTU_DISCOVERY && !from->mtuprobes)
|
||||||
send_mtu_probe(from);
|
send_mtu_probe(from);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue