|
Mixe for Privacy and Anonymity in the Internet
|
#include <CASocket.hpp>
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 |
Definition at line 34 of file CASocket.hpp.
| 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();}
| SINT32 CASocket::accept | ( | CASocket & | s | ) | [virtual] |
Accepts a new connection.
The new socket is returned in s.
| E_SUCCESS | if successful |
| E_SOCKETCLOSED | if the listening socket was closed |
| E_SOCKET_LIMIT | if the could not create a new socket for the new connection |
| E_UNKNOWN | otherwise |
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;
}
| 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;
}
| virtual SINT32 CASocket::connect | ( | const CASocketAddr & | psa | ) | [inline, virtual] |
Definition at line 48 of file CASocket.hpp.
Referenced by connect(), CAMuxSocket::connect(), CATLSClientSocket::connect(), CAInfoService::getPaymentInstance(), CALastMixA::loop(), CALastMixB::loop(), CAInfoService::sendCascadeHelo(), CAInfoService::sendMixHelo(), CAInfoService::sendStatus(), and CACmdLnOptions::setTargetInterfaces().
{
return connect(psa,1,0);
}
| SINT32 CASocket::connect | ( | const CASocketAddr & | psa, |
| UINT32 | retry, | ||
| UINT32 | time | ||
| ) | [virtual] |
Tries to connect to the peer described by psa.
| 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;
}
| SINT32 CASocket::connect | ( | const CASocketAddr & | psa, |
| UINT32 | msTimeOut | ||
| ) | [virtual] |
Tries to connect to peer psa.
| 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;
}
| static UINT32 CASocket::countOpenSockets | ( | ) | [inline, static] |
Definition at line 111 of file CASocket.hpp.
References m_u32NormalSocketsOpen.
Referenced by fm_loopAcceptUsers().
{
return m_u32NormalSocketsOpen;
}
| SINT32 CASocket::create | ( | ) | [virtual] |
Definition at line 56 of file CASocket.cpp.
Referenced by CAMuxSocket::accept(), connect(), create(), CACmdLnOptions::createSockets(), getMaxOpenSockets(), CALocalProxy::init(), CAMiddleMix::init(), CAFirstMix::init(), listen(), CALastMixA::loop(), CALastMixB::loop(), CACmdLnOptions::parse(), and CAFirstMixChannelList::test().
{
return create(AF_INET, true);
}
| SINT32 CASocket::create | ( | bool | a_bShowTypicalError | ) | [virtual] |
Definition at line 66 of file CASocket.cpp.
References create().
{
return create(AF_INET, a_bShowTypicalError);
}
| SINT32 CASocket::create | ( | int | type | ) | [virtual] |
Definition at line 61 of file CASocket.cpp.
References create().
| SINT32 CASocket::create | ( | int | type, |
| bool | a_bShowTypicalError | ||
| ) | [private] |
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;
}
| SINT32 CASocket::getLocalIP | ( | UINT8 | r_Ip[4] | ) | [virtual] |
LERNGRUPPE Returns the source address of the socket.
| E_SUCCESS | upon success |
| SOCKET_ERROR | otherwise |
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;
}
| SINT32 CASocket::getLocalPort | ( | ) | [virtual] |
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);
}
| SINT32 CASocket::getMaxOpenSockets | ( | ) | [static] |
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.
| max | numbers of sockets we can have open at the same time |
| E_UNKNOWN | in 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;
}
| 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;
}
| SINT32 CASocket::getPeerPort | ( | ) | [virtual] |
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);
}
| SINT32 CASocket::getRecvBuff | ( | ) | [virtual] |
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;
}
| SINT32 CASocket::getSendBuff | ( | ) | [virtual] |
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;
}
| SINT32 CASocket::getSendTimeOut | ( | ) | [virtual] |
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;
}
| SOCKET CASocket::getSocket | ( | ) | [inline] |
Returns the number of the Socket used.
Which will be always the same number, even after close(), until the Socket is recreated using create()
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.
| E_SUCCESS,if | successful |
| E_SOCKET_LISTEN,if | call to listen() returns an error |
| E_SOCKET_BIND,if | call 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;
}
| SINT32 CASocket::listen | ( | UINT16 | port | ) | [virtual] |
Definition at line 161 of file CASocket.cpp.
References listen().
{
CASocketAddrINet oSocketAddrINet(port);
return listen(oSocketAddrINet);
}
| 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!
| buff | the buffer which get the received data |
| len | size of buff |
| E_AGAIN,if | socket was in non-blocking mode and receive would block or a timeout was reached |
| 0 | if socket was gracefully closed |
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;
}
| 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.
| buff | byte array, where the received bytes would be stored |
| len | on input holds the number of bytes which should be read, |
| msTimeOut | the timout in milli seconds |
| E_TIMEDOUT | if not all byts could be read |
| E_UNKNOWN | if an error occured |
| E_SUCCESS | if 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);
}
}
| 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;
}
| SINT32 CASocket::send | ( | const UINT8 * | buff, |
| UINT32 | len | ||
| ) | [virtual] |
Sends some data over the network.
This may block, if socket is in blocking mode.
| buff | the buffer of data to send |
| len | content length |
| E_AGAIN | if non blocking socket would block or a timeout was reached |
| E_UNKNOWN | if an error occured |
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;
}
| SINT32 CASocket::sendFully | ( | const UINT8 * | buff, |
| UINT32 | len | ||
| ) | [virtual] |
Sends all data over the network.
This may block until all data is send.
| buff | - the buffer of data to send |
| len | - content length |
| E_UNKNOWN,if | an error occured |
| E_SUCCESS,if | successful |
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....
}
| 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.
| buff | - the buffer of data to send |
| len | - content length |
| E_UNKNOWN,if | an error occured |
| E_TIMEDOUT | if the timeout was reached |
| E_SUCCESS,if | successful |
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....
}
}
| 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
| buff | the buffer to send |
| len | content length |
| msTimeOut | Maximum MilliSeconds to wait |
| E_AGAIN | if Operation would block on a non-blocking socket |
| E_TIMEDOUT | if the timeout was reached |
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;
}
| SINT32 CASocket::setKeepAlive | ( | bool | b | ) | [virtual] |
Enables/disables the socket keep-alive option.
| b | true if option should be enabled, false 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;
}
| SINT32 CASocket::setKeepAlive | ( | UINT32 | sec | ) | [virtual] |
Enables the socket keep-alive option with a given ping time (in seconds).
| sec | the time intervall(in seconds) of a keep-alive message |
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
}
| static SINT32 CASocket::setMaxNormalSockets | ( | UINT32 | u | ) | [inline, static] |
Sets the max number of allowed "normal" sockets.
| E_SUCCESS | if call was successful |
| E_UNKNOWN | otherwise |
Definition at line 99 of file CASocket.hpp.
References E_SUCCESS, and m_u32MaxNormalSockets.
Referenced by main().
{
m_u32MaxNormalSockets=u;
return E_SUCCESS;
}
| 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;
}
| SINT32 CASocket::setRecvBuff | ( | UINT32 | r | ) | [virtual] |
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));
}
| SINT32 CASocket::setSendBuff | ( | SINT32 | r | ) | [virtual] |
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();
}
| 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));
}
bool CASocket::m_bIsReservedSocket [private] |
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().
CAMutex CASocket::m_csClose [private] |
Definition at line 137 of file CASocket.hpp.
SOCKET CASocket::m_Socket [protected] |
Definition at line 133 of file CASocket.hpp.
Referenced by accept(), CASocket(), close(), connect(), create(), CATLSClientSocket::doTLSConnect(), getLocalIP(), getLocalPort(), getNonBlocking(), getPeerIP(), getPeerPort(), getRecvBuff(), getSendBuff(), getSendTimeOut(), getSocket(), listen(), receive(), send(), setKeepAlive(), setNonBlocking(), setRecvBuff(), setReuseAddr(), setSendBuff(), and setSendTimeOut().
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().
1.7.6.1