#include "nSocket.h"
#include "aa_config.h"
#include "tRandom.h"
#include "tSysTime.h"
#include <string>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <errno.h>
#include <stdlib.h>
#include <vector>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include "tConfiguration.h"
#include "tRecorder.h"
Go to the source code of this file.
Classes | |
class | OneSocketOpened |
Exception to throw when a single socket was opened by request. More... | |
struct | nSocketType |
structure defining a socket type More... | |
struct | nHostInfo |
all information to reach a host More... | |
class | BindArchiver< Archiver > |
class | ReadArchiver< Archiver > |
Read or write network read data. More... | |
Defines | |
#define | MAXHOSTNAMELEN 256 |
#define | NET_NAMELEN 100 |
Typedefs | |
typedef std::vector< nHostInfo > | nHostList |
typedef int | NET_SIZE |
typedef int | Socket |
Enumerations | |
enum | nSocketError { nSocketError_Ignore, nSocketError_Reset } |
Functions | |
std::istream & | operator>> (std::istream &s, nAddress &address) |
std::istream & | operator>> (std::istream &s, nSocketType &type) |
std::istream & | operator>> (std::istream &s, nHostInfo &hostInfo) |
std::ostream & | operator<< (std::ostream &s, nAddress const &address) |
std::ostream & | operator<< (std::ostream &s, nSocketType const &type) |
std::ostream & | operator<< (std::ostream &s, nHostInfo const &hostInfo) |
tRECORD_AS (nSocketError, int) | |
char * | ANET_AddrToString (const struct sockaddr *addr) |
int | ANET_GetSocketAddr (int sock, struct sockaddr *addr) |
static void | Sys_Error (const char *x) |
static void | Con_Printf (const char *x) |
static void | Con_SafePrintf (const char *x) |
static void | Con_DPrintf (const char *x) |
static nSocketError | ANET_Error () |
static nOSNetworking const & | sn_InitOSNetworking () |
initialize OS networking system and automatically shut it down later | |
tString const & | GetMyHostName () |
determine name of this host | |
bool | ANET_ListenOn (nHostList const &addresses, nSocketListener::SocketArray &sockets, bool onesocketonly, bool ignoreErrors) |
void | ANET_GetHostList (hostent const *hostentry, nHostList &hostList, int net_hostport, bool server=true) |
void | ANET_GetHostList (char const *hostname, nHostList &hostList, int net_hostport, bool server=true) |
bool | ANET_ListenOnConst (char const *hostname, int net_hostport, nSocketListener::SocketArray &sockets, bool &onesocketonly, bool &relaxed, bool &ignoreErrors) |
bool | ANET_ListenOn (char *hostname, int net_hostport, nSocketListener::SocketArray &sockets, bool &onesocketonly, bool &relaxed, bool &ignoreErrors) |
bool | ANET_Listen (bool state, int net_hostport, const tString &net_hostip, nSocketListener::SocketArray &sockets) |
int | ANET_CloseSocket (int sock) |
static int | PartialIPAddress (const char *in, struct sockaddr *hostaddr, int default_port, int default_addr) |
char * | ANET_AddrToString (const struct sockaddr *addr) |
int | ANET_GetSocketAddr (int sock, struct sockaddr *addr) |
int | ANET_AddrCompare (struct sockaddr *addr1, struct sockaddr *addr2) |
Variables | |
static bool | sn_listen = false |
static char const * | hostnameSection = "HOSTNAME" |
static char const * | recordingSection = "BIND" |
static char const * | recordingSectionRead = "READ" |
#define MAXHOSTNAMELEN 256 |
#define NET_NAMELEN 100 |
Definition at line 229 of file nSocket.cpp.
typedef int NET_SIZE [static] |
Definition at line 253 of file nSocket.cpp.
Definition at line 212 of file nSocket.cpp.
typedef int Socket [static] |
Definition at line 331 of file nSocket.cpp.
enum nSocketError |
Definition at line 214 of file nSocket.cpp.
00217 { 00218 nSocketError_Ignore, // nothing special happened
int @94::ANET_AddrCompare | ( | struct sockaddr * | addr1, | |
struct sockaddr * | addr2 | |||
) | [static] |
Definition at line 842 of file nSocket.cpp.
00845 { 00846 if (addr1->sa_family != addr2->sa_family) 00847 return -1; 00848 00849 if (((struct sockaddr_in *)addr1)->sin_addr.s_addr != ((struct sockaddr_in *)addr2)->sin_addr.s_addr) 00850 return -1; 00851 00852 if (((struct sockaddr_in *)addr1)->sin_port != ((struct sockaddr_in *)addr2)->sin_port) 00853 return 1; 00854
char* @94::ANET_AddrToString | ( | const struct sockaddr * | addr | ) | [static] |
Definition at line 814 of file nSocket.cpp.
References buffer.
00817 { 00818 static char buffer[23]; 00819 int haddr; 00820 00821 haddr = ntohl(((struct sockaddr_in const *)addr)->sin_addr.s_addr); 00822 snprintf(buffer,22, "%d.%d.%d.%d:%d", (haddr >> 24) & 0xff, (haddr >> 16) & 0xff, (haddr >> 8) & 0xff, haddr & 0xff, ntohs(((struct sockaddr_in const *)addr)->sin_port));
char* @94::ANET_AddrToString | ( | const struct sockaddr * | addr | ) | [static] |
int @94::ANET_CloseSocket | ( | int | sock | ) | [static] |
Definition at line 746 of file nSocket.cpp.
Referenced by nSocket::Bind(), and nSocket::Close().
static nSocketError @94::ANET_Error | ( | ) | [static] |
Definition at line 256 of file nSocket.cpp.
References con, nSocketError_Ignore, nSocketError_Reset, tRecorder::PlaybackStrict(), tRecorder::Record(), and section.
Referenced by nSocket::Bind(), nSocket::CheckNewConnection(), nSocket::Read(), and nSocket::Write().
00259 { 00260 int error = 0; 00261 nSocketError aError = nSocketError_Ignore; 00262 00263 // play back error message 00264 static char const * section = "NETERROR"; 00265 if ( !tRecorder::PlaybackStrict( section, aError ) ) 00266 { 00267 // get error from OS 00268 #ifdef WIN32 00269 error = WSAGetLastError(); 00270 #else 00271 error = errno; 00272 #endif 00273 switch ( error ) 00274 { 00275 case EADDRINUSE: 00276 break; 00277 case ENOTSOCK: 00278 aError = nSocketError_Reset; 00279 break; 00280 case ECONNRESET: 00281 aError = nSocketError_Reset; 00282 break; 00283 case ECONNREFUSED: 00284 break; 00285 case EWOULDBLOCK: 00286 case ENETUNREACH: 00287 aError = nSocketError_Ignore; 00288 break; 00289 // case NOTINITIALISED: 00290 // break; 00291 case ENETDOWN: 00292 break; 00293 case EFAULT: 00294 aError = nSocketError_Reset; 00295 break; 00296 case EINTR: 00297 break; 00298 case EINVAL: 00299 break; 00300 case EISCONN: 00301 break; 00302 case ENETRESET: 00303 break; 00304 case EOPNOTSUPP: 00305 case EAFNOSUPPORT: 00306 case EADDRNOTAVAIL: 00307 aError = nSocketError_Reset; 00308 break; 00309 case ESHUTDOWN: 00310 break; 00311 #ifndef WIN32 00312 case EMSGSIZE: 00313 break; 00314 #endif 00315 case ETIMEDOUT: 00316 break; 00317 default: 00318 #ifdef DEBUG 00319 con << "Unknown network error " << error << "\n"; 00320 #endif 00321 break; 00322 } 00323 } 00324 00325 // record error message 00326 tRecorder::Record( section, aError ); 00327 00328 00329 // st_Breakpoint();
void @94::ANET_GetHostList | ( | char const * | hostname, | |
nHostList & | hostList, | |||
int | net_hostport, | |||
bool | server = true | |||
) | [static] |
Definition at line 530 of file nSocket.cpp.
References nHostInfo::address, ANET_GetHostList(), con, nHostInfo::name, tRecorder::Playback(), tRecorder::Record(), section, server(), nAddress::SetPort(), and sn_InitOSNetworking().
00533 { 00534 sn_InitOSNetworking(); 00535 00536 hostList.clear(); 00537 00538 // if hostname is NULL, add generic host entry 00539 if ( !hostname ) 00540 { 00541 nHostInfo info; 00542 info.name = "localhost"; 00543 info.address.SetPort( net_hostport ); 00544 00545 // add it to list and return 00546 hostList.push_back( info ); 00547 return; 00548 } 00549 00550 // read addresses from recording 00551 static char const * section = "MULTIHOSTBYNAME"; 00552 static char const * sectionEnd = "MULTIHOSTBYNAMEEND"; 00553 nHostInfo read; 00554 while ( tRecorder::Playback( section, read ) ) 00555 { 00556 hostList.push_back( read ); 00557 } 00558 if ( !tRecorder::Playback( sectionEnd ) ) 00559 { 00560 // look up hostname 00561 struct hostent *hostentry; 00562 hostentry = gethostbyname (hostname); 00563 if (!hostentry) 00564 { 00565 #ifndef WIN32 00566 con << "Error looking up " << ( hostname ? hostname : "localhost" ) << " : " << gai_strerror( h_errno ) << "\n"; 00567 #endif 00568 return; 00569 } 00570 00571 // delegate 00572 ANET_GetHostList( hostentry, hostList, net_hostport, server ); 00573 } 00574 00575 // write addresses to recording 00576 for ( nHostList::const_iterator iter = hostList.begin(); iter != hostList.end(); ++iter ) 00577 tRecorder::Record( section, read );
void @94::ANET_GetHostList | ( | hostent const * | hostentry, | |
nHostList & | hostList, | |||
int | net_hostport, | |||
bool | server = true | |||
) | [static] |
Definition at line 509 of file nSocket.cpp.
References nHostInfo::address, nAddress::FromHostent(), nHostInfo::name, nAddress::SetPort(), nSocketType::type, and nHostInfo::type.
Referenced by ANET_GetHostList().
00512 { 00513 // iterate over addresses 00514 char * * addressList = hostentry->h_addr_list; 00515 while (*addressList) 00516 { 00517 // prepare host info (TODO: IPV6/TCP compatibility) 00518 nHostInfo info; 00519 info.type.type = hostentry->h_addrtype; 00520 info.name = hostentry->h_name; 00521 info.address.FromHostent( hostentry->h_length, *addressList ); 00522 info.address.SetPort( net_hostport ); 00523 00524 // add it to list 00525 hostList.push_back( info ); 00526 00527 ++addressList; // next address
int @94::ANET_GetSocketAddr | ( | int | sock, | |
struct sockaddr * | addr | |||
) | [static] |
Definition at line 826 of file nSocket.cpp.
00829 { 00830 NET_SIZE addrlen = sizeof(struct sockaddr); 00831 // unsigned int a; 00832 00833 memset(addr, 0, sizeof(struct sockaddr)); 00834 getsockname(sock, (struct sockaddr *)addr, &addrlen); 00835 // a = ((struct sockaddr_in *)addr)->sin_addr.s_addr; 00836 //if (a == 0 || a == inet_addr("127.0.0.1")) 00837 // ((struct sockaddr_in *)addr)->sin_addr.s_addr = 0x7f000001; 00838
int @94::ANET_GetSocketAddr | ( | int | sock, | |
struct sockaddr * | addr | |||
) | [static] |
bool @94::ANET_Listen | ( | bool | state, | |
int | net_hostport, | |||
const tString & | net_hostip, | |||
nSocketListener::SocketArray & | sockets | |||
) | [static] |
Definition at line 686 of file nSocket.cpp.
Referenced by nSocketListener::Listen().
00689 { 00690 sn_listen = state; 00691 00692 // enable listening 00693 if (state) 00694 { 00695 // reset sockets if we are already listening 00696 if (!sockets.empty()) 00697 ANET_Listen( false, net_hostport, net_hostip, sockets ); 00698 00699 bool relaxed = false, onesocketonly = false, ignoreErrors = false; 00700 00701 // first try: generate sockets for explicitly requested IP 00702 tString ips = net_hostip; // copy of the hostname string 00703 size_t lastpos = 0; // position where the current IP starts 00704 for ( size_t pos = 0; pos < ips.Size(); ++pos ) 00705 { 00706 if (isblank(ips[pos])) 00707 { 00708 ips[pos] = '\0'; 00709 if ( pos > lastpos ) 00710 if ( !ANET_ListenOn( &ips[lastpos], net_hostport, sockets, onesocketonly, relaxed, ignoreErrors ) ) 00711 return false; 00712 ips[pos] = ' '; 00713 lastpos = pos + 1; 00714 } 00715 } 00716 // don't forget the last IP entry 00717 if ( ips.Size() > lastpos ) 00718 if ( !ANET_ListenOn( &ips[lastpos], net_hostport, sockets, onesocketonly, relaxed, ignoreErrors ) ) 00719 return false; 00720 00721 //#else 00722 // old fallback code 00723 // nSocket socket; 00724 // socket.Open( net_hostport ); 00725 // sockets.push_back( socket ); 00726 //#endif 00727 00728 // report success or failure ( in relaxed mode when no socket was created ) 00729 return !relaxed || !sockets.empty(); 00730 } 00731 00732 // disable listening 00733 if (sockets.empty()) 00734 return false; 00735 00736 // close sockets 00737 for ( nSocketListener::SocketArray::iterator iter = sockets.begin(); iter != sockets.end(); ++iter ) 00738 { 00739 (*iter).Close(); 00740 } 00741 sockets.clear(); 00742
bool @94::ANET_ListenOn | ( | char * | hostname, | |
int | net_hostport, | |||
nSocketListener::SocketArray & | sockets, | |||
bool & | onesocketonly, | |||
bool & | relaxed, | |||
bool & | ignoreErrors | |||
) | [static] |
Definition at line 659 of file nSocket.cpp.
00662 { 00663 // skip whitespace 00664 while ( isblank( *hostname ) ) 00665 hostname ++; 00666 00667 // quit silently on empty hostname 00668 if ( !*hostname ) 00669 return true; 00670 00671 // replace colon by null temporarily, add port offset to net_hostport 00672 char * colon = NULL; 00673 if ( hostname ) 00674 colon = strrchr (hostname, ':'); 00675 if ( colon ) 00676 { 00677 *colon = 0; 00678 net_hostport += atoi ( colon + 1 ); 00679 } 00680 00681 // don't forget to restore the colon when we're done here 00682 nColonRestaurator restaurator( colon ); 00683 00684 // delegate to function that does not modify the hostname
bool @94::ANET_ListenOn | ( | nHostList const & | addresses, | |
nSocketListener::SocketArray & | sockets, | |||
bool | onesocketonly, | |||
bool | ignoreErrors | |||
) | [static] |
Definition at line 453 of file nSocket.cpp.
References con, tException::GetDescription(), tException::GetName(), and nSocket::Open().
00456 { 00457 bool ret = true; 00458 00459 for (nHostList::const_iterator iter = addresses.begin(); iter != addresses.end(); ++iter) 00460 { 00461 nHostInfo const & address = *iter; 00462 00463 nSocket socket; 00464 int error = -1; 00465 try 00466 { 00467 error = socket.Open( address ); 00468 } 00469 catch ( nSocket::PermanentError & e ) 00470 { 00471 // ignore errors on request 00472 if ( ignoreErrors ) 00473 { 00474 con << "sn_SetNetState: can't setup listening socket. Reason given:\n" 00475 << e.GetName() << ": " << e.GetDescription() << "\nIgnoring on user request.\n"; 00476 return true; 00477 } 00478 else 00479 { 00480 throw; 00481 } 00482 } 00483 00484 if ( error == 0 ) 00485 { 00486 // store the socket 00487 sockets.push_back( socket ); 00488 00489 // return if we only want one socket 00490 if ( onesocketonly ) 00491 { 00492 #ifndef NOEXCEPT 00493 throw OneSocketOpened(); 00494 #endif 00495 return true; 00496 } 00497 } 00498 else 00499 { 00500 // report error 00501 ret = false; 00502 } 00503 } 00504 00505 // return result
bool @94::ANET_ListenOnConst | ( | char const * | hostname, | |
int | net_hostport, | |||
nSocketListener::SocketArray & | sockets, | |||
bool & | onesocketonly, | |||
bool & | relaxed, | |||
bool & | ignoreErrors | |||
) | [static] |
Definition at line 579 of file nSocket.cpp.
00582 { 00583 if ( hostname ) 00584 { 00585 // check if only one of the following sockets is required 00586 if ( 0 == strcmp( hostname, "ONEOF" ) ) 00587 { 00588 onesocketonly = true; 00589 return true; 00590 } 00591 00592 // check if partial failures are tolerated 00593 if ( 0 == strcmp( hostname, "RELAXED" ) ) 00594 { 00595 relaxed = true; 00596 return true; 00597 } 00598 00599 // check if errors should be ignored 00600 if ( 0 == strcmp( hostname, "IGNOREERRORS" ) ) 00601 { 00602 ignoreErrors = true; 00603 return true; 00604 } 00605 00606 // replace "ALL" by hostname 00607 else if ( 0 == strcmp( hostname, "ALL" ) ) 00608 { 00609 hostname = GetMyHostName(); 00610 } 00611 00612 // replace "ANY" by 0 00613 if ( 0 == strcmp( hostname, "ANY" ) ) 00614 hostname = NULL; 00615 } 00616 00617 // look up hostname 00618 nHostList hostList; 00619 ANET_GetHostList( hostname, hostList, net_hostport ); 00620 00621 if ( hostList.empty() ) 00622 { 00623 // name lookup failures won't be tolerated here 00624 #ifndef NOEXCEPT 00625 if ( !ignoreErrors ) 00626 { 00627 tString details( "Hostname lookup failed for " ); 00628 details += hostname ? hostname : "localhost"; 00629 details += " while trying to open listening sockets."; 00630 throw nSocket::PermanentError( details ); 00631 } 00632 #endif 00633 00634 // fallback for nonexceptional systems 00635 if ( hostname ) 00636 con << "ANET_ListenOn: Could not resolve " << hostname << " to bind socket to its IPs.\n"; 00637 else 00638 con << "ANET_ListenOn: Could not determine generic IP to bind socket on.\n"; 00639 00640 return ignoreErrors; 00641 } 00642 bool ret = ANET_ListenOn( hostList, sockets, onesocketonly, ignoreErrors ); 00643 00644 // in relaxed mode, only one socket needs to be opened ( the caller needs to check that finally ). Otherwise, all socket openings need to have succeeded.
static void @94::Con_DPrintf | ( | const char * | x | ) | [inline, static] |
static void @94::Con_Printf | ( | const char * | x | ) | [inline, static] |
Definition at line 238 of file nSocket.cpp.
Referenced by nSocket::Broadcast().
static void @94::Con_SafePrintf | ( | const char * | x | ) | [inline, static] |
tString const& @94::GetMyHostName | ( | ) | [static] |
determine name of this host
Definition at line 429 of file nSocket.cpp.
References tString::Len(), MAXHOSTNAMELEN, tRecorder::PlaybackStrict(), and tRecorder::Record().
00432 { 00433 static tString ret; 00434 if ( ret.Len() <= 1 ) 00435 { 00436 // read hostname from recording 00437 if ( !tRecorder::PlaybackStrict( hostnameSection, ret ) ) 00438 { 00439 // look up hostname 00440 char buff[MAXHOSTNAMELEN]="\0"; 00441 if ( 0 == gethostname(buff, MAXHOSTNAMELEN) ) 00442 ret = buff; 00443 else 00444 ret = "localhost"; 00445 } 00446 00447 // write hostname to recording 00448 tRecorder::Record( hostnameSection, ret ); 00449 } 00450
std::ostream& operator<< | ( | std::ostream & | s, | |
nHostInfo const & | hostInfo | |||
) |
Definition at line 200 of file nSocket.cpp.
00203 { 00204 // write name 00205 s << tLineString( hostInfo.name ); 00206 00207 // write address and type 00208 s << hostInfo.address; 00209 s << hostInfo.type; 00210
std::ostream& operator<< | ( | std::ostream & | s, | |
nSocketType const & | type | |||
) |
Definition at line 192 of file nSocket.cpp.
00195 { 00196 // write data 00197 s << type.family << ' ' << type.type << ' ' << type.protocol; 00198
std::ostream& operator<< | ( | std::ostream & | s, | |
nAddress const & | address | |||
) |
Definition at line 184 of file nSocket.cpp.
00187 { 00188 // write address 00189 s << tLineString( address.ToString() ); 00190
std::istream& operator>> | ( | std::istream & | s, | |
nHostInfo & | hostInfo | |||
) |
Definition at line 170 of file nSocket.cpp.
00173 { 00174 // read name 00175 tLineString name; 00176 s >> name; 00177 hostInfo.name = name; 00178 00179 // read address and type 00180 s >> hostInfo.address; 00181 s >> hostInfo.type; 00182
std::istream& operator>> | ( | std::istream & | s, | |
nSocketType & | type | |||
) |
std::istream& operator>> | ( | std::istream & | s, | |
nAddress & | address | |||
) |
Definition at line 152 of file nSocket.cpp.
References nAddress::FromString().
00155 { 00156 // read address 00157 tLineString line; 00158 s >> line; 00159 address.FromString( line ); 00160
static int @94::PartialIPAddress | ( | const char * | in, | |
struct sockaddr * | hostaddr, | |||
int | default_port, | |||
int | default_addr | |||
) | [static] |
Definition at line 763 of file nSocket.cpp.
References b.
Referenced by nAddress::SetAddress(), and nAddress::SetHostname().
00766 { 00767 char buff[256]; 00768 char *b; 00769 int addr; 00770 int num; 00771 int mask; 00772 int run; 00773 int port; 00774 00775 buff[0] = '.'; 00776 b = buff; 00777 strncpy(buff+1, in,254); 00778 if (buff[1] == '.') 00779 b++; 00780 00781 addr = 0; 00782 mask=-1; 00783 while (*b == '.') 00784 { 00785 b++; 00786 num = 0; 00787 run = 0; 00788 while (!( *b < '0' || *b > '9')) 00789 { 00790 num = num*10 + *b++ - '0'; 00791 if (++run > 3) 00792 return -1; 00793 } 00794 if ((*b < '0' || *b > '9') && *b != '.' && *b != ':' && *b != 0) 00795 return -1; 00796 if (num < 0 || num > 255) 00797 return -1; 00798 mask<<=8; 00799 addr = (addr<<8) + num; 00800 } 00801 00802 if (*b++ == ':') 00803 port = atoi(b); 00804 else 00805 port = default_port; 00806 00807 hostaddr->sa_family = AF_INET; 00808 ((struct sockaddr_in *)hostaddr)->sin_port = htons((short)port); 00809 ((struct sockaddr_in *)hostaddr)->sin_addr.s_addr = (default_addr & htonl(mask)) | htonl(addr); 00810
static nOSNetworking const& @94::sn_InitOSNetworking | ( | ) | [static] |
initialize OS networking system and automatically shut it down later
Definition at line 420 of file nSocket.cpp.
Referenced by ANET_GetHostList(), nSocket::Create(), nAddress::GetAddress(), nAddress::GetHostname(), nBasicNetworkSystem::Init(), nAddress::SetAddress(), and nAddress::SetHostname().
static void @94::Sys_Error | ( | const char * | x | ) | [inline, static] |
Definition at line 233 of file nSocket.cpp.
References con.
Referenced by nSocket::CheckNewConnection(), and nBasicNetworkSystem::Init().
tRECORD_AS | ( | nSocketError | , | |
int | ||||
) |
char* colon_ |
Definition at line 656 of file nSocket.cpp.
char const* hostnameSection = "HOSTNAME" [static] |
Definition at line 426 of file nSocket.cpp.
char const* recordingSection = "BIND" [static] |
Definition at line 1557 of file nSocket.cpp.
Referenced by EventArchiver< Archiver >::Archive(), and tReproducibleRandomizer::tReproducibleRandomizer().
char const* recordingSectionRead = "READ" [static] |
Definition at line 1946 of file nSocket.cpp.
bool sn_listen = false [static] |
Definition at line 400 of file nSocket.cpp.