reSIProcate/rutil  9694
Socket.hxx
Go to the documentation of this file.
00001 #if !defined(RESIP_SOCKET_HXX)
00002 #define RESIP_SOCKET_HXX  
00003 
00004 #include <cassert>
00005 #include <errno.h>
00006 #include <algorithm>
00007 
00008 #ifdef WIN32
00009 #include <winsock2.h>
00010 #include <stdlib.h>
00011 #include <io.h>
00012 #include <WS2TCPIP.H>
00013 #endif
00014 
00015 #include "compat.hxx"
00016 #include "rutil/TransportType.hxx"
00017 
00023 #ifdef WIN32
00024 
00031 #if defined(_MSC_VER) && (_MSC_VER >= 1600)
00032 #pragma warning (push)
00033 #pragma warning (disable: 4005 )
00034 #endif
00035 typedef int socklen_t;
00036 
00037 //this list taken from <winsock2.h>, see #if 0 removed block.
00038 #define EWOULDBLOCK             WSAEWOULDBLOCK
00039 #define EINPROGRESS             WSAEINPROGRESS
00040 #define EALREADY                WSAEALREADY
00041 #define ENOTSOCK                WSAENOTSOCK
00042 #define EDESTADDRREQ            WSAEDESTADDRREQ
00043 #define EMSGSIZE                WSAEMSGSIZE
00044 #define EPROTOTYPE              WSAEPROTOTYPE
00045 #define ENOPROTOOPT             WSAENOPROTOOPT
00046 #define EPROTONOSUPPORT         WSAEPROTONOSUPPORT
00047 #define ESOCKTNOSUPPORT         WSAESOCKTNOSUPPORT
00048 #define EOPNOTSUPP              WSAEOPNOTSUPP
00049 #define EPFNOSUPPORT            WSAEPFNOSUPPORT
00050 #define EAFNOSUPPORT            WSAEAFNOSUPPORT
00051 #define EADDRINUSE              WSAEADDRINUSE
00052 #define EADDRNOTAVAIL           WSAEADDRNOTAVAIL
00053 #define ENETDOWN                WSAENETDOWN
00054 #define ENETUNREACH             WSAENETUNREACH
00055 #define ENETRESET               WSAENETRESET
00056 #define ECONNABORTED            WSAECONNABORTED
00057 #define ECONNRESET              WSAECONNRESET
00058 #define ENOBUFS                 WSAENOBUFS
00059 #define EISCONN                 WSAEISCONN
00060 #define ENOTCONN                WSAENOTCONN
00061 #define ESHUTDOWN               WSAESHUTDOWN
00062 #define ETOOMANYREFS            WSAETOOMANYREFS
00063 #define ETIMEDOUT               WSAETIMEDOUT
00064 #define ECONNREFUSED            WSAECONNREFUSED
00065 #define ELOOP                   WSAELOOP
00066 //#define ENAMETOOLONG            WSAENAMETOOLONG
00067 #define EHOSTDOWN               WSAEHOSTDOWN
00068 #define EHOSTUNREACH            WSAEHOSTUNREACH
00069 //#define ENOTEMPTY               WSAENOTEMPTY
00070 #define EPROCLIM                WSAEPROCLIM
00071 #define EUSERS                  WSAEUSERS
00072 #define EDQUOT                  WSAEDQUOT
00073 #define ESTALE                  WSAESTALE
00074 #define EREMOTE                 WSAEREMOTE
00075 
00076 #if defined(_MSC_VER) && (_MSC_VER >= 1600)
00077 #pragma warning (pop)
00078 #endif
00079 
00080 #else
00081 
00082 #define WSANOTINITIALISED  EPROTONOSUPPORT
00083 
00084 #endif
00085 
00086 namespace resip
00087 {
00088 
00090 void
00091 initNetwork();
00092 
00093 #ifndef WIN32
00094 typedef int Socket;             // Un*x fds are signed
00095 #define INVALID_SOCKET (-1)
00096 #define SOCKET_ERROR   (-1)
00097 inline int getErrno() { return errno; }
00098 #else
00099 typedef SOCKET Socket;          // Windows defines as *unsigned* something
00100 // INVALID_SOCKET is defined by Windows as ~0 (since Windows socket unsigned)
00101 // SOCKET_ERROR is defined by Windows as -1 (most func retvals are signed)
00102 inline int getErrno() { return WSAGetLastError(); }
00103 #endif
00104 
00105 //c function pointer because of ares
00106 extern "C" {
00107 typedef void(*AfterSocketCreationFuncPtr)(Socket s, int transportType, const char* file, int line);
00108 }
00109 
00110 bool makeSocketNonBlocking(Socket fd);
00111 bool makeSocketBlocking(Socket fd);
00112 int closeSocket( Socket fd );
00113 int getSocketError(Socket fd);  // getsockopt(SOCK_SOCKET,SO_ERROR)
00114 int increaseLimitFds(unsigned int targetFds);
00115 int setSocketRcvBufLen(Socket fd, int buflen);  // setsockopt(SO_RCVBUF)
00116 
00117 
00121 class FdSet
00122 {
00123 public:
00124    FdSet() : size(0), numReady(0)
00125    {
00126       FD_ZERO(&read);
00127       FD_ZERO(&write);
00128       FD_ZERO(&except);
00129    }
00130 
00131    int select(struct timeval& tv)
00132    {
00133       return numReady = ::select(size, &read, &write, &except, &tv);
00134    }
00135 
00136    int selectMilliSeconds(unsigned long ms)
00137    {
00138       struct timeval tv;
00139       tv.tv_sec = (ms/1000);
00140       tv.tv_usec = (ms%1000)*1000;
00141       return select(tv);
00142    }
00143 
00144    bool readyToRead(Socket fd)
00145    {
00146       return (FD_ISSET(fd, &read) != 0);
00147    }
00148 
00149    bool readyToWrite(Socket fd)
00150    {
00151       return (FD_ISSET(fd, &write) != 0);
00152    }
00153 
00154    bool hasException(Socket fd)
00155    {
00156       return (FD_ISSET(fd,&except) != 0);
00157    }
00158 
00159    void setRead(Socket fd)
00160    {
00161       assert( FD_SETSIZE >= 8 );
00162 #ifndef WIN32 // windows fd are not int's and don't start at 0 - this won't work in windows
00163       assert( fd < (int)FD_SETSIZE ); // redefineing FD_SETSIZE will not work 
00164 #else
00165       assert(read.fd_count < FD_SETSIZE); // Ensure there is room to add new FD
00166 #endif
00167       FD_SET(fd, &read);
00168       size = ( int(fd+1) > size) ? int(fd+1) : size;
00169    }
00170 
00171    void setWrite(Socket fd)
00172    {
00173 #ifndef WIN32 // windows fd are not int's and don't start at 0 - this won't work in windows
00174       assert( fd < (int)FD_SETSIZE ); // redefinitn FD_SETSIZE will not work 
00175 #else
00176       assert(write.fd_count < FD_SETSIZE); // Ensure there is room to add new FD
00177 #endif
00178       FD_SET(fd, &write);
00179       size = ( int(fd+1) > size) ? int(fd+1) : size;
00180    }
00181 
00182    void setExcept(Socket fd)
00183    {
00184 #ifndef WIN32 // windows fd are not int's and don't start at 0 - this won't work in windows
00185       assert( fd < (int)FD_SETSIZE ); // redefinitn FD_SETSIZE will not work 
00186 #else
00187       assert(except.fd_count < FD_SETSIZE); // Ensure there is room to add new FD
00188 #endif
00189       FD_SET(fd,&except);
00190       size = ( int(fd+1) > size) ? int(fd+1) : size;
00191    }
00192 
00193 
00194    void clear(Socket fd)
00195    {
00196       FD_CLR(fd, &read);
00197       FD_CLR(fd, &write);
00198       FD_CLR(fd, &except);
00199    }
00200 
00201    void reset()
00202    {
00203       size = 0;
00204       numReady = 0;
00205       FD_ZERO(&read);
00206       FD_ZERO(&write);
00207       FD_ZERO(&except);
00208    }
00209 
00210    // Make this stuff public for async dns/ares to use
00211    fd_set read;
00212    fd_set write;
00213    fd_set except;
00214    int size;
00215    int numReady;  // set after each select call
00216 };
00217 
00218         
00219 }
00220 
00221 #endif 
00222 
00223 /* ====================================================================
00224  * The Vovida Software License, Version 1.0 
00225  * 
00226  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
00227  * 
00228  * Redistribution and use in source and binary forms, with or without
00229  * modification, are permitted provided that the following conditions
00230  * are met:
00231  * 
00232  * 1. Redistributions of source code must retain the above copyright
00233  *    notice, this list of conditions and the following disclaimer.
00234  * 
00235  * 2. Redistributions in binary form must reproduce the above copyright
00236  *    notice, this list of conditions and the following disclaimer in
00237  *    the documentation and/or other materials provided with the
00238  *    distribution.
00239  * 
00240  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
00241  *    and "Vovida Open Communication Application Library (VOCAL)" must
00242  *    not be used to endorse or promote products derived from this
00243  *    software without prior written permission. For written
00244  *    permission, please contact vocal@vovida.org.
00245  *
00246  * 4. Products derived from this software may not be called "VOCAL", nor
00247  *    may "VOCAL" appear in their name, without prior written
00248  *    permission of Vovida Networks, Inc.
00249  * 
00250  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
00251  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00252  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
00253  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
00254  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
00255  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
00256  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00257  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00258  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
00259  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00260  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00261  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
00262  * DAMAGE.
00263  * 
00264  * ====================================================================
00265  * 
00266  * This software consists of voluntary contributions made by Vovida
00267  * Networks, Inc. and many individuals on behalf of Vovida Networks,
00268  * Inc.  For more information on Vovida Networks, Inc., please see
00269  * <http://www.vovida.org/>.
00270  *
00271  * vi: set shiftwidth=3 expandtab:
00272  */