@@ -10,10 +10,11 @@ */ #include "config.h" #include +#include #include #include #ifndef HAVE_GETADDRINFO # include @@ -51,40 +52,28 @@ close(sock); [super dealloc]; } -/* - * FIXME: Maybe we could copy the result of the name lookup and release the - * lock so that we don't keep the lock during connection attemps. - */ - connectToService: (OFString*)service onNode: (OFString*)node { if (sock != INVALID_SOCKET) @throw [OFAlreadyConnectedException newWithClass: isa]; -#ifdef HAVE_GETADDRINFO +#ifdef HAVE_THREADSAFE_GETADDRINFO struct addrinfo hints, *res, *res0; memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; -#if defined(OF_THREADS) && !defined(HAVE_THREADSAFE_GETADDRINFO) - [mutex lock]; -#endif - - if (getaddrinfo([node cString], [service cString], &hints, &res0)) { -#if defined(OF_THREADS) && !defined(HAVE_THREADSAFE_GETADDRINFO) - [mutex unlock]; -#endif + if (getaddrinfo([node cString], [service cString], &hints, &res0)) @throw [OFAddressTranslationFailedException newWithClass: isa node: node service: service]; - } for (res = res0; res != NULL; res = res->ai_next) { if ((sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == INVALID_SOCKET) continue; @@ -97,28 +86,27 @@ break; } freeaddrinfo(res0); - -#if defined(OF_THREADS) && !defined(HAVE_THREADSAFE_GETADDRINFO) - [mutex unlock]; -#endif #else BOOL connected = NO; struct hostent *he; struct servent *se; struct sockaddr_in addr; uint16_t port; char **ip; - #ifdef OF_THREADS + OFDataArray *addrlist; + + addrlist = [[OFDataArray alloc] initWithItemSize: sizeof(char**)]; [mutex lock]; #endif if ((he = gethostbyname([node cString])) == NULL) { #ifdef OF_THREADS + [addrlist release]; [mutex unlock]; #endif @throw [OFAddressTranslationFailedException newWithClass: isa node: node @@ -125,12 +113,14 @@ service: service]; } if ((se = getservbyname([service cString], "TCP")) != NULL) port = se->s_port; - else if ((port = OF_BSWAP16_IF_LE(atoi([service cString]))) == 0) { + else if ((port = OF_BSWAP16_IF_LE(strtol([service cString], NULL, + 10))) == 0) { #ifdef OF_THREADS + [addrlist release]; [mutex unlock]; #endif @throw [OFAddressTranslationFailedException newWithClass: isa node: node @@ -142,19 +132,37 @@ addr.sin_port = port; if (he->h_addrtype != AF_INET || (sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { #ifdef OF_THREADS + [addrlist release]; [mutex unlock]; #endif @throw [OFConnectionFailedException newWithClass: isa node: node service: service]; } +#ifdef OF_THREADS + @try { + for (ip = he->h_addr_list; *ip != NULL; ip++) + [addrlist addItem: ip]; + + /* Add the terminating NULL */ + [addrlist addItem: ip]; + } @catch (OFException *e) { + [addrlist release]; + @throw e; + } @finally { + [mutex unlock]; + } + + for (ip = [addrlist cArray]; *ip != NULL; ip++) { +#else for (ip = he->h_addr_list; *ip != NULL; ip++) { +#endif memcpy(&addr.sin_addr.s_addr, *ip, he->h_length); if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) continue; @@ -161,11 +169,11 @@ connected = YES; break; } #ifdef OF_THREADS - [mutex unlock]; + [addrlist release]; #endif if (!connected) { close(sock); sock = INVALID_SOCKET; @@ -191,47 +199,32 @@ @throw [OFBindFailedException newWithClass: isa node: node service: service family: family]; -#ifdef HAVE_GETADDRINFO +#ifdef HAVE_THREADSAFE_GETADDRINFO struct addrinfo hints, *res; memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = family; hints.ai_socktype = SOCK_STREAM; -#if defined(OF_THREADS) && !defined(HAVE_THREADSAFE_GETADDRINFO) - [mutex lock]; -#endif - - if (getaddrinfo([node cString], [service cString], &hints, &res)) { -#if defined(OF_THREADS) && !defined(HAVE_THREADSAFE_GETADDRINFO) - [mutex unlock]; -#endif + if (getaddrinfo([node cString], [service cString], &hints, &res)) @throw [OFAddressTranslationFailedException newWithClass: isa node: node service: service]; - } if (bind(sock, res->ai_addr, res->ai_addrlen) == -1) { freeaddrinfo(res); -#if defined(OF_THREADS) && !defined(HAVE_THREADSAFE_GETADDRINFO) - [mutex unlock]; -#endif @throw [OFBindFailedException newWithClass: isa node: node service: service family: family]; } freeaddrinfo(res); - -#if defined(OF_THREADS) && !defined(HAVE_THREADSAFE_GETADDRINFO) - [mutex unlock]; -#endif #else struct hostent *he; struct servent *se; struct sockaddr_in addr; uint16_t port; @@ -256,11 +249,12 @@ service: service]; } if ((se = getservbyname([service cString], "TCP")) != NULL) port = se->s_port; - else if ((port = OF_BSWAP16_IF_LE(atoi([service cString]))) == 0) { + else if ((port = OF_BSWAP16_IF_LE(strtol([service cString], NULL, + 10))) == 0) { #ifdef OF_THREADS [mutex unlock]; #endif @throw [OFAddressTranslationFailedException newWithClass: isa