diff -up ./cmd/selfserv/selfserv.c.ipv6_fix ./cmd/selfserv/selfserv.c --- ./cmd/selfserv/selfserv.c.ipv6_fix 2021-09-14 11:40:06.176408531 -0700 +++ ./cmd/selfserv/selfserv.c 2021-09-14 11:49:46.361907308 -0700 @@ -1717,14 +1717,28 @@ getBoundListenSocket(unsigned short port PRNetAddr addr; PRSocketOptionData opt; - addr.inet.family = PR_AF_INET; - addr.inet.ip = PR_INADDR_ANY; - addr.inet.port = PR_htons(port); + if (PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, port, &addr) != PR_SUCCESS) { + errExit("PR_SetNetAddr"); + } - listen_sock = PR_NewTCPSocket(); + listen_sock = PR_OpenTCPSocket(PR_AF_INET6); if (listen_sock == NULL) { errExit("PR_NewTCPSocket"); } + /* NSPR has a bug where set inheritable doesn't work unless it's a pure + * NSPR socket. If we have an IPV6 emulator on an IPV4 socket, it will fail. + * In that case just open an IPV4 socket instead */ + if (PR_NSPR_IO_LAYER != PR_GetLayersIdentity(listen_sock)) { + PR_Close(listen_sock); + addr.inet.family = PR_AF_INET; + addr.inet.ip = PR_INADDR_ANY; + addr.inet.port = PR_htons(port); + + listen_sock = PR_NewTCPSocket(); + if (listen_sock == NULL) { + errExit("PR_NewTCPSocket"); + } + } opt.option = PR_SockOpt_Nonblocking; opt.value.non_blocking = PR_FALSE;