From 39672b2df6d565840c64326c56a70eeb6f56650f Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 7 Oct 2015 18:59:58 -0400 Subject: [PATCH 1/5] fixed typo causing non free of mutex_buf structure in pqissl.cc --- libretroshare/src/pqi/authssl.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libretroshare/src/pqi/authssl.cc b/libretroshare/src/pqi/authssl.cc index 661894512..274187f5b 100644 --- a/libretroshare/src/pqi/authssl.cc +++ b/libretroshare/src/pqi/authssl.cc @@ -198,7 +198,7 @@ void tls_cleanup() CRYPTO_set_locking_callback(NULL); CRYPTO_set_id_callback(NULL); - if (mutex_buf == NULL) { + if (mutex_buf != NULL) { for (int i = 0; i < CRYPTO_num_locks(); i++) { pthread_mutex_destroy(&mutex_buf[i]); } From f1f722a767437b06ed1cdbe16e87bbb57e9e909e Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 7 Oct 2015 19:08:35 -0400 Subject: [PATCH 2/5] added missing shutdown of non responsive socket that could leak FDs (suggested by GuessWho --- libretroshare/src/pqi/pqissllistener.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libretroshare/src/pqi/pqissllistener.cc b/libretroshare/src/pqi/pqissllistener.cc index b46b946ed..12cd3adc5 100644 --- a/libretroshare/src/pqi/pqissllistener.cc +++ b/libretroshare/src/pqi/pqissllistener.cc @@ -123,6 +123,10 @@ int pqissllistenbase::setuplisten() err = fcntl(lsock, F_SETFL, O_NONBLOCK); if (err < 0) { + shutdown(lsock,SHUT_RDWR) ; + close(lsock) ; + lsock = -1 ; + std::string out; rs_sprintf(out, "Error: Cannot make socket NON-Blocking: %d", err); pqioutput(PQL_ERROR, pqissllistenzone, out); @@ -145,6 +149,9 @@ int pqissllistenbase::setuplisten() unsigned long int on = 1; if (0 != (err = ioctlsocket(lsock, FIONBIO, &on))) { + closesocket(lsock) ; + lsock = -1 ; + std::string out; rs_sprintf(out, "pqissllistenbase::setuplisten() Error: Cannot make socket NON-Blocking: %d\n", err); out += "Socket Error: " + socket_errorType(WSAGetLastError()); From e776effc0dec069097a4fc2b6eba4a79933b8b08 Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 7 Oct 2015 21:24:31 -0400 Subject: [PATCH 3/5] added new method rsGetHostByName to use gethostbyname_r for re-entrant calls. Updated dnsresolver and extaddrfinder to use it. Suggestion by GuessWho #125 --- libretroshare/src/util/dnsresolver.cc | 38 ++++++++++++-------- libretroshare/src/util/extaddrfinder.cc | 11 +++--- libretroshare/src/util/rsmemory.h | 46 +++++++++++++++---------- libretroshare/src/util/rsnet.cc | 31 +++++++++++++++++ libretroshare/src/util/rsnet.h | 3 ++ 5 files changed, 90 insertions(+), 39 deletions(-) diff --git a/libretroshare/src/util/dnsresolver.cc b/libretroshare/src/util/dnsresolver.cc index a91e34821..b45f810a3 100644 --- a/libretroshare/src/util/dnsresolver.cc +++ b/libretroshare/src/util/dnsresolver.cc @@ -62,25 +62,33 @@ void *solveDNSEntries(void *p) if(!next_call.empty()) { - hostent *pHost = gethostbyname(next_call.c_str()); + in_addr in ; + + bool succeed = rsGetHostByName(next_call.c_str(),in); + + { + RsStackMutex mut(dnsr->_rdnsMtx) ; - { - RsStackMutex mut(dnsr->_rdnsMtx) ; + DNSResolver::AddrInfo &info = (*dnsr->_addr_map)[next_call]; - DNSResolver::AddrInfo &info = (*dnsr->_addr_map)[next_call]; - - if(pHost) + if(succeed) + { + info.state = DNSResolver::DNS_HAVE ; + // IPv4 for the moment. + struct sockaddr_in *addrv4p = (struct sockaddr_in *) &(info.addr); + addrv4p->sin_family = AF_INET; + addrv4p->sin_addr= in ; + addrv4p->sin_port = htons(0); + + std::cerr << "LOOKUP succeeded: " << next_call.c_str() << " => " << rs_inet_ntoa(addrv4p->sin_addr) << std::endl; + } + else { - info.state = DNSResolver::DNS_HAVE ; - // IPv4 for the moment. - struct sockaddr_in *addrv4p = (struct sockaddr_in *) &(info.addr); - addrv4p->sin_family = AF_INET; - addrv4p->sin_addr.s_addr = *(unsigned long*) (pHost->h_addr); - addrv4p->sin_port = htons(0); - } - else info.state = DNSResolver::DNS_LOOKUP_ERROR ; - } + + std::cerr << "DNSResolver: lookup error for address \"" << next_call.c_str() << "\"" << std::endl; + } + } } } diff --git a/libretroshare/src/util/extaddrfinder.cc b/libretroshare/src/util/extaddrfinder.cc index 226f27f92..a7da88fa4 100644 --- a/libretroshare/src/util/extaddrfinder.cc +++ b/libretroshare/src/util/extaddrfinder.cc @@ -2,6 +2,7 @@ #include "pqi/pqinetwork.h" #include "util/rsstring.h" +#include "util/rsmemory.h" #ifndef WIN32 #include @@ -58,7 +59,6 @@ static void getPage(const std::string& server_name,std::string& page) int sockfd,n=0; // socket descriptor struct sockaddr_in serveur; // server's parameters memset(&serveur.sin_zero, 0, sizeof(serveur.sin_zero)); - struct hostent *hostinfo=NULL; // structure for storing the server's ip char buf[1024]; char request[1024]; @@ -78,20 +78,21 @@ static void getPage(const std::string& server_name,std::string& page) // get server's ipv4 adress - hostinfo = gethostbyname(server_name.c_str()); - - if (hostinfo == NULL) /* l'hôte n'existe pas */ + in_addr in ; + + if(!rsGetHostByName(server_name.c_str(),in)) /* l'hôte n'existe pas */ { std::cerr << "ExtAddrFinder: Unknown host " << server_name << std::endl; unix_close(sockfd); return ; } - serveur.sin_addr = *(struct in_addr*) hostinfo->h_addr; + serveur.sin_addr = in ; serveur.sin_port = htons(80); #ifdef EXTADDRSEARCH_DEBUG printf("Connection attempt\n"); #endif + std::cerr << "ExtAddrFinder: resolved hostname " << server_name << " to " << rs_inet_ntoa(in) << std::endl; if(unix_connect(sockfd,(struct sockaddr *)&serveur, sizeof(serveur)) == -1) { diff --git a/libretroshare/src/util/rsmemory.h b/libretroshare/src/util/rsmemory.h index a7ba409b8..c6b88ed2b 100644 --- a/libretroshare/src/util/rsmemory.h +++ b/libretroshare/src/util/rsmemory.h @@ -21,29 +21,37 @@ // class RsTemporaryMemory { - public: - RsTemporaryMemory(size_t s) - { - _mem = (unsigned char *)malloc(s) ; - } +public: + RsTemporaryMemory(size_t s) + { + _mem = (unsigned char *)malloc(s) ; - operator unsigned char *() { return _mem ; } + if(_mem) + _size = s ; + else + _size = 0 ; + } - ~RsTemporaryMemory() - { - if(_mem != NULL) - { - free(_mem) ; - _mem = NULL ; - } - } + operator unsigned char *() { return _mem ; } + + size_t size() const { return _size ; } - private: - unsigned char *_mem ; + ~RsTemporaryMemory() + { + if(_mem != NULL) + { + free(_mem) ; + _mem = NULL ; + } + } - // make it noncopyable - RsTemporaryMemory& operator=(const RsTemporaryMemory&) { return *this ;} - RsTemporaryMemory(const RsTemporaryMemory&) {} +private: + unsigned char *_mem ; + size_t _size ; + + // make it noncopyable + RsTemporaryMemory& operator=(const RsTemporaryMemory&) { return *this ;} + RsTemporaryMemory(const RsTemporaryMemory&) {} }; diff --git a/libretroshare/src/util/rsnet.cc b/libretroshare/src/util/rsnet.cc index 7ec34c625..0608abc67 100644 --- a/libretroshare/src/util/rsnet.cc +++ b/libretroshare/src/util/rsnet.cc @@ -26,6 +26,7 @@ #include "util/rsnet.h" #include "util/rsthreads.h" #include "util/rsstring.h" +#include "util/rsmemory.h" #ifdef WINDOWS_SYS #else @@ -72,6 +73,36 @@ void sockaddr_clear(struct sockaddr_in *addr) addr->sin_family = AF_INET; } +bool rsGetHostByName(const std::string& hostname, in_addr& returned_addr) +{ + RsTemporaryMemory mem(8192) ; + + if(!mem) + { + std::cerr << __PRETTY_FUNCTION__ << ": Cannot allocate memory!" << std::endl; + return false; // Do something. + } + + int error = 0; + struct hostent pHost; + struct hostent *result; + + if(gethostbyname_r(hostname.c_str(), &pHost, (char*)(unsigned char*)mem, mem.size(), &result, &error) != 0) + { + std::cerr << __PRETTY_FUNCTION__ << ": cannot call gethostname_r. Internal error reported. Check buffer size." << std::endl; + return false ; + } + if(!result) + { + std::cerr << __PRETTY_FUNCTION__ << ": gethostname_r returned null result." << std::endl; + return false ; + } + // Use contents of result. + + returned_addr.s_addr = *(unsigned long*) (result->h_addr); + + return true ; +} bool isValidNet(const struct in_addr *addr) { diff --git a/libretroshare/src/util/rsnet.h b/libretroshare/src/util/rsnet.h index 2bc06e1cd..5226bfba2 100644 --- a/libretroshare/src/util/rsnet.h +++ b/libretroshare/src/util/rsnet.h @@ -70,6 +70,9 @@ bool isLoopbackNet(const struct in_addr *addr); bool isPrivateNet(const struct in_addr *addr); bool isExternalNet(const struct in_addr *addr); +// uses a re-entrant version of gethostbyname +bool rsGetHostByName(const std::string& hostname, in_addr& returned_addr) ; + std::ostream& operator<<(std::ostream& o,const struct sockaddr_in&) ; /* thread-safe version of inet_ntoa */ From 4a4625e2bf461f4f185ab5facf6c1c07b8a7ab32 Mon Sep 17 00:00:00 2001 From: csoler Date: Thu, 8 Oct 2015 18:54:12 -0400 Subject: [PATCH 4/5] fixed compilation for windows (to be tested) --- libretroshare/src/util/rsnet.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libretroshare/src/util/rsnet.cc b/libretroshare/src/util/rsnet.cc index 0608abc67..3068bcef3 100644 --- a/libretroshare/src/util/rsnet.cc +++ b/libretroshare/src/util/rsnet.cc @@ -75,6 +75,9 @@ void sockaddr_clear(struct sockaddr_in *addr) bool rsGetHostByName(const std::string& hostname, in_addr& returned_addr) { +#ifdef WINDOWS_SYS + hostent *result = gethostbyname(hostname.c_str()) ; +#else RsTemporaryMemory mem(8192) ; if(!mem) @@ -92,9 +95,10 @@ bool rsGetHostByName(const std::string& hostname, in_addr& returned_addr) std::cerr << __PRETTY_FUNCTION__ << ": cannot call gethostname_r. Internal error reported. Check buffer size." << std::endl; return false ; } +#endif if(!result) { - std::cerr << __PRETTY_FUNCTION__ << ": gethostname_r returned null result." << std::endl; + std::cerr << __PRETTY_FUNCTION__ << ": gethostname returned null result." << std::endl; return false ; } // Use contents of result. From 1cf9c34207faaec3edbf4b9109626e9656549dff Mon Sep 17 00:00:00 2001 From: csoler Date: Thu, 8 Oct 2015 19:48:22 -0400 Subject: [PATCH 5/5] fixed compilation for MacOS --- libretroshare/src/util/rsnet.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libretroshare/src/util/rsnet.cc b/libretroshare/src/util/rsnet.cc index 3068bcef3..8f07d16c4 100644 --- a/libretroshare/src/util/rsnet.cc +++ b/libretroshare/src/util/rsnet.cc @@ -75,7 +75,7 @@ void sockaddr_clear(struct sockaddr_in *addr) bool rsGetHostByName(const std::string& hostname, in_addr& returned_addr) { -#ifdef WINDOWS_SYS +#if defined(WINDOWS_SYS) || defined(__APPLE__) hostent *result = gethostbyname(hostname.c_str()) ; #else RsTemporaryMemory mem(8192) ;