@@ -13,13 +13,16 @@ #include #include #include #include + +#include #if !defined(HAVE_THREADSAFE_GETADDRINFO) && !defined(_WIN32) # include +# include #endif #import "OFTCPSocket.h" #import "OFString.h" #import "OFExceptions.h" @@ -94,22 +97,22 @@ struct hostent *he; struct servent *se; struct sockaddr_in addr; uint16_t port; char **ip; -#ifdef OF_THREADS +# ifdef OF_THREADS OFDataArray *addrlist; addrlist = [[OFDataArray alloc] initWithItemSize: sizeof(char**)]; [mutex lock]; -#endif +# endif if ((he = gethostbyname([node cString])) == NULL) { -#ifdef OF_THREADS +# ifdef OF_THREADS [addrlist release]; [mutex unlock]; -#endif +# endif @throw [OFAddressTranslationFailedException newWithClass: isa node: node service: service]; } @@ -116,14 +119,14 @@ if ((se = getservbyname([service cString], "TCP")) != NULL) port = se->s_port; else if ((port = OF_BSWAP16_IF_LE(strtol([service cString], NULL, 10))) == 0) { -#ifdef OF_THREADS +# ifdef OF_THREADS [addrlist release]; [mutex unlock]; -#endif +# endif @throw [OFAddressTranslationFailedException newWithClass: isa node: node service: service]; } @@ -132,21 +135,21 @@ addr.sin_family = AF_INET; addr.sin_port = port; if (he->h_addrtype != AF_INET || (sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { -#ifdef OF_THREADS +# ifdef OF_THREADS [addrlist release]; [mutex unlock]; -#endif +# endif @throw [OFConnectionFailedException newWithClass: isa node: node service: service]; } -#ifdef OF_THREADS +# ifdef OF_THREADS @try { for (ip = he->h_addr_list; *ip != NULL; ip++) [addrlist addItem: ip]; /* Add the terminating NULL */ @@ -157,25 +160,25 @@ } @finally { [mutex unlock]; } for (ip = [addrlist cArray]; *ip != NULL; ip++) { -#else +# else for (ip = he->h_addr_list; *ip != NULL; ip++) { -#endif +# endif memcpy(&addr.sin_addr.s_addr, *ip, he->h_length); if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) continue; connected = YES; break; } -#ifdef OF_THREADS +# ifdef OF_THREADS [addrlist release]; -#endif +# endif if (!connected) { close(sock); sock = INVALID_SOCKET; } @@ -241,18 +244,18 @@ struct hostent *he; struct servent *se; struct sockaddr_in addr; uint16_t port; -#ifdef OF_THREADS +# ifdef OF_THREADS [mutex lock]; -#endif +# endif if ((he = gethostbyname([node cString])) == NULL) { -#ifdef OF_THREADS +# ifdef OF_THREADS [mutex unlock]; -#endif +# endif @throw [OFAddressTranslationFailedException newWithClass: isa node: node service: service]; } @@ -259,13 +262,13 @@ if ((se = getservbyname([service cString], "TCP")) != NULL) port = se->s_port; else if ((port = OF_BSWAP16_IF_LE(strtol([service cString], NULL, 10))) == 0) { -#ifdef OF_THREADS +# ifdef OF_THREADS [mutex unlock]; -#endif +# endif close(sock); sock = INVALID_SOCKET; @throw [OFAddressTranslationFailedException newWithClass: isa node: node @@ -275,13 +278,13 @@ memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = port; if (he->h_addrtype != AF_INET || he->h_addr_list[0] == NULL) { -#ifdef OF_THREADS +# ifdef OF_THREADS [mutex unlock]; -#endif +# endif close(sock); sock = INVALID_SOCKET; @throw [OFAddressTranslationFailedException newWithClass: isa node: node @@ -288,13 +291,13 @@ service: service]; } memcpy(&addr.sin_addr.s_addr, he->h_addr_list[0], he->h_length); -#ifdef OF_THREADS +# ifdef OF_THREADS [mutex unlock]; -#endif +# endif if (bind(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) { close(sock); sock = INVALID_SOCKET; @throw [OFBindFailedException newWithClass: isa @@ -367,10 +370,58 @@ if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char*)&v, sizeof(v))) @throw [OFSetOptionFailedException newWithClass: isa]; return self; } + +- (OFString*)remoteAddress +{ + if (saddr == NULL || saddr_len == 0) + @throw [OFInvalidArgumentException newWithClass: isa + selector: _cmd]; + +#ifdef HAVE_THREADSAFE_GETADDRINFO + char *node = [self allocMemoryWithSize: NI_MAXHOST]; + + @try { + if (getnameinfo(saddr, saddr_len, node, NI_MAXHOST, NULL, 0, + NI_NUMERICHOST)) + @throw [OFAddressTranslationFailedException + newWithClass: isa]; + + return [OFString stringWithCString: node]; + } @finally { + [self freeMemory: node]; + } + + /* Get rid of a warning, never reached anyway */ + assert(0); +#else + char *node; + +# ifdef OF_THREADS + [mutex lock]; + + @try { +# endif + node = inet_ntoa(((struct sockaddr_in*)saddr)->sin_addr); + + if (node == NULL) + @throw [OFAddressTranslationFailedException + newWithClass: isa]; + + return [OFString stringWithCString: node]; +# ifdef OF_THREADS + } @finally { + [mutex unlock]; + } + + /* Get rid of a warning, never reached anyway */ + assert(0); +# endif +#endif +} - close { if (sock == INVALID_SOCKET) @throw [OFNotConnectedException newWithClass: isa];