The branch main has been updated by des: URL: https://cgit.FreeBSD.org/src/commit/?id=1538284a5fddfce546db678cb873b7edc6adb9ed
commit 1538284a5fddfce546db678cb873b7edc6adb9ed Author: Dag-Erling Smørgrav <[email protected]> AuthorDate: 2026-01-31 17:52:53 +0000 Commit: Dag-Erling Smørgrav <[email protected]> CommitDate: 2026-01-31 17:52:53 +0000 libc/resolv: Switch default to loopback address If no resolver configuration was found, we would fall back to INADDR_ANY and IN6ADDR_ANY. This made sense when it was first written thirty or forty years ago but not today, especially since connecting to INADDR_ANY or IN6ADDR_ANY is no longer supported. Switch to the loopback address and simplify the code. Note that (as the pre-existing comment in the code states) running without a resolver configuration is not really supported. Still, if we're going to have a hardcoded fallback, it might as well work. PR: 291790 MFC after: 1 week Reviewed by: kevans Differential Revision: https://reviews.freebsd.org/D55011 --- lib/libc/resolv/res_init.c | 67 ++++++++++++++++++---------------------------- 1 file changed, 26 insertions(+), 41 deletions(-) diff --git a/lib/libc/resolv/res_init.c b/lib/libc/resolv/res_init.c index 5a2fce013c8c..b21a3fa1670f 100644 --- a/lib/libc/resolv/res_init.c +++ b/lib/libc/resolv/res_init.c @@ -118,21 +118,12 @@ static u_int32_t net_mask(struct in_addr); /*% * Set up default settings. If the configuration file exist, the values * there will have precedence. Otherwise, the server address is set to - * INADDR_ANY and the default domain name comes from the gethostname(). - * - * An interim version of this code (BIND 4.9, pre-4.4BSD) used 127.0.0.1 - * rather than INADDR_ANY ("0.0.0.0") as the default name server address - * since it was noted that INADDR_ANY actually meant ``the first interface - * you "ifconfig"'d at boot time'' and if this was a SLIP or PPP interface, - * it had to be "up" in order for you to reach your own name server. It - * was later decided that since the recommended practice is to always - * install local static routes through 127.0.0.1 for all your network - * interfaces, that we could solve this problem without a code change. + * the loopback address the default domain name comes from gethostname(). * * The configuration file should always be used, since it is the only way - * to specify a default domain. If you are running a server on your local - * machine, you should say "nameserver 0.0.0.0" or "nameserver 127.0.0.1" - * in the configuration file. + * to specify options and a default domain. If you are running a server + * on your local machine, you should say "nameserver 127.0.0.1" or + * "nameserver ::1" in the configuration file. * * Return 0 if completes successfully, -1 on error */ @@ -146,6 +137,26 @@ res_ninit(res_state statp) { /*% This function has to be reachable by res_data.c but not publicly. */ int __res_vinit(res_state statp, int preinit) { + union res_sockaddr_union u[] = { + { .sin = { + .sin_family = AF_INET, +#ifdef HAVE_SA_LEN + .sin_len = sizeof(struct sockaddr_in), +#endif + .sin_port = htons(NAMESERVER_PORT), + .sin_addr = { htonl(INADDR_LOOPBACK) }, + } }, +#ifdef HAS_INET6_STRUCTS + { .sin6 = { + .sin6_family = AF_INET6, +#ifdef HAVE_SA_LEN + .sin6_len = sizeof(struct sockaddr_in6), +#endif + .sin6_port = htons(NAMESERVER_PORT), + .sin6_addr = IN6ADDR_LOOPBACK_INIT, + } }, +#endif + }; FILE *fp; char *cp, **pp; int n; @@ -158,7 +169,6 @@ __res_vinit(res_state statp, int preinit) { char *net; #endif int dots; - union res_sockaddr_union u[2]; int maxns = MAXNS; RES_SET_H_ERRNO(statp, 0); @@ -173,23 +183,6 @@ __res_vinit(res_state statp, int preinit) { statp->id = res_nrandomid(statp); - memset(u, 0, sizeof(u)); - u[nserv].sin.sin_addr.s_addr = INADDR_ANY; - u[nserv].sin.sin_family = AF_INET; - u[nserv].sin.sin_port = htons(NAMESERVER_PORT); -#ifdef HAVE_SA_LEN - u[nserv].sin.sin_len = sizeof(struct sockaddr_in); -#endif - nserv++; -#ifdef HAS_INET6_STRUCTS - u[nserv].sin6.sin6_addr = in6addr_any; - u[nserv].sin6.sin6_family = AF_INET6; - u[nserv].sin6.sin6_port = htons(NAMESERVER_PORT); -#ifdef HAVE_SA_LEN - u[nserv].sin6.sin6_len = sizeof(struct sockaddr_in6); -#endif - nserv++; -#endif statp->nscount = 0; statp->ndots = 1; statp->pfcode = 0; @@ -224,7 +217,7 @@ __res_vinit(res_state statp, int preinit) { #ifdef RESOLVSORT statp->nsort = 0; #endif - res_setservers(statp, u, nserv); + res_setservers(statp, u, nitems(u)); #ifdef SOLARIS2 /* @@ -288,7 +281,6 @@ __res_vinit(res_state statp, int preinit) { (line[sizeof(name) - 1] == ' ' || \ line[sizeof(name) - 1] == '\t')) - nserv = 0; if ((fp = fopen(_PATH_RESCONF, "re")) != NULL) { struct stat sb; struct timespec now; @@ -507,15 +499,8 @@ __res_vinit(res_state statp, int preinit) { #endif (void) fclose(fp); } -/* - * Last chance to get a nameserver. This should not normally - * be necessary - */ -#ifdef NO_RESOLV_CONF - if(nserv == 0) - nserv = get_nameservers(statp); -#endif + /* guess default domain if not set */ if (statp->defdname[0] == 0 && gethostname(buf, sizeof(statp->defdname) - 1) == 0 && (cp = strchr(buf, '.')) != NULL)
