mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
added new method rsGetHostByName to use gethostbyname_r for re-entrant calls. Updated dnsresolver and extaddrfinder to use it. Suggestion by GuessWho #125
This commit is contained in:
parent
f1f722a767
commit
e776effc0d
@ -62,24 +62,32 @@ void *solveDNSEntries(void *p)
|
|||||||
|
|
||||||
if(!next_call.empty())
|
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 ;
|
info.state = DNSResolver::DNS_HAVE ;
|
||||||
// IPv4 for the moment.
|
// IPv4 for the moment.
|
||||||
struct sockaddr_in *addrv4p = (struct sockaddr_in *) &(info.addr);
|
struct sockaddr_in *addrv4p = (struct sockaddr_in *) &(info.addr);
|
||||||
addrv4p->sin_family = AF_INET;
|
addrv4p->sin_family = AF_INET;
|
||||||
addrv4p->sin_addr.s_addr = *(unsigned long*) (pHost->h_addr);
|
addrv4p->sin_addr= in ;
|
||||||
addrv4p->sin_port = htons(0);
|
addrv4p->sin_port = htons(0);
|
||||||
|
|
||||||
|
std::cerr << "LOOKUP succeeded: " << next_call.c_str() << " => " << rs_inet_ntoa(addrv4p->sin_addr) << std::endl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
info.state = DNSResolver::DNS_LOOKUP_ERROR ;
|
info.state = DNSResolver::DNS_LOOKUP_ERROR ;
|
||||||
|
|
||||||
|
std::cerr << "DNSResolver: lookup error for address \"" << next_call.c_str() << "\"" << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "pqi/pqinetwork.h"
|
#include "pqi/pqinetwork.h"
|
||||||
#include "util/rsstring.h"
|
#include "util/rsstring.h"
|
||||||
|
#include "util/rsmemory.h"
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
@ -58,7 +59,6 @@ static void getPage(const std::string& server_name,std::string& page)
|
|||||||
int sockfd,n=0; // socket descriptor
|
int sockfd,n=0; // socket descriptor
|
||||||
struct sockaddr_in serveur; // server's parameters
|
struct sockaddr_in serveur; // server's parameters
|
||||||
memset(&serveur.sin_zero, 0, sizeof(serveur.sin_zero));
|
memset(&serveur.sin_zero, 0, sizeof(serveur.sin_zero));
|
||||||
struct hostent *hostinfo=NULL; // structure for storing the server's ip
|
|
||||||
|
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
char request[1024];
|
char request[1024];
|
||||||
@ -78,20 +78,21 @@ static void getPage(const std::string& server_name,std::string& page)
|
|||||||
|
|
||||||
// get server's ipv4 adress
|
// get server's ipv4 adress
|
||||||
|
|
||||||
hostinfo = gethostbyname(server_name.c_str());
|
in_addr in ;
|
||||||
|
|
||||||
if (hostinfo == NULL) /* l'hôte n'existe pas */
|
if(!rsGetHostByName(server_name.c_str(),in)) /* l'hôte n'existe pas */
|
||||||
{
|
{
|
||||||
std::cerr << "ExtAddrFinder: Unknown host " << server_name << std::endl;
|
std::cerr << "ExtAddrFinder: Unknown host " << server_name << std::endl;
|
||||||
unix_close(sockfd);
|
unix_close(sockfd);
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
serveur.sin_addr = *(struct in_addr*) hostinfo->h_addr;
|
serveur.sin_addr = in ;
|
||||||
serveur.sin_port = htons(80);
|
serveur.sin_port = htons(80);
|
||||||
|
|
||||||
#ifdef EXTADDRSEARCH_DEBUG
|
#ifdef EXTADDRSEARCH_DEBUG
|
||||||
printf("Connection attempt\n");
|
printf("Connection attempt\n");
|
||||||
#endif
|
#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)
|
if(unix_connect(sockfd,(struct sockaddr *)&serveur, sizeof(serveur)) == -1)
|
||||||
{
|
{
|
||||||
|
@ -21,14 +21,21 @@
|
|||||||
//
|
//
|
||||||
class RsTemporaryMemory
|
class RsTemporaryMemory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RsTemporaryMemory(size_t s)
|
RsTemporaryMemory(size_t s)
|
||||||
{
|
{
|
||||||
_mem = (unsigned char *)malloc(s) ;
|
_mem = (unsigned char *)malloc(s) ;
|
||||||
|
|
||||||
|
if(_mem)
|
||||||
|
_size = s ;
|
||||||
|
else
|
||||||
|
_size = 0 ;
|
||||||
}
|
}
|
||||||
|
|
||||||
operator unsigned char *() { return _mem ; }
|
operator unsigned char *() { return _mem ; }
|
||||||
|
|
||||||
|
size_t size() const { return _size ; }
|
||||||
|
|
||||||
~RsTemporaryMemory()
|
~RsTemporaryMemory()
|
||||||
{
|
{
|
||||||
if(_mem != NULL)
|
if(_mem != NULL)
|
||||||
@ -38,8 +45,9 @@ class RsTemporaryMemory
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned char *_mem ;
|
unsigned char *_mem ;
|
||||||
|
size_t _size ;
|
||||||
|
|
||||||
// make it noncopyable
|
// make it noncopyable
|
||||||
RsTemporaryMemory& operator=(const RsTemporaryMemory&) { return *this ;}
|
RsTemporaryMemory& operator=(const RsTemporaryMemory&) { return *this ;}
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "util/rsnet.h"
|
#include "util/rsnet.h"
|
||||||
#include "util/rsthreads.h"
|
#include "util/rsthreads.h"
|
||||||
#include "util/rsstring.h"
|
#include "util/rsstring.h"
|
||||||
|
#include "util/rsmemory.h"
|
||||||
|
|
||||||
#ifdef WINDOWS_SYS
|
#ifdef WINDOWS_SYS
|
||||||
#else
|
#else
|
||||||
@ -72,6 +73,36 @@ void sockaddr_clear(struct sockaddr_in *addr)
|
|||||||
addr->sin_family = AF_INET;
|
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)
|
bool isValidNet(const struct in_addr *addr)
|
||||||
{
|
{
|
||||||
|
@ -70,6 +70,9 @@ bool isLoopbackNet(const struct in_addr *addr);
|
|||||||
bool isPrivateNet(const struct in_addr *addr);
|
bool isPrivateNet(const struct in_addr *addr);
|
||||||
bool isExternalNet(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&) ;
|
std::ostream& operator<<(std::ostream& o,const struct sockaddr_in&) ;
|
||||||
|
|
||||||
/* thread-safe version of inet_ntoa */
|
/* thread-safe version of inet_ntoa */
|
||||||
|
Loading…
Reference in New Issue
Block a user