Index: lib/libc/net/getaddrinfo.c diff -u lib/libc/net/getaddrinfo.c.orig lib/libc/net/getaddrinfo.c --- lib/libc/net/getaddrinfo.c.orig Sat Jun 16 07:08:28 2001 +++ lib/libc/net/getaddrinfo.c Sat Aug 11 02:00:12 2001 @@ -99,6 +99,9 @@ #include #include #include + +#include "res_config.h" + #ifdef DEBUG #include #endif @@ -1194,6 +1197,94 @@ } #endif +#ifdef RESOLVSORT +struct addr_ptr { + struct addrinfo *ai; + int aval; +}; + +static int +addrsort(struct addrinfo *sentinel) +{ + struct addrinfo *ai, *ai0; + struct addr_ptr *addrs, addr; + u_char *ap, *sp, *mp; + int alen, naddrs, i, j, n; + int needsort = 0; + + if (!sentinel) + return -1; + naddrs = 0; + for (ai = sentinel->ai_next; ai; ai = ai->ai_next) + naddrs++; + if (naddrs < 2) + return 0; + if ((addrs = malloc(sizeof(struct addr_ptr) * naddrs)) == NULL) + return -1; + i = 0; + for (ai = sentinel->ai_next; ai; ai = ai->ai_next) { + for (j = 0; (unsigned)j < _res.nsort; j++) { + if (ai->ai_family != _res_ext.sort_list[j].af) + continue; + switch (ai->ai_family) { + case AF_INET: + ap = (u_char *)&((struct sockaddr_in *)ai->ai_addr)->sin_addr; + alen = sizeof(struct in_addr); + break; + case AF_INET6: + ap = (u_char *)&((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr; + alen = sizeof(struct in6_addr); + break; + default: + continue; + } + sp = (u_char *)&_res_ext.sort_list[j].addr; + mp = (u_char *)&_res_ext.sort_list[j].mask; + for (n = 0; n < alen; n++) { + if ((ap[n] & mp[n]) != sp[n]) + break; + } + if (n == alen) + break; + } + addrs[i].ai = ai; + addrs[i].aval = j; + if (needsort == 0 && i > 0 && j < addrs[i-1].aval) + needsort = i; + i++; + } + if (!needsort) { + free(addrs); + return 0; + } + + while (needsort < naddrs) { + for (j = needsort - 1; j >= 0; j--) { + if (addrs[j].aval <= addrs[j+1].aval) + break; + addr = addrs[j]; + addrs[j] = addrs[j+1]; + addrs[j+1] = addr; + } + needsort++; + } + + ai0 = sentinel->ai_next; + ai = sentinel; + for (i = 0; i < naddrs; i++) { + ai->ai_next = addrs[i].ai; + ai = ai->ai_next; + } + ai->ai_next = NULL; + free(addrs); + if (!sentinel->ai_next->ai_canonname) { + sentinel->ai_next->ai_canonname = ai0->ai_canonname; + ai0->ai_canonname = NULL; + } + return 0; +} +#endif /*RESOLVSORT*/ + #ifdef DEBUG static const char AskedForGot[] = "gethostby*.getanswer: asked for \"%s\", got \"%s\""; @@ -1467,6 +1558,18 @@ default: return EAI_FAIL; } +#ifdef RESOLVSORT + /* + * We need to support for backward compatibility against + * gethostbyname(3). + */ + if (_res.nsort) { + if (addrsort(&sentinel) < 0) { + freeaddrinfo(sentinel.ai_next); + return EAI_MEMORY; + } + } +#endif /*RESOLVSORT*/ *res = sentinel.ai_next; return 0; }