diff --git a/runtime/bin/socket_linux.cc b/runtime/bin/socket_linux.cc index b0e4aec307e..99fa9754f15 100644 --- a/runtime/bin/socket_linux.cc +++ b/runtime/bin/socket_linux.cc @@ -81,6 +81,10 @@ intptr_t Socket::CreateBindConnect(const RawAddr& addr, return fd; } + int optval = 1; + VOID_NO_RETRY_EXPECTED( + setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))); + intptr_t result = TEMP_FAILURE_RETRY( bind(fd, &source_addr.addr, SocketAddress::GetAddrLength(source_addr))); if (result != 0) { diff --git a/runtime/bin/socket_macos.cc b/runtime/bin/socket_macos.cc index 0760f2f04e4..6aa863f5a35 100644 --- a/runtime/bin/socket_macos.cc +++ b/runtime/bin/socket_macos.cc @@ -86,6 +86,10 @@ intptr_t Socket::CreateBindConnect(const RawAddr& addr, return fd; } + int optval = 1; + VOID_NO_RETRY_EXPECTED( + setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))); + intptr_t result = TEMP_FAILURE_RETRY( bind(fd, &source_addr.addr, SocketAddress::GetAddrLength(source_addr))); if (result != 0) { diff --git a/tests/standalone/io/socket_local_port_test.dart b/tests/standalone/io/socket_local_port_test.dart index 05b8d6c0cb1..a0dbcf10b06 100644 --- a/tests/standalone/io/socket_local_port_test.dart +++ b/tests/standalone/io/socket_local_port_test.dart @@ -8,46 +8,40 @@ import "dart:io"; import "package:expect/expect.dart"; Future testCustomPortIPv4() { - String clientAddress = "127.0.0.1"; + String host = "127.0.0.1"; int customLocalPort = 50988; - String serverAddress = clientAddress; - int port = 50989; + String customAddress = host; - return testCustomPort(serverAddress, port, clientAddress, customLocalPort); + return testCustomPort(host, customAddress, customLocalPort); } Future testCustomPortIPv6() { - String clientAddress = "::1"; - int customLocalPort = 50988; - String serverAddress = clientAddress; - int port = 50989; + String host = "::1"; + int customLocalPort = 50989; + String customAddress = host; - return testCustomPort(serverAddress, port, clientAddress, customLocalPort); + return testCustomPort(host, customAddress, customLocalPort); } Future testCustomPortIPv4NoSourceAddress() { - String expectedClientAddress = "127.0.0.1"; - int customLocalPort = 50988; - String serverAddress = expectedClientAddress; - int port = 50989; + String host = "127.0.0.1"; + int customLocalPort = 50990; + String expectedClientAddress = host; - return testCustomPort( - serverAddress, - port, + return testCustomPortNoSourceAddress( + host, expectedClientAddress, customLocalPort, ); } Future testCustomPortIPv6NoSourceAddress() { - String expectedClientAddress = "::1"; - int customLocalPort = 50988; - String serverAddress = expectedClientAddress; - int port = 50989; + String host = "::1"; + int customLocalPort = 50991; + String expectedClientAddress = host; - return testCustomPort( - serverAddress, - port, + return testCustomPortNoSourceAddress( + host, expectedClientAddress, customLocalPort, ); @@ -56,134 +50,118 @@ Future testCustomPortIPv6NoSourceAddress() { Future testNoCustomPortIPv4() { String host = "127.0.0.1"; String clientAddress = host; - int serverPort = 39998; - return testNoCustomPortNoSourceAddress(host, serverPort, clientAddress); + return testNoCustomPort(host, clientAddress); } Future testNoCustomPortIPv6() { String host = "::1"; String clientAddress = host; - int serverPort = 39998; - return testNoCustomPortNoSourceAddress(host, serverPort, clientAddress); + return testNoCustomPort(host, clientAddress); } Future testNoCustomPortNoSourceAddressIPv4() { String host = "127.0.0.1"; String expectedAddress = host; - int serverPort = 39998; - return testNoCustomPortNoSourceAddress(host, serverPort, expectedAddress); + return testNoCustomPortNoSourceAddress(host, expectedAddress); } Future testNoCustomPortNoSourceAddressIPv6() { String host = "::1"; String expectedAddress = host; - int serverPort = 39998; - return testNoCustomPortNoSourceAddress(host, serverPort, expectedAddress); + return testNoCustomPortNoSourceAddress(host, expectedAddress); } // Core functionality -Future testCustomPort( - String host, - int port, - String sourceAddress, - int sourcePort, -) async { - var server = await ServerSocket.bind(host, port); - server.listen((client) { - Expect.equals(server.port, port); + +Future testCustomPort(String host, String sourceAddress, int sourcePort) async { + final serverTestDone = Completer(); + final server = await ServerSocket.bind(host, 0); + server.listen((Socket client) async { Expect.equals(client.remotePort, sourcePort); Expect.equals(client.address.address, sourceAddress); - client.destroy(); + await (client.close(), client.drain()).wait; + serverTestDone.complete(); }); - - Socket s = await Socket.connect( + final client = await Socket.connect( host, - port, + server.port, sourceAddress: sourceAddress, sourcePort: sourcePort, ); - s.destroy(); + await (client.close(), client.drain()).wait; + await serverTestDone.future; await server.close(); } Future testCustomPortNoSourceAddress( String host, - int port, String expectedAddress, int sourcePort, ) async { - Completer completer = new Completer(); - var server = await ServerSocket.bind(host, port); - - server.listen((client) { - Expect.equals(server.port, port); + final serverTestDone = Completer(); + final server = await ServerSocket.bind(host, 0); + server.listen((Socket client) async { Expect.equals(client.remotePort, sourcePort); Expect.equals(client.address.address, expectedAddress); - client.destroy(); - completer.complete(); + await (client.close(), client.drain()).wait; + serverTestDone.complete(); }); - - Socket s = await Socket.connect(host, port, sourcePort: sourcePort); - s.destroy(); + final client = await Socket.connect( + host, + server.port, + sourcePort: sourcePort, + ); + await (client.close(), client.drain()).wait; + await serverTestDone.future; await server.close(); - - return completer.future; } -Future testNoCustomPort(String host, int port, String sourceAddress) async { - Completer serverCompleter = new Completer(); - Completer clientCompleter = new Completer(); - var server = await ServerSocket.bind(host, port); - Socket.connect(host, port, sourceAddress: sourceAddress).then(( - clientSocket, - ) async { - server.listen((client) async { - Expect.equals(server.port, port); - Expect.equals(client.remotePort, clientSocket.port); - Expect.equals(client.address.address, sourceAddress); - - client.destroy(); - clientCompleter.complete(); - }); - - clientSocket.destroy(); - await server.close(); - serverCompleter.complete(); +Future testNoCustomPort(String host, String sourceAddress) async { + final serverTestDone = Completer(); + final server = await ServerSocket.bind(host, 0); + server.listen((Socket client) async { + Expect.equals(client.address.address, sourceAddress); + await (client.close(), client.drain()).wait; + serverTestDone.complete(); }); - - await serverCompleter.future; - await clientCompleter.future; + final client = await Socket.connect( + host, + server.port, + sourceAddress: sourceAddress, + ); + await (client.close(), client.drain()).wait; + await serverTestDone.future; + await server.close(); } Future testNoCustomPortNoSourceAddress( String host, - int port, String expectedAddress, ) async { - Completer completer = new Completer(); - var server = await ServerSocket.bind(host, port); - Socket.connect(host, port).then((clientSocket) { - server.listen((client) async { - Expect.equals(server.port, port); - Expect.equals(client.remotePort, clientSocket.port); - Expect.equals(client.address.address, expectedAddress); - clientSocket.destroy(); - client.destroy(); - await server.close(); - completer.complete(); - }); + final serverTestDone = Completer(); + final server = await ServerSocket.bind(host, 0); + server.listen((Socket client) async { + Expect.equals(client.address.address, expectedAddress); + await (client.close(), client.drain()).wait; + serverTestDone.complete(); }); - return completer.future; + final client = await Socket.connect(host, server.port); + await (client.close(), client.drain()).wait; + await serverTestDone.future; + await server.close(); } Future main() async { await testCustomPortIPv4(); await testCustomPortIPv6(); + await testCustomPortIPv4NoSourceAddress(); + await testCustomPortIPv6NoSourceAddress(); + await testNoCustomPortIPv4(); await testNoCustomPortIPv6();