Mixe for Privacy and Anonymity in the Internet
Public Member Functions | Static Public Member Functions | Protected Attributes | Private Member Functions | Private Attributes | Static Private Attributes
CASocket Class Reference

#include <CASocket.hpp>

Inheritance diagram for CASocket:
[legend]
Collaboration diagram for CASocket:
[legend]

List of all members.

Public Member Functions

 CASocket (bool bIsReserved=false)
 ~CASocket ()
virtual SINT32 create ()
virtual SINT32 create (bool a_bShowTypicalError)
virtual SINT32 create (int type)
virtual SINT32 listen (const CASocketAddr &psa)
 Starts listening on address psa.
virtual SINT32 listen (UINT16 port)
virtual SINT32 accept (CASocket &s)
 Accepts a new connection.
virtual SINT32 connect (const CASocketAddr &psa)
virtual SINT32 connect (const CASocketAddr &psa, UINT32 retry, UINT32 sWaitTime)
 Tries to connect to the peer described by psa.
virtual SINT32 connect (const CASocketAddr &psa, UINT32 msTimeOut)
 Tries to connect to peer psa.
virtual SINT32 close ()
virtual SINT32 send (const UINT8 *buff, UINT32 len)
 Sends some data over the network.
virtual SINT32 sendFully (const UINT8 *buff, UINT32 len)
 Sends all data over the network.
virtual SINT32 sendFullyTimeOut (const UINT8 *buff, UINT32 len, UINT32 msTimeOut, UINT32 msTimeOutSingleSend)
 Sends all data over the network.
virtual SINT32 sendTimeOut (const UINT8 *buff, UINT32 len, UINT32 msTimeOut)
 Sends some data over the network.
virtual SINT32 receive (UINT8 *buff, UINT32 len)
 Will receive some bytes from the socket.
virtual SINT32 receiveFullyT (UINT8 *buff, UINT32 len, UINT32 msTimeOut)
 Trys to receive all bytes.
virtual SINT32 receiveLine (UINT8 *line, UINT32 maxLen, UINT32 msTimeOut)
SOCKET getSocket ()
 Returns the number of the Socket used.
virtual SINT32 getLocalIP (UINT8 r_Ip[4])
 LERNGRUPPE Returns the source address of the socket.
virtual SINT32 getLocalPort ()
virtual SINT32 getPeerIP (UINT8 ip[4])
virtual SINT32 getPeerPort ()
virtual SINT32 setReuseAddr (bool b)
virtual SINT32 setSendTimeOut (UINT32 msTimeOut)
virtual SINT32 getSendTimeOut ()
virtual SINT32 setRecvBuff (UINT32 r)
virtual SINT32 getRecvBuff ()
virtual SINT32 setSendBuff (SINT32 r)
 Returns < 0 on error, otherwise the new sendbuffersize (which may be less than r)
virtual SINT32 getSendBuff ()
virtual SINT32 setKeepAlive (bool b)
 Enables/disables the socket keep-alive option.
virtual SINT32 setKeepAlive (UINT32 sec)
 Enables the socket keep-alive option with a given ping time (in seconds).
virtual SINT32 setNonBlocking (bool b)
virtual SINT32 getNonBlocking (bool *b)
virtual bool isClosed ()

Static Public Member Functions

static SINT32 setMaxNormalSockets (UINT32 u)
 Sets the max number of allowed "normal" sockets.
static SINT32 getMaxOpenSockets ()
 Tries to find out how many socket we can open by open as many socket as possible witthout errors.
static UINT32 countOpenSockets ()

Protected Attributes

volatile bool m_bSocketIsClosed
 check
SOCKET m_Socket

Private Member Functions

SINT32 create (int type, bool a_bShowTypicalError)

Private Attributes

CAMutex m_csClose
bool m_bIsReservedSocket

Static Private Attributes

static volatile UINT32 m_u32NormalSocketsOpen = 0
 The following two variables are use to realise "reserved" sockets.
static UINT32 m_u32MaxNormalSockets = 0xFFFFFFFF

Detailed Description

Definition at line 34 of file CASocket.hpp.


Constructor & Destructor Documentation

CASocket::CASocket ( bool  bIsReserved = false)

Definition at line 49 of file CASocket.cpp.

References m_bIsReservedSocket, m_bSocketIsClosed, and m_Socket.

  {
    m_Socket=0;
    m_bSocketIsClosed=true;
    m_bIsReservedSocket=bIsReservedSocket;
  }
CASocket::~CASocket ( ) [inline]

Definition at line 38 of file CASocket.hpp.

References close().

{close();}

Here is the call graph for this function:


Member Function Documentation

SINT32 CASocket::accept ( CASocket s) [virtual]

Accepts a new connection.

The new socket is returned in s.

Return values:
E_SUCCESSif successful
E_SOCKETCLOSEDif the listening socket was closed
E_SOCKET_LIMITif the could not create a new socket for the new connection
E_UNKNOWNotherwise

Definition at line 173 of file CASocket.cpp.

References E_SOCKET_LIMIT, E_SOCKETCLOSED, E_SUCCESS, E_UNKNOWN, ERR_INTERN_SOCKET_CLOSED, GET_NET_ERROR, CAMutex::lock(), m_bSocketIsClosed, m_csClose, m_Socket, m_u32MaxNormalSockets, m_u32NormalSocketsOpen, CAMsg::printMsg(), SOCKET_ERROR, and CAMutex::unlock().

Referenced by CAMuxSocket::accept(), fm_loopAcceptUsers(), and CALocalProxy::loop().

  {
    if(m_bSocketIsClosed) //the accept socket should not be closed!!
      return E_SOCKETCLOSED;
    if(!s.m_bSocketIsClosed) //but the new socket should be closed!!!
      return E_UNKNOWN;
    if(m_u32NormalSocketsOpen>=m_u32MaxNormalSockets)
      {
        CAMsg::printMsg(LOG_CRIT,"CASocket::accept() -- Could not create a new normal Socket -- allowed number of normal sockets exeded!\n");
        return E_SOCKET_LIMIT;
      }
    s.m_Socket=::accept(m_Socket,NULL,NULL);
    if(s.m_Socket==SOCKET_ERROR)
      {
        s.m_Socket=0;
        if(GET_NET_ERROR==ERR_INTERN_SOCKET_CLOSED)
          return E_SOCKETCLOSED;
        return E_UNKNOWN;
      }
    s.m_csClose.lock();
    m_u32NormalSocketsOpen++;
    s.m_bSocketIsClosed=false;
    s.m_csClose.unlock();
    //CAMsg::printMsg(LOG_DEBUG,"Opened socket: %d\n", s.m_Socket);

    return E_SUCCESS;
  }

Here is the call graph for this function:

SINT32 CASocket::close ( ) [virtual]

Reimplemented in CATLSClientSocket.

Definition at line 331 of file CASocket.cpp.

References closesocket, E_SUCCESS, GET_NET_ERROR, CAMutex::lock(), m_bIsReservedSocket, m_bSocketIsClosed, m_csClose, m_Socket, m_u32NormalSocketsOpen, CAMsg::printMsg(), and CAMutex::unlock().

Referenced by CAMuxSocket::accept(), CALocalProxy::clean(), CALastMix::clean(), CAFirstMix::clean(), CAMuxSocket::close(), CAChain::closeChainInternal(), connect(), getMaxOpenSockets(), CAInfoService::getPaymentInstance(), listen(), CALastMixA::loop(), CALastMixB::loop(), CALocalProxy::loop(), CAInfoService::sendCascadeHelo(), CAInfoService::sendMixHelo(), CAInfoService::sendStatus(), CACmdLnOptions::setListenerInterfaces(), CACmdLnOptions::setTargetInterfaces(), CAChain::~CAChain(), and ~CASocket().

  {
    SINT32 ret;

    if(m_bSocketIsClosed)
    {
      return E_SUCCESS;
    }

    ret = m_csClose.lock();
    if (ret != E_SUCCESS)
    {
      CAMsg::printMsg(LOG_CRIT,
        "Could not get lock for closing socket! Error code: %d\n", ret);
      return ret;
    }

    if (!m_bSocketIsClosed)
    {
      shutdown(m_Socket,SHUT_RDWR); //call shutdown here because some OSes seems to ned it to
      //wakeup other threads which block in read() or write()
      ret=::closesocket(m_Socket);
      if(!m_bIsReservedSocket)
      {
        m_u32NormalSocketsOpen--;
      }
      //CAMsg::printMsg(LOG_DEBUG,"Open Sockets: %d\n", m_u32NormalSocketsOpen);
      //CAMsg::printMsg(LOG_DEBUG,"Closed socket: %d\n", m_Socket);
      m_Socket=0;
      m_bSocketIsClosed=true;
    }

    if (ret != E_SUCCESS)
    {
      ret = GET_NET_ERROR;
    }

    m_csClose.unlock();
    return ret;
  }

Here is the call graph for this function:

virtual SINT32 CASocket::connect ( const CASocketAddr psa) [inline, virtual]
SINT32 CASocket::connect ( const CASocketAddr psa,
UINT32  retry,
UINT32  time 
) [virtual]

Tries to connect to the peer described by psa.

Parameters:
psa- peer
retry- number of retries
time- time between retries in seconds

Definition at line 207 of file CASocket.cpp.

References connect(), create(), E_SUCCESS, E_UNKNOWN, ERR_INTERN_CONNREFUSED, ERR_INTERN_TIMEDOUT, GET_NET_ERROR, CASocketAddr::getSize(), CASocketAddr::LPSOCKADDR(), m_bSocketIsClosed, m_Socket, CAMsg::printMsg(), and sSleep().

  {
//    CAMsg::printMsg(LOG_DEBUG,"Socket:connect\n");
    if(m_bSocketIsClosed&&create()!=E_SUCCESS)
      {
        return E_UNKNOWN;
      }
#ifdef _DEBUG
    sockets++;
#endif
    int err=0;
    const SOCKADDR* addr=psa.LPSOCKADDR();
    int addr_len=psa.getSize();
    for(UINT32 i=0;i<retry;i++)
      {
//        CAMsg::printMsg(LOG_DEBUG,"Socket:connect-connect\n");
        err=::connect(m_Socket,addr,addr_len);
//        CAMsg::printMsg(LOG_DEBUG,"Socket:connect-connect-finished err: %i\n",err);
        if(err!=0)
          {
            err=GET_NET_ERROR;
            #ifdef _DEBUG
             CAMsg::printMsg(LOG_DEBUG,"Con-Error: %i\n",err);
            #endif
            if(err!=ERR_INTERN_TIMEDOUT&&err!=ERR_INTERN_CONNREFUSED)
              return E_UNKNOWN; //Should be better.....
            #ifdef _DEBUG
              CAMsg::printMsg(LOG_DEBUG,"Cannot connect... retrying\n");
            #endif
            sSleep((UINT16)time);
          }
        else
            return E_SUCCESS;
      }
    return err;
  }

Here is the call graph for this function:

SINT32 CASocket::connect ( const CASocketAddr psa,
UINT32  msTimeOut 
) [virtual]

Tries to connect to peer psa.

Parameters:
psa- peer
msTimeOut- abort after msTimeOut milli seconds

Definition at line 250 of file CASocket.cpp.

References close(), connect(), create(), E_SOCKET_CONNECT, E_SUCCESS, E_UNKNOWN, GET_NET_ERROR, getNonBlocking(), CASocketAddr::getSize(), CASocketAddr::getType(), len, CASocketAddr::LPSOCKADDR(), m_bSocketIsClosed, m_Socket, SET_NET_ERROR, and setNonBlocking().

  {
    if(m_bSocketIsClosed&&create(psa.getType())!=E_SUCCESS)
      {
        return E_UNKNOWN;
      }
#ifdef _DEBUG
    sockets++;
#endif
    bool bWasNonBlocking=false;
    getNonBlocking(&bWasNonBlocking);
    setNonBlocking(true);
    int err=0;
    const LPSOCKADDR addr=(const LPSOCKADDR)psa.LPSOCKADDR();
    int addr_len=psa.getSize();

    err=::connect(m_Socket,addr,addr_len);
    if(err==0)
      return E_SUCCESS;
    err=GET_NET_ERROR;
#ifdef _WIN32
    if(err!=WSAEWOULDBLOCK)
      return E_SOCKET_CONNECT;
#else
    if(err!=EINPROGRESS)
    {
      return E_SOCKET_CONNECT;
    }
#endif

#ifndef HAVE_POLL
    struct timeval tval;
    tval.tv_sec=msTimeOut/1000;
    tval.tv_usec=(msTimeOut%1000)*1000;
    fd_set readSet,writeSet;
    FD_ZERO(&readSet);
    FD_ZERO(&writeSet);
    #pragma warning( push )
    #pragma warning( disable : 4127 ) //Disable: Bedingter Ausdruck ist konstant
    FD_SET(m_Socket,&readSet);
    FD_SET(m_Socket,&writeSet);
    #pragma warning( pop )
    err=::select(m_Socket+1,&readSet,&writeSet,NULL,&tval);
#else
    struct pollfd opollfd;
    opollfd.fd=m_Socket;
    opollfd.events=POLLIN|POLLOUT;
    err=::poll(&opollfd,1,msTimeOut);
#endif
    if (err<1) //timeout or error Note: we do not check for !=1 here because for some strange reasons FreeBSD 8.0-rc2 returns: 2 - Why?
    {
      err = GET_NET_ERROR;
      close();
      SET_NET_ERROR(err);
      
      if (GET_NET_ERROR == EINPROGRESS)
      {
        return E_UNKNOWN;
      }
      
      return E_SOCKET_CONNECT;
    }
    socklen_t len=sizeof(err);
    err=0;
    if (::getsockopt(m_Socket,SOL_SOCKET,SO_ERROR,(char*)&err,&len)<0||err!=0) //error by connect
    {
      err = GET_NET_ERROR;
      close();
      SET_NET_ERROR(err);
      
      if (GET_NET_ERROR == EINPROGRESS)
      {
        return E_UNKNOWN;
      }
      
      return E_SOCKET_CONNECT;
    }
    setNonBlocking(bWasNonBlocking);
    return E_SUCCESS;
  }

Here is the call graph for this function:

static UINT32 CASocket::countOpenSockets ( ) [inline, static]

Definition at line 111 of file CASocket.hpp.

References m_u32NormalSocketsOpen.

Referenced by fm_loopAcceptUsers().

SINT32 CASocket::create ( ) [virtual]
SINT32 CASocket::create ( bool  a_bShowTypicalError) [virtual]

Definition at line 66 of file CASocket.cpp.

References create().

{
  return create(AF_INET, a_bShowTypicalError);
}

Here is the call graph for this function:

SINT32 CASocket::create ( int  type) [virtual]

Definition at line 61 of file CASocket.cpp.

References create().

{
  return create(type, true);
}

Here is the call graph for this function:

SINT32 CASocket::create ( int  type,
bool  a_bShowTypicalError 
) [private]
Todo:
Not thread safe!

Definition at line 72 of file CASocket.cpp.

References E_SOCKET_CREATE, E_SOCKET_LIMIT, E_SUCCESS, E_UNKNOWN, GET_NET_ERROR, GET_NET_ERROR_STR, INVALID_SOCKET, CAMutex::lock(), m_bIsReservedSocket, m_bSocketIsClosed, m_csClose, m_Socket, m_u32MaxNormalSockets, m_u32NormalSocketsOpen, CAMsg::printMsg(), and CAMutex::unlock().

  {
    if(m_bSocketIsClosed)
    {
      if(m_bIsReservedSocket||m_u32NormalSocketsOpen<m_u32MaxNormalSockets)
      {
        m_Socket=socket(type,SOCK_STREAM,0);
        //CAMsg::printMsg(LOG_DEBUG,"Opened socket: %d\n", m_Socket);
      }
      else
      {
        CAMsg::printMsg(LOG_CRIT,"Could not create a new normal Socket -- allowed number of normal sockets exceeded!\n");
        return E_SOCKET_LIMIT;
      }
    }
    else
      return E_UNKNOWN;
    if(m_Socket==INVALID_SOCKET)
      {
        m_Socket=0;
        int er=GET_NET_ERROR;
        if (a_bShowTypicalError)
        {
          if(er==EMFILE)
          {
            CAMsg::printMsg(LOG_CRIT,"Could not create a new Socket!\n");
          }
          else
          {
            CAMsg::printMsg(LOG_CRIT,"Could not create a new Socket! - Error: %s (%i)\n",
              GET_NET_ERROR_STR(er), er);
          }
        }
        return E_SOCKET_CREATE;
      }
    m_bSocketIsClosed=false;
    m_csClose.lock();
    if(!m_bIsReservedSocket)
    {
      m_u32NormalSocketsOpen++;
    }
    m_csClose.unlock();
    return E_SUCCESS;
  }

Here is the call graph for this function:

SINT32 CASocket::getLocalIP ( UINT8  r_Ip[4]) [virtual]

LERNGRUPPE Returns the source address of the socket.

Returns:
r_Ip the source IP address
Return values:
E_SUCCESSupon success
SOCKET_ERRORotherwise
Todo:
: Question: Correct for Unix domain sockets?

Definition at line 716 of file CASocket.cpp.

References E_SUCCESS, m_Socket, and SOCKET_ERROR.

Referenced by CALastMixA::loop().

{
      struct sockaddr_in addr;
      socklen_t namelen=sizeof(struct sockaddr_in);
      if(getsockname(m_Socket,(struct sockaddr*)&addr,&namelen)==SOCKET_ERROR)
         return SOCKET_ERROR;
      memcpy(r_Ip,&addr.sin_addr,4);
      return E_SUCCESS;
}

Definition at line 726 of file CASocket.cpp.

References m_Socket, and SOCKET_ERROR.

Referenced by CALastMixA::loop(), and CALocalProxy::loop().

  {
    struct sockaddr_in addr;
    socklen_t namelen=sizeof(struct sockaddr_in);
    if(getsockname(m_Socket,(struct sockaddr*)&addr,&namelen)==SOCKET_ERROR)
      return SOCKET_ERROR;
    return ntohs(addr.sin_port);
  }

Tries to find out how many socket we can open by open as many socket as possible witthout errors.

If we can open more than 10.000 sockets we stop the test and return 10000.

Return values:
maxnumbers of sockets we can have open at the same time
E_UNKNOWNin case of some unexpected error

Definition at line 898 of file CASocket.cpp.

References close(), create(), and E_SUCCESS.

Referenced by main().

{
  CASocket* parSocket=new CASocket[10001];
  UINT32 maxSocket=0;
  for(UINT32 t=0;t<10001;t++)
    {
    if(parSocket[t].create(false)!=E_SUCCESS)
      {
      maxSocket=t;
      break;
      }
    }
  for(UINT32 t=0;t<maxSocket;t++)
    {
    parSocket[t].close();
    }
  delete []parSocket;
  parSocket = NULL;
  return maxSocket;
}

Here is the call graph for this function:

SINT32 CASocket::getNonBlocking ( bool *  b) [virtual]

Definition at line 887 of file CASocket.cpp.

References E_SUCCESS, flags, m_Socket, and SOCKET_ERROR.

Referenced by connect(), CAHttpClient::parseHTTPHeader(), sendFullyTimeOut(), and sendTimeOut().

  {
    #ifndef _WIN32
        int flags=fcntl(m_Socket,F_GETFL,0);
        *b=((flags&O_NONBLOCK)==O_NONBLOCK);
        return E_SUCCESS;
    #else
        return SOCKET_ERROR;
    #endif
  }
SINT32 CASocket::getPeerIP ( UINT8  ip[4]) [virtual]

Definition at line 735 of file CASocket.cpp.

References E_SUCCESS, m_Socket, and SOCKET_ERROR.

Referenced by fm_loopAcceptUsers(), and isAllowedToPassRestrictions().

  {
    struct sockaddr_in addr;
    socklen_t namelen=sizeof(struct sockaddr_in);
    if(getpeername(m_Socket,(struct sockaddr*)&addr,&namelen)==SOCKET_ERROR)
      return SOCKET_ERROR;
    memcpy(ip,&addr.sin_addr,4);
    return E_SUCCESS;
  }

Definition at line 745 of file CASocket.cpp.

References m_Socket, and SOCKET_ERROR.

Referenced by CAFirstMixChannelList::add().

  {
    struct sockaddr_in addr;
    socklen_t namelen=sizeof(struct sockaddr_in);
    if(getpeername(m_Socket,(struct sockaddr*)&addr,&namelen)==SOCKET_ERROR)
      return SOCKET_ERROR;
    return ntohs(addr.sin_port);
  }

Definition at line 767 of file CASocket.cpp.

References E_UNKNOWN, m_Socket, and SOCKET_ERROR.

Referenced by CAFirstMix::init().

  {
    int val;
    socklen_t size=sizeof(val);
    if(getsockopt(m_Socket,SOL_SOCKET,SO_RCVBUF,(char*)&val,&size)==SOCKET_ERROR)
      return E_UNKNOWN;
    else
      return val;
  }

Definition at line 788 of file CASocket.cpp.

References E_UNKNOWN, m_Socket, and SOCKET_ERROR.

Referenced by CAFirstMix::init(), and setSendBuff().

  {
    SINT32 val;
    socklen_t size=sizeof(val);
    if(getsockopt(m_Socket,SOL_SOCKET,SO_SNDBUF,(char*)&val,&size)==SOCKET_ERROR)
      return E_UNKNOWN;
    else
      return val;
  }

Definition at line 806 of file CASocket.cpp.

References E_UNKNOWN, m_Socket, and SOCKET_ERROR.

Referenced by sendFullyTimeOut(), and sendTimeOut().

  {
    timeval val;
    socklen_t size=sizeof(val);
    if(getsockopt(m_Socket,SOL_SOCKET,SO_SNDTIMEO,(char*)&val,&size)==SOCKET_ERROR)
      return E_UNKNOWN;
    else
      return val.tv_sec*1000+val.tv_usec/1000;
  }

Returns the number of the Socket used.

Which will be always the same number, even after close(), until the Socket is recreated using create()

Returns:
number of the associated socket

Definition at line 70 of file CASocket.hpp.

References m_Socket.

Referenced by CASocketGroupEpoll::add(), CASocketGroup::add(), CAMuxSocket::getSocket(), CASocketGroup::isSignaled(), CASocketGroup::remove(), and CASingleSocketGroup::select_once().

        {
          return m_Socket;
        }
virtual bool CASocket::isClosed ( ) [inline, virtual]

Definition at line 115 of file CASocket.hpp.

References m_bSocketIsClosed.

Referenced by CAFirstMix::doUserLogin_internal(), and CAMuxSocket::receive().

      {
        return m_bSocketIsClosed;
      }
SINT32 CASocket::listen ( const CASocketAddr psa) [virtual]

Starts listening on address psa.

Return values:
E_SUCCESS,ifsuccessful
E_SOCKET_LISTEN,ifcall to listen() returns an error
E_SOCKET_BIND,ifcall to bind() returns an error
E_UNKNOWN,otherwise

Definition at line 123 of file CASocket.cpp.

References close(), create(), E_SOCKET_BIND, E_SOCKET_LISTEN, E_SUCCESS, E_UNKNOWN, GET_NET_ERROR, CASocketAddr::getSize(), CASocketAddr::getType(), CASocketAddr::LPSOCKADDR(), m_bSocketIsClosed, m_Socket, CAMsg::printMsg(), SET_NET_ERROR, SOCKET_ERROR, and type.

Referenced by CAMuxSocket::accept(), CACmdLnOptions::createSockets(), CALocalProxy::init(), and listen().

  {
    UINT32 iError;
    SINT32 type=psa.getType();
    if(m_bSocketIsClosed&&create(type)!=E_SUCCESS)
      return E_UNKNOWN;
#ifdef HAVE_UNIX_DOMAIN_PROTOCOL
    //we have to delete the file before...
    if(psa.getType()==AF_LOCAL)
      {
        UINT8* path=((CASocketAddrUnix&)psa).getPath();
        if(path!=NULL)
          {
            SINT32 ret=::unlink((char*)path);
            if(ret!=0)
              CAMsg::printMsg(LOG_ERR,"CASocket::listen() -- could not unlink unix domain socket file name %s -- a call to bind or listen may fail...\n",path);
            delete[] path;
            path = NULL;
          }
      }
#endif
    if(::bind(m_Socket,psa.LPSOCKADDR(),psa.getSize())==SOCKET_ERROR)
      {
        iError = GET_NET_ERROR;
        close();
        SET_NET_ERROR(iError);
        return E_SOCKET_BIND;
      }
    if(::listen(m_Socket,SOMAXCONN)==SOCKET_ERROR)
      {
        iError = GET_NET_ERROR;
        close();
        SET_NET_ERROR(iError);
        return E_SOCKET_LISTEN;
      }
    return E_SUCCESS;
  }

Here is the call graph for this function:

SINT32 CASocket::listen ( UINT16  port) [virtual]

Definition at line 161 of file CASocket.cpp.

References listen().

  {
    CASocketAddrINet oSocketAddrINet(port);
    return listen(oSocketAddrINet);
  }

Here is the call graph for this function:

SINT32 CASocket::receive ( UINT8 buff,
UINT32  len 
) [virtual]

Will receive some bytes from the socket.

May block or not depending on whatever this socket was set to blocking or non-blocking mode. Warning: If socket is in blocking mode and receive is called, receive will block until some data is available, EVEN IF AN OTHER THREAD WILL CLOSE THIS SOCKET!

Parameters:
buffthe buffer which get the received data
lensize of buff
Returns:
SOCKET_ERROR if an error occured
Return values:
E_AGAIN,ifsocket was in non-blocking mode and receive would block or a timeout was reached
0if socket was gracefully closed
Returns:
the number of bytes received (always >0)

Implements CAClientSocket.

Reimplemented in CATLSClientSocket.

Definition at line 595 of file CASocket.cpp.

References E_AGAIN, ERR_INTERN_WOULDBLOCK, GET_NET_ERROR, GET_NET_ERROR_STR, m_Socket, MSG_NOSIGNAL, CAMsg::printMsg(), and SOCKET_ERROR.

Referenced by CAHttpClient::getContent(), CALastMixA::loop(), CALocalProxy::loop(), CAHttpClient::parseHTTPHeader(), CAChain::processDownstream(), CAMuxSocket::receive(), receiveFullyT(), and receiveLine().

  {
    int ret;
    int ef=0;
    do
      {
        ret=::recv(m_Socket,(char*)buff,len,MSG_NOSIGNAL);
      }
    while(ret==SOCKET_ERROR&&(ef=GET_NET_ERROR)==EINTR);
    if(ret==SOCKET_ERROR)
      {
        if(ef==ERR_INTERN_WOULDBLOCK)
          return E_AGAIN;
      }
#ifdef _DEBUG
    if(ret==SOCKET_ERROR)
        CAMsg::printMsg(LOG_DEBUG,"CASocket Receive error %d (%s)\n",ef,GET_NET_ERROR_STR(ef));
#endif
    return ret;
  }

Here is the call graph for this function:

SINT32 CASocket::receiveFullyT ( UINT8 buff,
UINT32  len,
UINT32  msTimeOut 
) [virtual]

Trys to receive all bytes.

If after the timeout value has elapsed, not all bytes are received the error E_TIMEDOUT is returned.

Parameters:
buffbyte array, where the received bytes would be stored
lenon input holds the number of bytes which should be read,
msTimeOutthe timout in milli seconds
Return values:
E_TIMEDOUTif not all byts could be read
E_UNKNOWNif an error occured
E_SUCCESSif all bytes could be read

Definition at line 627 of file CASocket.cpp.

References CASocketGroup::add(), add64(), diff64(), E_SUCCESS, E_TIMEDOUT, E_UNKNOWN, getcurrentTimeMillis(), isLesser64(), receive(), CASocketGroup::select(), set64(), and SET_NET_ERROR.

Referenced by CAFirstMix::doUserLogin_internal(), CAMuxSocket::receiveFully(), CAInfoService::sendCascadeHelo(), CAInfoService::sendMixHelo(), CAAccountingBIInterface::settle(), and CAAccountingBIInterface::settleAll().

  {
    SINT32 ret;
    UINT32 pos=0;
    UINT64 currentTime,endTime;
    getcurrentTimeMillis(currentTime);
    set64(endTime,currentTime);
    add64(endTime,msTimeOut);
    CASingleSocketGroup oSG(false);
    oSG.add(*this);
    for(;;)
      {
        ret=oSG.select(msTimeOut);
        if(ret==1)
          {
            ret=receive(buff+pos,len);
            if(ret<=0)
              return E_UNKNOWN;
            pos+=ret;
            len-=ret;
          }
        else if(ret==E_TIMEDOUT)
        {
          return E_TIMEDOUT;
        }
        if(len==0)
          return E_SUCCESS;
        getcurrentTimeMillis(currentTime);
        if(!isLesser64(currentTime,endTime))
        {
          SET_NET_ERROR(E_TIMEDOUT);
          return E_TIMEDOUT;
        }
        msTimeOut=diff64(endTime,currentTime);
      }
  }

Here is the call graph for this function:

SINT32 CASocket::receiveLine ( UINT8 line,
UINT32  maxLen,
UINT32  msTimeOut 
) [virtual]

Definition at line 664 of file CASocket.cpp.

References CASocketGroup::add(), add64(), diff64(), E_TIMEDOUT, getcurrentTimeMillis(), isLesser64(), receive(), CASocketGroup::select(), set64(), and SET_NET_ERROR.

{
  UINT32 i = 0;
  UINT8 byte = 0;
  SINT32 ret = 0;
  UINT64 currentTime, endTime;
  getcurrentTimeMillis(currentTime);
  set64(endTime,currentTime);
  add64(endTime,msTimeOut);
  CASingleSocketGroup oSG(false);
  oSG.add(*this);
  do
  {
    ret = oSG.select(msTimeOut);
    if(ret == 1)
    {
      ret = receive(&byte, 1);
      if(byte == '\r' || byte == '\n')
      {
        line[i++] = 0;
      }
      else
      {
        line[i++] = byte;
      }
    }
    else if(ret == E_TIMEDOUT)
    {
      return E_TIMEDOUT;
    }
    getcurrentTimeMillis(currentTime);
    if(!isLesser64(currentTime,endTime))
    {
      SET_NET_ERROR(E_TIMEDOUT);
      return E_TIMEDOUT;
    }
    msTimeOut=diff64(endTime,currentTime);
  }
  while(byte != '\n' && i<maxLen && ret > 0);

  return ret;
}

Here is the call graph for this function:

SINT32 CASocket::send ( const UINT8 buff,
UINT32  len 
) [virtual]

Sends some data over the network.

This may block, if socket is in blocking mode.

Parameters:
buffthe buffer of data to send
lencontent length
Return values:
E_AGAINif non blocking socket would block or a timeout was reached
E_UNKNOWNif an error occured
Returns:
number of bytes send

Reimplemented in CATLSClientSocket.

Definition at line 380 of file CASocket.cpp.

References E_AGAIN, E_UNKNOWN, ERR_INTERN_WOULDBLOCK, GET_NET_ERROR, m_Socket, MSG_NOSIGNAL, CAMsg::printMsg(), and SOCKET_ERROR.

Referenced by CALastMixA::loop(), CAFirstMixB::loop(), CALocalProxy::loop(), CALocalProxy::processKeyExchange(), CAMiddleMix::processKeyExchange(), CALastMix::processKeyExchange(), CAFirstMix::processKeyExchange(), sendFully(), sendFullyTimeOut(), sendTimeOut(), CAFirstMixA::sendToUsers(), and CAChain::sendUpstreamDataInternal().

  {
    if(len==0)
      return 0; //nothing to send
    int ret;
    SINT32 ef=0;
    do
      {
        ret=::send(m_Socket,(char*)buff,len,MSG_NOSIGNAL);
        #ifdef _DEBUG
          if(ret==SOCKET_ERROR)
            CAMsg::printMsg(LOG_DEBUG,"Fehler beim Socket-send: %i (Socket: %i)\n",GET_NET_ERROR,m_Socket);
        #endif
      }
    while(ret==SOCKET_ERROR&&(ef=GET_NET_ERROR)==EINTR);
    if(ret==SOCKET_ERROR)
      {
        if(ef==ERR_INTERN_WOULDBLOCK)
          {
            #ifdef _DEBUG
              CAMsg::printMsg(LOG_DEBUG,"Fehler beim Socket-send: E_AGAIN\n");
            #endif
            return E_AGAIN;
          }
        #ifdef _DEBUG
          CAMsg::printMsg(LOG_DEBUG,"Fehler beim Socket-send:E_UNKNOWN (ef=%i)\n",ef);
        #endif
        return E_UNKNOWN;
      }
    return ret;
  }

Here is the call graph for this function:

SINT32 CASocket::sendFully ( const UINT8 buff,
UINT32  len 
) [virtual]

Sends all data over the network.

This may block until all data is send.

Parameters:
buff- the buffer of data to send
len- content length
Return values:
E_UNKNOWN,ifan error occured
E_SUCCESS,ifsuccessful

Implements CAClientSocket.

Reimplemented in CATLSClientSocket.

Definition at line 549 of file CASocket.cpp.

References E_AGAIN, E_SUCCESS, E_TIMEDOUT, E_UNKNOWN, CAMsg::printMsg(), CASingleSocketGroup::select_once(), and send().

Referenced by CAMuxSocket::send(), and sendFullyTimeOut().

  {
    if(len==0)
      return E_SUCCESS; //nothing to send
    SINT32 ret;
    for(;;)
      {
        ret=send(buff,len);
        if((UINT32)ret==len)
          return E_SUCCESS;
        else if(ret==E_AGAIN)
          {
            ret=CASingleSocketGroup::select_once(*this,true,1000);
            if(ret>=0||ret==E_TIMEDOUT)
              continue;
            #ifdef _DEBUG
              CAMsg::printMsg(LOG_DEBUG,"CASocket::sendFully() - error near select_once() ret=%i\n",ret);
            #endif
            return E_UNKNOWN;
          }
        else if(ret<0)
          {
            #ifdef _DEBUG
              CAMsg::printMsg(LOG_DEBUG,"CASocket::sendFully() - send returned %i\n",ret);
            #endif
            return E_UNKNOWN;
          }
        len-=ret;
        buff+=ret;
      }
      //could never be here....
  }

Here is the call graph for this function:

SINT32 CASocket::sendFullyTimeOut ( const UINT8 buff,
UINT32  len,
UINT32  msTimeOut,
UINT32  msTimeOutSingleSend 
) [virtual]

Sends all data over the network.

This may block until all data is send.

Parameters:
buff- the buffer of data to send
len- content length
Return values:
E_UNKNOWN,ifan error occured
E_TIMEDOUTif the timeout was reached
E_SUCCESS,ifsuccessful

Definition at line 468 of file CASocket.cpp.

References E_AGAIN, E_SUCCESS, E_TIMEDOUT, E_UNKNOWN, getcurrentTimeMillis(), getNonBlocking(), getSendTimeOut(), CAMsg::printMsg(), CASingleSocketGroup::select_once(), send(), sendFully(), SET_NET_ERROR, and setSendTimeOut().

Referenced by CAFirstMix::doUserLogin_internal(), CAInfoService::sendCascadeHelo(), CAHttpClient::sendGetRequest(), CAInfoService::sendMixHelo(), CAHttpClient::sendPostRequest(), and CAInfoService::sendStatus().

{
  if(len==0)
  {
    return E_SUCCESS; //nothing to send
  }

  SINT32 ret;
  SINT32 aktTimeOut=0;
  UINT64 startupTime, currentMillis;


  bool bWasNonBlocking;
  getNonBlocking(&bWasNonBlocking);
  aktTimeOut=getSendTimeOut();
  getcurrentTimeMillis(startupTime);

  if(bWasNonBlocking)
  {
    //we are in non-blocking mode
    return sendFully(buff, len);
  }
  else if (setSendTimeOut(msTimeOutSingleSend)!=E_SUCCESS)
  {
    // it is not possible to set the socket timeout
    CAMsg::printMsg(LOG_ERR,"CASocket::sendFullyTimeOut() - could not set socket timeout!\n");
    return sendFully(buff, len);
  }
  else
  {
    for(;;)
    {
      getcurrentTimeMillis(currentMillis);
      if (currentMillis >= (startupTime + msTimeOut))
      {
        #ifdef DEBUG
        CAMsg::printMsg(LOG_DEBUG,"CASocket::sendFullyTimeOut() - timed out!\n");
        #endif
        setSendTimeOut(aktTimeOut);
        SET_NET_ERROR(E_TIMEDOUT);
        return E_TIMEDOUT;
      }

      ret=send(buff,len);
      if((UINT32)ret==len)
      {
        setSendTimeOut(aktTimeOut);
        return E_SUCCESS;
      }
      else if(ret==E_AGAIN)
      {
        ret=CASingleSocketGroup::select_once(*this,true,1000);
        if(ret>=0||ret==E_TIMEDOUT)
          continue;
        #ifdef _DEBUG
          CAMsg::printMsg(LOG_DEBUG,"CASocket::sendTimeOutFully() - error near select_once() ret=%i\n",ret);
        #endif
        setSendTimeOut(aktTimeOut);
        return E_UNKNOWN;
      }
      else if(ret<0)
      {
        #ifdef _DEBUG
          CAMsg::printMsg(LOG_DEBUG,"CASocket::sendTimeOutFully() - send returned %i\n",ret);
        #endif
        setSendTimeOut(aktTimeOut);
        return E_UNKNOWN;
      }
      len-=ret;
      buff+=ret;
    }
    //could never be here....
  }
}

Here is the call graph for this function:

SINT32 CASocket::sendTimeOut ( const UINT8 buff,
UINT32  len,
UINT32  msTimeOut 
) [virtual]

Sends some data over the network.

Using a Timeout if socket is in blocking mode. Otherwise E_AGAIN may returned

Parameters:
buffthe buffer to send
lencontent length
msTimeOutMaximum MilliSeconds to wait
Return values:
E_AGAINif Operation would block on a non-blocking socket
E_TIMEDOUTif the timeout was reached
Returns:
number of bytes send, or -1 in case of an error /FIXME really buggy!!!!

Definition at line 422 of file CASocket.cpp.

References E_AGAIN, E_SUCCESS, getNonBlocking(), getSendTimeOut(), msSleep(), CAMsg::printMsg(), send(), setNonBlocking(), and setSendTimeOut().

Referenced by CALastMixA::loop(), and CALastMixB::loop().

{
  SINT32 ret;
  SINT32 aktTimeOut=0;
  bool bWasNonBlocking;
  getNonBlocking(&bWasNonBlocking);
  if(bWasNonBlocking) //we are in non-blocking mode
  {
    ret=send(buff,len);
  }
  else
  {
    aktTimeOut=getSendTimeOut();
    if(aktTimeOut>0&&(UINT32)aktTimeOut==msTimeOut) //we already have the right timeout
    {
      ret=send(buff,len);
    }
    else if(aktTimeOut<0||setSendTimeOut(msTimeOut)!=E_SUCCESS)
    {//do it complicate but still to simple!!!! more work TODO
      setNonBlocking(true);
      ret=send(buff,len);
      if(ret==E_AGAIN)
        {
          CAMsg::printMsg(LOG_DEBUG,"Send again...\n");
          msSleep((UINT16)msTimeOut);
          ret=send(buff,len);
        }
      setNonBlocking(bWasNonBlocking);
    }
    else
    {
      ret=send(buff,len);
      setSendTimeOut(aktTimeOut);
    }
  }
  return ret;
}

Here is the call graph for this function:

SINT32 CASocket::setKeepAlive ( bool  b) [virtual]

Enables/disables the socket keep-alive option.

Parameters:
btrue if option should be enabled, false otherwise
Returns:
E_SUCCESS if no error occured
E_UNKOWN otherwise

Definition at line 821 of file CASocket.cpp.

References E_SUCCESS, E_UNKNOWN, GET_NET_ERROR, GET_NET_ERROR_STR, m_Socket, CAMsg::printMsg(), and SOCKET_ERROR.

Referenced by CAFirstMix::doUserLogin_internal(), CAMiddleMix::init(), CALastMix::init(), CAFirstMix::init(), and setKeepAlive().

  {
    int val=0;
    if(b) val=1;
    if(setsockopt(m_Socket,SOL_SOCKET,SO_KEEPALIVE,(char*)&val,sizeof(val))==SOCKET_ERROR)
    {
      int errnum=GET_NET_ERROR;
      CAMsg::printMsg(LOG_ERR, "Could not set KEEP_ALIVE options. Reason: %s (%i)\n", GET_NET_ERROR_STR(errnum), errnum);
      return E_UNKNOWN;
    }
    return E_SUCCESS;
  }

Here is the call graph for this function:

SINT32 CASocket::setKeepAlive ( UINT32  sec) [virtual]

Enables the socket keep-alive option with a given ping time (in seconds).

Parameters:
secthe time intervall(in seconds) of a keep-alive message
Returns:
E_SUCCESS if no error occured
E_UNKOWN otherwise

Definition at line 839 of file CASocket.cpp.

References E_SUCCESS, E_UNKNOWN, GET_NET_ERROR, GET_NET_ERROR_STR, m_Socket, CAMsg::printMsg(), setKeepAlive(), and SOCKET_ERROR.

  {
    if(setKeepAlive(true)!=E_SUCCESS)
    {
      return E_UNKNOWN;
    }

#ifdef HAVE_TCP_KEEPALIVE
    int val=sec;
    if(setsockopt(m_Socket,IPPROTO_TCP,TCP_KEEPALIVE,(char*)&val,sizeof(val))==SOCKET_ERROR)
    {
      CAMsg::printMsg(LOG_ERR,"Socket option TCP-KEEP-ALIVE was not set! Reason: %s (%i)\n",
          GET_NET_ERROR_STR(GET_NET_ERROR), GET_NET_ERROR);
      return E_UNKNOWN;
    }
    return E_SUCCESS;
#else
    CAMsg::printMsg(LOG_INFO,"Socket option TCP-KEEP-ALIVE was not set as it is not available on this machine.\n");
    return E_UNKNOWN;
#endif
  }

Here is the call graph for this function:

static SINT32 CASocket::setMaxNormalSockets ( UINT32  u) [inline, static]

Sets the max number of allowed "normal" sockets.

Return values:
E_SUCCESSif call was successful
E_UNKNOWNotherwise

Definition at line 99 of file CASocket.hpp.

References E_SUCCESS, and m_u32MaxNormalSockets.

Referenced by main().

SINT32 CASocket::setNonBlocking ( bool  b) [virtual]

Definition at line 862 of file CASocket.cpp.

References E_SUCCESS, flags, ioctlsocket, and m_Socket.

Referenced by connect(), CAFirstMix::doUserLogin_internal(), CALastMixA::loop(), CALastMixB::loop(), CAHttpClient::parseHTTPHeader(), sendTimeOut(), CAAccountingBIInterface::settle(), and CAAccountingBIInterface::settleAll().

  {
    if(b)
      {
        #ifndef _WIN32
            int flags=fcntl(m_Socket,F_GETFL,0);
            fcntl(m_Socket,F_SETFL,flags|O_NONBLOCK);
        #else
            unsigned long flags=1;
            ioctlsocket(m_Socket,FIONBIO,&flags);
        #endif
      }
    else
      {
        #ifndef _WIN32
            int flags=fcntl(m_Socket,F_GETFL,0);
            fcntl(m_Socket,F_SETFL,flags&~O_NONBLOCK);
        #else
            unsigned long flags=0;
            ioctlsocket(m_Socket,FIONBIO,&flags);
        #endif
      }
    return E_SUCCESS;
  }

Definition at line 761 of file CASocket.cpp.

References m_Socket.

Referenced by CALocalProxy::init(), CAMiddleMix::init(), CALastMix::init(), CAFirstMix::init(), CALastMixA::loop(), CALastMixB::loop(), CAInfoService::sendMixHelo(), and CACmdLnOptions::setTargetInterfaces().

  {
    int val=r;
    return setsockopt(m_Socket,SOL_SOCKET,SO_RCVBUF,(char*)&val,sizeof(val));
  }
SINT32 CASocket::setReuseAddr ( bool  b) [virtual]

Definition at line 754 of file CASocket.cpp.

References m_Socket.

Referenced by CAMuxSocket::accept(), CACmdLnOptions::createSockets(), and CALocalProxy::init().

  {
    int val=0;
    if(b) val=1;
    return setsockopt(m_Socket,SOL_SOCKET,SO_REUSEADDR,(char*)&val,sizeof(val));
  }

Returns < 0 on error, otherwise the new sendbuffersize (which may be less than r)

Definition at line 777 of file CASocket.cpp.

References E_UNKNOWN, getSendBuff(), and m_Socket.

Referenced by CALocalProxy::init(), CAMiddleMix::init(), CALastMix::init(), CAFirstMix::init(), CALastMixA::loop(), CALastMixB::loop(), and CACmdLnOptions::setTargetInterfaces().

  {
    if(r<0)
      return E_UNKNOWN;
    SINT32 val=r;
    SINT32 ret=setsockopt(m_Socket,SOL_SOCKET,SO_SNDBUF,(char*)&val,sizeof(val));
    if(ret!=0)
      return E_UNKNOWN;
    return getSendBuff();
  }

Here is the call graph for this function:

SINT32 CASocket::setSendTimeOut ( UINT32  msTimeOut) [virtual]

Definition at line 798 of file CASocket.cpp.

References m_Socket.

Referenced by sendFullyTimeOut(), and sendTimeOut().

  {
    timeval t;
    t.tv_sec=msTimeOut/1000;
    t.tv_usec=(msTimeOut%1000)*1000;
    return setsockopt(m_Socket,SOL_SOCKET,SO_SNDTIMEO,(char*)&t,sizeof(t));
  }

Member Data Documentation

Definition at line 142 of file CASocket.hpp.

Referenced by CASocket(), close(), and create().

volatile bool CASocket::m_bSocketIsClosed [protected]

check

end check

Definition at line 128 of file CASocket.hpp.

Referenced by accept(), CASocket(), close(), connect(), create(), isClosed(), and listen().

Definition at line 137 of file CASocket.hpp.

Referenced by accept(), close(), and create().

UINT32 CASocket::m_u32MaxNormalSockets = 0xFFFFFFFF [static, private]

Definition at line 141 of file CASocket.hpp.

Referenced by accept(), create(), and setMaxNormalSockets().

volatile UINT32 CASocket::m_u32NormalSocketsOpen = 0 [static, private]

The following two variables are use to realise "reserved" sockets.

The rational behind is to ensure that we could allway crate "reserved" socket why we may fail to create normal sockets because of to many open files related restrictions

Definition at line 140 of file CASocket.hpp.

Referenced by accept(), close(), countOpenSockets(), and create().


The documentation for this class was generated from the following files: