From: James Turner Date: Mon, 22 Aug 2011 09:15:05 +0000 (+0100) Subject: Revert "Support non-blocking address lookups, and switch to getaddrinfo over gethostb... X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=f18a9493b3a067ae56cb350cd6a390649ba6b35d;p=simgear.git Revert "Support non-blocking address lookups, and switch to getaddrinfo over gethostbyname. (Only affects netChannel - raw socket will use blocking behaviour by default, as previously)" This reverts commit 878b504f8e044bc0e59903caa8641492421b76d8. --- diff --git a/simgear/io/CMakeLists.txt b/simgear/io/CMakeLists.txt index 1f2ee11d..a2638e1b 100644 --- a/simgear/io/CMakeLists.txt +++ b/simgear/io/CMakeLists.txt @@ -32,24 +32,22 @@ set(SOURCES sg_socket_udp.cxx HTTPClient.cxx HTTPRequest.cxx - HostLookup.cxx - HostLookup.hxx ) simgear_component(io io "${SOURCES}" "${HEADERS}") add_executable(test_sock socktest.cxx) -target_link_libraries(test_sock sgio sgstructure sgdebug sgthreads) +target_link_libraries(test_sock sgio sgstructure sgdebug) add_executable(test_http test_HTTP.cxx) target_link_libraries(test_http - sgio sgstructure sgtiming sgmisc sgdebug sgthreads + sgio sgstructure sgtiming sgmisc sgdebug ${RT_LIBRARY}) add_test(http ${EXECUTABLE_OUTPUT_PATH}/test_http) add_executable(httpget httpget.cxx) target_link_libraries(httpget - sgio sgstructure sgtiming sgmisc sgdebug sgthreads + sgio sgstructure sgtiming sgmisc sgdebug ${RT_LIBRARY}) \ No newline at end of file diff --git a/simgear/io/HTTPClient.cxx b/simgear/io/HTTPClient.cxx index ad06756f..96ef25bd 100644 --- a/simgear/io/HTTPClient.cxx +++ b/simgear/io/HTTPClient.cxx @@ -17,7 +17,7 @@ #include "version.h" #else # if !defined(SIMGEAR_VERSION) -# define SIMGEAR_VERSION development +# define SIMGEAR_VERSION "simgear-development" # endif #endif diff --git a/simgear/io/HostLookup.cxx b/simgear/io/HostLookup.cxx deleted file mode 100644 index a9028e9f..00000000 --- a/simgear/io/HostLookup.cxx +++ /dev/null @@ -1,139 +0,0 @@ -#include "HostLookup.hxx" - -#include -#include -#include - -#include - -#include - -using std::string; - -namespace simgear -{ - -class Resolver : public SGThread -{ -public: - Resolver() - { - // take lock when resolver starts, - // won't release until it's actually running, and waiting on the - // condition. Otherwise we get a race when starting. - _lock.lock(); - } - - virtual void run() - { - while (true) { - _cond.wait(_lock); // wait until there's something to lookup - - // find the first un-resolved entry in the cache - HostCache::iterator it; - for (it = _cache.begin(); it != _cache.end(); ++it) { - if (!it->second->resolved()) { - break; - } - } - - if (it == _cache.end()) { - continue; - } - - string host = it->first; - // don't hold any locks while looking up - _lock.unlock(); - - // start the actual lookup - may take a long period of time! - // (eg, one, five or sixty seconds) - struct addrinfo hints; - bzero(&hints, sizeof(struct addrinfo)); - hints.ai_family = PF_UNSPEC; - - struct addrinfo *results; - - int result = getaddrinfo(host.c_str(), NULL, &hints, &results); - _lock.lock(); // take the lock back before going any further - - if (result == 0) { - _cache[host]->resolve(IPAddress(results->ai_addr, results->ai_addrlen)); - freeaddrinfo(results); - } else if (result == EAGAIN) { - - } else { - const char* errMsg = gai_strerror(result); - // bad lookup, remove from cache? or set as failed? - _cache[host]->fail(); - } - } // of thread loop - - _lock.unlock(); - } - - void addLookup(HostLookup* l) - { - _lock.lock(); - _cache[l->host()] = l; - _cond.signal(); - _lock.unlock(); - } - - HostLookup* lookup(const string& host) - { - _lock.lock(); - HostCache::iterator it = _cache.find(host); - HostLookup* result = it->second; - _lock.unlock(); - return result; - } -private: - SGMutex _lock; - SGPthreadCond _cond; - - typedef std::map HostCache; - HostCache _cache; -}; - -Resolver* static_resolve = NULL; - -HostLookup* HostLookup::lookup(const string& host) -{ - if (!static_resolve) { - static_resolve = new Resolver; - static_resolve->start(); - } - - HostLookup* l = static_resolve->lookup(host); - if (l) { - return l; - } - - l = new HostLookup(host); - SGReferenced::get(l); - static_resolve->addLookup(l); - return l; -} - -HostLookup::HostLookup(const std::string& h) : - _host(h), - _resolved(false) -{ -} - -void HostLookup::resolve(const IPAddress& addr) -{ - _failed = false; - _address = addr; - _age.stamp(); - _resolved = true; -} - -void HostLookup::fail() -{ - _failed = true; - _resolved = false; - _age.stamp(); -} - -} // of namespace diff --git a/simgear/io/HostLookup.hxx b/simgear/io/HostLookup.hxx deleted file mode 100644 index ee8b0297..00000000 --- a/simgear/io/HostLookup.hxx +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef SG_HOST_LOOKUP_HXX -#define SG_HOST_LOOKUP_HXX - -#include -#include - -#include - -namespace simgear -{ - -class HostLookup : public SGReferenced -{ -public: - static HostLookup* lookup(const std::string& h); - - bool resolved() const - { return _resolved; } - - bool failed() const - { return _failed; } - - const IPAddress& address() const - { return _address; } - - const std::string& host() const - { return _host; } -private: - HostLookup(const std::string& h); - - friend class Resolver; - - void resolve(const IPAddress& addr); - void fail(); - - std::string _host; - bool _resolved; - bool _failed; - IPAddress _address; - SGTimeStamp _age; -}; - -} // of namespace simgear - -#endif // of SG_HOST_LOOKUP_HXX diff --git a/simgear/io/raw_socket.cxx b/simgear/io/raw_socket.cxx index bc9acc54..63c9b55e 100644 --- a/simgear/io/raw_socket.cxx +++ b/simgear/io/raw_socket.cxx @@ -37,7 +37,6 @@ #include #include #include // for snprintf -#include #if defined(WINSOCK) # include @@ -68,30 +67,13 @@ IPAddress::IPAddress ( const char* host, int port ) set ( host, port ) ; } -IPAddress::IPAddress ( struct sockaddr* addr, size_t len ) -{ - memset(&_raw, 0, sizeof(struct sockaddr_in)); - if ((addr->sa_family != AF_INET) || - (len != sizeof(struct sockaddr_in))) - { - std::cout << "address size mismatch" << std::endl; - return; - } - - memcpy(&_raw, addr, len); -} - -void IPAddress::setPort(unsigned int port) -{ - _raw.sin_port = htons(port); -} void IPAddress::set ( const char* host, int port ) { - memset(&_raw, 0, sizeof(struct sockaddr_in)); + memset(this, 0, sizeof(IPAddress)); - _raw.sin_family = AF_INET ; - _raw.sin_port = htons (port); + sin_family = AF_INET ; + sin_port = htons (port); /* Convert a string specifying a host name or one of a few symbolic ** names to a numeric IP address. This usually calls gethostbyname() @@ -99,28 +81,28 @@ void IPAddress::set ( const char* host, int port ) */ if (!host || host[0] == '\0') { - _raw.sin_addr.s_addr = INADDR_ANY; + sin_addr = INADDR_ANY; return; } if (strcmp(host, "") == 0) { - _raw.sin_addr.s_addr = INADDR_BROADCAST; + sin_addr = INADDR_BROADCAST; return; } - _raw.sin_addr.s_addr = inet_addr ( host ) ; - if (_raw.sin_addr.s_addr != INADDR_NONE) { + sin_addr = inet_addr ( host ) ; + if (sin_addr != INADDR_NONE) { return; } // finally, try gethostbyname struct hostent *hp = gethostbyname ( host ) ; if (!hp) { SG_LOG(SG_IO, SG_WARN, "gethostbyname failed for " << host); - _raw.sin_addr.s_addr = INADDR_ANY ; + sin_addr = INADDR_ANY ; return; } - memcpy ( (char *) &_raw.sin_addr, hp->h_addr, hp->h_length ) ; + memcpy ( (char *) &sin_addr, hp->h_addr, hp->h_length ) ; } @@ -134,7 +116,7 @@ const char* IPAddress::getHost () const const char* buf = inet_ntoa ( sin_addr ) ; #else static char buf [32]; - long x = ntohl(_raw.sin_addr.s_addr); + long x = ntohl(sin_addr); sprintf(buf, "%d.%d.%d.%d", (int) (x>>24) & 0xff, (int) (x>>16) & 0xff, (int) (x>> 8) & 0xff, (int) (x>> 0) & 0xff ); @@ -144,17 +126,17 @@ const char* IPAddress::getHost () const unsigned int IPAddress::getIP () const { - return _raw.sin_addr.s_addr; + return sin_addr; } unsigned int IPAddress::getPort() const { - return ntohs(_raw.sin_port); + return ntohs(sin_port); } unsigned int IPAddress::getFamily () const { - return _raw.sin_family; + return sin_family; } const char* IPAddress::getLocalHost () @@ -181,7 +163,7 @@ const char* IPAddress::getLocalHost () bool IPAddress::getBroadcast () const { - return (_raw.sin_addr.s_addr == INADDR_BROADCAST); + return sin_addr == INADDR_BROADCAST; } @@ -339,8 +321,8 @@ int Socket::accept ( IPAddress* addr ) } else { - socklen_t addr_len = addr->getAddressSize(); - return ::accept(handle,(sockaddr*)addr->getAddress(),&addr_len); + socklen_t addr_len = (socklen_t) sizeof(IPAddress) ; + return ::accept(handle,(sockaddr*)addr,&addr_len); } } @@ -352,18 +334,9 @@ int Socket::connect ( const char* host, int port ) if ( addr.getBroadcast() ) { setBroadcast( true ); } - return ::connect(handle,(const sockaddr*) addr.getAddress(), addr.getAddressSize()); + return ::connect(handle,(const sockaddr*)&addr,sizeof(IPAddress)); } -int Socket::connect ( const IPAddress& addr ) -{ - assert ( handle != -1 ) ; - if ( addr.getBroadcast() ) { - setBroadcast( true ); - } - - return ::connect(handle,(const sockaddr*) addr.getAddress(), addr.getAddressSize()); -} int Socket::send (const void * buffer, int size, int flags) { diff --git a/simgear/io/raw_socket.hxx b/simgear/io/raw_socket.hxx index 1af74ce0..4eb30448 100644 --- a/simgear/io/raw_socket.hxx +++ b/simgear/io/raw_socket.hxx @@ -37,11 +37,24 @@ namespace simgear */ class IPAddress { + /* DANGER!!! This MUST match 'struct sockaddr_in' exactly! */ +#if defined(__APPLE__) || defined(__FreeBSD__) + __uint8_t sin_len; + __uint8_t sin_family; + in_port_t sin_port; + in_addr_t sin_addr; + char sin_zero[8]; +#else + short sin_family ; + unsigned short sin_port ; + unsigned int sin_addr ; + char sin_zero [ 8 ] ; +#endif + public: IPAddress () {} IPAddress ( const char* host, int port ) ; - IPAddress ( struct sockaddr* addr, size_t len ); - + void set ( const char* host, int port ) ; const char* getHost () const ; unsigned int getPort() const ; @@ -50,15 +63,6 @@ public: static const char* getLocalHost () ; bool getBroadcast () const ; - - void setPort(unsigned int port); - const struct sockaddr_in* getAddress() const - { return &_raw; } - - const size_t getAddressSize() const - { return sizeof(struct sockaddr_in); } -private: - struct sockaddr_in _raw; }; @@ -85,7 +89,6 @@ public: int listen ( int backlog ) ; int accept ( IPAddress* addr ) ; int connect ( const char* host, int port ) ; - int connect ( const IPAddress& addr ) ; int send ( const void * buffer, int size, int flags = 0 ) ; int sendto ( const void * buffer, int size, int flags, const IPAddress* to ) ; int recv ( void * buffer, int size, int flags = 0 ) ; diff --git a/simgear/io/sg_netChannel.cxx b/simgear/io/sg_netChannel.cxx index d34a521b..c6502565 100644 --- a/simgear/io/sg_netChannel.cxx +++ b/simgear/io/sg_netChannel.cxx @@ -36,7 +36,6 @@ #include #include -#include namespace simgear { @@ -107,11 +106,21 @@ NetChannel::listen ( int backlog ) } int -NetChannel::connect ( const char* host, int p ) +NetChannel::connect ( const char* host, int port ) { - host_lookup = HostLookup::lookup(host); - port = p; - return 0; + int result = Socket::connect ( host, port ) ; + if (result == 0) { + connected = true ; + //this->handleConnect(); + return 0; + } else if (isNonBlockingError ()) { + return 0; + } else { + // some other error condition + this->handleError (result); + close(); + return -1; + } } int @@ -202,25 +211,6 @@ NetChannel::handleWriteEvent (void) this->handleWrite(); } -void -NetChannel::doConnect() -{ - IPAddress addr( host_lookup->address() ); - addr.setPort(port); - int result = Socket::connect ( addr ) ; - host_lookup = NULL; - - if (result == 0) { - connected = true ; - } else if (isNonBlockingError ()) { - - } else { - // some other error condition - handleError (result); - close(); - } -} - bool NetChannel::poll (unsigned int timeout) { @@ -246,16 +236,6 @@ NetChannel::poll (unsigned int timeout) else if ( ! ch -> closed ) { nopen++ ; - if (ch->host_lookup) { - if (ch->host_lookup->resolved()) { - ch->doConnect(); - } else if (ch->host_lookup->failed()) { - ch->handleError (-1); - ch->close(); - } - continue; - } - if (ch -> readable()) { assert(nreads -#include - namespace simgear { -class HostLookup; - class NetChannel : public Socket { bool closed, connected, accepting, write_blocked, should_delete ; NetChannel* next_channel ; - SGSharedPtr host_lookup ; - int port; friend bool netPoll (unsigned int timeout); - void doConnect(); public: NetChannel () ;