/*
simgear::Socket, adapted from PLIB Socket by James Turner
Copyright (C) 2010 James Turner
/*
simgear::Socket, adapted from PLIB Socket by James Turner
Copyright (C) 2010 James Turner
PLIB - A Suite of Portable Game Libraries
Copyright (C) 1998,2002 Steve Baker
PLIB - A Suite of Portable Game Libraries
Copyright (C) 1998,2002 Steve Baker
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free Software
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
static_instance = new Resolver;
atexit(&Resolver::cleanup);
static_instance->start();
}
static_instance = new Resolver;
atexit(&Resolver::cleanup);
static_instance->start();
}
_lock.unlock();
simgear::IPAddress* addr = new simgear::IPAddress;
// may take seconds or even minutes!
lookupHost(h.c_str(), *addr);
_lock.lock();
_lock.unlock();
simgear::IPAddress* addr = new simgear::IPAddress;
// may take seconds or even minutes!
lookupHost(h.c_str(), *addr);
_lock.lock();
// cahce may have changed while we had the lock released -
// so iterators may be invalid: restart the traversal
it = _cache.begin();
_cache[h] = addr;
} // of found un-resolved entry
// cahce may have changed while we had the lock released -
// so iterators may be invalid: restart the traversal
it = _cache.begin();
_cache[h] = addr;
} // of found un-resolved entry
/**
* The actual synchronous, blocking host lookup function
* do *not* call this with any locks (mutexs) held, since depending
/**
* The actual synchronous, blocking host lookup function
* do *not* call this with any locks (mutexs) held, since depending
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_INET;
bool ok = false;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_INET;
bool ok = false;
struct addrinfo* result0 = NULL;
int err = getaddrinfo(host, NULL, &hints, &result0);
if (err) {
struct addrinfo* result0 = NULL;
int err = getaddrinfo(host, NULL, &hints, &result0);
if (err) {
if (strcmp(host, "<broadcast>") == 0) {
addr->sin_addr.s_addr = INADDR_BROADCAST;
return;
}
if (strcmp(host, "<broadcast>") == 0) {
addr->sin_addr.s_addr = INADDR_BROADCAST;
return;
}
// check the cache
IPAddress* cached = Resolver::instance()->lookupSync(host);
if (cached) {
memcpy(addr, cached->getAddr(), cached->getAddrLen());
}
// check the cache
IPAddress* cached = Resolver::instance()->lookupSync(host);
if (cached) {
memcpy(addr, cached->getAddr(), cached->getAddrLen());
}
static char buf [32];
long x = ntohl(addr->sin_addr.s_addr);
sprintf(buf, "%d.%d.%d.%d",
static char buf [32];
long x = ntohl(addr->sin_addr.s_addr);
sprintf(buf, "%d.%d.%d.%d",
addr = (struct sockaddr_in*) malloc(sizeof(struct sockaddr_in));
memset(addr, 0, sizeof(struct sockaddr_in));
}
addr = (struct sockaddr_in*) malloc(sizeof(struct sockaddr_in));
memset(addr, 0, sizeof(struct sockaddr_in));
}
} else {
result = ::setsockopt( handle, SOL_SOCKET, SO_BROADCAST, NULL, 0 );
}
} else {
result = ::setsockopt( handle, SOL_SOCKET, SO_BROADCAST, NULL, 0 );
}
// Usage of 239.x.x.x is recommended for local scope
// Reference: http://tools.ietf.org/html/rfc5771
if( ntohl(addr.getIP()) >= 0xe0000000 && ntohl(addr.getIP()) <= 0xefffffff ) {
// Usage of 239.x.x.x is recommended for local scope
// Reference: http://tools.ietf.org/html/rfc5771
if( ntohl(addr.getIP()) >= 0xe0000000 && ntohl(addr.getIP()) <= 0xefffffff ) {
if( (result = ::bind(handle,(const sockaddr*)&a,sizeof(a))) < 0 ) {
SG_LOG(SG_IO, SG_ALERT, "bind(any:" << port << ") failed. Errno " << errno << " (" << strerror(errno) << ")");
return result;
if( (result = ::bind(handle,(const sockaddr*)&a,sizeof(a))) < 0 ) {
SG_LOG(SG_IO, SG_ALERT, "bind(any:" << port << ") failed. Errno " << errno << " (" << strerror(errno) << ")");
return result;
// It bothers me that select()'s first argument does not appear to
// work as advertised... [it hangs like this if called with
// anything less than FD_SETSIZE, which seems wasteful?]
// It bothers me that select()'s first argument does not appear to
// work as advertised... [it hangs like this if called with
// anything less than FD_SETSIZE, which seems wasteful?]
// Note: we ignore the 'exception' fd_set - I have never had a
// need to use it. The name is somewhat misleading - the only
// thing I have ever seen it used for is to detect urgent data -
// Note: we ignore the 'exception' fd_set - I have never had a
// need to use it. The name is somewhat misleading - the only
// thing I have ever seen it used for is to detect urgent data -