diff --git a/CHANGES b/CHANGES index fe86f5d7d3..efe92aa550 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +4238. [bug] Don't send to servers on net zero (0.0.0.0/8). + [RT #40947] + 4237. [doc] Upgraded documentation toolchain to use DocBook 5 and dblatex. [RT #40766] diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index 5515705382..4469b48464 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -3430,6 +3430,9 @@ possibly_mark(fetchctx_t *fctx, dns_adbaddrinfo_t *addr) { if (aborted) { addr->flags |= FCTX_ADDRINFO_MARK; msg = "ignoring blackholed / bogus server: "; + } else if (isc_sockaddr_isnetzero(sa)) { + addr->flags |= FCTX_ADDRINFO_MARK; + msg = "ignoring net zero address: "; } else if (isc_sockaddr_ismulticast(sa)) { addr->flags |= FCTX_ADDRINFO_MARK; msg = "ignoring multicast address: "; diff --git a/lib/isc/include/isc/netaddr.h b/lib/isc/include/isc/netaddr.h index 954d77019b..3e2e5fb929 100644 --- a/lib/isc/include/isc/netaddr.h +++ b/lib/isc/include/isc/netaddr.h @@ -155,6 +155,12 @@ isc_netaddr_issitelocal(isc_netaddr_t *na); * Returns #ISC_TRUE if the address is a site local address. */ +isc_boolean_t +isc_netaddr_isnetzero(isc_netaddr_t *na); +/*%< + * Returns #ISC_TRUE if the address is in net zero. + */ + void isc_netaddr_fromv4mapped(isc_netaddr_t *t, const isc_netaddr_t *s); /*%< diff --git a/lib/isc/include/isc/sockaddr.h b/lib/isc/include/isc/sockaddr.h index 4d811dd649..3952c18279 100644 --- a/lib/isc/include/isc/sockaddr.h +++ b/lib/isc/include/isc/sockaddr.h @@ -220,6 +220,12 @@ isc_sockaddr_issitelocal(const isc_sockaddr_t *sa); * Returns ISC_TRUE if the address is a sitelocal address. */ +isc_boolean_t +isc_sockaddr_isnetzero(const isc_sockaddr_t *sa); +/*%< + * Returns ISC_TRUE if the address is in net zero. + */ + isc_result_t isc_sockaddr_frompath(isc_sockaddr_t *sockaddr, const char *path); /* diff --git a/lib/isc/netaddr.c b/lib/isc/netaddr.c index dcbfba42ea..ad098fc0aa 100644 --- a/lib/isc/netaddr.c +++ b/lib/isc/netaddr.c @@ -419,6 +419,22 @@ isc_netaddr_issitelocal(isc_netaddr_t *na) { } } +#ifndef IN_ZERONET +#define IN_ZERONET(x) (((x) & htonl(0xff000000U)) == 0) +#endif + +isc_boolean_t +isc_netaddr_isnetzero(isc_netaddr_t *na) { + switch (na->family) { + case AF_INET: + return (ISC_TF(IN_ZERONET(na->type.in.s_addr))); + case AF_INET6: + return (ISC_FALSE); + default: + return (ISC_FALSE); + } +} + void isc_netaddr_fromv4mapped(isc_netaddr_t *t, const isc_netaddr_t *s) { isc_netaddr_t *src; diff --git a/lib/isc/sockaddr.c b/lib/isc/sockaddr.c index cee6d700c0..b1bff4e00e 100644 --- a/lib/isc/sockaddr.c +++ b/lib/isc/sockaddr.c @@ -483,6 +483,17 @@ isc_sockaddr_islinklocal(const isc_sockaddr_t *sockaddr) { return (ISC_FALSE); } +isc_boolean_t +isc_sockaddr_isnetzero(const isc_sockaddr_t *sockaddr) { + isc_netaddr_t netaddr; + + if (sockaddr->type.sa.sa_family == AF_INET) { + isc_netaddr_fromsockaddr(&netaddr, sockaddr); + return (isc_netaddr_isnetzero(&netaddr)); + } + return (ISC_FALSE); +} + isc_result_t isc_sockaddr_frompath(isc_sockaddr_t *sockaddr, const char *path) { #ifdef ISC_PLATFORM_HAVESYSUNH diff --git a/lib/isc/tests/sockaddr_test.c b/lib/isc/tests/sockaddr_test.c index 87ce551df0..e66d1f6c62 100644 --- a/lib/isc/tests/sockaddr_test.c +++ b/lib/isc/tests/sockaddr_test.c @@ -67,11 +67,70 @@ ATF_TC_BODY(sockaddr_hash, tc) { isc_test_end(); } +ATF_TC(sockaddr_isnetzero); +ATF_TC_HEAD(sockaddr_isnetzero, tc) { + atf_tc_set_md_var(tc, "descr", "sockaddr is net zero"); +} +ATF_TC_BODY(sockaddr_isnetzero, tc) { + isc_sockaddr_t addr; + struct in_addr in; + struct in6_addr in6; + isc_boolean_t r; + int ret; + size_t i; + struct { + const char *string; + isc_boolean_t expect; + } data4[] = { + { "0.0.0.0", ISC_TRUE }, + { "0.0.0.1", ISC_TRUE }, + { "0.0.1.0", ISC_TRUE }, + { "0.1.0.0", ISC_TRUE }, + { "1.0.0.0", ISC_FALSE }, + { "0.0.0.127", ISC_TRUE }, + { "0.0.0.255", ISC_TRUE }, + { "127.0.0.1", ISC_FALSE }, + { "255.255.255.255", ISC_FALSE }, + }; + /* + * Mapped addresses are currently not netzero. + */ + struct { + const char *string; + isc_boolean_t expect; + } data6[] = { + { "::ffff:0.0.0.0", ISC_FALSE }, + { "::ffff:0.0.0.1", ISC_FALSE }, + { "::ffff:0.0.0.127", ISC_FALSE }, + { "::ffff:0.0.0.255", ISC_FALSE }, + { "::ffff:127.0.0.1", ISC_FALSE }, + { "::ffff:255.255.255.255", ISC_FALSE }, + }; + + UNUSED(tc); + + for (i = 0; i < sizeof(data4)/sizeof(data4[0]); i++) { + in.s_addr = inet_addr(data4[0].string); + isc_sockaddr_fromin(&addr, &in, 1); + r = isc_sockaddr_isnetzero(&addr); + ATF_CHECK_EQ(r, data4[0].expect); + } + + for (i = 0; i < sizeof(data6)/sizeof(data6[0]); i++) { + ret = inet_pton(AF_INET6, "::ffff:127.0.0.1", &in6); + ATF_CHECK_EQ(ret, 1); + isc_sockaddr_fromin6(&addr, &in6, 1); + r = isc_sockaddr_isnetzero(&addr); + ATF_CHECK_EQ(r, data6[0].expect); + } +} + /* * Main */ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, sockaddr_hash); + ATF_TP_ADD_TC(tp, sockaddr_isnetzero); return (atf_no_error()); } diff --git a/lib/isc/win32/libisc.def.in b/lib/isc/win32/libisc.def.in index 033f119f40..f2c7141773 100644 --- a/lib/isc/win32/libisc.def.in +++ b/lib/isc/win32/libisc.def.in @@ -452,6 +452,7 @@ isc_netaddr_getzone isc_netaddr_isexperimental isc_netaddr_islinklocal isc_netaddr_ismulticast +isc_netaddr_isnetzero isc_netaddr_issitelocal isc_netaddr_masktoprefixlen isc_netaddr_prefixok @@ -569,6 +570,7 @@ isc_sockaddr_hash isc_sockaddr_isexperimental isc_sockaddr_islinklocal isc_sockaddr_ismulticast +isc_sockaddr_isnetzero isc_sockaddr_issitelocal isc_sockaddr_pf isc_sockaddr_setport