Index: src/OFDDPSocket.h ================================================================== --- src/OFDDPSocket.h +++ src/OFDDPSocket.h @@ -66,12 +66,14 @@ * specified packet type. * * @param port The port to bind to. 0 means to pick one and return it via the * returned socket address. * @return The address on which this socket can be reached - * @throw OFBindFailedException Binding failed + * @throw OFBindDDPSockeFailedException Binding failed * @throw OFAlreadyConnectedException The socket is already bound */ -- (OFSocketAddress)bindToPort: (uint8_t)port; +- (OFSocketAddress)bindToNetwork: (uint16_t)network + node: (uint8_t)node + port: (uint8_t)port; @end OF_ASSUME_NONNULL_END Index: src/OFDDPSocket.m ================================================================== --- src/OFDDPSocket.m +++ src/OFDDPSocket.m @@ -29,28 +29,32 @@ #import "OFBindDDPSocketFailedException.h" @implementation OFDDPSocket @dynamic delegate; -- (OFSocketAddress)bindToPort: (uint8_t)port +- (OFSocketAddress)bindToNetwork: (uint16_t)network + node: (uint8_t)node + port: (uint8_t)port { OFSocketAddress address; #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL_H) && defined(FD_CLOEXEC) int flags; #endif if (_socket != OFInvalidSocketHandle) @throw [OFAlreadyConnectedException exceptionWithSocket: self]; - address = OFSocketAddressMakeAppleTalk(0, 0, port); + address = OFSocketAddressMakeAppleTalk(network, node, port); if ((_socket = socket(address.sockaddr.at.sat_family, SOCK_DGRAM | SOCK_CLOEXEC, 0)) == OFInvalidSocketHandle) @throw [OFBindDDPSocketFailedException - exceptionWithPort: port - socket: self - errNo: OFSocketErrNo()]; + exceptionWithNetwork: network + node: node + port: port + socket: self + errNo: OFSocketErrNo()]; _canBlock = true; #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL_H) && defined(FD_CLOEXEC) if ((flags = fcntl(_socket, F_GETFD, 0)) != -1) @@ -63,13 +67,15 @@ closesocket(_socket); _socket = OFInvalidSocketHandle; @throw [OFBindDDPSocketFailedException - exceptionWithPort: port - socket: self - errNo: errNo]; + exceptionWithNetwork: network + node: node + port: port + socket: self + errNo: errNo]; } memset(&address, 0, sizeof(address)); address.family = OFSocketAddressFamilyAppleTalk; address.length = (socklen_t)sizeof(address.sockaddr); @@ -80,23 +86,27 @@ closesocket(_socket); _socket = OFInvalidSocketHandle; @throw [OFBindDDPSocketFailedException - exceptionWithPort: port - socket: self - errNo: errNo]; + exceptionWithNetwork: network + node: node + port: port + socket: self + errNo: errNo]; } if (address.sockaddr.at.sat_family != AF_APPLETALK) { closesocket(_socket); _socket = OFInvalidSocketHandle; @throw [OFBindDDPSocketFailedException - exceptionWithPort: port - socket: self - errNo: EAFNOSUPPORT]; + exceptionWithNetwork: network + node: node + port: port + socket: self + errNo: EAFNOSUPPORT]; } return address; } @end Index: src/exceptions/OFBindDDPSocketFailedException.h ================================================================== --- src/exceptions/OFBindDDPSocketFailedException.h +++ src/exceptions/OFBindDDPSocketFailedException.h @@ -25,44 +25,63 @@ * @brief An exception indicating that binding a DDP socket failed. */ OF_SUBCLASSING_RESTRICTED @interface OFBindDDPSocketFailedException: OFBindSocketFailedException { - uint8_t _port; + uint16_t _network; + uint8_t _node, _port; } +/** + * @brief The DDP network on which binding failed. + */ +@property (readonly, nonatomic) uint16_t network; + +/** + * @brief The DDP node for which binding failed. + */ +@property (readonly, nonatomic) uint8_t node; + /** * @brief The DDP port on which binding failed. */ @property (readonly, nonatomic) uint8_t port; /** * @brief Creates a new, autoreleased bind DDP socket failed exception. * - * @param port The DDP port to which binding failed + * @param network The DDP network on which binding failed + * @param node The DDP node for which binding failed + * @param port The DDP port on which binding failed * @param socket The socket which could not be bound * @param errNo The errno of the error that occurred * @return A new, autoreleased bind DDP socket failed exception */ -+ (instancetype)exceptionWithPort: (uint8_t)port - socket: (id)socket - errNo: (int)errNo; ++ (instancetype)exceptionWithNetwork: (uint16_t)network + node: (uint8_t)node + port: (uint8_t)port + socket: (id)socket + errNo: (int)errNo; + (instancetype)exceptionWithSocket: (id)socket errNo: (int)errNo OF_UNAVAILABLE; /** * @brief Initializes an already allocated bind DDP socket failed exception. * - * @param port The DDP port to which binding failed + * @param network The DDP network on which binding failed + * @param node The DDP node for which binding failed + * @param port The DDP port on which binding failed * @param socket The socket which could not be bound * @param errNo The errno of the error that occurred * @return An initialized bind DDP socket failed exception */ -- (instancetype)initWithPort: (uint8_t)port - socket: (id)socket - errNo: (int)errNo OF_DESIGNATED_INITIALIZER; +- (instancetype)initWithNetwork: (uint16_t)network + node: (uint8_t)node + port: (uint8_t)port + socket: (id)socket + errNo: (int)errNo OF_DESIGNATED_INITIALIZER; - (instancetype)initWithSocket: (id)socket errNo: (int)errNo OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END Index: src/exceptions/OFBindDDPSocketFailedException.m ================================================================== --- src/exceptions/OFBindDDPSocketFailedException.m +++ src/exceptions/OFBindDDPSocketFailedException.m @@ -18,38 +18,46 @@ #import "OFBindDDPSocketFailedException.h" #import "OFData.h" #import "OFString.h" @implementation OFBindDDPSocketFailedException -@synthesize port = _port; +@synthesize network = _network, node = _node, port = _port; + (instancetype)exceptionWithSocket: (id)sock errNo: (int)errNo { OF_UNRECOGNIZED_SELECTOR } -+ (instancetype)exceptionWithPort: (uint8_t)port - socket: (id)sock - errNo: (int)errNo ++ (instancetype)exceptionWithNetwork: (uint16_t)network + node: (uint8_t)node + port: (uint8_t)port + socket: (id)sock + errNo: (int)errNo { - return [[[self alloc] initWithPort: port - socket: sock - errNo: errNo] autorelease]; + return [[[self alloc] initWithNetwork: network + node: node + port: port + socket: sock + errNo: errNo] autorelease]; } - (instancetype)initWithSocket: (id)sock errNo: (int)errNo { OF_INVALID_INIT_METHOD } -- (instancetype)initWithPort: (uint8_t)port - socket: (id)sock - errNo: (int)errNo +- (instancetype)initWithNetwork: (uint16_t)network + node: (uint8_t)node + port: (uint8_t)port + socket: (id)sock + errNo: (int)errNo { self = [super initWithSocket: sock errNo: errNo]; @try { + _network = network; + _node = node; _port = port; } @catch (id e) { [self release]; @throw e; } @@ -58,9 +66,10 @@ } - (OFString *)description { return [OFString stringWithFormat: - @"Binding to port %" @PRIx8 @" failed in socket of type %@: %@", - _port, [_socket class], OFStrError(_errNo)]; + @"Binding to port %" @PRIx8 @" of node %" @PRIx8 @" on network " + @"%" PRIx16 @" failed in socket of type %@: %@", + _port, _node, _network, [_socket class], OFStrError(_errNo)]; } @end Index: tests/OFDDPSocketTests.m ================================================================== --- tests/OFDDPSocketTests.m +++ tests/OFDDPSocketTests.m @@ -30,23 +30,24 @@ char buffer[5]; TEST(@"+[socket]", (sock = [OFDDPSocket socket])) @try { - TEST(@"-[bindToPort:]", R(address1 = [sock bindToPort: 0])) + TEST(@"-[bindToNetwork:node:port:]", + R(address1 = [sock bindToNetwork: 0 node: 0 port: 0])) } @catch (OFBindSocketFailedException *e) { switch (e.errNo) { case EAFNOSUPPORT: [OFStdOut setForegroundColor: [OFColor lime]]; [OFStdOut writeLine: - @"\r[OFDDPSocket] -[bindToPort:] " + @"\r[OFDDPSocket] -[bindToNetwork:node:port:] " @"AppleTalk unsupported, skipping tests"]; break; case EADDRNOTAVAIL: [OFStdOut setForegroundColor: [OFColor lime]]; [OFStdOut writeLine: - @"\r[OFDDPSocket] -[bindToPort:]: " + @"\r[OFDDPSocket] -[bindToNetwork:node:port:] " @"AppleTalk not configured, skipping tests"]; break; default: @throw e; }