Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F160949000
D57925.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D57925.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D57925: libc/resolv: Reimplement the sortlist parser
Attached
Detach File
Event Timeline
Log In to Comment