00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "nSocket.h"
00035
00036 #include "aa_config.h"
00037 #include "tRandom.h"
00038 #include "tSysTime.h"
00039 #include "tRandom.h"
00040
00041 #include <string>
00042 #include <stdio.h>
00043 #include <string.h>
00044
00045 #include <sys/types.h>
00046
00047 #include <errno.h>
00048 #include <stdlib.h>
00049 #include <vector>
00050
00051 #ifndef WIN32
00052 #include <arpa/inet.h>
00053
00054 #ifndef MACOSX
00055 # include <netinet/ip.h>
00056 #else
00057 # define IPTOS_LOWDELAY 0x10 // http://www.tcpdump.org/cgi-bin/cvsweb/tcpdump/ip.h?rev=1.11
00058 #endif
00059
00060 #include <netinet/in_systm.h>
00061 #include <netinet/in.h>
00062 #include <netdb.h>
00063 #include <sys/param.h>
00064 #include <sys/ioctl.h>
00065 #include <sys/socket.h>
00066 #else
00067
00068
00069
00070
00071
00072 #define ioctl(a,b,c) ioctlsocket((a),(b),(u_long *)(c))
00073
00074 #undef EINVAL
00075 #undef EINTR
00076 #define EADDRINUSE WSAEADDRINUSE
00077 #define EWOULDBLOCK WSAEWOULDBLOCK
00078 #define ECONNREFUSED WSAECONNREFUSED
00079 #define ENOTSOCK WSAENOTSOCK
00080 #define ECONNRESET WSAECONNRESET
00081 #define ECONNREFUSED WSAECONNREFUSED
00082 #define ENETDOWN WSAENETDOWN
00083 #ifndef EINTR
00084 #define EINTR WSAEINTR
00085 #endif
00086 #define EINVAL WSAEINVAL
00087 #define EISCONN WSAEISCONN
00088 #define ENETRESET WSAENETRESET
00089 #define EOPNOTSUPP WSAEOPNOTSUPP
00090 #define EAFNOSUPPORT WSAEAFNOSUPPORT
00091 #define EADDRNOTAVAIL WSAEADDRNOTAVAIL
00092 #define ESHUTDOWN WSAESHUTDOWN
00093 #define EMSGSIZE WSAEMSGSIZE
00094 #define ETIMEDOUT WSAETIMEDOUT
00095 #define ENETUNREACH WSAENETUNREACH
00096 #define close closesocket
00097 #define snprintf _snprintf
00098 #endif
00099
00100
00101 #ifdef __sun__
00102 #include <sys/filio.h>
00103 #endif
00104
00105 #ifdef NeXT
00106 #include <libc.h>
00107 #endif
00108
00109 #ifndef MAXHOSTNAMELEN
00110 #define MAXHOSTNAMELEN 256
00111 #endif
00112
00113 #if HAVE_UNISTD_H
00114 #include <unistd.h>
00115 #endif
00116
00117 #include "tConfiguration.h"
00118 #include "tRecorder.h"
00119
00120
00121 #ifdef DEBUG
00122 #ifdef DEDICATED
00123
00124 #endif
00125 #endif
00126
00128 class OneSocketOpened{};
00129
00131 struct nSocketType
00132 {
00133 int family;
00134 int type;
00135 int protocol;
00136
00138 nSocketType()
00139 : family(PF_INET)
00140 , type(SOCK_DGRAM)
00141 , protocol(IPPROTO_UDP)
00142 {}
00143 };
00144
00146 struct nHostInfo
00147 {
00148 nSocketType type;
00149 nAddress address;
00150 tString name;
00151 };
00152
00153
00154 std::istream & operator >> ( std::istream & s, nAddress & address )
00155 {
00156
00157 tLineString line;
00158 s >> line;
00159 address.FromString( line );
00160
00161 return s;
00162 }
00163
00164 std::istream & operator >> ( std::istream & s, nSocketType & type )
00165 {
00166
00167 s >> type.family >> type.type >> type.protocol;
00168
00169 return s;
00170 }
00171
00172 std::istream & operator >> ( std::istream & s, nHostInfo & hostInfo )
00173 {
00174
00175 tLineString name;
00176 s >> name;
00177 hostInfo.name = name;
00178
00179
00180 s >> hostInfo.address;
00181 s >> hostInfo.type;
00182
00183 return s;
00184 }
00185
00186 std::ostream & operator << ( std::ostream & s, nAddress const & address )
00187 {
00188
00189 s << tLineString( address.ToString() );
00190
00191 return s;
00192 }
00193
00194 std::ostream & operator << ( std::ostream & s, nSocketType const & type )
00195 {
00196
00197 s << type.family << ' ' << type.type << ' ' << type.protocol;
00198
00199 return s;
00200 }
00201
00202 std::ostream & operator << ( std::ostream & s, nHostInfo const & hostInfo )
00203 {
00204
00205 s << tLineString( hostInfo.name );
00206
00207
00208 s << hostInfo.address;
00209 s << hostInfo.type;
00210
00211 return s;
00212 }
00213
00214 typedef std::vector< nHostInfo > nHostList;
00215
00216 enum nSocketError
00217 {
00218 nSocketError_Ignore,
00219 nSocketError_Reset
00220 };
00221
00222 tRECORD_AS( nSocketError, int );
00223
00224
00225 namespace
00226 {
00227
00228 char *ANET_AddrToString (const struct sockaddr *addr);
00229 int ANET_GetSocketAddr (int sock, struct sockaddr *addr);
00230
00231 #define NET_NAMELEN 100
00232
00233
00234
00235 static inline void Sys_Error(const char *x){
00236 con << x;
00237 exit(-1);
00238 }
00239
00240 static inline void Con_Printf(const char *x){
00241 con << x;
00242 }
00243
00244 static inline void Con_SafePrintf(const char *x){
00245 con << x;
00246 }
00247
00248 static inline void Con_DPrintf(const char *x){
00249 con << x;
00250 }
00251
00252 #ifdef HAVE_SOCKLEN_T
00253 typedef socklen_t NET_SIZE;
00254 #else
00255 typedef int NET_SIZE;
00256 #endif
00257
00258 static nSocketError ANET_Error()
00259 {
00260 int error = 0;
00261 nSocketError aError = nSocketError_Ignore;
00262
00263
00264 static char const * section = "NETERROR";
00265 if ( !tRecorder::PlaybackStrict( section, aError ) )
00266 {
00267
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
00290
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
00326 tRecorder::Record( section, aError );
00327
00328
00329
00330 return aError;
00331 }
00332
00333 typedef int Socket;
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402 static bool sn_listen = false;
00403
00404 class nOSNetworking
00405 {
00406 #ifdef WIN32
00407 public:
00408 nOSNetworking()
00409 {
00410 WSADATA winsockdata;
00411 WSAStartup( MAKEWORD(1, 1), &winsockdata );
00412 }
00413
00414 ~nOSNetworking()
00415 {
00416 WSACleanup();
00417 }
00418 #endif
00419 };
00420
00422 static nOSNetworking const & sn_InitOSNetworking()
00423 {
00424 static nOSNetworking osNetworking;
00425 return osNetworking;
00426 }
00427
00428 static char const * hostnameSection = "HOSTNAME";
00429
00431 tString const & GetMyHostName()
00432 {
00433 static tString ret;
00434 if ( ret.Len() <= 1 )
00435 {
00436
00437 if ( !tRecorder::PlaybackStrict( hostnameSection, ret ) )
00438 {
00439
00440 char buff[MAXHOSTNAMELEN]="\0";
00441 if ( 0 == gethostname(buff, MAXHOSTNAMELEN) )
00442 ret = buff;
00443 else
00444 ret = "localhost";
00445 }
00446
00447
00448 tRecorder::Record( hostnameSection, ret );
00449 }
00450
00451 return ret;
00452 }
00453
00454
00455 bool ANET_ListenOn( nHostList const & addresses, nSocketListener::SocketArray & sockets, bool onesocketonly, bool ignoreErrors )
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
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
00487 sockets.push_back( socket );
00488
00489
00490 if ( onesocketonly )
00491 {
00492 #ifndef NOEXCEPT
00493 throw OneSocketOpened();
00494 #endif
00495 return true;
00496 }
00497 }
00498 else
00499 {
00500
00501 ret = false;
00502 }
00503 }
00504
00505
00506 return ret;
00507 }
00508
00509
00510
00511 void ANET_GetHostList( hostent const * hostentry, nHostList & hostList, int net_hostport, bool server = true )
00512 {
00513
00514 char * * addressList = hostentry->h_addr_list;
00515 while (*addressList)
00516 {
00517
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
00525 hostList.push_back( info );
00526
00527 ++addressList;
00528 }
00529 }
00530
00531
00532 void ANET_GetHostList( char const * hostname, nHostList & hostList, int net_hostport, bool server = true )
00533 {
00534 sn_InitOSNetworking();
00535
00536 hostList.clear();
00537
00538
00539 if ( !hostname )
00540 {
00541 nHostInfo info;
00542 info.name = "localhost";
00543 info.address.SetPort( net_hostport );
00544
00545
00546 hostList.push_back( info );
00547 return;
00548 }
00549
00550
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
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
00572 ANET_GetHostList( hostentry, hostList, net_hostport, server );
00573 }
00574
00575
00576 for ( nHostList::const_iterator iter = hostList.begin(); iter != hostList.end(); ++iter )
00577 tRecorder::Record( section, read );
00578 tRecorder::Record( sectionEnd );
00579 }
00580
00581 bool ANET_ListenOnConst( char const * hostname, int net_hostport, nSocketListener::SocketArray & sockets, bool & onesocketonly, bool & relaxed, bool & ignoreErrors )
00582 {
00583 if ( hostname )
00584 {
00585
00586 if ( 0 == strcmp( hostname, "ONEOF" ) )
00587 {
00588 onesocketonly = true;
00589 return true;
00590 }
00591
00592
00593 if ( 0 == strcmp( hostname, "RELAXED" ) )
00594 {
00595 relaxed = true;
00596 return true;
00597 }
00598
00599
00600 if ( 0 == strcmp( hostname, "IGNOREERRORS" ) )
00601 {
00602 ignoreErrors = true;
00603 return true;
00604 }
00605
00606
00607 else if ( 0 == strcmp( hostname, "ALL" ) )
00608 {
00609 hostname = GetMyHostName();
00610 }
00611
00612
00613 if ( 0 == strcmp( hostname, "ANY" ) )
00614 hostname = NULL;
00615 }
00616
00617
00618 nHostList hostList;
00619 ANET_GetHostList( hostname, hostList, net_hostport );
00620
00621 if ( hostList.empty() )
00622 {
00623
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
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
00645 return relaxed || ret;
00646 }
00647
00648 class nColonRestaurator
00649 {
00650 public:
00651 nColonRestaurator( char * colon ): colon_(colon){}
00652 ~nColonRestaurator()
00653 {
00654 if ( colon_ )
00655 *colon_ = ':';
00656 }
00657
00658 char * colon_;
00659 };
00660
00661 bool ANET_ListenOn( char * hostname, int net_hostport, nSocketListener::SocketArray & sockets, bool & onesocketonly, bool & relaxed, bool & ignoreErrors )
00662 {
00663
00664 while ( isblank( *hostname ) )
00665 hostname ++;
00666
00667
00668 if ( !*hostname )
00669 return true;
00670
00671
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
00682 nColonRestaurator restaurator( colon );
00683
00684
00685 return ANET_ListenOnConst( hostname, net_hostport, sockets, onesocketonly, relaxed, ignoreErrors );
00686 }
00687
00688 bool ANET_Listen (bool state, int net_hostport, const tString & net_hostip, nSocketListener::SocketArray & sockets )
00689 {
00690 sn_listen = state;
00691
00692
00693 if (state)
00694 {
00695
00696 if (!sockets.empty())
00697 ANET_Listen( false, net_hostport, net_hostip, sockets );
00698
00699 bool relaxed = false, onesocketonly = false, ignoreErrors = false;
00700
00701
00702 tString ips = net_hostip;
00703 size_t lastpos = 0;
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
00717 if ( ips.Size() > lastpos )
00718 if ( !ANET_ListenOn( &ips[lastpos], net_hostport, sockets, onesocketonly, relaxed, ignoreErrors ) )
00719 return false;
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729 return !relaxed || !sockets.empty();
00730 }
00731
00732
00733 if (sockets.empty())
00734 return false;
00735
00736
00737 for ( nSocketListener::SocketArray::iterator iter = sockets.begin(); iter != sockets.end(); ++iter )
00738 {
00739 (*iter).Close();
00740 }
00741 sockets.clear();
00742
00743 return true;
00744 }
00745
00746
00747
00748 int ANET_CloseSocket (int sock)
00749 {
00750
00751
00752 return close (sock);
00753 }
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765 static int PartialIPAddress (const char *in, struct sockaddr *hostaddr, int default_port, int default_addr )
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
00811 return 0;
00812 }
00813
00814
00815
00816 char *ANET_AddrToString (const struct sockaddr *addr)
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));
00823 return buffer;
00824 }
00825
00826
00827
00828 int ANET_GetSocketAddr (int sock, struct sockaddr *addr)
00829 {
00830 NET_SIZE addrlen = sizeof(struct sockaddr);
00831
00832
00833 memset(addr, 0, sizeof(struct sockaddr));
00834 getsockname(sock, (struct sockaddr *)addr, &addrlen);
00835
00836
00837
00838
00839 return 0;
00840 }
00841
00842
00843
00844 int ANET_AddrCompare (struct sockaddr *addr1, struct sockaddr *addr2)
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
00855 return 0;
00856 }
00857
00858 }
00859
00860
00861
00862
00863
00864
00865
00866
00867
00871
00872
00873 nSocketListener const & nBasicNetworkSystem::GetListener( void ) const
00874 {
00875 return this->listener_;
00876 }
00877
00878
00879
00880
00881
00882
00883
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00923
00924
00925 nSocketListener & nBasicNetworkSystem::AccessListener( void )
00926 {
00927 return this->listener_;
00928 }
00929
00930
00931
00932
00933
00934
00938
00939
00940 nSocket const & nBasicNetworkSystem::GetControlSocket( void ) const
00941 {
00942 return this->controlSocket_;
00943 }
00944
00945
00946
00947
00948
00949
00950
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00990
00991
00992 nSocket & nBasicNetworkSystem::AccessControlSocket( void )
00993 {
00994 return this->controlSocket_;
00995 }
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01013
01014
01015 nAddress::nAddress( void )
01016 {
01017
01018 memset( &addr_, 0, size );
01019 addrLen_ = size;
01020
01021
01022 addr_.addr_in.sin_addr.s_addr = INADDR_ANY;
01023 addr_.addr_in.sin_family = AF_INET;
01024 addr_.addr_in.sin_port = 0;
01025 }
01026
01027
01028
01029
01030
01031
01034
01035
01036 nAddress::~nAddress( void )
01037 {
01038
01039 }
01040
01041
01042
01043
01044
01045
01050
01051
01052 const nAddress & nAddress::ToString( tString & string ) const
01053 {
01054 if( addr_.addr_in.sin_addr.s_addr != INADDR_ANY )
01055 string = ANET_AddrToString( *this );
01056 else
01057 {
01058 string = "*.*.*.*";
01059 string << ":" << GetPort();
01060 }
01061 return *this;
01062 }
01063
01064
01065
01066
01067
01068
01072
01073
01074 tString nAddress::ToString( void ) const
01075 {
01076
01077 tString ret;
01078 ToString( ret );
01079 return ret;
01080 }
01081
01082
01083
01084
01085
01086
01091
01092
01093 int nAddress::FromString( const char * string )
01094 {
01095 int ha1, ha2, ha3, ha4, hp;
01096 int ipaddr;
01097
01098 tString source( string );
01099
01100
01101 if (string[0] >= '0' && string[0] <= '9')
01102 {
01103
01104 sscanf(string, "%d.%d.%d.%d:%d", &ha1, &ha2, &ha3, &ha4, &hp);
01105 ipaddr = (ha1 << 24) | (ha2 << 16) | (ha3 << 8) | ha4;
01106
01107
01108 addr_.addr .sa_family = AF_INET;
01109 addr_.addr_in.sin_addr.s_addr = htonl(ipaddr);
01110 addr_.addr_in.sin_port = htons(hp);
01111 return 0;
01112 }
01113 else
01114 {
01115 addr_.addr .sa_family = AF_INET;
01116
01117
01118 int colonPos = source.StrPos(":");
01119 if ( colonPos > 0 )
01120 {
01121 tString addr = source.SubStr( 0, colonPos );
01122
01123
01124 SetPort( source.ToInt( colonPos + 1 ) );
01125
01126
01127 if ( addr == "*.*.*.*" )
01128 addr_.addr_in.sin_addr.s_addr = INADDR_ANY;
01129 else
01130 SetHostname( addr );
01131
01132 return 0;
01133 }
01134 else
01135 {
01136 tERR_ERROR( "Invalid string representation ( IP:PORT ): " << string );
01137
01138 return -1;
01139 }
01140 }
01141 }
01142
01143
01144
01145
01146
01147
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01178
01179
01180 void nAddress::FromHostent( int length, const char * addr )
01181 {
01182
01183 tASSERT( length == 4 );
01184
01185
01186 addr_.addr .sa_family = AF_INET;
01187 addr_.addr_in.sin_addr.s_addr = *reinterpret_cast< int const * >( addr );
01188
01189
01190 addrLen_ = sizeof( sockaddr_in );
01191 }
01192
01193
01194
01195
01196
01197
01202
01203
01204 const nAddress & nAddress::GetHostname( tString & hostname ) const
01205 {
01206
01207 sn_InitOSNetworking();
01208
01209 int haddr;
01210 haddr = ntohl(addr_.addr_in.sin_addr.s_addr);
01211
01212 hostname.Clear();
01213 hostname << ((haddr >> 24) & 0xff) << "." << ((haddr >> 16) & 0xff) << "." << ((haddr >> 8) & 0xff) << "." << (haddr & 0xff);
01214
01215
01216 static char const * section = "HOSTBYADDR";
01217 if ( !tRecorder::PlaybackStrict( section, hostname ) )
01218 {
01219 struct hostent *hostentry;
01220
01221 hostentry = gethostbyaddr ( reinterpret_cast< const char * >( &addr_ ), size, AF_INET);
01222 if (hostentry)
01223 {
01224 hostname = tString( (char *)hostentry->h_name );
01225 }
01226 }
01227
01228
01229 tRecorder::Record( section, hostname );
01230
01231 return *this;
01232 }
01233
01234
01235
01236
01237
01238
01242
01243
01244 tString nAddress::GetHostname( void ) const
01245 {
01246 tString ret;
01247 GetHostname( ret );
01248 return ret;
01249 }
01250
01251
01252
01253
01254
01255
01260
01261
01262 nAddress & nAddress::SetHostname( const char * hostname )
01263 {
01264
01265 sn_InitOSNetworking();
01266
01267
01268 if (hostname[0] >= '0' && hostname[0] <= '9')
01269 {
01270 PartialIPAddress (hostname, &addr_.addr, GetPort(), 0x7f000001 );
01271 return *this;
01272 }
01273
01274
01275 static char const * section = "SINGLEHOSTNAME";
01276 if ( !tRecorder::PlaybackStrict( section, *this ) )
01277 {
01278
01279 struct hostent *hostentry;
01280 hostentry = gethostbyname (hostname);
01281 if (hostentry)
01282 {
01283
01284 addr_.addr .sa_family = AF_INET;
01285 addr_.addr_in.sin_addr.s_addr = *(int *)hostentry->h_addr_list[0];
01286 }
01287 else
01288 {
01289
01290 *this = nAddress();
01291 }
01292 }
01293
01294
01295 tRecorder::Record( section, *this );
01296
01297 return *this;
01298 }
01299
01300
01301
01302
01303
01304
01309
01310
01311 const nAddress & nAddress::GetAddress( tString & hostname ) const
01312 {
01313
01314 sn_InitOSNetworking();
01315
01316 int haddr;
01317 haddr = ntohl(addr_.addr_in.sin_addr.s_addr);
01318
01319 hostname << ((haddr >> 24) & 0xff) << "." << ((haddr >> 16) & 0xff) << "." << ((haddr >> 8) & 0xff) << "." << (haddr & 0xff);
01320
01321 return *this;
01322 }
01323
01324
01325
01326
01327
01328
01332
01333
01334 tString nAddress::GetAddress( void ) const
01335 {
01336 tString ret;
01337 GetAddress( ret );
01338 return ret;
01339 }
01340
01341
01342
01343
01344
01345
01350
01351
01352 nAddress & nAddress::SetAddress( const char * hostname )
01353 {
01354
01355 sn_InitOSNetworking();
01356
01357
01358 tVERIFY(hostname[0] >= '0' && hostname[0] <= '9')
01359
01360 PartialIPAddress (hostname, &addr_.addr, GetPort(), 0x7f000001 );
01361 return *this;
01362 }
01363
01364
01365
01366
01367
01368
01373
01374
01375 nAddress & nAddress::SetPort( int port )
01376 {
01377
01378 addr_.addr_in.sin_port = htons(port);
01379
01380 return *this;
01381 }
01382
01383
01384
01385
01386
01387
01391
01392
01393 int nAddress::GetPort( void ) const
01394 {
01395 return ntohs(addr_.addr_in.sin_port);
01396 }
01397
01398
01399
01400
01401
01402
01407
01408
01409 const nAddress & nAddress::GetPort( int & port ) const
01410 {
01411 port = GetPort();
01412
01413 return *this;
01414 }
01415
01416
01417
01418
01419
01420
01421
01425
01426
01427 bool nAddress::IsSet () const
01428 {
01429 return addr_.addr_in.sin_addr.s_addr != INADDR_ANY;
01430 }
01431
01432
01433
01434
01435
01436
01442
01443
01444 int nAddress::Compare( const nAddress & a1, const nAddress & a2 )
01445 {
01446 if (a1.addr_.addr.sa_family != a2.addr_.addr.sa_family)
01447 return -1;
01448
01449 if (a1.addr_.addr_in.sin_addr.s_addr != a2.addr_.addr_in.sin_addr.s_addr)
01450 return -1;
01451
01452 if (a1.addr_.addr_in.sin_port != a2.addr_.addr_in.sin_port)
01453 return 1;
01454
01455 return 0;
01456 }
01457
01458
01459
01460
01461
01462
01466
01467
01468 unsigned int nAddress::GetAddressLength( void ) const
01469 {
01470 return this->addrLen_;
01471 }
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01486
01487
01488 nSocket::nSocket( void )
01489 :socket_( -1 ), family_( PF_INET ), socktype_( SOCK_DGRAM ), protocol_( IPPROTO_UDP ), broadcast_( false )
01490 {
01491 }
01492
01493
01494
01495
01496
01497
01500
01501
01502 nSocket::~nSocket( void )
01503 {
01504 if ( IsOpen() )
01505 Close();
01506 }
01507
01508
01509
01510
01511
01512
01516
01517
01518 int nSocket::Create( void )
01519 {
01520 tASSERT( !IsOpen() );
01521
01522
01523 sn_InitOSNetworking();
01524
01525
01526 socket_ = socket( family_, socktype_, protocol_ );
01527 if ( socket_ < 0 )
01528 return -1;
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538 #ifndef WIN32
01539 char tos = IPTOS_LOWDELAY;
01540
01541 int ret = setsockopt( socket_, IPPROTO_IP, IP_TOS, &tos, sizeof(char) );
01542
01543
01544 if ( ret != 0 )
01545 {
01546 static bool warn=true;
01547 if ( warn )
01548 con << "Setting TOS to LOWDELAY failed.\n";
01549 warn=false;
01550 }
01551 #endif
01552
01553
01554 bool _true = true;
01555 return ioctl (socket_, FIONBIO, reinterpret_cast<char *>(&_true)) == -1;
01556 }
01557
01558
01559 static char const * recordingSection = "BIND";
01560
01561 template< class Archiver > class BindArchiver
01562 {
01563 public:
01564 static void Archive( Archiver & archiver, nAddress & trueAddress )
01565 {
01566
01567 struct sockaddr * addr = static_cast< struct sockaddr * >( trueAddress );
01568 unsigned char * addr_char = reinterpret_cast< unsigned char *>( addr );
01569 for( int i = sizeof( sockaddr )-1; i>=0; --i )
01570 archiver.Archive( addr_char[i] ).DontSeparate();
01571
01572 archiver.Separator();
01573 }
01574
01575 static bool Archive( int & ret, nAddress & trueAddress )
01576 {
01577
01578 Archiver archive;
01579 if ( archive.Initialize( recordingSection ) )
01580 {
01581 archive.Archive( ret );
01582 archive.Archive( trueAddress );
01583
01584
01585 return true;
01586 }
01587
01588 return false;
01589 }
01590 };
01591
01592
01593
01594
01595
01596
01601
01602
01603 int nSocket::Bind( nAddress const & addr )
01604 {
01605 tASSERT( IsOpen() );
01606
01607
01608 address_ = addr;
01609
01610 int ret = 0;
01611
01612
01613 if ( !BindArchiver< tPlaybackBlock >::Archive( ret, trueAddress_ ) )
01614 {
01615
01616 ret = bind( socket_, addr, addr.GetAddressLength() );
01617
01618
01619 if ( 0 == ret )
01620 ANET_GetSocketAddr( socket_, trueAddress_ );
01621 }
01622
01623
01624 BindArchiver< tRecordingBlock >::Archive( ret, trueAddress_ );
01625
01626 if ( 0 == ret )
01627 {
01628
01629 #ifdef DEDICATED
01630 static nAddress nullAddress;
01631 if ( 0 == nAddress::Compare( trueAddress_, addr ) || 0 == nAddress::Compare( nullAddress, addr ) )
01632 con << "Bound socket to " << trueAddress_.ToString() << ".\n";
01633 else
01634 con << "Bound socket to " << trueAddress_.ToString() << " ( " << address_.ToString() << " was requested ).\n";
01635 #endif
01636
01637 return 0;
01638 }
01639 else
01640 {
01641
01642
01643
01644 ANET_CloseSocket( socket_ );
01645 socket_ = -1;
01646
01647
01648 #ifndef NOEXCEPT
01649
01650 if ( ANET_Error() == nSocketError_Reset )
01651 {
01652 tString details( "Unable to bind to " );
01653 details += address_.ToString();
01654 details += " because that is not an address of the local machine.";
01655 throw nSocket::PermanentError( details );
01656 }
01657 #endif
01658
01659 return -1;
01660 }
01661
01662 return ret;
01663 }
01664
01665
01666
01667
01668
01669
01674
01675
01676 int nSocket::Open( nAddress const & addr )
01677 {
01678 tASSERT( !IsOpen() );
01679
01680
01681 if ( Create() != 0 )
01682 {
01683 return -2;
01684 }
01685
01686
01687 return Bind( addr );
01688 }
01689
01690
01691
01692
01693
01694
01698
01699
01700 int nSocket::Open( void )
01701 {
01702
01703 nAddress addr;
01704 return Open( addr );
01705 }
01706
01707
01708
01709
01710
01711
01716
01717
01718 int nSocket::Open( int port )
01719 {
01720
01721 nAddress addr;
01722 addr.SetPort( port );
01723 return Open( addr );
01724 }
01725
01726
01727
01728
01729
01730
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757
01758
01759
01760
01761
01766
01767
01768 int nSocket::Open( const nHostInfo & addr )
01769 {
01770 tASSERT( !IsOpen() );
01771
01772 family_ = addr.type.family;
01773 socktype_ = addr.type.type;
01774 protocol_ = addr.type.protocol;
01775
01776 return Open( addr.address );
01777 }
01778
01779
01780
01781
01782
01783
01787
01788
01789 int nSocket::Close( void )
01790 {
01791 #ifdef DEDICATED
01792 if ( socket_ != -1 )
01793 con << "Closing socket bound to " << trueAddress_.ToString() << "\n";
01794 #endif
01795
01796 ANET_CloseSocket( socket_ );
01797 socket_ = -1;
01798 broadcast_ = false;
01799
01800 return 0;
01801 }
01802
01803
01804
01805
01806
01807
01811
01812
01813 void nSocket::Reset( void ) const
01814 {
01815
01816 nSocket * reset = const_cast< nSocket * >( this );
01817
01818
01819 nAddress trueAddress = trueAddress_;
01820
01821
01822 reset->Close();
01823
01824
01825 nAddress oldAddress = address_;
01826
01827
01828 nAddress wishAddress = address_;
01829 wishAddress.SetPort( trueAddress.GetPort() );
01830 if ( 0 == reset->Open( wishAddress ) )
01831 return;
01832
01833
01834 if ( 0 == reset->Open( oldAddress ) )
01835 return;
01836
01837
01838 reset->Open( trueAddress );
01839 }
01840
01841
01842
01843
01844
01845
01849
01850
01851 bool nSocket::IsOpen( void ) const
01852 {
01853 return socket_ >= 0;
01854 }
01855
01856
01857
01858
01859
01860
01865
01866
01867 int nSocket::Connect( const nAddress & addr )
01868 {
01869
01870 return 0;
01871 }
01872
01873 #ifdef DEBUG
01874
01875 bool sn_ResetSocket = false;
01876 void ResetSocket( std::istream& s )
01877 {
01878 sn_ResetSocket = true;
01879 }
01880
01881 static tConfItemFunc sn_cireset ( "RESET_SOCKET", ResetSocket );
01882 #endif
01883
01884
01885
01886
01887
01888
01889
01890
01891
01895
01896
01897 const nSocket * nSocket::CheckNewConnection( void ) const
01898 {
01899 tASSERT( IsOpen() );
01900
01901 int available=-1;
01902
01903
01904
01905
01906
01907
01908 if ( tRecorder::IsRunning() )
01909 return this;
01910
01911
01912 #ifdef DEBUG
01913 if ( sn_ResetSocket )
01914 {
01915 sn_ResetSocket = false;
01916 Reset();
01917 }
01918 #endif
01919
01920
01921 int ret = ioctl (socket_, FIONREAD, &available);
01922 if ( ret == -1)
01923 {
01924 switch ( ANET_Error() )
01925 {
01926 case nSocketError_Reset:
01927 Reset();
01928 break;
01929 case nSocketError_Ignore:
01930 break;
01931 default:
01932 Sys_Error ("UDP: ioctlsocket (FIONREAD) failed\n");
01933 break;
01934 }
01935 }
01936
01937 if ( ret >= 0 )
01938 {
01939
01940
01941 return this;
01942 }
01943
01944 return NULL;
01945 }
01946
01947
01948 static char const * recordingSectionRead = "READ";
01949
01951 template< class Archiver > class ReadArchiver
01952 {
01953 public:
01954 static bool Archive( int8 * buf, int & len, nAddress & addr )
01955 {
01956
01957 Archiver archive;
01958 if( archive.Initialize( recordingSectionRead ) )
01959 {
01960
01961 archive.Archive( len );
01962 if ( len < 0 )
01963 return true;
01964
01965
01966
01967 archive.Archive( addr );
01968
01969
01970 for( int i = 0; i < len; ++i )
01971 archive.Archive( buf[ i ] );
01972
01973 archive.Separator();
01974
01975 return true;
01976 }
01977
01978 return false;
01979 }
01980 };
01981
01982 #ifdef DEBUG
01983 static REAL sn_simulateReceivePacketLoss = 0;
01984 static tSettingItem<REAL> sn_sumulateReceivePacketLossConfig( "SIMULATE_RECEIVE_PACKET_LOSS", sn_simulateReceivePacketLoss );
01985 #endif
01986
01987
01988
01989
01990
01991
01998
01999
02000 int nSocket::Read( int8 * buf, int len, nAddress & addr ) const
02001 {
02002 tASSERT( IsOpen() );
02003
02004
02005 int ret = 0;
02006
02007 static tReproducibleRandomizer randomizer;
02008 #ifdef DEBUG
02009
02010 if ( sn_simulateReceivePacketLoss > randomizer.Get() )
02011 return -1;
02012 #endif
02013
02014
02015 if ( !ReadArchiver< tPlaybackBlock >::Archive( buf, ret, addr ) )
02016 {
02017
02018 #ifdef DEBUG
02019 if ( sn_ResetSocket )
02020 {
02021 sn_ResetSocket = false;
02022 Reset();
02023 }
02024 #endif
02025
02026
02027 NET_SIZE addrlen = addr.GetAddressLength();
02028 ret = recvfrom (socket_, buf, len, 0, addr, &addrlen );
02029 tASSERT( addrlen <= static_cast< NET_SIZE >( addr.GetAddressLength() ) );
02030 }
02031
02032
02033 ReadArchiver< tRecordingBlock >::Archive( buf, ret, addr );
02034
02035 if ( ret <= 0 )
02036 {
02037 switch ( ANET_Error() )
02038 {
02039 case nSocketError_Reset:
02040 {
02041 Reset();
02042 return -1;
02043 }
02044 break;
02045 case nSocketError_Ignore:
02046 return -1;
02047 break;
02048 }
02049 }
02050
02051 if ( ret >= 0 )
02052 {
02053
02054 }
02055
02056 #ifdef PRINTPACKETS
02057 con << trueAddress_.ToString() << " << " << addr.ToString() << "\n";
02058 #endif
02059
02060 return ret;
02061 }
02062
02063 #ifdef DEBUG
02064 static REAL sn_simulateSendPacketLoss = 0;
02065 static tSettingItem<REAL> sn_sumulateSendPacketLossConfig( "SIMULATE_SEND_PACKET_LOSS", sn_simulateSendPacketLoss );
02066 #endif
02067
02068
02069
02070
02071
02072
02080
02081
02082 int nSocket::Write( const int8 * buf, int len, const sockaddr * addr, int addrlen ) const
02083 {
02084 tASSERT( IsOpen() );
02085
02086 #ifdef DEBUG
02087 if ( sn_ResetSocket )
02088 {
02089 sn_ResetSocket = false;
02090 Reset();
02091 }
02092 #endif
02093
02094 int ret = 0;
02095
02096
02097 static char const * section = "SEND";
02098 if ( !tRecorder::Playback( section, ret ) )
02099 {
02100 static tReproducibleRandomizer randomizer;
02101 #ifdef DEBUG
02102
02103 if ( sn_simulateSendPacketLoss > randomizer.Get() )
02104 ret = len;
02105 else
02106 #endif
02107 {
02108
02109 if ( !tRecorder::IsPlayingBack() )
02110 ret = sendto (socket_, buf, len, 0, addr, addrlen );
02111 }
02112 }
02113
02114 if ( ret < 0 )
02115 {
02116
02117 tRecorder::Record( section, ret );
02118
02119
02120 switch ( ANET_Error() )
02121 {
02122 case nSocketError_Reset:
02123 {
02124 Reset();
02125 return -1;
02126 }
02127 break;
02128 case nSocketError_Ignore:
02129 return -1;
02130 break;
02131 }
02132 }
02133
02134 return ret;
02135 }
02136
02137
02138
02139
02140
02141
02148
02149
02150 int nSocket::Write( const int8 * buf, int len, const nAddress & addr ) const
02151 {
02152 #ifdef PRINTPACKETS
02153 con << trueAddress_.ToString() << " >> " << addr.ToString() << "\n";
02154 #endif
02155
02156
02157 return Write( buf, len, addr, addr.GetAddressLength() );
02158 }
02159
02160
02161
02162
02163
02164
02171
02172
02173 int nSocket::Broadcast( const char * buf, int len, unsigned int port ) const
02174 {
02175 tASSERT( IsOpen() );
02176
02177 if ( !broadcast_ )
02178 {
02179 int i = 1;
02180
02181
02182 if (setsockopt(socket_, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof(i)) < 0)
02183 {
02184 Con_Printf("Unable to make socket broadcast capable\n");
02185 return -1;
02186 }
02187
02188 broadcast_ = true;
02189 }
02190
02191
02192 sockaddr_in broadcastaddr;
02193 broadcastaddr.sin_family = AF_INET;
02194 broadcastaddr.sin_addr.s_addr = INADDR_BROADCAST;
02195 broadcastaddr.sin_port = htons(port);
02196
02197
02198 return Write ( buf, len, reinterpret_cast< sockaddr *>( &broadcastaddr ), sizeof( sockaddr_in ) );
02199 }
02200
02201
02202
02203
02204
02205
02209
02210
02211 const nAddress & nSocket::GetAddress( void ) const
02212 {
02213 return trueAddress_;
02214 }
02215
02216
02217
02218
02219
02220
02225
02226
02227 const nSocket & nSocket::GetAddress( nAddress & address ) const
02228 {
02229 address = trueAddress_;
02230
02231 return *this;
02232 }
02233
02234
02235
02236
02237
02238
02243
02244
02245 nSocket & nSocket::SetAddress( nAddress const & address )
02246 {
02247 address_ = address;
02248 trueAddress_ = address;
02249
02250 return *this;
02251 }
02252
02253
02254
02255
02256
02257
02258
02262
02263
02264 void nSocket::MoveFrom( const nSocket & other )
02265 {
02266
02267 if ( IsOpen() )
02268 Close();
02269
02270
02271
02272 address_ = other.address_;
02273 trueAddress_ = other.trueAddress_;
02274 family_ = other.family_;
02275 socktype_ = other.socktype_;
02276 protocol_ = other.protocol_;
02277 broadcast_ = other.broadcast_;
02278
02279
02280 socket_ = other.socket_;
02281 const_cast< nSocket & >( other ).socket_ = -1;
02282 }
02283
02284
02285
02286
02287
02288
02292
02293
02294 nSocket::nSocket( const nSocket & other )
02295 {
02296 socket_ = -1;
02297 MoveFrom( other );
02298 }
02299
02300
02301
02302
02303
02304
02309
02310
02311 nSocket & nSocket::operator =( const nSocket & other )
02312 {
02313 MoveFrom( other );
02314 return *this;
02315 }
02316
02317
02318
02319
02320
02321
02322
02323
02324
02325
02326
02327
02330
02331
02332 nSocketListener::nSocketListener( void )
02333 : port_( 0 ), ipList_( "ANY" )
02334 {
02335 }
02336
02337
02338
02339
02340
02341
02344
02345
02346 nSocketListener::~nSocketListener( void )
02347 {
02348
02349 Listen( false );
02350 }
02351
02352
02353
02354
02355
02356
02361
02362
02363 bool nSocketListener::Listen( bool state )
02364 {
02365 bool ret = false;
02366 try{
02367
02368 ret = ANET_Listen( state, port_, ipList_, sockets_ );
02369 }
02370 catch ( OneSocketOpened const & )
02371 {
02372
02373 ret = true;
02374 }
02375
02376
02377 if ( state && !ret )
02378 Listen( false );
02379
02380
02381 return ret;
02382 }
02383
02384
02385
02386
02387
02388
02392
02393
02394 nSocketListener::iterator nSocketListener::begin( void ) const
02395 {
02396 return sockets_.begin();
02397 }
02398
02399
02400
02401
02402
02403
02407
02408
02409 nSocketListener::iterator nSocketListener::end( void ) const
02410 {
02411 return sockets_.end();
02412 }
02413
02414
02415
02416
02417
02418
02422
02423
02424 unsigned int nSocketListener::GetPort( void ) const
02425 {
02426 return this->port_;
02427 }
02428
02429
02430
02431
02432
02433
02438
02439
02440 nSocketListener const & nSocketListener::GetPort( unsigned int & port ) const
02441 {
02442 port = this->port_;
02443 return *this;
02444 }
02445
02446
02447
02448
02449
02450
02455
02456
02457 nSocketListener & nSocketListener::SetPort( unsigned int port )
02458 {
02459 Listen( false );
02460
02461 this->port_ = port;
02462 return *this;
02463 }
02464
02465
02466
02467
02468
02469
02473
02474
02475 tString const & nSocketListener::GetIpList( void ) const
02476 {
02477 return this->ipList_;
02478 }
02479
02480
02481
02482
02483
02484
02489
02490
02491 nSocketListener const & nSocketListener::GetIpList( tString & ipList ) const
02492 {
02493 ipList = this->ipList_;
02494 return *this;
02495 }
02496
02497
02498
02499
02500
02501
02506
02507
02508 nSocketListener & nSocketListener::SetIpList( tString const & ipList )
02509 {
02510 Listen( false );
02511
02512 this->ipList_ = ipList;
02513 return *this;
02514 }
02515
02516
02517
02518
02519
02520
02521
02522
02523
02524
02525
02526
02527
02530
02531
02532 nBasicNetworkSystem::nBasicNetworkSystem( void )
02533 {
02534
02535 }
02536
02537
02538
02539
02540
02541
02544
02545
02546 nBasicNetworkSystem::~nBasicNetworkSystem( void )
02547 {
02548
02549 Shutdown();
02550 }
02551
02552
02553
02554
02555
02556
02560
02561
02562 nSocket * nBasicNetworkSystem::Init()
02563 {
02564
02565 if ( controlSocket_.IsOpen() )
02566 return &controlSocket_;
02567
02568
02569 sn_InitOSNetworking();
02570
02571 if ( 0 != controlSocket_.Open() )
02572 Sys_Error("ANET_Init: Unable to open control socket\n");
02573
02574 return &controlSocket_;
02575
02576
02577
02578
02579
02580
02581
02582
02583
02584
02585
02586
02587
02588
02589
02590
02591
02592
02593
02594
02595
02596
02597
02598
02599
02600
02601
02602
02603
02604
02605
02606
02607
02608
02609
02610
02611
02612
02613
02614
02615
02616
02617
02618
02619
02620
02621
02622
02623
02624
02625
02626
02627
02628
02629
02630 }
02631
02632
02633
02634
02635
02636
02641
02642
02643 bool nBasicNetworkSystem::Select( REAL dt )
02644 {
02645 int retval = 0;
02646 static char const * section = "NETSELECT";
02647 if ( !tRecorder::PlaybackStrict( section, retval ) )
02648 {
02649 if ( controlSocket_.GetSocket() < 0 )
02650 {
02651 tDelay( int( dt * 1000000 ) );
02652 return false;
02653 }
02654
02655 fd_set rfds;
02656 struct timeval tv;
02657
02658 FD_ZERO( &rfds );
02659
02660
02661 FD_SET( controlSocket_.GetSocket(), &rfds );
02662
02663
02664 int max = controlSocket_.GetSocket();
02665
02666
02667 for( nSocketListener::SocketArray::const_iterator iter = listener_.GetSockets().begin(); iter != listener_.GetSockets().end(); ++iter )
02668 {
02669 FD_SET( (*iter).GetSocket(), &rfds );
02670 if ( (*iter).GetSocket() > max )
02671 max = (*iter).GetSocket();
02672
02673 }
02674
02675
02676 tv.tv_sec = static_cast< long int >( dt );
02677 tv.tv_usec = static_cast< long int >( (dt-tv.tv_sec)*1000000 );
02678
02679
02680 retval = select(max+1, &rfds, NULL, NULL, &tv);
02681 }
02682 tRecorder::Record( section, retval );
02683
02684
02685
02686
02687 return ( retval > 0 );
02688 }
02689
02690
02691
02692
02693
02694
02697
02698
02699 void nBasicNetworkSystem::Shutdown()
02700 {
02701
02702 listener_.Listen(false);
02703
02704
02705 controlSocket_.Close();
02706 }
02707
02708
02709
02710
02711
02712
02713
02716
02717
02718 nSocket::PermanentError::PermanentError( void )
02719 : description_( "No details available" )
02720 {
02721 }
02722
02723
02724
02725
02726
02727
02731
02732
02733 nSocket::PermanentError::PermanentError( const tString & details )
02734 : description_( details )
02735 {
02736 }
02737
02738
02739
02740
02741
02742
02745
02746
02747 nSocket::PermanentError::~PermanentError( void )
02748 {
02749 }
02750
02751
02752
02753
02754
02755
02759
02760
02761 tString nSocket::PermanentError::DoGetName( void ) const
02762 {
02763 return tString( "Permanent network error" );
02764 }
02765
02766
02767
02768
02769
02770
02774
02775
02776 tString nSocket::PermanentError::DoGetDescription( void ) const
02777 {
02778 return description_;
02779 }
02780
02781