Index: src/OFUDPSocket+Private.h ================================================================== --- src/OFUDPSocket+Private.h +++ src/OFUDPSocket+Private.h @@ -17,10 +17,9 @@ OF_ASSUME_NONNULL_BEGIN OF_DIRECT_MEMBERS @interface OFUDPSocket () -- (uint16_t)of_bindToAddress: (OFSocketAddress *)address - extraType: (int)extraType; +- (void)of_bindToAddress: (OFSocketAddress *)address extraType: (int)extraType; @end OF_ASSUME_NONNULL_END Index: src/OFUDPSocket.h ================================================================== --- src/OFUDPSocket.h +++ src/OFUDPSocket.h @@ -69,13 +69,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 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/OFUDPSocket.m ================================================================== --- src/OFUDPSocket.m +++ src/OFUDPSocket.m @@ -38,17 +38,19 @@ #import "OFBindIPSocketFailedException.h" @implementation OFUDPSocket @dynamic delegate; -- (uint16_t)of_bindToAddress: (OFSocketAddress *)address - extraType: (int)extraType OF_DIRECT +- (void)of_bindToAddress: (OFSocketAddress *)address + extraType: (int)extraType OF_DIRECT { - void *pool = objc_autoreleasePoolPush(); - uint16_t port; #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC) int flags; +#endif +#if !defined(OF_HPUX) && !defined(OF_WII) && !defined(OF_NINTENDO_3DS) + OFString *host; + uint16_t port; #endif if ((_socket = socket( ((struct sockaddr *)&address->sockaddr)->sa_family, SOCK_DGRAM | SOCK_CLOEXEC | extraType, 0)) == OFInvalidSocketHandle) @@ -100,11 +102,11 @@ break; if (OFSocketErrNo() != EADDRINUSE) { int errNo = OFSocketErrNo(); OFString *host = OFSocketAddressString(address); - port = OFSocketAddressIPPort(address); + uint16_t port = OFSocketAddressIPPort(address); closesocket(_socket); _socket = OFInvalidSocketHandle; @throw [OFBindIPSocketFailedException @@ -115,16 +117,14 @@ } } } #endif - objc_autoreleasePoolPop(pool); - - if ((port = OFSocketAddressIPPort(address)) > 0) - return port; - #if !defined(OF_HPUX) && !defined(OF_WII) && !defined(OF_NINTENDO_3DS) + host = OFSocketAddressString(address); + port = OFSocketAddressIPPort(address); + memset(address, 0, sizeof(*address)); address->length = (socklen_t)sizeof(address->sockaddr); if (OFGetSockName(_socket, (struct sockaddr *)&address->sockaddr, &address->length) != 0) { @@ -131,47 +131,39 @@ int errNo = OFSocketErrNo(); closesocket(_socket); _socket = OFInvalidSocketHandle; - @throw [OFBindIPSocketFailedException - exceptionWithHost: OFSocketAddressString(address) - port: OFSocketAddressIPPort(address) - socket: self - errNo: errNo]; + @throw [OFBindIPSocketFailedException exceptionWithHost: host + port: port + socket: self + 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; @throw [OFBindIPSocketFailedException - exceptionWithHost: OFSocketAddressString(address) - port: OFSocketAddressIPPort(address) + exceptionWithHost: host + port: port socket: self errNo: EAFNOSUPPORT]; } -#else - closesocket(_socket); - _socket = OFInvalidSocketHandle; - - @throw [OFBindIPSocketFailedException - exceptionWithHost: OFSocketAddressString(address) - port: OFSocketAddressIPPort(address) - socket: self - errNo: EADDRNOTAVAIL]; #endif } -- (uint16_t)bindToHost: (OFString *)host port: (uint16_t)port +- (OFSocketAddress)bindToHost: (OFString *)host port: (uint16_t)port { void *pool = objc_autoreleasePoolPush(); OFData *socketAddresses; OFSocketAddress address; @@ -183,12 +175,12 @@ addressFamily: OFSocketAddressFamilyAny]; address = *(OFSocketAddress *)[socketAddresses itemAtIndex: 0]; OFSocketAddressSetIPPort(&address, port); - port = [self of_bindToAddress: &address extraType: 0]; + [self of_bindToAddress: &address extraType: 0]; objc_autoreleasePoolPop(pool); - return port; + return address; } @end Index: tests/OFUDPSocketTests.m ================================================================== --- tests/OFUDPSocketTests.m +++ tests/OFUDPSocketTests.m @@ -24,31 +24,29 @@ @implementation TestsAppDelegate (OFUDPSocketTests) - (void)UDPSocketTests { void *pool = objc_autoreleasePoolPush(); OFUDPSocket *sock; - uint16_t port1; OFSocketAddress addr1, addr2, addr3; char buf[6]; TEST(@"+[socket]", (sock = [OFUDPSocket socket])) TEST(@"-[bindToHost:port:]", - (port1 = [sock bindToHost: @"127.0.0.1" port: 0])) - - addr1 = OFSocketAddressParseIP(@"127.0.0.1", port1); + R(addr1 = [sock bindToHost: @"127.0.0.1" port: 0])) TEST(@"-[sendBuffer:length:receiver:]", R([sock sendBuffer: "Hello" length: 6 receiver: &addr1])) TEST(@"-[receiveIntoBuffer:length:sender:]", [sock receiveIntoBuffer: buf length: 6 sender: &addr2] == 6 && !memcmp(buf, "Hello", 6) && [OFSocketAddressString(&addr2) isEqual: @"127.0.0.1"] && - OFSocketAddressIPPort(&addr2) == port1) + OFSocketAddressIPPort(&addr2) == OFSocketAddressIPPort(&addr1)) - addr3 = OFSocketAddressParseIP(@"127.0.0.1", port1 + 1); + addr3 = OFSocketAddressParseIP(@"127.0.0.1", + OFSocketAddressIPPort(&addr1) + 1); TEST(@"OFSocketAddressEqual()", OFSocketAddressEqual(&addr1, &addr2) && !OFSocketAddressEqual(&addr1, &addr3))