LCOV - code coverage report
Current view: top level - src/foreign/tcpip - socket.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 81.0 % 174 141
Test Date: 2024-11-20 15:55:46 Functions: 81.0 % 21 17

            Line data    Source code
       1              : /************************************************************************
       2              :  ** This file is part of the network simulator Shawn.                  **
       3              :  ** Copyright (C) 2004-2007 by the SwarmNet (www.swarmnet.de) project  **
       4              :  ** Shawn is free software; you can redistribute it and/or modify it   **
       5              :  ** under the terms of the BSD License. Refer to the shawn-licence.txt **
       6              :  ** file in the root of the Shawn source tree for further details.     **
       7              :  ************************************************************************/
       8              : 
       9              : #ifdef SHAWN
      10              :         #include <apps/tcpip/socket.h>
      11              :         #include <sys/simulation/simulation_controller.h>
      12              : #else
      13              :         #include "socket.h"
      14              : #endif
      15              : 
      16              : #ifdef BUILD_TCPIP
      17              : 
      18              : 
      19              : #ifndef WIN32
      20              :         #include <sys/types.h>
      21              :         #include <sys/socket.h>
      22              :         #include <netinet/in.h>
      23              :         #include <netinet/tcp.h>
      24              :         #include <arpa/inet.h>
      25              :         #include <netdb.h>
      26              :         #include <errno.h>
      27              :         #include <fcntl.h>
      28              :         #include <unistd.h>
      29              : #else
      30              :         #ifdef ERROR
      31              :                 #undef ERROR
      32              :         #endif
      33              : 
      34              :         #include <winsock2.h>
      35              :         #include <ws2tcpip.h>
      36              : 
      37              :         #ifndef vsnprintf
      38              :                 #define vsnprintf _vsnprintf
      39              :         #endif
      40              : 
      41              : #endif
      42              : 
      43              : #include <cstdio>
      44              : #include <cstring>
      45              : #include <cstdarg>
      46              : #include <cassert>
      47              : #include <string>
      48              : #include <vector>
      49              : #include <string>
      50              : #include <algorithm>
      51              : #include <string.h>
      52              : 
      53              : 
      54              : #ifdef SHAWN
      55              :     extern "C" void init_tcpip( shawn::SimulationController& sc )
      56              :     {
      57              :             // std::cout << "tcpip init" << std::endl;
      58              :     }
      59              : #endif
      60              : 
      61              : namespace tcpip
      62              : {
      63              :         const int Socket::lengthLen = 4;
      64              : 
      65              : #ifdef WIN32
      66              :         bool Socket::init_windows_sockets_ = true;
      67              :         bool Socket::windows_sockets_initialized_ = false;
      68              :         int Socket::instance_count_ = 0;
      69              : #endif
      70              : 
      71              :         // ----------------------------------------------------------------------
      72         1860 :         Socket::
      73         1860 :                 Socket(std::string host, int port)
      74         1860 :                 : host_( host ),
      75         1860 :                 port_( port ),
      76         1860 :                 socket_(-1),
      77         1860 :                 server_socket_(-1),
      78         1860 :                 blocking_(true),
      79         1860 :                 verbose_(false)
      80              :         {
      81         1860 :                 init();
      82         1860 :         }
      83              : 
      84              :         // ----------------------------------------------------------------------
      85         5683 :         Socket::
      86         5683 :                 Socket(int port)
      87         5683 :                 : host_(""),
      88         5683 :                 port_( port ),
      89         5683 :                 socket_(-1),
      90         5683 :                 server_socket_(-1),
      91         5683 :                 blocking_(true),
      92         5683 :                 verbose_(false)
      93              :         {
      94         5683 :                 init();
      95         5683 :         }
      96              : 
      97              :         // ----------------------------------------------------------------------
      98              :         void
      99         7543 :                 Socket::
     100              :                 init()
     101              :         {
     102              : #ifdef WIN32
     103              :                 instance_count_++;
     104              : 
     105              :                 if( init_windows_sockets_ && !windows_sockets_initialized_ )
     106              :                 {
     107              :                         WSAData wsaData;
     108              :                         if( WSAStartup(MAKEWORD(1, 1), &wsaData) != 0 )
     109              :                                 BailOnSocketError("Unable to init WSA Sockets");
     110              :                         windows_sockets_initialized_ = true;
     111              :                 }
     112              : #endif
     113         7543 :         }
     114              : 
     115              : 
     116              :     int
     117          569 :         Socket::
     118              :         getFreeSocketPort()
     119              :     {
     120          569 :         Socket dummy(0); // just to trigger initialization on Windows and cleanup on end
     121              :         // Create socket to find a random free port that can be handed to the app
     122          569 :         int sock = static_cast<int>(socket( AF_INET, SOCK_STREAM, 0 ));
     123              :         struct sockaddr_in self;
     124              :         memset(&self, 0, sizeof(self));
     125          569 :         self.sin_family = AF_INET;
     126              :         self.sin_port = htons(0);
     127              :         self.sin_addr.s_addr = htonl(INADDR_ANY);
     128              : 
     129          569 :         socklen_t address_len = sizeof(self);
     130              :         // bind with port==0 assigns free port
     131          569 :         if ( bind(sock, (struct sockaddr*) &self, address_len) < 0)
     132            0 :             BailOnSocketError("tcpip::Socket::getFreeSocketPort() Unable to bind socket");
     133              :         // get the assigned port with getsockname
     134          569 :         if ( getsockname(sock, (struct sockaddr*) &self, &address_len) < 0)
     135            0 :             BailOnSocketError("tcpip::Socket::getFreeSocketPort() Unable to get socket name");
     136          569 :         const int port = ntohs(self.sin_port);
     137              : #ifdef WIN32
     138              :         ::closesocket( sock );
     139              : #else
     140          569 :         ::close( sock );
     141              : #endif
     142          569 :         return port;
     143          569 :     }
     144              : 
     145              : 
     146              :         // ----------------------------------------------------------------------
     147         7530 :         Socket::
     148              :                 ~Socket()
     149              :         {
     150              :                 // Close first an existing client connection ...
     151         7530 :                 close();
     152              : #ifdef WIN32
     153              :                 instance_count_--;
     154              : #endif
     155              : 
     156              :                 // ... then the server socket
     157         7530 :                 if( server_socket_ >= 0 )
     158              :                 {
     159              : #ifdef WIN32
     160              :                         ::closesocket( server_socket_ );
     161              : #else
     162         2476 :                         ::close( server_socket_ );
     163              : #endif
     164         2476 :                         server_socket_ = -1;
     165              :                 }
     166              : 
     167              : #ifdef WIN32
     168              :                 if( server_socket_ == -1 && socket_ == -1
     169              :                     && init_windows_sockets_ && instance_count_ == 0 )
     170              :                                 WSACleanup();
     171              :                 windows_sockets_initialized_ = false;
     172              : #endif
     173         7530 :         }
     174              : 
     175              :         // ----------------------------------------------------------------------
     176              :         void
     177         1375 :                 Socket::
     178              :                 BailOnSocketError( std::string context)
     179              :         {
     180              : #ifdef WIN32
     181              :                 int e = WSAGetLastError();
     182              :                 std::string msg = GetWinsockErrorString( e );
     183              : #else
     184         1375 :                 std::string msg = strerror( errno );
     185              : #endif
     186         2750 :                 throw SocketException( context + ": " + msg );
     187              :         }
     188              : 
     189              :         // ----------------------------------------------------------------------
     190              :         int
     191            0 :                 Socket::
     192              :                 port()
     193              :         {
     194            0 :                 return port_;
     195              :         }
     196              : 
     197              : 
     198              :         // ----------------------------------------------------------------------
     199              : #ifdef _MSC_VER
     200              : #pragma warning(push)
     201              : /* Disable warning about while (0, 0) in the expansion of FD_SET, see https://developercommunity.visualstudio.com/t/fd-clr-and-fd-set-macros-generate-warning-c4548/172702 */
     202              : #pragma warning(disable: 4548)
     203              : #endif
     204              :         bool
     205            0 :                 Socket::
     206              :                 datawaiting(int sock)
     207              :                 const
     208              :         {
     209              :                 fd_set fds;
     210            0 :                 FD_ZERO( &fds );
     211            0 :                 FD_SET( (unsigned int)sock, &fds );
     212              : 
     213              :                 struct timeval tv;
     214            0 :                 tv.tv_sec = 0;
     215            0 :                 tv.tv_usec = 0;
     216              : 
     217            0 :                 int r = select( sock+1, &fds, nullptr, nullptr, &tv);
     218              : 
     219            0 :                 if (r < 0)
     220            0 :                         BailOnSocketError("tcpip::Socket::datawaiting @ select");
     221              : 
     222            0 :                 if( FD_ISSET( sock, &fds ) )
     223              :                         return true;
     224              :                 else
     225            0 :                         return false;
     226              :         }
     227              : #ifdef _MSC_VER
     228              : #pragma warning(pop)
     229              : #endif
     230              : 
     231              :         // ----------------------------------------------------------------------
     232              :         Socket*
     233         2642 :                 Socket::
     234              :                 accept(const bool create)
     235              :         {
     236         2642 :                 if( socket_ >= 0 )
     237              :                         return nullptr;
     238              : 
     239              :                 struct sockaddr_in client_addr;
     240              : #ifdef WIN32
     241              :                 int addrlen = sizeof(client_addr);
     242              : #else
     243         2642 :                 socklen_t addrlen = sizeof(client_addr);
     244              : #endif
     245              : 
     246         2642 :                 if( server_socket_ < 0 )
     247              :                 {
     248              :                         struct sockaddr_in self;
     249              : 
     250              :                         //Create the server socket
     251         2476 :                         server_socket_ = static_cast<int>(socket( AF_INET, SOCK_STREAM, 0 ));
     252         2476 :                         if( server_socket_ < 0 )
     253            0 :                                 BailOnSocketError("tcpip::Socket::accept() @ socket");
     254              : 
     255              :                         //"Address already in use" error protection
     256              :                         {
     257              : 
     258              :                                 #ifdef WIN32
     259              :                                         //setsockopt(server_socket_, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuseaddr, sizeof(reuseaddr));
     260              :                                         // No address reuse in Windows!!!
     261              :                                 #else
     262         2476 :                                 int reuseaddr = 1;
     263         2476 :                                         setsockopt(server_socket_, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr));
     264              :                                 #endif
     265              :                         }
     266              : 
     267              :                         // Initialize address/port structure
     268              :                         memset(&self, 0, sizeof(self));
     269         2476 :                         self.sin_family = AF_INET;
     270         2476 :                         self.sin_port = htons((unsigned short)port_);
     271              :                         self.sin_addr.s_addr = htonl(INADDR_ANY);
     272              : 
     273              :                         // Assign a port number to the socket
     274         2476 :                         if ( bind(server_socket_, (struct sockaddr*)&self, sizeof(self)) != 0 )
     275            4 :                                 BailOnSocketError("tcpip::Socket::accept() Unable to create listening socket");
     276              : 
     277              : 
     278              :                         // Make it a "listening socket"
     279         2472 :                         if ( listen(server_socket_, 10) == -1 )
     280            0 :                                 BailOnSocketError("tcpip::Socket::accept() Unable to listen on server socket");
     281              : 
     282              :                         // Make the newly created socket blocking or not
     283         2472 :                         set_blocking(blocking_);
     284              :                 }
     285              : 
     286         2638 :                 socket_ = static_cast<int>(::accept(server_socket_, (struct sockaddr*)&client_addr, &addrlen));
     287              : 
     288         2638 :                 if( socket_ >= 0 )
     289              :                 {
     290         2638 :                         int x = 1;
     291         2638 :                         setsockopt(socket_, IPPROTO_TCP, TCP_NODELAY, (const char*)&x, sizeof(x));
     292         2638 :             if (create) {
     293         2638 :                 Socket* result = new Socket(0);
     294         2638 :                 result->socket_ = socket_;
     295         2638 :                 socket_ = -1;
     296         2638 :                 return result;
     297              :             }
     298              :                 }
     299              :         return nullptr;
     300              :         }
     301              : 
     302              :         // ----------------------------------------------------------------------
     303              :         void
     304         2472 :                 Socket::
     305              :                 set_blocking(bool blocking)
     306              :         {
     307         2472 :                 blocking_ = blocking;
     308              : 
     309         2472 :                 if( server_socket_ > 0 )
     310              :                 {
     311              : #ifdef WIN32
     312              :                         ULONG NonBlock = blocking_ ? 0 : 1;
     313              :                         if (ioctlsocket(server_socket_, FIONBIO, &NonBlock) == SOCKET_ERROR)
     314              :                                 BailOnSocketError("tcpip::Socket::set_blocking() Unable to initialize non blocking I/O");
     315              : #else
     316         2472 :                         long arg = fcntl(server_socket_, F_GETFL, NULL);
     317         2472 :                         if (blocking_)
     318              :                         {
     319         2472 :                                 arg &= ~O_NONBLOCK;
     320              :                         } else {
     321            0 :                                 arg |= O_NONBLOCK;
     322              :                         }
     323         2472 :                         fcntl(server_socket_, F_SETFL, arg);
     324              : #endif
     325              :                 }
     326              : 
     327         2472 :         }
     328              : 
     329              :         // ----------------------------------------------------------------------
     330              :         void
     331         2616 :                 Socket::
     332              :                 connect()
     333              :         {
     334              :                 struct addrinfo* servinfo; // will point to the results
     335              :                 struct addrinfo hints;
     336              :                 memset(&hints, 0, sizeof hints); // make sure the struct is empty
     337              :                 hints.ai_family = AF_UNSPEC; // IP4 and IP6 are possible
     338         2616 :                 hints.ai_socktype = SOCK_STREAM; // TCP stream sockets
     339         2616 :                 hints.ai_flags = AI_PASSIVE; // fill in my IP for me
     340              : 
     341         5232 :                 if (getaddrinfo(host_.c_str(), std::to_string(port_).c_str(), &hints, &servinfo) != 0) {
     342            0 :                         BailOnSocketError("tcpip::Socket::connect() @ Invalid network address");
     343              :                 }
     344         2616 :                 socket_ = -1;
     345         3983 :                 for (struct addrinfo* p = servinfo; p != nullptr; p = p->ai_next) {
     346         2616 :                         socket_ = (int)socket(p->ai_family, p->ai_socktype, p->ai_protocol);
     347         2616 :                         if (socket_ >= 0) {
     348         2616 :                                 if (::connect(socket_, p->ai_addr, (int)p->ai_addrlen) == 0) {
     349         1249 :                                         int x = 1;
     350         1249 :                                         setsockopt(socket_, IPPROTO_TCP, TCP_NODELAY, (const char*)&x, sizeof(x));
     351              :                                         break;
     352              :                                 }
     353         1367 :                                 close();
     354              :                         }
     355              :                 }
     356         2616 :                 freeaddrinfo(servinfo); // free the linked list
     357         2616 :                 if (socket_ < 0) {
     358         1367 :                         BailOnSocketError("tcpip::Socket::connect() @ socket");
     359              :                 }
     360         1249 :         }
     361              : 
     362              :         // ----------------------------------------------------------------------
     363              :         void
     364        10899 :                 Socket::
     365              :                 close()
     366              :         {
     367              :                 // Close client-connection
     368        10899 :                 if( socket_ >= 0 )
     369              :                 {
     370              : #ifdef WIN32
     371              :                         ::closesocket( socket_ );
     372              : #else
     373         5241 :                         ::close( socket_ );
     374              : #endif
     375              : 
     376         5241 :                         socket_ = -1;
     377              :                 }
     378        10899 :         }
     379              : 
     380              :         // ----------------------------------------------------------------------
     381              :         void
     382     18340344 :                 Socket::
     383              :                 send( const std::vector<unsigned char> &buffer)
     384              :         {
     385     18340344 :                 if( socket_ < 0 )
     386              :                         return;
     387              : 
     388     18340344 :                 printBufferOnVerbose(buffer, "Send");
     389              : 
     390              :                 size_t numbytes = buffer.size();
     391              :                 unsigned char const *bufPtr = &buffer[0];
     392     36680686 :                 while( numbytes > 0 )
     393              :                 {
     394              : #ifdef WIN32
     395              :                         int bytesSent = ::send( socket_, (const char*)bufPtr, static_cast<int>(numbytes), 0 );
     396              : #else
     397     18340344 :                         int bytesSent = ::send( socket_, bufPtr, numbytes, 0 );
     398              : #endif
     399     18340344 :                         if( bytesSent < 0 )
     400            2 :                                 BailOnSocketError( "send failed" );
     401              : 
     402     18340342 :                         numbytes -= bytesSent;
     403     18340342 :                         bufPtr += bytesSent;
     404              :                 }
     405              :         }
     406              : 
     407              : 
     408              : 
     409              :         // ----------------------------------------------------------------------
     410              : 
     411              :         void
     412     18340296 :                 Socket::
     413              :                 sendExact( const Storage &b)
     414              :         {
     415     18340296 :                 int length = static_cast<int>(b.size());
     416     18340296 :                 Storage length_storage;
     417     18340296 :                 length_storage.writeInt(lengthLen + length);
     418              : 
     419              :                 // Sending length_storage and b independently would probably be possible and
     420              :                 // avoid some copying here, but both parts would have to go through the
     421              :                 // TCP/IP stack on their own which probably would cost more performance.
     422              :                 std::vector<unsigned char> msg;
     423     18340296 :                 msg.insert(msg.end(), length_storage.begin(), length_storage.end());
     424     18340296 :                 msg.insert(msg.end(), b.begin(), b.end());
     425     18340296 :                 send(msg);
     426     18340296 :         }
     427              : 
     428              : 
     429              :         // ----------------------------------------------------------------------
     430              :         size_t
     431     36680626 :                 Socket::
     432              :                 recvAndCheck(unsigned char * const buffer, std::size_t len)
     433              :                 const
     434              :         {
     435              : #ifdef WIN32
     436              :                 const int bytesReceived = recv( socket_, (char*)buffer, static_cast<int>(len), 0 );
     437              : #else
     438     36680626 :                 const int bytesReceived = static_cast<int>(recv( socket_, buffer, len, 0 ));
     439              : #endif
     440     36680626 :                 if( bytesReceived == 0 )
     441           48 :                         throw SocketException( "tcpip::Socket::recvAndCheck @ recv: peer shutdown" );
     442     36680602 :                 if( bytesReceived < 0 )
     443            2 :                         BailOnSocketError( "tcpip::Socket::recvAndCheck @ recv" );
     444              : 
     445     36680600 :                 return static_cast<size_t>(bytesReceived);
     446              :         }
     447              : 
     448              : 
     449              :         // ----------------------------------------------------------------------
     450              :         void
     451     36680626 :                 Socket::
     452              :                 receiveComplete(unsigned char * buffer, size_t len)
     453              :                 const
     454              :         {
     455     73361226 :                 while (len > 0)
     456              :                 {
     457     36680626 :                         const size_t bytesReceived = recvAndCheck(buffer, len);
     458     36680600 :                         len -= bytesReceived;
     459     36680600 :                         buffer += bytesReceived;
     460              :                 }
     461     36680600 :         }
     462              : 
     463              : 
     464              :         // ----------------------------------------------------------------------
     465              :         void
     466     36680644 :                 Socket::
     467              :                 printBufferOnVerbose(const std::vector<unsigned char> buffer, const std::string &label)
     468              :                 const
     469              :         {
     470     36680644 :                 if (verbose_)
     471              :                 {
     472            0 :                         std::cerr << label << " " << buffer.size() <<  " bytes via tcpip::Socket: [";
     473              :                         // cache end iterator for performance
     474              :                         const std::vector<unsigned char>::const_iterator end = buffer.end();
     475            0 :                         for (std::vector<unsigned char>::const_iterator it = buffer.begin(); end != it; ++it)
     476            0 :                                 std::cerr << " " << static_cast<int>(*it) << " ";
     477              :                         std::cerr << "]" << std::endl;
     478              :                 }
     479     36680644 :         }
     480              : 
     481              : 
     482              :         // ----------------------------------------------------------------------
     483              :         std::vector<unsigned char>
     484            0 :                 Socket::
     485              :                 receive(int bufSize)
     486              :         {
     487              :                 std::vector<unsigned char> buffer;
     488              : 
     489            0 :                 if( socket_ < 0 )
     490            0 :                         connect();
     491              : 
     492            0 :                 if( !datawaiting( socket_) )
     493              :                         return buffer;
     494              : 
     495            0 :                 buffer.resize(bufSize);
     496            0 :                 const size_t bytesReceived = recvAndCheck(&buffer[0], bufSize);
     497              : 
     498            0 :                 buffer.resize(bytesReceived);
     499              : 
     500            0 :                 printBufferOnVerbose(buffer, "Rcvd");
     501              : 
     502            0 :                 return buffer;
     503            0 :         }
     504              : 
     505              :         // ----------------------------------------------------------------------
     506              : 
     507              : 
     508              :         bool
     509     18340326 :                 Socket::
     510              :                 receiveExact( Storage &msg )
     511              :         {
     512              :                 // buffer for received bytes
     513              :                 // According to the C++ standard elements of a std::vector are stored
     514              :                 // contiguously. Explicitly &buffer[n] == &buffer[0] + n for 0 <= n < buffer.size().
     515     18340326 :                 std::vector<unsigned char> buffer(lengthLen);
     516              : 
     517              :                 // receive length of TraCI message
     518     18340326 :                 receiveComplete(&buffer[0], lengthLen);
     519     18340300 :                 Storage length_storage(&buffer[0], lengthLen);
     520     18340300 :                 const int totalLen = length_storage.readInt();
     521              :                 assert(totalLen > lengthLen);
     522              : 
     523              :                 // extent buffer
     524     18340300 :                 buffer.resize(totalLen);
     525              : 
     526              :                 // receive remaining TraCI message
     527     18340300 :                 receiveComplete(&buffer[lengthLen], totalLen - lengthLen);
     528              : 
     529              :                 // copy message content into passed Storage
     530     18340300 :                 msg.reset();
     531     18340300 :                 msg.writePacket(&buffer[lengthLen], totalLen - lengthLen);
     532              : 
     533     18340300 :                 printBufferOnVerbose(buffer, "Rcvd Storage with");
     534              : 
     535     18340300 :                 return true;
     536     18340326 :         }
     537              : 
     538              : 
     539              :         // ----------------------------------------------------------------------
     540              :         bool
     541       646277 :                 Socket::
     542              :                 has_client_connection()
     543              :                 const
     544              :         {
     545       646277 :                 return socket_ >= 0;
     546              :         }
     547              : 
     548              :         // ----------------------------------------------------------------------
     549              :         bool
     550            0 :                 Socket::
     551              :                 is_blocking()
     552              :         {
     553            0 :                 return blocking_;
     554              :         }
     555              : 
     556              : 
     557              : #ifdef WIN32
     558              :         // ----------------------------------------------------------------------
     559              :         std::string
     560              :                 Socket::
     561              :                 GetWinsockErrorString(int err)
     562              :         {
     563              : 
     564              :                 switch( err)
     565              :                 {
     566              :                 case 0:                                 return "No error";
     567              :                 case WSAEINTR:                  return "Interrupted system call";
     568              :                 case WSAEBADF:                  return "Bad file number";
     569              :                 case WSAEACCES:                 return "Permission denied";
     570              :                 case WSAEFAULT:                 return "Bad address";
     571              :                 case WSAEINVAL:                 return "Invalid argument";
     572              :                 case WSAEMFILE:                 return "Too many open sockets";
     573              :                 case WSAEWOULDBLOCK:    return "Operation would block";
     574              :                 case WSAEINPROGRESS:    return "Operation now in progress";
     575              :                 case WSAEALREADY:               return "Operation already in progress";
     576              :                 case WSAENOTSOCK:               return "Socket operation on non-socket";
     577              :                 case WSAEDESTADDRREQ:   return "Destination address required";
     578              :                 case WSAEMSGSIZE:               return "Message too long";
     579              :                 case WSAEPROTOTYPE:             return "Protocol wrong type for socket";
     580              :                 case WSAENOPROTOOPT:    return "Bad protocol option";
     581              :                 case WSAEPROTONOSUPPORT:        return "Protocol not supported";
     582              :                 case WSAESOCKTNOSUPPORT:        return "Socket type not supported";
     583              :                 case WSAEOPNOTSUPP:             return "Operation not supported on socket";
     584              :                 case WSAEPFNOSUPPORT:   return "Protocol family not supported";
     585              :                 case WSAEAFNOSUPPORT:   return "Address family not supported";
     586              :                 case WSAEADDRINUSE:             return "Address already in use";
     587              :                 case WSAEADDRNOTAVAIL:  return "Can't assign requested address";
     588              :                 case WSAENETDOWN:               return "Network is down";
     589              :                 case WSAENETUNREACH:    return "Network is unreachable";
     590              :                 case WSAENETRESET:              return "Net Socket reset";
     591              :                 case WSAECONNABORTED:   return "Software caused tcpip::Socket abort";
     592              :                 case WSAECONNRESET:             return "Socket reset by peer";
     593              :                 case WSAENOBUFS:                return "No buffer space available";
     594              :                 case WSAEISCONN:                return "Socket is already connected";
     595              :                 case WSAENOTCONN:               return "Socket is not connected";
     596              :                 case WSAESHUTDOWN:              return "Can't send after socket shutdown";
     597              :                 case WSAETOOMANYREFS:   return "Too many references, can't splice";
     598              :                 case WSAETIMEDOUT:              return "Socket timed out";
     599              :                 case WSAECONNREFUSED:   return "Socket refused";
     600              :                 case WSAELOOP:                  return "Too many levels of symbolic links";
     601              :                 case WSAENAMETOOLONG:   return "File name too long";
     602              :                 case WSAEHOSTDOWN:              return "Host is down";
     603              :                 case WSAEHOSTUNREACH:   return "No route to host";
     604              :                 case WSAENOTEMPTY:              return "Directory not empty";
     605              :                 case WSAEPROCLIM:               return "Too many processes";
     606              :                 case WSAEUSERS:                 return "Too many users";
     607              :                 case WSAEDQUOT:                 return "Disc quota exceeded";
     608              :                 case WSAESTALE:                 return "Stale NFS file handle";
     609              :                 case WSAEREMOTE:                return "Too many levels of remote in path";
     610              :                 case WSASYSNOTREADY:    return "Network system is unavailable";
     611              :                 case WSAVERNOTSUPPORTED:        return "Winsock version out of range";
     612              :                 case WSANOTINITIALISED: return "WSAStartup not yet called";
     613              :                 case WSAEDISCON:                return "Graceful shutdown in progress";
     614              :                 case WSAHOST_NOT_FOUND: return "Host not found";
     615              :                 case WSANO_DATA:                return "No host data of that type was found";
     616              :                 }
     617              : 
     618              :                 return "unknown";
     619              :         }
     620              : 
     621              : #endif // WIN32
     622              : 
     623              : } // namespace tcpip
     624              : 
     625              : #endif // BUILD_TCPIP
     626              : 
     627              : /*-----------------------------------------------------------------------
     628              : * Source  $Source: $
     629              : * Version $Revision: 645 $
     630              : * Date    $Date: 2012-04-27 14:03:33 +0200 (Fri, 27 Apr 2012) $
     631              : *-----------------------------------------------------------------------
     632              : * $Log: $
     633              : *-----------------------------------------------------------------------*/
        

Generated by: LCOV version 2.0-1