int cmpaddr(struct sockaddr_storage *ss1, socklen_t sslen1, struct sockaddr_storage *ss2, socklen_t sslen2) { int ss1_offset = 0, ss2_offset = 0; struct sockaddr_in6 *ss1_addr6 = (struct sockaddr_in6 *)ss1; struct sockaddr_in6 *ss2_addr6 = (struct sockaddr_in6 *)ss2; struct sockaddr_in *ss1_addr = (struct sockaddr_in *)ss1; struct sockaddr_in *ss2_addr = (struct sockaddr_in *)ss2; char *addr1, *addr2; if (ss1->ss_family == ss2->ss_family) return memcmp(ss1, ss2, sslen1); if (ss1->ss_family == AF_INET6) { if (is_v4_mapped(ss1, sslen1)) return 1; addr1 = (char *)&ss1_addr6->sin6_addr; ss1_offset = 12; } else addr1 = (char *)&ss1_addr->sin_addr; if (ss2->ss_family == AF_INET6) { if (is_v4_mapped(ss2, sslen2)) return 1; addr2 = (char *)&ss2_addr6->sin6_addr; ss2_offset = 12; } else addr2 = (char *)&ss2_addr->sin_addr; return memcmp(addr1+ss1_offset, addr2+ss2_offset, 4); }
static bool isLoopback(const boost::asio::ip::address& addr) { if (addr.is_loopback()) { return true; } // Workaround for loopback IPv4-mapped IPv6 addresses // see https://svn.boost.org/trac/boost/ticket/9084 else if (addr.is_v6()) { auto addr6 = addr.to_v6(); if (addr6.is_v4_mapped()) { return addr6.to_v4().is_loopback(); } } return false; }