diff options
Diffstat (limited to 'src/network/lookup_name.c')
-rw-r--r-- | src/network/lookup_name.c | 47 |
1 files changed, 32 insertions, 15 deletions
diff --git a/src/network/lookup_name.c b/src/network/lookup_name.c index a1851f1f..0e6db9ef 100644 --- a/src/network/lookup_name.c +++ b/src/network/lookup_name.c @@ -355,36 +355,53 @@ int __lookup_name(struct address buf[static MAXADDRS], char canon[static 256], c * excessive runtime and code size cost and dubious benefit. * So far the label/precedence table cannot be customized. */ for (i=0; i<cnt; i++) { + int family = buf[i].family; int key = 0; - struct sockaddr_in6 sa, da = { + struct sockaddr_in6 sa6 = { 0 }, da6 = { .sin6_family = AF_INET6, .sin6_scope_id = buf[i].scopeid, .sin6_port = 65535 }; - if (buf[i].family == AF_INET6) { - memcpy(da.sin6_addr.s6_addr, buf[i].addr, 16); + struct sockaddr_in sa4 = { 0 }, da4 = { + .sin_family = AF_INET, + .sin_port = 65535 + }; + void *sa, *da; + socklen_t salen, dalen; + if (family == AF_INET6) { + memcpy(da6.sin6_addr.s6_addr, buf[i].addr, 16); + da = &da6; dalen = sizeof da6; + sa = &sa6; salen = sizeof sa6; } else { - memcpy(da.sin6_addr.s6_addr, + memcpy(sa6.sin6_addr.s6_addr, + "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12); + memcpy(da6.sin6_addr.s6_addr+12, buf[i].addr, 4); + memcpy(da6.sin6_addr.s6_addr, "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12); - memcpy(da.sin6_addr.s6_addr+12, buf[i].addr, 4); + memcpy(da6.sin6_addr.s6_addr+12, buf[i].addr, 4); + memcpy(&da4.sin_addr, buf[i].addr, 4); + da = &da4; dalen = sizeof da4; + sa = &sa4; salen = sizeof sa4; } - const struct policy *dpolicy = policyof(&da.sin6_addr); - int dscope = scopeof(&da.sin6_addr); + const struct policy *dpolicy = policyof(&da6.sin6_addr); + int dscope = scopeof(&da6.sin6_addr); int dlabel = dpolicy->label; int dprec = dpolicy->prec; int prefixlen = 0; - int fd = socket(AF_INET6, SOCK_DGRAM|SOCK_CLOEXEC, IPPROTO_UDP); + int fd = socket(family, SOCK_DGRAM|SOCK_CLOEXEC, IPPROTO_UDP); if (fd >= 0) { - if (!connect(fd, (void *)&da, sizeof da)) { + if (!connect(fd, da, dalen)) { key |= DAS_USABLE; - if (!getsockname(fd, (void *)&sa, - &(socklen_t){sizeof sa})) { - if (dscope == scopeof(&sa.sin6_addr)) + if (!getsockname(fd, sa, &salen)) { + if (family == AF_INET) memcpy( + &sa6.sin6_addr.s6_addr+12, + &sa4.sin_addr, 4); + if (dscope == scopeof(&sa6.sin6_addr)) key |= DAS_MATCHINGSCOPE; - if (dlabel == labelof(&sa.sin6_addr)) + if (dlabel == labelof(&sa6.sin6_addr)) key |= DAS_MATCHINGLABEL; - prefixlen = prefixmatch(&sa.sin6_addr, - &da.sin6_addr); + prefixlen = prefixmatch(&sa6.sin6_addr, + &da6.sin6_addr); } } close(fd); |