@@ -18,16 +18,16 @@ #define __NO_EXT_QNX #include "config.h" +#include +#include #include #include #include -#include - #import "OFTCPSocket.h" #import "OFTCPSocket+SOCKS5.h" #import "OFString.h" #import "OFThread.h" #import "OFTimer.h" @@ -267,10 +267,11 @@ port: (uint16_t)port { OFString *destinationHost = host; uint16_t destinationPort = port; of_resolver_result_t **results, **iter; + int errNo = 0; if (_socket != INVALID_SOCKET) @throw [OFAlreadyConnectedException exceptionWithSocket: self]; _listening = false; @@ -294,22 +295,28 @@ int flags; #endif if ((_socket = socket(result->family, result->type | SOCK_CLOEXEC, - result->protocol)) == INVALID_SOCKET) + result->protocol)) == INVALID_SOCKET) { + errNo = of_socket_errno(); + continue; + } #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC) if ((flags = fcntl(_socket, F_GETFD, 0)) != -1) fcntl(_socket, F_SETFD, flags | FD_CLOEXEC); #endif if (connect(_socket, result->address, result->addressLength) == -1) { + errNo = of_socket_errno(); + close(_socket); _socket = INVALID_SOCKET; + continue; } break; } @@ -317,11 +324,12 @@ of_resolver_free(results); if (_socket == INVALID_SOCKET) @throw [OFConnectionFailedException exceptionWithHost: host port: port - socket: self]; + socket: self + errNo: errNo]; if (_SOCKS5Host != nil) [self OF_SOCKS5ConnectToHost: destinationHost port: destinationPort]; } @@ -399,31 +407,35 @@ #endif if ((_socket = socket(results[0]->family, results[0]->type | SOCK_CLOEXEC, results[0]->protocol)) == INVALID_SOCKET) - @throw [OFBindFailedException exceptionWithHost: host - port: port - socket: self]; + @throw [OFBindFailedException + exceptionWithHost: host + port: port + socket: self + errNo: of_socket_errno()]; #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC) if ((flags = fcntl(_socket, F_GETFD, 0)) != -1) fcntl(_socket, F_SETFD, flags | FD_CLOEXEC); #endif - if (setsockopt(_socket, SOL_SOCKET, SO_REUSEADDR, - (const char*)&one, (socklen_t)sizeof(one))) - @throw [OFSetOptionFailedException - exceptionWithStream: self]; + setsockopt(_socket, SOL_SOCKET, SO_REUSEADDR, + (const char*)&one, (socklen_t)sizeof(one)); if (bind(_socket, results[0]->address, results[0]->addressLength) == -1) { + int errNo = of_socket_errno(); + close(_socket); _socket = INVALID_SOCKET; + @throw [OFBindFailedException exceptionWithHost: host port: port - socket: self]; + socket: self + errNo: errNo]; } } @finally { of_resolver_free(results); } @@ -431,15 +443,19 @@ return port; #ifndef __wii__ addrLen = (socklen_t)sizeof(addr.storage); if (getsockname(_socket, (struct sockaddr*)&addr.storage, &addrLen)) { + int errNo = of_socket_errno(); + close(_socket); _socket = INVALID_SOCKET; + @throw [OFBindFailedException exceptionWithHost: host port: port - socket: self]; + socket: self + errNo: errNo]; } if (addr.storage.ss_family == AF_INET) return OF_BSWAP16_IF_LE(addr.in.sin_port); # ifdef AF_INET6 @@ -450,11 +466,12 @@ close(_socket); _socket = INVALID_SOCKET; @throw [OFBindFailedException exceptionWithHost: host port: port - socket: self]; + socket: self + errNo: EAFNOSUPPORT]; } - (void)listen { [self listenWithBackLog: SOMAXCONN]; @@ -464,12 +481,14 @@ { if (_socket == INVALID_SOCKET) @throw [OFNotConnectedException exceptionWithSocket: self]; if (listen(_socket, backLog) == -1) - @throw [OFListenFailedException exceptionWithSocket: self - backLog: backLog]; + @throw [OFListenFailedException + exceptionWithSocket: self + backLog: backLog + errNo: of_socket_errno()]; _listening = true; } - (instancetype)accept @@ -486,19 +505,25 @@ client->_addressLength = (socklen_t)sizeof(struct sockaddr_storage); #if defined(HAVE_PACCEPT) && defined(SOCK_CLOEXEC) if ((client->_socket = paccept(_socket, client->_address, &client->_addressLength, NULL, SOCK_CLOEXEC)) == INVALID_SOCKET) - @throw [OFAcceptFailedException exceptionWithSocket: self]; + @throw [OFAcceptFailedException + exceptionWithSocket: self + errNo: of_socket_errno()]; #elif defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) if ((client->_socket = accept4(_socket, client->_address, &client->_addressLength, SOCK_CLOEXEC)) == INVALID_SOCKET) - @throw [OFAcceptFailedException exceptionWithSocket: self]; + @throw [OFAcceptFailedException + exceptionWithSocket: self + errNo: of_socket_errno()]; #else if ((client->_socket = accept(_socket, client->_address, &client->_addressLength)) == INVALID_SOCKET) - @throw [OFAcceptFailedException exceptionWithSocket: self]; + @throw [OFAcceptFailedException + exceptionWithSocket: self + errNo: of_socket_errno()]; # if defined(HAVE_FCNTL) && defined(FD_CLOEXEC) if ((flags = fcntl(client->_socket, F_GETFD, 0)) != -1) fcntl(client->_socket, F_SETFD, flags | FD_CLOEXEC); # endif @@ -539,11 +564,13 @@ { int v = enable; if (setsockopt(_socket, SOL_SOCKET, SO_KEEPALIVE, (char*)&v, (socklen_t)sizeof(v))) - @throw [OFSetOptionFailedException exceptionWithStream: self]; + @throw [OFSetOptionFailedException + exceptionWithStream: self + errNo: of_socket_errno()]; } - (OFString*)remoteAddress { OFString *ret;