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
#include "version.h"
#else
# if !defined(SIMGEAR_VERSION)
-# define SIMGEAR_VERSION development
+# define SIMGEAR_VERSION "simgear-development"
# endif
#endif
+++ /dev/null
-#include "HostLookup.hxx"
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
-
-#include <map>
-
-#include <simgear/threads/SGThread.hxx>
-
-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<string, HostLookup*> 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
+++ /dev/null
-#ifndef SG_HOST_LOOKUP_HXX
-#define SG_HOST_LOOKUP_HXX
-
-#include <simgear/io/raw_socket.hxx>
-#include <simgear/timing/timestamp.hxx>
-
-#include <simgear/structure/SGReferenced.hxx>
-
-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
#include <cstring>
#include <cassert>
#include <cstdio> // for snprintf
-#include <iostream>
#if defined(WINSOCK)
# include <winsock.h>
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()
*/
if (!host || host[0] == '\0') {
- _raw.sin_addr.s_addr = INADDR_ANY;
+ sin_addr = INADDR_ANY;
return;
}
if (strcmp(host, "<broadcast>") == 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 ) ;
}
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 );
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 ()
bool IPAddress::getBroadcast () const
{
- return (_raw.sin_addr.s_addr == INADDR_BROADCAST);
+ return sin_addr == INADDR_BROADCAST;
}
}
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);
}
}
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)
{
*/
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 ;
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;
};
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 ) ;
#include <cstring>
#include <simgear/debug/logstream.hxx>
-#include <simgear/io/HostLookup.hxx>
namespace simgear {
}
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
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)
{
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<MAX_SOCKETS);
reads[nreads++] = ch ;
#define SG_NET_CHANNEL_H
#include <simgear/io/raw_socket.hxx>
-#include <simgear/structure/SGSharedPtr.hxx>
-
namespace simgear
{
-class HostLookup;
-
class NetChannel : public Socket
{
bool closed, connected, accepting, write_blocked, should_delete ;
NetChannel* next_channel ;
- SGSharedPtr<HostLookup> host_lookup ;
- int port;
friend bool netPoll (unsigned int timeout);
- void doConnect();
public:
NetChannel () ;