From 0b6e72ef03a3562d843a88adcd53c1abdb1ef13d Mon Sep 17 00:00:00 2001 From: Kai Engert Date: Fri, 13 May 2022 20:12:57 +0200 Subject: Bug 1769295 - selfserv and tstclnt should use PR_GetPrefLoopbackAddrInfo. r=rrelyea Differential Revision: https://phabricator.services.mozilla.com/D146334 --- cmd/selfserv/selfserv.c | 23 +++++++++++++----- cmd/tstclnt/tstclnt.c | 63 +++++++++++++++++++++++++++++-------------------- 2 files changed, 55 insertions(+), 31 deletions(-) (limited to 'cmd') diff --git a/cmd/selfserv/selfserv.c b/cmd/selfserv/selfserv.c index 5094cc7bf..d26851d98 100644 --- a/cmd/selfserv/selfserv.c +++ b/cmd/selfserv/selfserv.c @@ -1711,19 +1711,30 @@ do_accepts( PRFileDesc * getBoundListenSocket(unsigned short port) { - PRFileDesc *listen_sock; + PRFileDesc *listen_sock = NULL; int listenQueueDepth = 5 + (2 * maxThreads); PRStatus prStatus; PRNetAddr addr; PRSocketOptionData opt; - addr.inet.family = PR_AF_INET; - addr.inet.ip = PR_INADDR_ANY; - addr.inet.port = PR_htons(port); + // We want to listen on the IP family that tstclnt will use. + // tstclnt uses PR_GetPrefLoopbackAddrInfo to decide, if it's + // asked to connect to localhost. + + prStatus = PR_GetPrefLoopbackAddrInfo(&addr, port); + if (prStatus == PR_FAILURE) { + addr.inet.family = PR_AF_INET; + addr.inet.ip = PR_INADDR_ANY; + addr.inet.port = PR_htons(port); + } - listen_sock = PR_NewTCPSocket(); + if (addr.inet.family == PR_AF_INET6) { + listen_sock = PR_OpenTCPSocket(PR_AF_INET6); + } else if (addr.inet.family == PR_AF_INET) { + listen_sock = PR_NewTCPSocket(); + } if (listen_sock == NULL) { - errExit("PR_NewTCPSocket"); + errExit("Couldn't create socket"); } opt.option = PR_SockOpt_Nonblocking; diff --git a/cmd/tstclnt/tstclnt.c b/cmd/tstclnt/tstclnt.c index 6d3359c03..453842b16 100644 --- a/cmd/tstclnt/tstclnt.c +++ b/cmd/tstclnt/tstclnt.c @@ -2190,32 +2190,45 @@ main(int argc, char **argv) if (status == PR_SUCCESS) { addr.inet.port = PR_htons(portno); } else { - /* Lookup host */ - PRAddrInfo *addrInfo; - void *enumPtr = NULL; - - addrInfo = PR_GetAddrInfoByName(host, PR_AF_UNSPEC, - PR_AI_ADDRCONFIG | PR_AI_NOCANONNAME); - if (!addrInfo) { - fprintf(stderr, "HOSTNAME=%s\n", host); - SECU_PrintError(progName, "error looking up host"); - error = 1; - goto done; - } - for (;;) { - enumPtr = PR_EnumerateAddrInfo(enumPtr, addrInfo, portno, &addr); - if (enumPtr == NULL) - break; - if (addr.raw.family == PR_AF_INET && allowIPv4) - break; - if (addr.raw.family == PR_AF_INET6 && allowIPv6) - break; + PRBool gotLoopbackIP = PR_FALSE; + if ((!strcmp(host, "localhost") || !strcmp(host, "localhost.localdomain")) + /* only check for preference if both types are allowed */ + && allowIPv4 && allowIPv6) { + /* make a decision which IP to prefer */ + status = PR_GetPrefLoopbackAddrInfo(&addr, portno); + if (status != PR_FAILURE) { + gotLoopbackIP = PR_TRUE; + } } - PR_FreeAddrInfo(addrInfo); - if (enumPtr == NULL) { - SECU_PrintError(progName, "error looking up host address"); - error = 1; - goto done; + + if (!gotLoopbackIP) { + /* Lookup host */ + PRAddrInfo *addrInfo; + void *enumPtr = NULL; + + addrInfo = PR_GetAddrInfoByName(host, PR_AF_UNSPEC, + PR_AI_ADDRCONFIG | PR_AI_NOCANONNAME); + if (!addrInfo) { + fprintf(stderr, "HOSTNAME=%s\n", host); + SECU_PrintError(progName, "error looking up host"); + error = 1; + goto done; + } + for (;;) { + enumPtr = PR_EnumerateAddrInfo(enumPtr, addrInfo, portno, &addr); + if (enumPtr == NULL) + break; + if (addr.raw.family == PR_AF_INET && allowIPv4) + break; + if (addr.raw.family == PR_AF_INET6 && allowIPv6) + break; + } + PR_FreeAddrInfo(addrInfo); + if (enumPtr == NULL) { + SECU_PrintError(progName, "error looking up host address"); + error = 1; + goto done; + } } } -- cgit v1.2.1