Page MenuHomeFreeBSD

D57925.diff
No OneTemporary

D57925.diff

diff --git a/lib/libc/resolv/Makefile.inc b/lib/libc/resolv/Makefile.inc
--- a/lib/libc/resolv/Makefile.inc
+++ b/lib/libc/resolv/Makefile.inc
@@ -7,4 +7,5 @@
SYM_MAPS+= ${LIBC_SRCTOP}/resolv/Symbol.map
+CFLAGS+=-I${LIBC_SRCTOP}/net
CFLAGS+=-I${SRCTOP}/lib/libmd
diff --git a/lib/libc/resolv/res_init.c b/lib/libc/resolv/res_init.c
--- a/lib/libc/resolv/res_init.c
+++ b/lib/libc/resolv/res_init.c
@@ -95,6 +95,7 @@
/* ensure that sockaddr_in6 and IN6ADDR_ANY_INIT are declared / defined */
#include <resolv.h>
+#include "res_config.h"
#include "res_private.h"
static void res_readconf(res_state, const char *, int, int);
@@ -104,10 +105,8 @@
static void res_setoptions(res_state, const char *, const char *);
#ifdef RESOLVSORT
-static const char sort_mask[] = "/&";
-#define ISSORTMASK(ch) (strchr(sort_mask, ch) != NULL)
-static u_int32_t net_mask(struct in_addr);
-#endif
+static int res_setsortlist(res_state, int, const char *, const char *);
+#endif /* RESOLVSORT */
#define res_space(ch) \
isspace((unsigned char)(ch))
@@ -285,8 +284,7 @@
size_t sz = 0;
int nserv = 0;
#ifdef RESOLVSORT
- int n, nsort = 0;
- char *net;
+ int nsort = 0;
#endif
if ((fp = fopen(resconf, "re")) == NULL)
@@ -357,101 +355,28 @@
continue;
}
#ifdef RESOLVSORT
+ /* read result sort order */
if (res_match(line, eow, "sortlist")) {
- struct in_addr a;
- struct in6_addr a6;
- int m, i;
- u_char *u;
- struct __res_state_ext *ext = statp->_u._ext.ext;
-
- cp = line + sizeof("sortlist") - 1;
while (nsort < MAXRESOLVSORT) {
- while (*cp == ' ' || *cp == '\t')
+ cp = eow;
+ while (cp < eol && res_space(*cp))
cp++;
- if (*cp == '\0' || *cp == '\n' || *cp == ';')
+ if (cp == eol)
break;
- net = cp;
- while (*cp && !ISSORTMASK(*cp) && *cp != ';' &&
- isascii(*cp) && !isspace((unsigned char)*cp))
- cp++;
- n = *cp;
- *cp = 0;
- if (inet_aton(net, &a)) {
- statp->sort_list[nsort].addr = a;
- if (ISSORTMASK(n)) {
- *cp++ = n;
- net = cp;
- while (*cp && *cp != ';' &&
- isascii(*cp) &&
- !isspace((unsigned char)*cp))
- cp++;
- n = *cp;
- *cp = 0;
- if (inet_aton(net, &a)) {
- statp->sort_list[nsort].mask = a.s_addr;
- } else {
- statp->sort_list[nsort].mask =
- net_mask(statp->sort_list[nsort].addr);
- }
- } else {
- statp->sort_list[nsort].mask =
- net_mask(statp->sort_list[nsort].addr);
- }
- ext->sort_list[nsort].af = AF_INET;
- ext->sort_list[nsort].addr.ina =
- statp->sort_list[nsort].addr;
- ext->sort_list[nsort].mask.ina.s_addr =
- statp->sort_list[nsort].mask;
- nsort++;
- }
- else if (inet_pton(AF_INET6, net, &a6) == 1) {
-
- ext->sort_list[nsort].af = AF_INET6;
- ext->sort_list[nsort].addr.in6a = a6;
- u = (u_char *)&ext->sort_list[nsort].mask.in6a;
- *cp++ = n;
- net = cp;
- while (*cp && *cp != ';' &&
- isascii(*cp) && !isspace(*cp))
- cp++;
- m = n;
- n = *cp;
- *cp = 0;
- switch (m) {
- case '/':
- m = atoi(net);
- break;
- case '&':
- if (inet_pton(AF_INET6, net, u) == 1) {
- m = -1;
- break;
- }
- /*FALLTHROUGH*/
- default:
- m = sizeof(struct in6_addr) * CHAR_BIT;
- break;
- }
- if (m >= 0) {
- for (i = 0; i < sizeof(struct in6_addr); i++) {
- if (m <= 0) {
- *u = 0;
- } else {
- m -= CHAR_BIT;
- *u = (u_char)~0;
- if (m < 0)
- *u <<= -m;
- }
- u++;
- }
- }
- statp->sort_list[nsort].addr.s_addr =
- (u_int32_t)0xffffffff;
- statp->sort_list[nsort].mask =
- (u_int32_t)0xffffffff;
+ eow = cp;
+ while (eow < eol && !res_space(*eow))
+ eow++;
+ if (res_setsortlist(statp, nsort, cp, eow))
nsort++;
- }
- *cp = n;
}
+#ifdef DEBUG
+ while (cp < eol && res_space(*cp))
+ cp++;
+ if (cp < eol) {
+ printf(";; sortlist overflow: %.*s\n",
+ (int)(eol - cp), cp);
+ }
+#endif
continue;
}
#endif /* RESOLVSORT */
@@ -651,6 +576,108 @@
return (ret);
}
+#ifdef RESOLVSORT
+/*%
+ * Set the sort order. Assumes no leading or trailing space.
+ */
+int
+res_setsortlist(res_state statp, int i, const char *str, const char *end)
+{
+ struct __res_state_ext *ext = statp->_u._ext.ext;
+ char addr[48], mask[48], *dst, *numend;
+ _Static_assert(sizeof(addr) > INET6_ADDRSTRLEN,
+ "address buffer too small for AF_INET6");
+ _Static_assert(sizeof(addr) > INET_ADDRSTRLEN,
+ "address buffer too small for AF_INET");
+ _Static_assert(sizeof(mask) > INET6_ADDRSTRLEN,
+ "mask buffer too small for AF_INET6");
+ _Static_assert(sizeof(mask) > INET_ADDRSTRLEN,
+ "mask buffer too small for AF_INET");
+ struct in_addr a;
+ struct in6_addr a6;
+ uint8_t *u;
+ long num;
+
+ /* copy the address */
+ dst = addr;
+ while (str < end && !res_space(*str) && *str != '/') {
+ *dst++ = *str++;
+ if (dst == addr + sizeof(addr))
+ return (0);
+ }
+ *dst = '\0';
+
+ /* copy the mask, if there is one */
+ dst = mask;
+ if (str < end) {
+ if (*str++ != '/')
+ return (0);
+ if (end - str >= sizeof(mask))
+ return (0);
+ memcpy(mask, str, end - str);
+ dst += end - str;
+ }
+ *dst = '\0';
+
+ /* IPv4 case */
+ if (inet_pton(AF_INET, addr, &a) == 1) {
+ statp->sort_list[i].addr = a;
+ if (mask[0] != '\0') {
+ if ((num = strtol(mask, &numend, 10)) < 0 ||
+ num > 32 || *numend != '\0')
+ return (0);
+ } else {
+ if (IN_CLASSA(ntohl(a.s_addr)))
+ num = 8;
+ else if (IN_CLASSB(ntohl(a.s_addr)))
+ num = 16;
+ else
+ num = 24;
+ }
+ statp->sort_list[i].mask =
+ htonl(0xffffffffU << (32 - num));
+ ext->sort_list[i].af = AF_INET;
+ ext->sort_list[i].addr.ina =
+ statp->sort_list[i].addr;
+ ext->sort_list[i].mask.ina.s_addr =
+ statp->sort_list[i].mask;
+#ifdef DEBUG
+ inet_ntop(AF_INET, &a, addr, sizeof(addr));
+ printf(";; sortlist %s/%ld\n", addr, num);
+#endif
+ return (1);
+ }
+
+ /* IPv6 case */
+ if (inet_pton(AF_INET6, addr, &a6) == 1) {
+ statp->sort_list[i].addr.s_addr = INADDR_NONE;
+ statp->sort_list[i].mask = INADDR_NONE;
+ ext->sort_list[i].af = AF_INET6;
+ ext->sort_list[i].addr.in6a = a6;
+ if (mask[0]) {
+ /* prefix length */
+ if ((num = strtol(mask, &numend, 10)) < 0 ||
+ num > 128 || *numend != '\0')
+ return (0);
+ } else {
+ num = 64;
+ }
+#ifdef DEBUG
+ inet_ntop(AF_INET6, &a6, addr, sizeof(addr));
+ printf(";; sortlist %s/%ld\n", addr, num);
+#endif
+ a6 = (struct in6_addr)IN6ADDR_ANY_INIT;
+ for (u = a6.s6_addr8; num > 0; num -= 8)
+ *u++ = num > 8 ? 0xffU : 0xffU << (8 - num);
+ ext->sort_list[i].mask.in6a = a6;
+ return (1);
+ }
+
+ /* invalid */
+ return (0);
+}
+#endif /* RESOLVSORT */
+
/*%
* Split the string up into words and interpret them as resolver options.
*/
@@ -790,21 +817,6 @@
}
}
-#ifdef RESOLVSORT
-/* XXX - should really support CIDR which means explicit masks always. */
-static u_int32_t
-net_mask(struct in_addr in) /*!< XXX - should really use system's version of this */
-{
- u_int32_t i = ntohl(in.s_addr);
-
- if (IN_CLASSA(i))
- return (htonl(IN_CLASSA_NET));
- else if (IN_CLASSB(i))
- return (htonl(IN_CLASSB_NET));
- return (htonl(IN_CLASSC_NET));
-}
-#endif
-
void
freebsd15_res_rndinit(res_state statp)
{
diff --git a/share/man/man5/resolver.5 b/share/man/man5/resolver.5
--- a/share/man/man5/resolver.5
+++ b/share/man/man5/resolver.5
@@ -100,20 +100,27 @@
.Pp
The search list is currently limited to six domains
with a total of 256 characters.
-.It Sy sortlist
-Sortlist allows addresses returned by the resolver to be sorted.
-A sortlist is specified by IP address netmask pairs.
-If the netmask is not specified,
-it defaults to the historical Class A/B/C netmask of the net;
-this usage is deprecated.
-The IP address
-and network pairs are separated by slashes.
-Up to 10 pairs may
-be specified.
-E.g.,
+.It Cm sortlist Ar addr1 Ns Oo Li / Ns Ar plen1 Oc Op addr2 Ns Oo Li / Ns Ar plen2 Oc ...
+Sort order for query results in the form of a list of
+.Ar addr Ns Li / Ns Ar plen
+entries, for instance:
+.Bd -literal
+sortlist 198.51.100.0/24 203.0.113.0/24 2001:db8::/32
+.Ed
+.Pp
+If the prefix length is omitted, it defaults to historical class-based
+addressing for IPv4 and to 64 for IPv6.
+.Pp
+Query results that match one of the sort list entries are sorted
+accordingly and ahead of query results that don't.
+If multiple results match a single sort list entry, the order is
+unspecified.
.Pp
-.Dl "sortlist 10.9.1.0/255.255.240.0 10.9.0.0/255.255.0.0"
-.It Cm options Ar option1 Op Ar option2 ...
+If multiple
+.Cm sortlist
+lines are encountered, entries are appended to the list in the order
+in which they were encountered, up to a maximum of ten.
+.It Cm options
Options allows certain internal resolver variables to be modified.
The following options are supported:
.Bl -tag -width indent

File Metadata

Mime Type
text/plain
Expires
Tue, Jun 30, 8:45 AM (6 h, 44 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34456554
Default Alt Text
D57925.diff (8 KB)

Event Timeline