Mixe for Privacy and Anonymity in the Internet
CASocket.cpp
Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2000, The JAP-Team
00003 All rights reserved.
00004 Redistribution and use in source and binary forms, with or without modification,
00005 are permitted provided that the following conditions are met:
00006 
00007   - Redistributions of source code must retain the above copyright notice,
00008     this list of conditions and the following disclaimer.
00009 
00010   - Redistributions in binary form must reproduce the above copyright notice,
00011     this list of conditions and the following disclaimer in the documentation and/or
00012     other materials provided with the distribution.
00013 
00014   - Neither the name of the University of Technology Dresden, Germany nor the names of its contributors
00015     may be used to endorse or promote products derived from this software without specific
00016     prior written permission.
00017 
00018 
00019 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
00020 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
00021 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS
00022 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00023 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
00024 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
00025 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00026 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
00027 */
00028 #include "StdAfx.h"
00029 #include "CASocket.hpp"
00030 #include "CAUtil.hpp"
00031 #include "CASocketAddrINet.hpp"
00032 #ifdef HAVE_UNIX_DOMAIN_PROTOCOL
00033   #include "CASocketAddrUnix.hpp"
00034 #endif
00035 #include "CASingleSocketGroup.hpp"
00036 #ifdef _DEBUG
00037   int sockets;
00038 #endif
00039 #include "CAMsg.hpp"
00040 #include "CAUtil.hpp"
00041 #define CLOSE_SEND    0x01
00042 #define CLOSE_RECEIVE 0x02
00043 #define CLOSE_BOTH    0x03
00044 
00045 volatile UINT32 CASocket::m_u32NormalSocketsOpen=0; //how many "normal" sockets are open
00046 UINT32 CASocket::m_u32MaxNormalSockets=0xFFFFFFFF; //how many "normal" sockets are allowed at max
00047 
00048 
00049 CASocket::CASocket(bool bIsReservedSocket)
00050   {
00051     m_Socket=0;
00052     m_bSocketIsClosed=true;
00053     m_bIsReservedSocket=bIsReservedSocket;
00054   }
00055 
00056 SINT32 CASocket::create()
00057   {
00058     return create(AF_INET, true);
00059   }
00060 
00061 SINT32 CASocket::create(int type)
00062 {
00063   return create(type, true);
00064 }
00065 
00066 SINT32 CASocket::create(bool a_bShowTypicalError)
00067 {
00068   return create(AF_INET, a_bShowTypicalError);
00069 }
00070 
00072 SINT32 CASocket::create(int type, bool a_bShowTypicalError)
00073   {
00074     if(m_bSocketIsClosed)
00075     {
00076       if(m_bIsReservedSocket||m_u32NormalSocketsOpen<m_u32MaxNormalSockets)
00077       {
00078         m_Socket=socket(type,SOCK_STREAM,0);
00079         //CAMsg::printMsg(LOG_DEBUG,"Opened socket: %d\n", m_Socket);
00080       }
00081       else
00082       {
00083         CAMsg::printMsg(LOG_CRIT,"Could not create a new normal Socket -- allowed number of normal sockets exceeded!\n");
00084         return E_SOCKET_LIMIT;
00085       }
00086     }
00087     else
00088       return E_UNKNOWN;
00089     if(m_Socket==INVALID_SOCKET)
00090       {
00091         m_Socket=0;
00092         int er=GET_NET_ERROR;
00093         if (a_bShowTypicalError)
00094         {
00095           if(er==EMFILE)
00096           {
00097             CAMsg::printMsg(LOG_CRIT,"Could not create a new Socket!\n");
00098           }
00099           else
00100           {
00101             CAMsg::printMsg(LOG_CRIT,"Could not create a new Socket! - Error: %s (%i)\n",
00102               GET_NET_ERROR_STR(er), er);
00103           }
00104         }
00105         return E_SOCKET_CREATE;
00106       }
00107     m_bSocketIsClosed=false;
00108     m_csClose.lock();
00109     if(!m_bIsReservedSocket)
00110     {
00111       m_u32NormalSocketsOpen++;
00112     }
00113     m_csClose.unlock();
00114     return E_SUCCESS;
00115   }
00116 
00123 SINT32 CASocket::listen(const CASocketAddr& psa)
00124   {
00125     UINT32 iError;
00126     SINT32 type=psa.getType();
00127     if(m_bSocketIsClosed&&create(type)!=E_SUCCESS)
00128       return E_UNKNOWN;
00129 #ifdef HAVE_UNIX_DOMAIN_PROTOCOL
00130     //we have to delete the file before...
00131     if(psa.getType()==AF_LOCAL)
00132       {
00133         UINT8* path=((CASocketAddrUnix&)psa).getPath();
00134         if(path!=NULL)
00135           {
00136             SINT32 ret=::unlink((char*)path);
00137             if(ret!=0)
00138               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);
00139             delete[] path;
00140             path = NULL;
00141           }
00142       }
00143 #endif
00144     if(::bind(m_Socket,psa.LPSOCKADDR(),psa.getSize())==SOCKET_ERROR)
00145       {
00146         iError = GET_NET_ERROR;
00147         close();
00148         SET_NET_ERROR(iError);
00149         return E_SOCKET_BIND;
00150       }
00151     if(::listen(m_Socket,SOMAXCONN)==SOCKET_ERROR)
00152       {
00153         iError = GET_NET_ERROR;
00154         close();
00155         SET_NET_ERROR(iError);
00156         return E_SOCKET_LISTEN;
00157       }
00158     return E_SUCCESS;
00159   }
00160 
00161 SINT32 CASocket::listen(UINT16 port)
00162   {
00163     CASocketAddrINet oSocketAddrINet(port);
00164     return listen(oSocketAddrINet);
00165   }
00166 
00173 SINT32 CASocket::accept(CASocket &s)
00174   {
00175     if(m_bSocketIsClosed) //the accept socket should not be closed!!
00176       return E_SOCKETCLOSED;
00177     if(!s.m_bSocketIsClosed) //but the new socket should be closed!!!
00178       return E_UNKNOWN;
00179     if(m_u32NormalSocketsOpen>=m_u32MaxNormalSockets)
00180       {
00181         CAMsg::printMsg(LOG_CRIT,"CASocket::accept() -- Could not create a new normal Socket -- allowed number of normal sockets exeded!\n");
00182         return E_SOCKET_LIMIT;
00183       }
00184     s.m_Socket=::accept(m_Socket,NULL,NULL);
00185     if(s.m_Socket==SOCKET_ERROR)
00186       {
00187         s.m_Socket=0;
00188         if(GET_NET_ERROR==ERR_INTERN_SOCKET_CLOSED)
00189           return E_SOCKETCLOSED;
00190         return E_UNKNOWN;
00191       }
00192     s.m_csClose.lock();
00193     m_u32NormalSocketsOpen++;
00194     s.m_bSocketIsClosed=false;
00195     s.m_csClose.unlock();
00196     //CAMsg::printMsg(LOG_DEBUG,"Opened socket: %d\n", s.m_Socket);
00197 
00198     return E_SUCCESS;
00199   }
00200 
00201 
00207 SINT32 CASocket::connect(const CASocketAddr & psa,UINT32 retry,UINT32 time)
00208   {
00209 //    CAMsg::printMsg(LOG_DEBUG,"Socket:connect\n");
00210     if(m_bSocketIsClosed&&create()!=E_SUCCESS)
00211       {
00212         return E_UNKNOWN;
00213       }
00214 #ifdef _DEBUG
00215     sockets++;
00216 #endif
00217     int err=0;
00218     const SOCKADDR* addr=psa.LPSOCKADDR();
00219     int addr_len=psa.getSize();
00220     for(UINT32 i=0;i<retry;i++)
00221       {
00222 //        CAMsg::printMsg(LOG_DEBUG,"Socket:connect-connect\n");
00223         err=::connect(m_Socket,addr,addr_len);
00224 //        CAMsg::printMsg(LOG_DEBUG,"Socket:connect-connect-finished err: %i\n",err);
00225         if(err!=0)
00226           {
00227             err=GET_NET_ERROR;
00228             #ifdef _DEBUG
00229              CAMsg::printMsg(LOG_DEBUG,"Con-Error: %i\n",err);
00230             #endif
00231             if(err!=ERR_INTERN_TIMEDOUT&&err!=ERR_INTERN_CONNREFUSED)
00232               return E_UNKNOWN; //Should be better.....
00233             #ifdef _DEBUG
00234               CAMsg::printMsg(LOG_DEBUG,"Cannot connect... retrying\n");
00235             #endif
00236             sSleep((UINT16)time);
00237           }
00238         else
00239             return E_SUCCESS;
00240       }
00241     return err;
00242   }
00243 
00244 
00250 SINT32 CASocket::connect(const CASocketAddr & psa,UINT32 msTimeOut)
00251   {
00252     if(m_bSocketIsClosed&&create(psa.getType())!=E_SUCCESS)
00253       {
00254         return E_UNKNOWN;
00255       }
00256 #ifdef _DEBUG
00257     sockets++;
00258 #endif
00259     bool bWasNonBlocking=false;
00260     getNonBlocking(&bWasNonBlocking);
00261     setNonBlocking(true);
00262     int err=0;
00263     const LPSOCKADDR addr=(const LPSOCKADDR)psa.LPSOCKADDR();
00264     int addr_len=psa.getSize();
00265 
00266     err=::connect(m_Socket,addr,addr_len);
00267     if(err==0)
00268       return E_SUCCESS;
00269     err=GET_NET_ERROR;
00270 #ifdef _WIN32
00271     if(err!=WSAEWOULDBLOCK)
00272       return E_SOCKET_CONNECT;
00273 #else
00274     if(err!=EINPROGRESS)
00275     {
00276       return E_SOCKET_CONNECT;
00277     }
00278 #endif
00279 
00280 #ifndef HAVE_POLL
00281     struct timeval tval;
00282     tval.tv_sec=msTimeOut/1000;
00283     tval.tv_usec=(msTimeOut%1000)*1000;
00284     fd_set readSet,writeSet;
00285     FD_ZERO(&readSet);
00286     FD_ZERO(&writeSet);
00287     #pragma warning( push )
00288     #pragma warning( disable : 4127 ) //Disable: Bedingter Ausdruck ist konstant
00289     FD_SET(m_Socket,&readSet);
00290     FD_SET(m_Socket,&writeSet);
00291     #pragma warning( pop )
00292     err=::select(m_Socket+1,&readSet,&writeSet,NULL,&tval);
00293 #else
00294     struct pollfd opollfd;
00295     opollfd.fd=m_Socket;
00296     opollfd.events=POLLIN|POLLOUT;
00297     err=::poll(&opollfd,1,msTimeOut);
00298 #endif
00299     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?
00300     {
00301       err = GET_NET_ERROR;
00302       close();
00303       SET_NET_ERROR(err);
00304       
00305       if (GET_NET_ERROR == EINPROGRESS)
00306       {
00307         return E_UNKNOWN;
00308       }
00309       
00310       return E_SOCKET_CONNECT;
00311     }
00312     socklen_t len=sizeof(err);
00313     err=0;
00314     if (::getsockopt(m_Socket,SOL_SOCKET,SO_ERROR,(char*)&err,&len)<0||err!=0) //error by connect
00315     {
00316       err = GET_NET_ERROR;
00317       close();
00318       SET_NET_ERROR(err);
00319       
00320       if (GET_NET_ERROR == EINPROGRESS)
00321       {
00322         return E_UNKNOWN;
00323       }
00324       
00325       return E_SOCKET_CONNECT;
00326     }
00327     setNonBlocking(bWasNonBlocking);
00328     return E_SUCCESS;
00329   }
00330 
00331 SINT32 CASocket::close()
00332   {
00333     SINT32 ret;
00334 
00335     if(m_bSocketIsClosed)
00336     {
00337       return E_SUCCESS;
00338     }
00339 
00340     ret = m_csClose.lock();
00341     if (ret != E_SUCCESS)
00342     {
00343       CAMsg::printMsg(LOG_CRIT,
00344         "Could not get lock for closing socket! Error code: %d\n", ret);
00345       return ret;
00346     }
00347 
00348     if (!m_bSocketIsClosed)
00349     {
00350       shutdown(m_Socket,SHUT_RDWR); //call shutdown here because some OSes seems to ned it to
00351       //wakeup other threads which block in read() or write()
00352       ret=::closesocket(m_Socket);
00353       if(!m_bIsReservedSocket)
00354       {
00355         m_u32NormalSocketsOpen--;
00356       }
00357       //CAMsg::printMsg(LOG_DEBUG,"Open Sockets: %d\n", m_u32NormalSocketsOpen);
00358       //CAMsg::printMsg(LOG_DEBUG,"Closed socket: %d\n", m_Socket);
00359       m_Socket=0;
00360       m_bSocketIsClosed=true;
00361     }
00362 
00363     if (ret != E_SUCCESS)
00364     {
00365       ret = GET_NET_ERROR;
00366     }
00367 
00368     m_csClose.unlock();
00369     return ret;
00370   }
00371 
00380 SINT32 CASocket::send(const UINT8* buff,UINT32 len)
00381   {
00382     if(len==0)
00383       return 0; //nothing to send
00384     int ret;
00385     SINT32 ef=0;
00386     do
00387       {
00388         ret=::send(m_Socket,(char*)buff,len,MSG_NOSIGNAL);
00389         #ifdef _DEBUG
00390           if(ret==SOCKET_ERROR)
00391             CAMsg::printMsg(LOG_DEBUG,"Fehler beim Socket-send: %i (Socket: %i)\n",GET_NET_ERROR,m_Socket);
00392         #endif
00393       }
00394     while(ret==SOCKET_ERROR&&(ef=GET_NET_ERROR)==EINTR);
00395     if(ret==SOCKET_ERROR)
00396       {
00397         if(ef==ERR_INTERN_WOULDBLOCK)
00398           {
00399             #ifdef _DEBUG
00400               CAMsg::printMsg(LOG_DEBUG,"Fehler beim Socket-send: E_AGAIN\n");
00401             #endif
00402             return E_AGAIN;
00403           }
00404         #ifdef _DEBUG
00405           CAMsg::printMsg(LOG_DEBUG,"Fehler beim Socket-send:E_UNKNOWN (ef=%i)\n",ef);
00406         #endif
00407         return E_UNKNOWN;
00408       }
00409     return ret;
00410   }
00411 
00421 
00422 SINT32 CASocket::sendTimeOut(const UINT8* buff,UINT32 len,UINT32 msTimeOut)
00423 {
00424   SINT32 ret;
00425   SINT32 aktTimeOut=0;
00426   bool bWasNonBlocking;
00427   getNonBlocking(&bWasNonBlocking);
00428   if(bWasNonBlocking) //we are in non-blocking mode
00429   {
00430     ret=send(buff,len);
00431   }
00432   else
00433   {
00434     aktTimeOut=getSendTimeOut();
00435     if(aktTimeOut>0&&(UINT32)aktTimeOut==msTimeOut) //we already have the right timeout
00436     {
00437       ret=send(buff,len);
00438     }
00439     else if(aktTimeOut<0||setSendTimeOut(msTimeOut)!=E_SUCCESS)
00440     {//do it complicate but still to simple!!!! more work TODO
00441       setNonBlocking(true);
00442       ret=send(buff,len);
00443       if(ret==E_AGAIN)
00444         {
00445           CAMsg::printMsg(LOG_DEBUG,"Send again...\n");
00446           msSleep((UINT16)msTimeOut);
00447           ret=send(buff,len);
00448         }
00449       setNonBlocking(bWasNonBlocking);
00450     }
00451     else
00452     {
00453       ret=send(buff,len);
00454       setSendTimeOut(aktTimeOut);
00455     }
00456   }
00457   return ret;
00458 }
00459 
00460 
00468 SINT32 CASocket::sendFullyTimeOut(const UINT8* buff,UINT32 len, UINT32 msTimeOut, UINT32 msTimeOutSingleSend)
00469 {
00470   if(len==0)
00471   {
00472     return E_SUCCESS; //nothing to send
00473   }
00474 
00475   SINT32 ret;
00476   SINT32 aktTimeOut=0;
00477   UINT64 startupTime, currentMillis;
00478 
00479 
00480   bool bWasNonBlocking;
00481   getNonBlocking(&bWasNonBlocking);
00482   aktTimeOut=getSendTimeOut();
00483   getcurrentTimeMillis(startupTime);
00484 
00485   if(bWasNonBlocking)
00486   {
00487     //we are in non-blocking mode
00488     return sendFully(buff, len);
00489   }
00490   else if (setSendTimeOut(msTimeOutSingleSend)!=E_SUCCESS)
00491   {
00492     // it is not possible to set the socket timeout
00493     CAMsg::printMsg(LOG_ERR,"CASocket::sendFullyTimeOut() - could not set socket timeout!\n");
00494     return sendFully(buff, len);
00495   }
00496   else
00497   {
00498     for(;;)
00499     {
00500       getcurrentTimeMillis(currentMillis);
00501       if (currentMillis >= (startupTime + msTimeOut))
00502       {
00503         #ifdef DEBUG
00504         CAMsg::printMsg(LOG_DEBUG,"CASocket::sendFullyTimeOut() - timed out!\n");
00505         #endif
00506         setSendTimeOut(aktTimeOut);
00507         SET_NET_ERROR(E_TIMEDOUT);
00508         return E_TIMEDOUT;
00509       }
00510 
00511       ret=send(buff,len);
00512       if((UINT32)ret==len)
00513       {
00514         setSendTimeOut(aktTimeOut);
00515         return E_SUCCESS;
00516       }
00517       else if(ret==E_AGAIN)
00518       {
00519         ret=CASingleSocketGroup::select_once(*this,true,1000);
00520         if(ret>=0||ret==E_TIMEDOUT)
00521           continue;
00522         #ifdef _DEBUG
00523           CAMsg::printMsg(LOG_DEBUG,"CASocket::sendTimeOutFully() - error near select_once() ret=%i\n",ret);
00524         #endif
00525         setSendTimeOut(aktTimeOut);
00526         return E_UNKNOWN;
00527       }
00528       else if(ret<0)
00529       {
00530         #ifdef _DEBUG
00531           CAMsg::printMsg(LOG_DEBUG,"CASocket::sendTimeOutFully() - send returned %i\n",ret);
00532         #endif
00533         setSendTimeOut(aktTimeOut);
00534         return E_UNKNOWN;
00535       }
00536       len-=ret;
00537       buff+=ret;
00538     }
00539     //could never be here....
00540   }
00541 }
00542 
00549 SINT32 CASocket::sendFully(const UINT8* buff,UINT32 len)
00550   {
00551     if(len==0)
00552       return E_SUCCESS; //nothing to send
00553     SINT32 ret;
00554     for(;;)
00555       {
00556         ret=send(buff,len);
00557         if((UINT32)ret==len)
00558           return E_SUCCESS;
00559         else if(ret==E_AGAIN)
00560           {
00561             ret=CASingleSocketGroup::select_once(*this,true,1000);
00562             if(ret>=0||ret==E_TIMEDOUT)
00563               continue;
00564             #ifdef _DEBUG
00565               CAMsg::printMsg(LOG_DEBUG,"CASocket::sendFully() - error near select_once() ret=%i\n",ret);
00566             #endif
00567             return E_UNKNOWN;
00568           }
00569         else if(ret<0)
00570           {
00571             #ifdef _DEBUG
00572               CAMsg::printMsg(LOG_DEBUG,"CASocket::sendFully() - send returned %i\n",ret);
00573             #endif
00574             return E_UNKNOWN;
00575           }
00576         len-=ret;
00577         buff+=ret;
00578       }
00579       //could never be here....
00580   }
00581 
00595 SINT32 CASocket::receive(UINT8* buff,UINT32 len)
00596   {
00597     int ret;
00598     int ef=0;
00599     do
00600       {
00601         ret=::recv(m_Socket,(char*)buff,len,MSG_NOSIGNAL);
00602       }
00603     while(ret==SOCKET_ERROR&&(ef=GET_NET_ERROR)==EINTR);
00604     if(ret==SOCKET_ERROR)
00605       {
00606         if(ef==ERR_INTERN_WOULDBLOCK)
00607           return E_AGAIN;
00608       }
00609 #ifdef _DEBUG
00610     if(ret==SOCKET_ERROR)
00611         CAMsg::printMsg(LOG_DEBUG,"CASocket Receive error %d (%s)\n",ef,GET_NET_ERROR_STR(ef));
00612 #endif
00613     return ret;
00614   }
00615 
00627 SINT32 CASocket::receiveFullyT(UINT8* buff,UINT32 len,UINT32 msTimeOut)
00628   {
00629     SINT32 ret;
00630     UINT32 pos=0;
00631     UINT64 currentTime,endTime;
00632     getcurrentTimeMillis(currentTime);
00633     set64(endTime,currentTime);
00634     add64(endTime,msTimeOut);
00635     CASingleSocketGroup oSG(false);
00636     oSG.add(*this);
00637     for(;;)
00638       {
00639         ret=oSG.select(msTimeOut);
00640         if(ret==1)
00641           {
00642             ret=receive(buff+pos,len);
00643             if(ret<=0)
00644               return E_UNKNOWN;
00645             pos+=ret;
00646             len-=ret;
00647           }
00648         else if(ret==E_TIMEDOUT)
00649         {
00650           return E_TIMEDOUT;
00651         }
00652         if(len==0)
00653           return E_SUCCESS;
00654         getcurrentTimeMillis(currentTime);
00655         if(!isLesser64(currentTime,endTime))
00656         {
00657           SET_NET_ERROR(E_TIMEDOUT);
00658           return E_TIMEDOUT;
00659         }
00660         msTimeOut=diff64(endTime,currentTime);
00661       }
00662   }
00663 
00664 SINT32 CASocket::receiveLine(UINT8* line, UINT32 maxLen, UINT32 msTimeOut)
00665 {
00666   UINT32 i = 0;
00667   UINT8 byte = 0;
00668   SINT32 ret = 0;
00669   UINT64 currentTime, endTime;
00670   getcurrentTimeMillis(currentTime);
00671   set64(endTime,currentTime);
00672   add64(endTime,msTimeOut);
00673   CASingleSocketGroup oSG(false);
00674   oSG.add(*this);
00675   do
00676   {
00677     ret = oSG.select(msTimeOut);
00678     if(ret == 1)
00679     {
00680       ret = receive(&byte, 1);
00681       if(byte == '\r' || byte == '\n')
00682       {
00683         line[i++] = 0;
00684       }
00685       else
00686       {
00687         line[i++] = byte;
00688       }
00689     }
00690     else if(ret == E_TIMEDOUT)
00691     {
00692       return E_TIMEDOUT;
00693     }
00694     getcurrentTimeMillis(currentTime);
00695     if(!isLesser64(currentTime,endTime))
00696     {
00697       SET_NET_ERROR(E_TIMEDOUT);
00698       return E_TIMEDOUT;
00699     }
00700     msTimeOut=diff64(endTime,currentTime);
00701   }
00702   while(byte != '\n' && i<maxLen && ret > 0);
00703 
00704   return ret;
00705 }
00706 
00716 SINT32 CASocket::getLocalIP(UINT8 r_Ip[4])
00717 {
00718       struct sockaddr_in addr;
00719       socklen_t namelen=sizeof(struct sockaddr_in);
00720       if(getsockname(m_Socket,(struct sockaddr*)&addr,&namelen)==SOCKET_ERROR)
00721          return SOCKET_ERROR;
00722       memcpy(r_Ip,&addr.sin_addr,4);
00723       return E_SUCCESS;
00724 }
00725 
00726 SINT32 CASocket::getLocalPort()
00727   {
00728     struct sockaddr_in addr;
00729     socklen_t namelen=sizeof(struct sockaddr_in);
00730     if(getsockname(m_Socket,(struct sockaddr*)&addr,&namelen)==SOCKET_ERROR)
00731       return SOCKET_ERROR;
00732     return ntohs(addr.sin_port);
00733   }
00734 
00735 SINT32 CASocket::getPeerIP(UINT8 ip[4])
00736   {
00737     struct sockaddr_in addr;
00738     socklen_t namelen=sizeof(struct sockaddr_in);
00739     if(getpeername(m_Socket,(struct sockaddr*)&addr,&namelen)==SOCKET_ERROR)
00740       return SOCKET_ERROR;
00741     memcpy(ip,&addr.sin_addr,4);
00742     return E_SUCCESS;
00743   }
00744 
00745 SINT32 CASocket::getPeerPort()
00746   {
00747     struct sockaddr_in addr;
00748     socklen_t namelen=sizeof(struct sockaddr_in);
00749     if(getpeername(m_Socket,(struct sockaddr*)&addr,&namelen)==SOCKET_ERROR)
00750       return SOCKET_ERROR;
00751     return ntohs(addr.sin_port);
00752   }
00753 
00754 SINT32 CASocket::setReuseAddr(bool b)
00755   {
00756     int val=0;
00757     if(b) val=1;
00758     return setsockopt(m_Socket,SOL_SOCKET,SO_REUSEADDR,(char*)&val,sizeof(val));
00759   }
00760 
00761 SINT32 CASocket::setRecvBuff(UINT32 r)
00762   {
00763     int val=r;
00764     return setsockopt(m_Socket,SOL_SOCKET,SO_RCVBUF,(char*)&val,sizeof(val));
00765   }
00766 
00767 SINT32 CASocket::getRecvBuff()
00768   {
00769     int val;
00770     socklen_t size=sizeof(val);
00771     if(getsockopt(m_Socket,SOL_SOCKET,SO_RCVBUF,(char*)&val,&size)==SOCKET_ERROR)
00772       return E_UNKNOWN;
00773     else
00774       return val;
00775   }
00777 SINT32 CASocket::setSendBuff(SINT32 r)
00778   {
00779     if(r<0)
00780       return E_UNKNOWN;
00781     SINT32 val=r;
00782     SINT32 ret=setsockopt(m_Socket,SOL_SOCKET,SO_SNDBUF,(char*)&val,sizeof(val));
00783     if(ret!=0)
00784       return E_UNKNOWN;
00785     return getSendBuff();
00786   }
00787 
00788 SINT32 CASocket::getSendBuff()
00789   {
00790     SINT32 val;
00791     socklen_t size=sizeof(val);
00792     if(getsockopt(m_Socket,SOL_SOCKET,SO_SNDBUF,(char*)&val,&size)==SOCKET_ERROR)
00793       return E_UNKNOWN;
00794     else
00795       return val;
00796   }
00797 
00798 SINT32 CASocket::setSendTimeOut(UINT32 msTimeOut)
00799   {
00800     timeval t;
00801     t.tv_sec=msTimeOut/1000;
00802     t.tv_usec=(msTimeOut%1000)*1000;
00803     return setsockopt(m_Socket,SOL_SOCKET,SO_SNDTIMEO,(char*)&t,sizeof(t));
00804   }
00805 
00806 SINT32 CASocket::getSendTimeOut()
00807   {
00808     timeval val;
00809     socklen_t size=sizeof(val);
00810     if(getsockopt(m_Socket,SOL_SOCKET,SO_SNDTIMEO,(char*)&val,&size)==SOCKET_ERROR)
00811       return E_UNKNOWN;
00812     else
00813       return val.tv_sec*1000+val.tv_usec/1000;
00814   }
00815 
00821 SINT32 CASocket::setKeepAlive(bool b)
00822   {
00823     int val=0;
00824     if(b) val=1;
00825     if(setsockopt(m_Socket,SOL_SOCKET,SO_KEEPALIVE,(char*)&val,sizeof(val))==SOCKET_ERROR)
00826     {
00827       int errnum=GET_NET_ERROR;
00828       CAMsg::printMsg(LOG_ERR, "Could not set KEEP_ALIVE options. Reason: %s (%i)\n", GET_NET_ERROR_STR(errnum), errnum);
00829       return E_UNKNOWN;
00830     }
00831     return E_SUCCESS;
00832   }
00833 
00839 SINT32 CASocket::setKeepAlive(UINT32 sec)
00840   {
00841     if(setKeepAlive(true)!=E_SUCCESS)
00842     {
00843       return E_UNKNOWN;
00844     }
00845 
00846 #ifdef HAVE_TCP_KEEPALIVE
00847     int val=sec;
00848     if(setsockopt(m_Socket,IPPROTO_TCP,TCP_KEEPALIVE,(char*)&val,sizeof(val))==SOCKET_ERROR)
00849     {
00850       CAMsg::printMsg(LOG_ERR,"Socket option TCP-KEEP-ALIVE was not set! Reason: %s (%i)\n",
00851           GET_NET_ERROR_STR(GET_NET_ERROR), GET_NET_ERROR);
00852       return E_UNKNOWN;
00853     }
00854     return E_SUCCESS;
00855 #else
00856     CAMsg::printMsg(LOG_INFO,"Socket option TCP-KEEP-ALIVE was not set as it is not available on this machine.\n");
00857     return E_UNKNOWN;
00858 #endif
00859   }
00860 
00861 
00862 SINT32 CASocket::setNonBlocking(bool b)
00863   {
00864     if(b)
00865       {
00866         #ifndef _WIN32
00867             int flags=fcntl(m_Socket,F_GETFL,0);
00868             fcntl(m_Socket,F_SETFL,flags|O_NONBLOCK);
00869         #else
00870             unsigned long flags=1;
00871             ioctlsocket(m_Socket,FIONBIO,&flags);
00872         #endif
00873       }
00874     else
00875       {
00876         #ifndef _WIN32
00877             int flags=fcntl(m_Socket,F_GETFL,0);
00878             fcntl(m_Socket,F_SETFL,flags&~O_NONBLOCK);
00879         #else
00880             unsigned long flags=0;
00881             ioctlsocket(m_Socket,FIONBIO,&flags);
00882         #endif
00883       }
00884     return E_SUCCESS;
00885   }
00886 
00887 SINT32 CASocket::getNonBlocking(bool* b)
00888   {
00889     #ifndef _WIN32
00890         int flags=fcntl(m_Socket,F_GETFL,0);
00891         *b=((flags&O_NONBLOCK)==O_NONBLOCK);
00892         return E_SUCCESS;
00893     #else
00894         return SOCKET_ERROR;
00895     #endif
00896   }
00897 
00898 SINT32 CASocket::getMaxOpenSockets()
00899 {
00900   CASocket* parSocket=new CASocket[10001];
00901   UINT32 maxSocket=0;
00902   for(UINT32 t=0;t<10001;t++)
00903     {
00904     if(parSocket[t].create(false)!=E_SUCCESS)
00905       {
00906       maxSocket=t;
00907       break;
00908       }
00909     }
00910   for(UINT32 t=0;t<maxSocket;t++)
00911     {
00912     parSocket[t].close();
00913     }
00914   delete []parSocket;
00915   parSocket = NULL;
00916   return maxSocket;
00917 }
00918