Index: src/OFHTTPServer.m ================================================================== --- src/OFHTTPServer.m +++ src/OFHTTPServer.m @@ -848,19 +848,21 @@ #endif - (void)start { void *pool = objc_autoreleasePoolPush(); + OFSocketAddress address; if (_host == nil) @throw [OFInvalidArgumentException exception]; if (_listeningSocket != nil) @throw [OFAlreadyOpenException exceptionWithObject: self]; _listeningSocket = [[OFTCPSocket alloc] init]; - _port = [_listeningSocket bindToHost: _host port: _port]; + address = [_listeningSocket bindToHost: _host port: _port]; + _port = OFSocketAddressIPPort(&address); [_listeningSocket listen]; #ifdef OF_HAVE_THREADS if (_numberOfThreads > 1) { OFMutableArray *threads = Index: src/OFTCPSocket.h ================================================================== --- src/OFTCPSocket.h +++ src/OFTCPSocket.h @@ -211,13 +211,13 @@ * * @param host The host to bind to. Use `@"0.0.0.0"` for IPv4 or `@"::"` for * IPv6 to bind to all. * @param port The port to bind to. If the port is 0, an unused port will be * chosen, which can be obtained using the return value. - * @return The port the socket was bound to + * @return The address the socket was bound to * @throw OFBindIPSocketFailedException Binding failed * @throw OFAlreadyOpenException The socket is already connected or bound */ -- (uint16_t)bindToHost: (OFString *)host port: (uint16_t)port; +- (OFSocketAddress)bindToHost: (OFString *)host port: (uint16_t)port; @end OF_ASSUME_NONNULL_END Index: src/OFTCPSocket.m ================================================================== --- src/OFTCPSocket.m +++ src/OFTCPSocket.m @@ -287,11 +287,11 @@ objc_autoreleasePoolPop(pool); } #endif -- (uint16_t)bindToHost: (OFString *)host port: (uint16_t)port +- (OFSocketAddress)bindToHost: (OFString *)host port: (uint16_t)port { const int one = 1; void *pool = objc_autoreleasePoolPush(); OFData *socketAddresses; OFSocketAddress address; @@ -359,14 +359,12 @@ OFSocketAddressSetIPPort(&address, rnd); if ((ret = bind(_socket, (struct sockaddr *)&address.sockaddr, - address.length)) == 0) { - port = rnd; + address.length)) == 0) break; - } if (OFSocketErrNo() != EADDRINUSE) { int errNo = OFSocketErrNo(); closesocket(_socket); @@ -380,15 +378,10 @@ } } } #endif - objc_autoreleasePoolPop(pool); - - if (port > 0) - return port; - #if !defined(OF_HPUX) && !defined(OF_WII) && !defined(OF_NINTENDO_3DS) memset(&address, 0, sizeof(address)); address.length = (socklen_t)sizeof(address.sockaddr); if (OFGetSockName(_socket, (struct sockaddr *)&address.sockaddr, @@ -404,14 +397,16 @@ errNo: errNo]; } switch (((struct sockaddr *)&address.sockaddr)->sa_family) { case AF_INET: - return OFFromBigEndian16(address.sockaddr.in.sin_port); + address.family = OFSocketAddressFamilyIPv4; + break; # ifdef OF_HAVE_IPV6 case AF_INET6: - return OFFromBigEndian16(address.sockaddr.in6.sin6_port); + address.family = OFSocketAddressFamilyIPv6; + break; # endif default: closesocket(_socket); _socket = OFInvalidSocketHandle; @@ -419,18 +414,15 @@ exceptionWithHost: host port: port socket: self errNo: EAFNOSUPPORT]; } -#else - closesocket(_socket); - _socket = OFInvalidSocketHandle; - @throw [OFBindIPSocketFailedException exceptionWithHost: host - port: port - socket: self - errNo: EADDRNOTAVAIL]; #endif + + objc_autoreleasePoolPop(pool); + + return address; } #if !defined(OF_WII) && !defined(OF_NINTENDO_3DS) - (void)setSendsKeepAlives: (bool)sendsKeepAlives { Index: tests/OFHTTPClientTests.m ================================================================== --- tests/OFHTTPClientTests.m +++ tests/OFHTTPClientTests.m @@ -36,16 +36,18 @@ @implementation HTTPClientTestsServer - (id)main { OFTCPSocket *listener, *client; + OFSocketAddress address; char buffer[5]; [condition lock]; listener = [OFTCPSocket socket]; - _port = [listener bindToHost: @"127.0.0.1" port: 0]; + address = [listener bindToHost: @"127.0.0.1" port: 0]; + _port = OFSocketAddressIPPort(&address); [listener listen]; [condition signal]; [condition unlock]; Index: tests/OFKernelEventObserverTests.m ================================================================== --- tests/OFKernelEventObserverTests.m +++ tests/OFKernelEventObserverTests.m @@ -51,20 +51,21 @@ - (instancetype)initWithTestsAppDelegate: (TestsAppDelegate *)testsAppDelegate { self = [super init]; @try { - uint16_t port; + OFSocketAddress address; _testsAppDelegate = testsAppDelegate; _server = [[OFTCPSocket alloc] init]; - port = [_server bindToHost: @"127.0.0.1" port: 0]; + address = [_server bindToHost: @"127.0.0.1" port: 0]; [_server listen]; _client = [[OFTCPSocket alloc] init]; - [_client connectToHost: @"127.0.0.1" port: port]; + [_client connectToHost: @"127.0.0.1" + port: OFSocketAddressIPPort(&address)]; [_client writeBuffer: "0" length: 1]; } @catch (id e) { [self release]; @throw e; } Index: tests/OFTCPSocketTests.m ================================================================== --- tests/OFTCPSocketTests.m +++ tests/OFTCPSocketTests.m @@ -24,23 +24,24 @@ @implementation TestsAppDelegate (OFTCPSocketTests) - (void)TCPSocketTests { void *pool = objc_autoreleasePoolPush(); OFTCPSocket *server, *client = nil, *accepted; - uint16_t port; + OFSocketAddress address; char buffer[6]; TEST(@"+[socket]", (server = [OFTCPSocket socket]) && (client = [OFTCPSocket socket])) TEST(@"-[bindToHost:port:]", - (port = [server bindToHost: @"127.0.0.1" port: 0])) + R(address = [server bindToHost: @"127.0.0.1" port: 0])) TEST(@"-[listen]", R([server listen])) TEST(@"-[connectToHost:port:]", - R([client connectToHost: @"127.0.0.1" port: port])) + R([client connectToHost: @"127.0.0.1" + port: OFSocketAddressIPPort(&address)])) TEST(@"-[accept]", (accepted = [server accept])) TEST(@"-[remoteAddress]", [OFSocketAddressString(accepted.remoteAddress)