From eda3d9248971a1c3df6e6c4b23ba89be30508b51 Mon Sep 17 00:00:00 2001 From: mruddy Date: Tue, 5 Apr 2016 22:26:38 +0000 Subject: [PATCH] Net: Add IPv6 Link-Local Address Support --- src/netbase.cpp | 10 +++++++--- src/netbase.h | 3 ++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/netbase.cpp b/src/netbase.cpp index 7f79dd02c6..281c6bcb7f 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -170,7 +170,8 @@ bool static LookupIntern(const char *pszName, std::vector& vIP, unsign if (aiTrav->ai_family == AF_INET6) { assert(aiTrav->ai_addrlen >= sizeof(sockaddr_in6)); - vIP.push_back(CNetAddr(((struct sockaddr_in6*)(aiTrav->ai_addr))->sin6_addr)); + struct sockaddr_in6* s6 = (struct sockaddr_in6*) aiTrav->ai_addr; + vIP.push_back(CNetAddr(s6->sin6_addr, s6->sin6_scope_id)); } aiTrav = aiTrav->ai_next; @@ -629,6 +630,7 @@ bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest void CNetAddr::Init() { memset(ip, 0, sizeof(ip)); + scopeId = 0; } void CNetAddr::SetIP(const CNetAddr& ipIn) @@ -678,9 +680,10 @@ CNetAddr::CNetAddr(const struct in_addr& ipv4Addr) SetRaw(NET_IPV4, (const uint8_t*)&ipv4Addr); } -CNetAddr::CNetAddr(const struct in6_addr& ipv6Addr) +CNetAddr::CNetAddr(const struct in6_addr& ipv6Addr, const uint32_t scope) { SetRaw(NET_IPV6, (const uint8_t*)&ipv6Addr); + scopeId = scope; } CNetAddr::CNetAddr(const char *pszIp, bool fAllowLookup) @@ -1099,7 +1102,7 @@ CService::CService(const struct sockaddr_in& addr) : CNetAddr(addr.sin_addr), po assert(addr.sin_family == AF_INET); } -CService::CService(const struct sockaddr_in6 &addr) : CNetAddr(addr.sin6_addr), port(ntohs(addr.sin6_port)) +CService::CService(const struct sockaddr_in6 &addr) : CNetAddr(addr.sin6_addr, addr.sin6_scope_id), port(ntohs(addr.sin6_port)) { assert(addr.sin6_family == AF_INET6); } @@ -1192,6 +1195,7 @@ bool CService::GetSockAddr(struct sockaddr* paddr, socklen_t *addrlen) const memset(paddrin6, 0, *addrlen); if (!GetIn6Addr(&paddrin6->sin6_addr)) return false; + paddrin6->sin6_scope_id = scopeId; paddrin6->sin6_family = AF_INET6; paddrin6->sin6_port = htons(port); return true; diff --git a/src/netbase.h b/src/netbase.h index 1db66ac27f..db736154fa 100644 --- a/src/netbase.h +++ b/src/netbase.h @@ -44,6 +44,7 @@ class CNetAddr { protected: unsigned char ip[16]; // in network byte order + uint32_t scopeId; // for scoped/link-local ipv6 addresses public: CNetAddr(); @@ -89,7 +90,7 @@ class CNetAddr std::vector GetGroup() const; int GetReachabilityFrom(const CNetAddr *paddrPartner = NULL) const; - CNetAddr(const struct in6_addr& pipv6Addr); + CNetAddr(const struct in6_addr& pipv6Addr, const uint32_t scope = 0); bool GetIn6Addr(struct in6_addr* pipv6Addr) const; friend bool operator==(const CNetAddr& a, const CNetAddr& b);