From 48e353e9fdf189c4fd5fa7ebc76a72535b4f6632 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Sun, 5 Jun 2016 15:23:07 +0200 Subject: [PATCH 1/1] Preserve IPv6 scope_id in edges. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit When creating an edge after authenticating a peer, we copy the address used for the TCP connection, but change the port to that used for UDP. But the way we did it discarded the scope_id for IPv6 addresses. This prevented UDP communication from working correctly when connecting to a peer on the same LAN using an IPv6 link-local address. Thanks to Rafał Leśniak for pointing out this issue. --- src/netutl.c | 19 +++++++++++++++++++ src/netutl.h | 1 + src/protocol_auth.c | 6 ++---- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/netutl.c b/src/netutl.c index 2abbe86..37887be 100644 --- a/src/netutl.c +++ b/src/netutl.c @@ -231,6 +231,25 @@ void sockaddrunmap(sockaddr_t *sa) { } } +void sockaddr_setport(sockaddr_t *sa, const char *port) { + uint16_t portnum = htons(atoi(port)); + if(!portnum) + return; + switch(sa->sa.sa_family) { + case AF_INET: + sa->in.sin_port = portnum; + break; + case AF_INET6: + sa->in6.sin6_port = portnum; + break; + case AF_UNKNOWN: + free(sa->unknown.port); + sa->unknown.port = xstrdup(port); + default: + return; + } +} + /* Subnet mask handling */ int maskcmp(const void *va, const void *vb, int masklen) { diff --git a/src/netutl.h b/src/netutl.h index 7fc41e8..7c31f2b 100644 --- a/src/netutl.h +++ b/src/netutl.h @@ -34,6 +34,7 @@ extern int sockaddrcmp_noport(const sockaddr_t *, const sockaddr_t *); extern void sockaddrunmap(sockaddr_t *); extern void sockaddrfree(sockaddr_t *); extern void sockaddrcpy(sockaddr_t *, const sockaddr_t *); +extern void sockaddr_setport(sockaddr_t *, const char *); extern int maskcmp(const void *, const void *, int); extern void maskcpy(void *, const void *, int, int); extern void mask(void *, int, int); diff --git a/src/protocol_auth.c b/src/protocol_auth.c index 8fa9b93..091629a 100644 --- a/src/protocol_auth.c +++ b/src/protocol_auth.c @@ -516,7 +516,6 @@ static void send_everything(connection_t *c) { bool ack_h(connection_t *c) { char hisport[MAX_STRING_SIZE]; - char *hisaddress; int weight, mtu; uint32_t options; node_t *n; @@ -585,9 +584,8 @@ bool ack_h(connection_t *c) { c->edge = new_edge(); c->edge->from = myself; c->edge->to = n; - sockaddr2str(&c->address, &hisaddress, NULL); - c->edge->address = str2sockaddr(hisaddress, hisport); - free(hisaddress); + sockaddrcpy(&c->edge->address, &c->address); + sockaddr_setport(&c->edge->address, hisport); c->edge->weight = (weight + c->estimated_weight) / 2; c->edge->connection = c; c->edge->options = c->options; -- 2.25.1