Mac OS X - bind a server socket port to all interfaces and prevent other binds with the same port
Asked Answered
G

0

7

On OS X, when creating a server socket on a specific port for all interfaces, a new server socket can bind to localhost with the same port and accept connections. I would expect the binding to localhost to fail, as it does when trying the same in Linux (I tried on Ubuntu specifically).

The behavior on OS X is weird to me, because client connections to localhost work when listening on all interfaces, but a new server can bind localhost on the same port and accept new connections, instead of the first listener.

How can a socket listen on all interfaces and also prevent other sockets from binding to localhost with the same port on OS X?

The following test passes on Mac and fails on Ubuntu, but should fail on both.

import org.junit.Assert;
import org.junit.Test;

import java.io.IOException;
import java.net.Inet4Address;
import java.net.ServerSocket;

public class MinimalTest {
    @Test
    public void listenOnAllInterfacesAndLocalhost() throws IOException {
        final int port = 12340;
        try (ServerSocket allInterfaces = new ServerSocket(port);
             ServerSocket onlyLocalhost = new ServerSocket(port, 100, Inet4Address.getByName("localhost"));) {
            Assert.assertEquals(allInterfaces.getLocalPort(), port);
            Assert.assertEquals(onlyLocalhost.getLocalPort(), port);

            Assert.assertTrue(allInterfaces.isBound());
            Assert.assertTrue(onlyLocalhost.isBound());
        }
    }
}

What I tried:

Gaseous answered 24/10, 2020 at 13:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.