diff --git a/src/sslip.io-dns-server/integration_test.go b/src/sslip.io-dns-server/integration_test.go index a98f31e..793f682 100644 --- a/src/sslip.io-dns-server/integration_test.go +++ b/src/sslip.io-dns-server/integration_test.go @@ -395,26 +395,22 @@ var _ = Describe("sslip.io-dns-server", func() { }) }) Describe("When it can't bind to a port on loopback", func() { - var udpConnSquatter *net.UDPConn + var squatter *net.UDPConn BeforeEach(func() { port = getFreePort() - // the following won't work on an IPv6-only machine; change to "::1" in that case - udpAddr := net.UDPAddr{ - IP: net.ParseIP("::1"), - Port: port, - } - udpConnSquatter, err = net.ListenUDP("udp", &udpAddr) + squatter, err = squatOnUdpLoopbackPort(port) Expect(err).ToNot(HaveOccurred()) + }) - It("prints an informative message and continues", func() { + It("prints an informative message and binds to the addresses it can", func() { Expect(err).ToNot(HaveOccurred()) secondServerCmd := exec.Command(serverPath, "-port", strconv.Itoa(port), "-blocklistURL", "file://../../etc/blocklist.txt") secondServerSession, err := Start(secondServerCmd, GinkgoWriter, GinkgoWriter) Expect(err).ToNot(HaveOccurred()) Eventually(secondServerSession.Err, 10).Should(Say(` version \d+\.\d+\.\d+ starting`)) Eventually(secondServerSession.Err, 10).Should(Say(`I couldn't bind via UDP to "\[::\]:\d+" \(INADDR_ANY, all interfaces\), so I'll try to bind to each address individually.`)) - Eventually(secondServerSession.Err, 10).Should(Say(`I couldn't bind via UDP to the following IPs:.* "::1"`)) - err = udpConnSquatter.Close() + Eventually(secondServerSession.Err, 10).Should(Say(`I couldn't bind via UDP to the following IPs:.* "(::1|127\.0\.0\.1)"`)) + err = squatter.Close() Expect(err).ToNot(HaveOccurred()) Eventually(secondServerSession.Err, 10).Should(Say("Ready to answer queries")) secondServerSession.Terminate() @@ -425,6 +421,24 @@ var _ = Describe("sslip.io-dns-server", func() { var listenPort = 1023 // lowest unprivileged port - 1 (immediately incremented) +func squatOnUdpLoopbackPort(port int) (squatter *net.UDPConn, err error) { + // try IPv6's loopback + udpAddr := net.UDPAddr{ + IP: net.ParseIP("::1"), + Port: port, + } + squatter, err = net.ListenUDP("udp", &udpAddr) + if err != nil { + // try IPv4's loopback + udpAddr = net.UDPAddr{ + IP: net.ParseIP("127.0.0.1"), + Port: port, + } + squatter, err = net.ListenUDP("udp", &udpAddr) + } + return squatter, err +} + // getFreePort should always succeed unless something awful has happened, e.g. port exhaustion func getFreePort() int { // we randomize the start based on the millisecond to avoid collisions in our test