src/network/nSocket.cpp

Go to the documentation of this file.
00001 /*
00002 
00003 *************************************************************************
00004 
00005 ArmageTron -- Just another Tron Lightcycle Game in 3D.
00006 Copyright (C) 2000  Manuel Moos (manuel@moosnet.de)
00007 
00008 **************************************************************************
00009 
00010 This program is free software; you can redistribute it and/or
00011 modify it under the terms of the GNU General Public License
00012 as published by the Free Software Foundation; either version 2
00013 of the License, or (at your option) any later version.
00014 
00015 This program is distributed in the hope that it will be useful,
00016 but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 GNU General Public License for more details.
00019 
00020 You should have received a copy of the GNU General Public License
00021 along with this program; if not, write to the Free Software
00022 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00023 
00024 ***************************************************************************
00025 
00026 */
00027 
00028 // nSocket.h
00029 
00030 // loosely based on the GNU Quake 1 base network code, so technicaly:
00031 // Copyright (C) 1996-1997 Id Software, Inc.
00032 // Modified for Armagetron by Manuel Moos (manuel@moosnet.de)
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 //#include <winsock2.h>
00068 //#include <ws2tcpip.h>
00069 //#include <Ws2tcpip.h>
00070 //#include <Wspiapi.h>
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 // print packet sources and destinations
00121 #ifdef DEBUG
00122 #ifdef DEDICATED
00123 //#define PRINTPACKETS
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 // streaming operators for addresses, socket types and host infos
00154 std::istream & operator >> ( std::istream & s, nAddress & address )
00155 {
00156     // read address
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     // read data
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     // 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 
00183     return s;
00184 }
00185 
00186 std::ostream & operator << ( std::ostream & s, nAddress const & address )
00187 {
00188     // write address
00189     s << tLineString( address.ToString() );
00190 
00191     return s;
00192 }
00193 
00194 std::ostream & operator << ( std::ostream & s, nSocketType const & type )
00195 {
00196     // write data
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     // write name
00205     s << tLineString( hostInfo.name );
00206 
00207     // write address and type
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,                                // nothing special happened
00219     nSocketError_Reset                                  // socket needs to be reset
00220 };
00221 
00222 tRECORD_AS( nSocketError, int );
00223 
00224 // anonymous namespace of helper functions
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 // typedef int Socket;
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     // 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();
00330     return aError;
00331 }
00332 
00333 typedef int Socket;
00334 
00335 
00336 /*
00337 int ANET_NewSocket ()
00338 {
00339     int newsocket=-1;
00340     bool _true = true;
00341 
00342     // create socket
00343     if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
00344         return -1;
00345 
00346     // unblock it
00347     if (ioctl (newsocket, FIONBIO, reinterpret_cast<char *>(&_true)) == -1)
00348         goto ErrorReturn;
00349 
00350     return newsocket;
00351 
00352 ErrorReturn:
00353     close (newsocket);
00354     return -1;
00355 }
00356 
00357 int ANET_OpenSocket (int port )
00358 {
00359     struct sockaddr_in address;
00360 
00361     // create socket
00362     int newsocket = ANET_NewSocket();
00363     if ( newsocket < 0 )
00364         return -1;
00365 
00366     // bind to no specific IP
00367     address.sin_addr.s_addr = INADDR_ANY;
00368     address.sin_family = AF_INET;
00369 
00370     address.sin_port = htons(port);
00371     if( bind (newsocket, reinterpret_cast<const sockaddr *>(&address), sizeof(address)) == -1)
00372         goto ErrorReturn;
00373 
00374     return newsocket;
00375 
00376 ErrorReturn:
00377     close (newsocket);
00378     return -1;
00379 }
00380 */
00381 
00382 /*
00383 int ANET_OpenSocket (int port, const tString& ip )
00384 {
00385     if ( ip.Len() > 1 && ip != "ANY" && ip != "ALL" )
00386     {
00387         return ANET_OpenSocket( port, static_cast< const char * >( ip ) );
00388     }
00389     else
00390     {
00391         return ANET_OpenSocket( port, NULL );
00392     }
00393 }
00394 
00395 int ANET_OpenSocket (int port)
00396 {
00397     return ANET_OpenSocket( port, net_hostip );
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         // 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 
00451     return ret;
00452 }
00453 
00454 // open ports that listens on the specified address list, returns true only if sockets for all addresses were created
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             // 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
00506     return ret;
00507 }
00508 
00509 
00510 // determines addresses of hostentry and adds them to hostList
00511 void ANET_GetHostList( hostent const * hostentry, nHostList & hostList, int net_hostport, bool server = true )
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
00528     }
00529 }
00530 
00531 // determines addresses of hostname and fills them into to hostList
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     // 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 );
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         // 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.
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     // 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
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     // 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 
00743     return true;
00744 }
00745 
00746 //=============================================================================
00747 
00748 int ANET_CloseSocket (int sock)
00749 {
00750     //if (sock == net_broadcastsocket)
00751     //    net_broadcastsocket = 0;
00752     return close (sock);
00753 }
00754 
00755 
00756 //=============================================================================
00757 /*
00758   ============
00759   PartialIPAddress
00760 
00761   this lets you type only as much of the net address as required, using
00762   the passed defaults to fill in the rest
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     // 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 
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 }   // namespace
00859 
00860 //=============================================================================
00861 
00862 
00863 // *******************************************************************************************
00864 // *
00865 // *    GetListener
00866 // *
00867 // *******************************************************************************************
00871 // *******************************************************************************************
00872 
00873 nSocketListener const & nBasicNetworkSystem::GetListener( void ) const
00874 {
00875     return this->listener_;
00876 }
00877 
00878 /*
00879 // *******************************************************************************************
00880 // *
00881 // *    GetListener
00882 // *
00883 // *******************************************************************************************
00888 // *******************************************************************************************
00889 
00890 nBasicNetworkSystem const & nBasicNetworkSystem::GetListener( nSocketListener & listener ) const
00891 {
00892         listener = this->listener_;
00893         return *this;
00894 }
00895 
00896 // *******************************************************************************************
00897 // *
00898 // *    SetListener
00899 // *
00900 // *******************************************************************************************
00905 // *******************************************************************************************
00906 
00907 nBasicNetworkSystem & nBasicNetworkSystem::SetListener( nSocketListener const & listener )
00908 {
00909         this->listener_ = listener;
00910         return *this;
00911 }
00912 */
00913 
00914 // *******************************************************************************************
00915 // *
00916 // *    accessListener
00917 // *    This function is dangerous; use only if you absolutely have to and do not store the returned reference longer than required.
00918 // *
00919 // *******************************************************************************************
00923 // *******************************************************************************************
00924 
00925 nSocketListener & nBasicNetworkSystem::AccessListener( void )
00926 {
00927     return this->listener_;
00928 }
00929 
00930 // *******************************************************************************************
00931 // *
00932 // *    GetControlSocket
00933 // *
00934 // *******************************************************************************************
00938 // *******************************************************************************************
00939 
00940 nSocket const & nBasicNetworkSystem::GetControlSocket( void ) const
00941 {
00942     return this->controlSocket_;
00943 }
00944 
00945 /*
00946 // *******************************************************************************************
00947 // *
00948 // *    GetControlSocket
00949 // *
00950 // *******************************************************************************************
00955 // *******************************************************************************************
00956 
00957 nBasicNetworkSystem const & nBasicNetworkSystem::GetControlSocket( nSocket & controlSocket ) const
00958 {
00959         controlSocket = this->controlSocket_;
00960         return *this;
00961 }
00962 
00963 // *******************************************************************************************
00964 // *
00965 // *    SetControlSocket
00966 // *
00967 // *******************************************************************************************
00972 // *******************************************************************************************
00973 
00974 nBasicNetworkSystem & nBasicNetworkSystem::SetControlSocket( nSocket const & controlSocket )
00975 {
00976         this->controlSocket_ = controlSocket;
00977         return *this;
00978 }
00979 */
00980 
00981 // *******************************************************************************************
00982 // *
00983 // *    accessControlSocket
00984 // *    This function is dangerous; use only if you absolutely have to and do not store the returned reference longer than required.
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 // *    nAddress
01009 // *
01010 // *******************************************************************************************
01013 // *******************************************************************************************
01014 
01015 nAddress::nAddress( void )
01016 {
01017     // clear address data, it's only POD
01018     memset( &addr_, 0, size );
01019     addrLen_ = size;
01020 
01021     // set to unspecific IP4 address
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 // *    ~nAddress
01030 // *
01031 // *******************************************************************************************
01034 // *******************************************************************************************
01035 
01036 nAddress::~nAddress( void )
01037 {
01038     // nothing to clean up
01039 }
01040 
01041 // *******************************************************************************************
01042 // *
01043 // *    ToString
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 // *    ToString
01067 // *
01068 // *******************************************************************************************
01072 // *******************************************************************************************
01073 
01074 tString nAddress::ToString( void ) const
01075 {
01076     // delegate
01077     tString ret;
01078     ToString( ret );
01079     return ret;
01080 }
01081 
01082 // *******************************************************************************************
01083 // *
01084 // *    FromString
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     // parse IP address if the passed name looks like one
01101     if (string[0] >= '0' && string[0] <= '9')
01102     {
01103         // parse IP address
01104         sscanf(string, "%d.%d.%d.%d:%d", &ha1, &ha2, &ha3, &ha4, &hp);
01105         ipaddr = (ha1 << 24) | (ha2 << 16) | (ha3 << 8) | ha4;
01106 
01107         // store values in address
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         // find colon
01118         int colonPos = source.StrPos(":");
01119         if ( colonPos > 0 )
01120         {
01121             tString addr = source.SubStr( 0, colonPos );
01122 
01123             // extract port
01124             SetPort( source.ToInt( colonPos + 1 ) );
01125 
01126             // extract hostname
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 // *    FromAddrInfo
01146 // *
01147 // *******************************************************************************************
01151 // *******************************************************************************************
01152 
01153 /*
01154 void nAddress::FromAddrInfo( const addrinfo & info )
01155 {
01156 #ifdef HAVE_ADDRINFO
01157     // check address size
01158     tASSERT( info.ai_addrlen <= size );
01159 
01160     // copy the address over
01161     memcpy( &addr_, info.ai_addr, info.ai_addrlen );
01162 
01163     // store length
01164     addrLen_ = info.ai_addrlen;
01165 #endif
01166 }
01167 */
01168 
01169 // *******************************************************************************************
01170 // *
01171 // *   FromHostent
01172 // *
01173 // *******************************************************************************************
01178 // *******************************************************************************************
01179 
01180 void nAddress::FromHostent( int length, const char * addr )
01181 {
01182     // check address size
01183     tASSERT( length == 4 );
01184 
01185     // copy the address over
01186     addr_.addr   .sa_family = AF_INET;
01187     addr_.addr_in.sin_addr.s_addr = *reinterpret_cast< int const * >( addr );
01188 
01189     // store length
01190     addrLen_ = sizeof( sockaddr_in );
01191 }
01192 
01193 // *******************************************************************************************
01194 // *
01195 // *    GetHostname
01196 // *
01197 // *******************************************************************************************
01202 // *******************************************************************************************
01203 
01204 const nAddress & nAddress::GetHostname( tString & hostname ) const
01205 {
01206     // initialize networking at OS level
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     // read hostname from recording
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     // write hostname to recording
01229     tRecorder::Record( section, hostname );
01230 
01231     return *this;
01232 }
01233 
01234 // *******************************************************************************************
01235 // *
01236 // *    GetHostname
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 // *    SetHostname
01254 // *
01255 // *******************************************************************************************
01260 // *******************************************************************************************
01261 
01262 nAddress & nAddress::SetHostname( const char * hostname )
01263 {
01264     // initialize networking at OS level
01265     sn_InitOSNetworking();
01266 
01267     // parse IP address if the passed name looks like one
01268     if (hostname[0] >= '0' && hostname[0] <= '9')
01269     {
01270         PartialIPAddress (hostname, &addr_.addr, GetPort(), 0x7f000001 );
01271         return *this;
01272     }
01273 
01274     // read address from recording
01275     static char const * section = "SINGLEHOSTNAME";
01276     if ( !tRecorder::PlaybackStrict( section, *this ) )
01277     {
01278         // look up hostname ( TODO: error handling )
01279         struct hostent *hostentry;
01280         hostentry = gethostbyname (hostname);
01281         if (hostentry)
01282         {
01283             // store values
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             // invalidate
01290             *this = nAddress();
01291         }
01292     }
01293 
01294     // write address to recording
01295     tRecorder::Record( section, *this );
01296 
01297     return *this;
01298 }
01299 
01300 // *******************************************************************************************
01301 // *
01302 // *    GetAddress
01303 // *
01304 // *******************************************************************************************
01309 // *******************************************************************************************
01310 
01311 const nAddress & nAddress::GetAddress( tString & hostname ) const
01312 {
01313     // initialize networking at OS level
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 // *    GetAddress
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 // *    SetAddress
01344 // *
01345 // *******************************************************************************************
01350 // *******************************************************************************************
01351 
01352 nAddress & nAddress::SetAddress( const char * hostname )
01353 {
01354     // initialize networking at OS level
01355     sn_InitOSNetworking();
01356 
01357     // parse IP address if the passed name looks like one
01358     tVERIFY(hostname[0] >= '0' && hostname[0] <= '9')
01359 
01360     PartialIPAddress (hostname, &addr_.addr, GetPort(), 0x7f000001 );
01361     return *this;
01362 }
01363 
01364 // *******************************************************************************************
01365 // *
01366 // *    SetPort
01367 // *
01368 // *******************************************************************************************
01373 // *******************************************************************************************
01374 
01375 nAddress & nAddress::SetPort( int port )
01376 {
01377     // store the port
01378     addr_.addr_in.sin_port = htons(port);
01379 
01380     return *this;
01381 }
01382 
01383 // *******************************************************************************************
01384 // *
01385 // *    GetPort
01386 // *
01387 // *******************************************************************************************
01391 // *******************************************************************************************
01392 
01393 int nAddress::GetPort( void ) const
01394 {
01395     return ntohs(addr_.addr_in.sin_port);
01396 }
01397 
01398 // *******************************************************************************************
01399 // *
01400 // *    GetPort
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 // *    IsSet
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 // *    Compare
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 // *   GetAddressLength
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 // *    nSocket
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 // *    ~nSocket
01496 // *
01497 // *******************************************************************************************
01500 // *******************************************************************************************
01501 
01502 nSocket::~nSocket( void )
01503 {
01504     if ( IsOpen() )
01505         Close();
01506 }
01507 
01508 // *******************************************************************************************
01509 // *
01510 // *    Create
01511 // *
01512 // *******************************************************************************************
01516 // *******************************************************************************************
01517 
01518 int nSocket::Create( void )
01519 {
01520     tASSERT( !IsOpen() );
01521 
01522     // initialize networking at OS level
01523     sn_InitOSNetworking();
01524 
01525     // open new socket
01526     socket_ = socket( family_, socktype_, protocol_ );
01527     if ( socket_ < 0 )
01528         return -1;
01529 
01530     // TODO: IP_TOS only Supported under Windows 2000
01531     // See: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/socket_options.asp
01532 
01533     // Tutorial on using Windows 98+ RSVP (QoS / Resource reSerVation Protocol)
01534     // http://msdn.microsoft.com/msdnmag/issues/01/04/qos/default.aspx
01535 
01536     // set TOS to low latency ( see manpages getsockopt(2), ip(7) and socket(7) )
01537     // maybe this works for Windows, too?
01538 #ifndef WIN32
01539     char tos = IPTOS_LOWDELAY;
01540 
01541     int ret = setsockopt( socket_, IPPROTO_IP, IP_TOS, &tos, sizeof(char) );
01542 
01543     // remove this error reporting some time later, the success is not critical
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     // unblock it
01554     bool _true = true;
01555     return ioctl (socket_, FIONBIO, reinterpret_cast<char *>(&_true)) == -1;
01556 }
01557 
01558 // archives the binding procedure
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         // byte-archive the address
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         // start archive block if archiving is active
01578         Archiver archive;
01579         if ( archive.Initialize( recordingSection ) )
01580         {
01581             archive.Archive( ret );
01582             archive.Archive( trueAddress );
01583             //Archive( archive, trueAddress );
01584 
01585             return true;
01586         }
01587 
01588         return false;
01589     }
01590 };
01591 
01592 // *******************************************************************************************
01593 // *
01594 // *    Bind
01595 // *
01596 // *******************************************************************************************
01601 // *******************************************************************************************
01602 
01603 int nSocket::Bind( nAddress const & addr )
01604 {
01605     tASSERT( IsOpen() );
01606 
01607     // copy address
01608     address_ = addr;
01609 
01610     int ret = 0;
01611 
01612     // see if the process was archived; if yes, return without action
01613     if ( !BindArchiver< tPlaybackBlock >::Archive( ret, trueAddress_ ) )
01614     {
01615         // just delegate
01616         ret = bind( socket_, addr, addr.GetAddressLength() );
01617 
01618         // read true address
01619         if ( 0 == ret )
01620             ANET_GetSocketAddr( socket_, trueAddress_ );
01621     }
01622 
01623     // record the bind
01624     BindArchiver< tRecordingBlock >::Archive( ret, trueAddress_ );
01625 
01626     if ( 0 == ret )
01627     {
01628         // report success
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         // con << "nSocket::Open: Failed to bind socket to " << addr.ToString() << ".\n";
01642 
01643         // close the socket and report an error
01644         ANET_CloseSocket( socket_ );
01645         socket_ = -1;
01646 
01647         // throw exception on fatal error
01648 #ifndef NOEXCEPT
01649         // name lookup failures won't be tolerated here
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 // *    Open
01668 // *
01669 // *******************************************************************************************
01674 // *******************************************************************************************
01675 
01676 int nSocket::Open( nAddress const & addr )
01677 {
01678     tASSERT( !IsOpen() );
01679 
01680     // create
01681     if ( Create() != 0 )
01682     {
01683         return -2;
01684     }
01685 
01686     // bind
01687     return Bind( addr );
01688 }
01689 
01690 // *******************************************************************************************
01691 // *
01692 // *    Open
01693 // *
01694 // *******************************************************************************************
01698 // *******************************************************************************************
01699 
01700 int nSocket::Open( void )
01701 {
01702     // bind to unspecific IP
01703     nAddress addr;
01704     return Open( addr );
01705 }
01706 
01707 // *******************************************************************************************
01708 // *
01709 // *    Open
01710 // *
01711 // *******************************************************************************************
01716 // *******************************************************************************************
01717 
01718 int nSocket::Open( int port )
01719 {
01720     // bind to unspecific IP, but specific port
01721     nAddress addr;
01722     addr.SetPort( port );
01723     return Open( addr );
01724 }
01725 
01726 // *******************************************************************************************
01727 // *
01728 // *    Open
01729 // *
01730 // *******************************************************************************************
01735 // *******************************************************************************************
01736 
01737 /*
01738 int nSocket::Open( const addrinfo & addr )
01739 {
01740 #ifdef HAVE_ADDRINFO
01741     tASSERT( !IsOpen() );
01742 
01743     // copy socket type data
01744     family_ = addr.ai_family;
01745     socktype_ = addr.ai_socktype;
01746     protocol_ = addr.ai_protocol;
01747 
01748     // open
01749     nAddress address;
01750     address.FromAddrInfo( addr );
01751     return Open( address );
01752 #endif
01753     return -1;
01754 }
01755 */
01756 
01757 // *******************************************************************************************
01758 // *
01759 // *   Open
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 // *    Close
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 // *    Reset
01806 // *
01807 // *******************************************************************************************
01811 // *******************************************************************************************
01812 
01813 void nSocket::Reset( void ) const
01814 {
01815     // logically, resetting is const. Physically not. const_cast is required.
01816     nSocket * reset = const_cast< nSocket * >( this );
01817 
01818     // remember the true address bound to
01819     nAddress trueAddress = trueAddress_;
01820 
01821     // try to reset a socket without disturbing the rest of the system
01822     reset->Close();
01823 
01824     // store old address
01825     nAddress oldAddress = address_;
01826 
01827     // first try: reopen with the same port as last time
01828     nAddress wishAddress = address_;
01829     wishAddress.SetPort( trueAddress.GetPort() );
01830     if ( 0 == reset->Open( wishAddress ) )
01831         return;
01832 
01833     // second try: reopen with the same premises
01834     if ( 0 == reset->Open( oldAddress ) )
01835         return;
01836 
01837     // last try: reopen with the last true address ( this is most probably wrong )
01838     reset->Open( trueAddress );
01839 }
01840 
01841 // *******************************************************************************************
01842 // *
01843 // *   IsOpen
01844 // *
01845 // *******************************************************************************************
01849 // *******************************************************************************************
01850 
01851 bool nSocket::IsOpen( void ) const
01852 {
01853     return socket_ >= 0;
01854 }
01855 
01856 // *******************************************************************************************
01857 // *
01858 // *    Connect
01859 // *
01860 // *******************************************************************************************
01865 // *******************************************************************************************
01866 
01867 int nSocket::Connect( const nAddress & addr )
01868 {
01869     // not implemented, does not make sense here
01870     return 0;
01871 }
01872 
01873 #ifdef DEBUG
01874 // reset sockets just for fun
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 // static char const * recordingSectionConnect = "CONNECT";
01886 
01887 // *******************************************************************************************
01888 // *
01889 // *    CheckNewConnection
01890 // *
01891 // *******************************************************************************************
01895 // *******************************************************************************************
01896 
01897 const nSocket * nSocket::CheckNewConnection( void ) const
01898 {
01899     tASSERT( IsOpen() );
01900 
01901     int available=-1;
01902 
01903     // see if the playback has anything to say
01904     //if ( tRecorder::Playback( recordingSectionConnect, available ) )
01905     //    return this;
01906 
01907     // always return this when recoring or playback are running
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     //    for ( SocketArray::iterator iter = sockets.begin(); iter != sockets.end(); ++iter )
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         // record result
01940         // tRecorder::Record( recordingSectionConnect, available );
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         // start archive block if archiving is active
01957         Archiver archive;
01958         if( archive.Initialize( recordingSectionRead ) )
01959         {
01960             // archive length of message
01961             archive.Archive( len );
01962             if ( len < 0 )
01963                 return true;
01964 
01965             // archive source address
01966             // BindArchiver< Archiver >::Archive( archive, addr );
01967             archive.Archive( addr );
01968 
01969             // archive data
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 // *    Read
01990 // *
01991 // *******************************************************************************************
01998 // *******************************************************************************************
01999 
02000 int nSocket::Read( int8 * buf, int len, nAddress & addr ) const
02001 {
02002     tASSERT( IsOpen() );
02003 
02004     // return value: real number of bytes read
02005     int ret = 0;
02006 
02007     static tReproducibleRandomizer randomizer;
02008 #ifdef DEBUG
02009     // pretend nothing was received
02010     if ( sn_simulateReceivePacketLoss > randomizer.Get() )
02011         return -1;
02012 #endif
02013 
02014     // check playback
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         // really receive
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     // write recording
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         // con << "Read " << ret << " bytes from socket " << GetSocket() << ".\n";
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 // *    Write
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     // check if return value was archived
02097     static char const * section = "SEND";
02098     if ( !tRecorder::Playback( section, ret ) )
02099     {
02100         static tReproducibleRandomizer randomizer;
02101 #ifdef DEBUG
02102         // pretend send was successful in packet loss simulation
02103         if ( sn_simulateSendPacketLoss > randomizer.Get() )
02104             ret = len;
02105         else
02106 #endif
02107         {
02108             // don't send if a playback is running
02109             if ( !tRecorder::IsPlayingBack() )
02110                 ret = sendto (socket_, buf, len, 0, addr, addrlen );
02111         }
02112     }
02113 
02114     if ( ret < 0 )
02115     {
02116         // log error
02117         tRecorder::Record( section, ret );
02118 
02119         // handle error
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 // *    Write
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     // delegate to low level write
02157     return Write( buf, len, addr, addr.GetAddressLength() );
02158 }
02159 
02160 // *******************************************************************************************
02161 // *
02162 // *    Broadcast
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         // make this socket broadcast capable
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     // prepare broadcasting address
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     // delegate to usual write function
02198     return Write ( buf, len, reinterpret_cast< sockaddr *>( &broadcastaddr ), sizeof( sockaddr_in ) );
02199 }
02200 
02201 // *******************************************************************************************
02202 // *
02203 // *    GetAddress
02204 // *
02205 // *******************************************************************************************
02209 // *******************************************************************************************
02210 
02211 const nAddress & nSocket::GetAddress( void ) const
02212 {
02213     return trueAddress_;
02214 }
02215 
02216 // *******************************************************************************************
02217 // *
02218 // *    GetAddress
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 // *    SetAddress
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 // *   MoveFrom
02257 // *
02258 // *******************************************************************************************
02262 // *******************************************************************************************
02263 
02264 void nSocket::MoveFrom( const nSocket & other )
02265 {
02266     // close this socket
02267     if ( IsOpen() )
02268         Close();
02269 
02270 
02271     // copy uncritical data
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     // move socket
02280     socket_ = other.socket_;
02281     const_cast< nSocket & >( other ).socket_ = -1;
02282 }
02283 
02284 // *******************************************************************************************
02285 // *
02286 // *   nSocket
02287 // *
02288 // *******************************************************************************************
02292 // *******************************************************************************************
02293 
02294 nSocket::nSocket( const nSocket & other )
02295 {
02296     socket_ = -1;
02297     MoveFrom( other );
02298 }
02299 
02300 // *******************************************************************************************
02301 // *
02302 // *   operator =
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 // *    nSocketListener
02326 // *
02327 // *******************************************************************************************
02330 // *******************************************************************************************
02331 
02332 nSocketListener::nSocketListener( void )
02333         : port_( 0 ), ipList_( "ANY" )
02334 {
02335 }
02336 
02337 // *******************************************************************************************
02338 // *
02339 // *    ~nSocketListener
02340 // *
02341 // *******************************************************************************************
02344 // *******************************************************************************************
02345 
02346 nSocketListener::~nSocketListener( void )
02347 {
02348     // not really required since the sockets close themselves automatically, but stop listening anyway
02349     Listen( false );
02350 }
02351 
02352 // *******************************************************************************************
02353 // *
02354 // *    Listen
02355 // *
02356 // *******************************************************************************************
02361 // *******************************************************************************************
02362 
02363 bool nSocketListener::Listen( bool state )
02364 {
02365     bool ret = false;
02366     try{
02367         // delegate to helper function
02368         ret = ANET_Listen( state, port_, ipList_, sockets_ );
02369     }
02370     catch ( OneSocketOpened const & )
02371     {
02372         // only one socket was upened on user request; this counts as succes
02373         ret = true;
02374     }
02375 
02376     // close sockets if opening failed
02377     if ( state && !ret )
02378         Listen( false );
02379 
02380     // return result
02381     return ret;
02382 }
02383 
02384 // *******************************************************************************************
02385 // *
02386 // *    begin
02387 // *
02388 // *******************************************************************************************
02392 // *******************************************************************************************
02393 
02394 nSocketListener::iterator nSocketListener::begin( void ) const
02395 {
02396     return sockets_.begin();
02397 }
02398 
02399 // *******************************************************************************************
02400 // *
02401 // *    end
02402 // *
02403 // *******************************************************************************************
02407 // *******************************************************************************************
02408 
02409 nSocketListener::iterator nSocketListener::end( void ) const
02410 {
02411     return sockets_.end();
02412 }
02413 
02414 // *******************************************************************************************
02415 // *
02416 // *   GetPort
02417 // *
02418 // *******************************************************************************************
02422 // *******************************************************************************************
02423 
02424 unsigned int nSocketListener::GetPort( void ) const
02425 {
02426     return this->port_;
02427 }
02428 
02429 // *******************************************************************************************
02430 // *
02431 // *   GetPort
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 // *   SetPort
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 // *   GetIpList
02468 // *
02469 // *******************************************************************************************
02473 // *******************************************************************************************
02474 
02475 tString const & nSocketListener::GetIpList( void ) const
02476 {
02477     return this->ipList_;
02478 }
02479 
02480 // *******************************************************************************************
02481 // *
02482 // *   GetIpList
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 // *   SetIpList
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 // *    nBasicNetworkSystem
02526 // *
02527 // *******************************************************************************************
02530 // *******************************************************************************************
02531 
02532 nBasicNetworkSystem::nBasicNetworkSystem( void )
02533 {
02534     // nothing to do
02535 }
02536 
02537 // *******************************************************************************************
02538 // *
02539 // *    ~nBasicNetworkSystem
02540 // *
02541 // *******************************************************************************************
02544 // *******************************************************************************************
02545 
02546 nBasicNetworkSystem::~nBasicNetworkSystem( void )
02547 {
02548     // shut down the system
02549     Shutdown();
02550 }
02551 
02552 // *******************************************************************************************
02553 // *
02554 // *    Init
02555 // *
02556 // *******************************************************************************************
02560 // *******************************************************************************************
02561 
02562 nSocket * nBasicNetworkSystem::Init()
02563 {
02564     // test if network was already initialized
02565     if ( controlSocket_.IsOpen() )
02566         return &controlSocket_;
02567 
02568     // initialize networking at OS level
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     //struct hostent *local;
02577     //char      buff[MAXHOSTNAMELEN]="\0";
02578     //struct sockaddr addr;
02579     //char *colon;
02580 
02581     /* not for armagetron
02582        if (COM_CheckParm ("-noudp"))
02583        return -1;
02584     */
02585 
02586     // determine my name & address
02587     //int myAddr = 0;
02588     //int hostnameres = gethostname(buff, MAXHOSTNAMELEN);
02589     //if ( 0 == hostnameres )
02590     //{
02591     //   local = gethostbyname(buff);
02592     //   if ( local )
02593     //   {
02594     //        myAddr = *reinterpret_cast<int *>(local->h_addr_list[0]);
02595     //   }
02596     //   else
02597     //    {
02598     //        Con_Printf ("ANET_Init: Unable to determine IP adress.\n");
02599     //    }
02600     //}
02601     //else
02602     //{
02603     //    Con_Printf ("ANET_Init: Unable to determine hostname.\n");
02604     // }
02605 
02606     // fallback: use loopback
02607     //if ( myAddr == 0 )
02608     //{
02609     //    myAddr = inet_addr("127.0.0.1");
02610     //}
02611 
02612     //tString hostname;
02613 
02614     // if the armagetron hostname isn't set, set it to the clamped machine name
02615     //if (strcmp(hostname, "UNNAMED") == 0 && buff[0] && hostnameres == 0 )
02616     //{
02617     //    buff[15] = 0;
02618     //    hostname=buff;
02619     //}
02620 
02621     //ANET_GetSocketAddr (controlSocket_, &addr);
02622     //my_tcpip_address=ANET_AddrToString (&addr);
02623     //colon = strrchr (my_tcpip_address, ':');
02624     //if (colon)
02625     //    *colon = 0;
02626 
02627     //  Con_Printf("UDP Initialized\n");
02628     //tcpipAvailable = true;
02629 
02630 }
02631 
02632 // *******************************************************************************
02633 // *
02634 // *    Select
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; // set of sockets to wathc
02656         struct timeval tv; // time value to pass to select()
02657 
02658         FD_ZERO( &rfds );
02659 
02660         // watch the control socket
02661         FD_SET( controlSocket_.GetSocket(), &rfds );
02662         // con << "Watching " << controlSocket_.GetSocket();
02663 
02664         int max = controlSocket_.GetSocket();
02665 
02666         // watch listening sockets
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             // con << ", " << (*iter).GetSocket();
02673         }
02674 
02675         // set time
02676         tv.tv_sec  = static_cast< long int >( dt );
02677         tv.tv_usec = static_cast< long int >( (dt-tv.tv_sec)*1000000 );
02678 
02679         // delegate to system select
02680         retval = select(max+1, &rfds, NULL, NULL, &tv);
02681     }
02682     tRecorder::Record( section, retval );
02683 
02684     // con << " : " << retval << "\n";
02685 
02686     // return result
02687     return ( retval > 0 );
02688 }
02689 
02690 // *******************************************************************************************
02691 // *
02692 // *    Shutdown
02693 // *
02694 // *******************************************************************************************
02697 // *******************************************************************************************
02698 
02699 void nBasicNetworkSystem::Shutdown()
02700 {
02701     // stop listening
02702     listener_.Listen(false);
02703 
02704     // close the control socket
02705     controlSocket_.Close();
02706 }
02707 
02708 
02709 // *******************************************************************************************
02710 // *
02711 // *    PermanentError
02712 // *
02713 // *******************************************************************************************
02716 // *******************************************************************************************
02717 
02718 nSocket::PermanentError::PermanentError( void )
02719         : description_( "No details available" )
02720 {
02721 }
02722 
02723 // *******************************************************************************************
02724 // *
02725 // *    PermanentError
02726 // *
02727 // *******************************************************************************************
02731 // *******************************************************************************************
02732 
02733 nSocket::PermanentError::PermanentError( const tString & details )
02734         : description_( details )
02735 {
02736 }
02737 
02738 // *******************************************************************************************
02739 // *
02740 // *    ~PermanentError
02741 // *
02742 // *******************************************************************************************
02745 // *******************************************************************************************
02746 
02747 nSocket::PermanentError::~PermanentError( void )
02748 {
02749 }
02750 
02751 // *******************************************************************************************
02752 // *
02753 // *    DoGetName
02754 // *
02755 // *******************************************************************************************
02759 // *******************************************************************************************
02760 
02761 tString nSocket::PermanentError::DoGetName( void ) const
02762 {
02763     return tString( "Permanent network error" );
02764 }
02765 
02766 // *******************************************************************************************
02767 // *
02768 // *    DoGetDescription
02769 // *
02770 // *******************************************************************************************
02774 // *******************************************************************************************
02775 
02776 tString nSocket::PermanentError::DoGetDescription( void ) const
02777 {
02778     return description_;
02779 }
02780 
02781 

Generated on Sat Mar 15 22:55:51 2008 for Armagetron Advanced by  doxygen 1.5.4