From: Guus Sliepen Date: Sun, 5 Jun 2016 13:23:07 +0000 (+0200) Subject: Preserve IPv6 scope_id in edges. X-Git-Tag: release-1.0.29~10 X-Git-Url: https://git.tinc-vpn.org/git/browse?a=commitdiff_plain;h=48e353e9fdf189c4fd5fa7ebc76a72535b4f6632;p=tinc Preserve IPv6 scope_id in edges. 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. --- diff --git a/src/netutl.c b/src/netutl.c index 2abbe86d..37887be8 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 7fc41e8a..7c31f2b0 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 8fa9b93c..091629a1 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;