Mixe for Privacy and Anonymity in the Internet
CASocket.cpp
Go to the documentation of this file.
1 /*
2 Copyright (c) 2000, The JAP-Team
3 All rights reserved.
4 Redistribution and use in source and binary forms, with or without modification,
5 are permitted provided that the following conditions are met:
6 
7  - Redistributions of source code must retain the above copyright notice,
8  this list of conditions and the following disclaimer.
9 
10  - Redistributions in binary form must reproduce the above copyright notice,
11  this list of conditions and the following disclaimer in the documentation and/or
12  other materials provided with the distribution.
13 
14  - Neither the name of the University of Technology Dresden, Germany nor the names of its contributors
15  may be used to endorse or promote products derived from this software without specific
16  prior written permission.
17 
18 
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
20 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
21 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS
22 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
27 */
28 #include "StdAfx.h"
29 #include "CASocket.hpp"
30 #include "CAUtil.hpp"
31 #include "CASocketAddrINet.hpp"
32 #ifdef HAVE_UNIX_DOMAIN_PROTOCOL
33  #include "CASocketAddrUnix.hpp"
34 #endif
35 #include "CASingleSocketGroup.hpp"
36 #ifdef _DEBUG
37  int sockets;
38 #endif
39 #include "CAMsg.hpp"
40 #include "CAUtil.hpp"
41 #define CLOSE_SEND 0x01
42 #define CLOSE_RECEIVE 0x02
43 #define CLOSE_BOTH 0x03
44 
45 volatile UINT32 CASocket::m_u32NormalSocketsOpen=0; //how many "normal" sockets are open
46 UINT32 CASocket::m_u32MaxNormalSockets=0xFFFFFFFF; //how many "normal" sockets are allowed at max
48 
49 CASocket::CASocket(bool bIsReservedSocket)
50  {
51  m_Socket=0;
52  m_bSocketIsClosed=true;
53  m_bIsReservedSocket=bIsReservedSocket;
55  }
56 
58  {
60  m_Socket = s;
61  if (s != 0)
62  {
65  }
66  else
67  {
69  }
70  return E_SUCCESS;
71  }
72 
74  {
75  return create(AF_INET, true);
76  }
77 
79 {
80  return create(type, true);
81 }
82 
83 SINT32 CASocket::create(bool a_bShowTypicalError)
84 {
85  return create(AF_INET, a_bShowTypicalError);
86 }
87 
89 SINT32 CASocket::create(SINT32 type, bool a_bShowTypicalError)
90  {
93  {
95  {
96  s=::socket(type,SOCK_STREAM,0);
97  //CAMsg::printMsg(LOG_DEBUG,"Opened socket: %d\n", m_Socket);
98  }
99  else
100  {
101  CAMsg::printMsg(LOG_CRIT,"Could not create a new normal Socket -- allowed number of normal sockets exceeded!\n");
102  return E_SOCKET_LIMIT;
103  }
104  }
105  else
106  return E_UNKNOWN;
107  if(s==INVALID_SOCKET)
108  {
109  setSocket(0);
110  int er=GET_NET_ERROR;
111  if (a_bShowTypicalError)
112  {
113  if(er==EMFILE)
114  {
115  CAMsg::printMsg(LOG_CRIT,"Could not create a new Socket!\n");
116  }
117  else
118  {
119  CAMsg::printMsg(LOG_CRIT,"Could not create a new Socket! - Error: %s (%i)\n",
120  GET_NET_ERROR_STR(er), er);
121  }
122  }
123  return E_SOCKET_CREATE;
124  }
125  m_bSocketIsClosed=false;
126  m_pcsClose->lock();
128  {
130  }
131  m_pcsClose->unlock();
132  setSocket(s);
133  return E_SUCCESS;
134  }
135 
143  {
144  UINT32 iError;
145  SINT32 type=psa.getType();
147  return E_UNKNOWN;
148 #ifdef HAVE_UNIX_DOMAIN_PROTOCOL
149  //we have to delete the file before...
150  if(psa.getType()==AF_LOCAL)
151  {
152  UINT8* path=((CASocketAddrUnix&)psa).getPath();
153  if(path!=NULL)
154  {
155  SINT32 ret=::unlink((char*)path);
156  if(ret!=0)
157  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);
158  delete[] path;
159  path = NULL;
160  }
161  }
162 #endif
163  if(::bind(m_Socket,psa.LPSOCKADDR(),psa.getSize())==SOCKET_ERROR)
164  {
165  iError = GET_NET_ERROR;
166  close();
167  SET_NET_ERROR(iError);
168  return E_SOCKET_BIND;
169  }
170  if(::listen(m_Socket,SOMAXCONN)==SOCKET_ERROR)
171  {
172  iError = GET_NET_ERROR;
173  close();
174  SET_NET_ERROR(iError);
175  return E_SOCKET_LISTEN;
176  }
177  return E_SUCCESS;
178  }
179 
181  {
182  CASocketAddrINet oSocketAddrINet(port);
183  return listen(oSocketAddrINet);
184  }
185 
193  {
194  if(m_bSocketIsClosed) //the accept socket should not be closed!!
195  return E_SOCKETCLOSED;
196  if(!s.m_bSocketIsClosed) //but the new socket should be closed!!!
197  return E_UNKNOWN;
199  {
200  CAMsg::printMsg(LOG_CRIT,"CASocket::accept() -- Could not create a new normal Socket -- allowed number of normal sockets exeded!\n");
201  return E_SOCKET_LIMIT;
202  }
203  SOCKET sock=::accept(m_Socket,NULL,NULL);
204  if (sock == SOCKET_ERROR)
205  {
206  s.setSocket(0);
208  return E_SOCKETCLOSED;
209  return E_UNKNOWN;
210  }
211  s.setSocket(sock);
212  m_pcsClose->lock();
214  s.m_bSocketIsClosed=false;
215  m_pcsClose->unlock();
216  //CAMsg::printMsg(LOG_DEBUG,"Opened socket: %d\n", s.m_Socket);
217 
218  return E_SUCCESS;
219  }
220 
221 
228  {
229 // CAMsg::printMsg(LOG_DEBUG,"Socket:connect\n");
231  {
232  return E_UNKNOWN;
233  }
234 #ifdef _DEBUG
235  sockets++;
236 #endif
237  int err=0;
238  const SOCKADDR* addr=psa.LPSOCKADDR();
239  int addr_len=psa.getSize();
240  for(UINT32 i=0;i<retry;i++)
241  {
242 // CAMsg::printMsg(LOG_DEBUG,"Socket:connect-connect\n");
243  err=::connect(m_Socket,addr,addr_len);
244 // CAMsg::printMsg(LOG_DEBUG,"Socket:connect-connect-finished err: %i\n",err);
245  if(err!=0)
246  {
247  err=GET_NET_ERROR;
248  #ifdef _DEBUG
249  CAMsg::printMsg(LOG_DEBUG,"Con-Error: %i\n",err);
250  #endif
252  return E_UNKNOWN; //Should be better.....
253  #ifdef _DEBUG
254  CAMsg::printMsg(LOG_DEBUG,"Cannot connect... retrying\n");
255  #endif
256  sSleep((UINT16)time);
257  }
258  else
259  return E_SUCCESS;
260  }
261  return err;
262  }
263 
264 
271  {
273  {
274  return E_UNKNOWN;
275  }
276 #ifdef _DEBUG
277  sockets++;
278 #endif
279  bool bWasNonBlocking=false;
280  getNonBlocking(&bWasNonBlocking);
281  setNonBlocking(true);
282  int err=0;
283  const LPSOCKADDR addr=(const LPSOCKADDR)psa.LPSOCKADDR();
284  int addr_len=psa.getSize();
285 
286  err=::connect(m_Socket,addr,addr_len);
287  if(err==0)
288  return E_SUCCESS;
289  err=GET_NET_ERROR;
290 #ifdef _WIN32
291  if(err!=WSAEWOULDBLOCK)
292  return E_SOCKET_CONNECT;
293 #else
294  if(err!=EINPROGRESS)
295  {
296  return E_SOCKET_CONNECT;
297  }
298 #endif
299 
300 #ifndef HAVE_POLL
301  struct timeval tval;
302  tval.tv_sec=msTimeOut/1000;
303  tval.tv_usec=(msTimeOut%1000)*1000;
304  fd_set readSet,writeSet;
305  FD_ZERO(&readSet);
306  FD_ZERO(&writeSet);
307  #pragma warning( push )
308  #pragma warning( disable : 4127 ) //Disable: Bedingter Ausdruck ist konstant
309  FD_SET(m_Socket,&readSet);
310  FD_SET(m_Socket,&writeSet);
311  #pragma warning( pop )
312  err=::select(m_Socket+1,&readSet,&writeSet,NULL,&tval);
313 #else
314  struct pollfd opollfd;
315  opollfd.fd=m_Socket;
316  opollfd.events=POLLIN|POLLOUT;
317  err=::poll(&opollfd,1,msTimeOut);
318 #endif
319  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?
320  {
321  err = GET_NET_ERROR;
322  close();
323  SET_NET_ERROR(err);
324 
325  if (GET_NET_ERROR == EINPROGRESS)
326  {
327  return E_UNKNOWN;
328  }
329 
330  return E_SOCKET_CONNECT;
331  }
332  socklen_t len=sizeof(err);
333  err=0;
334  if (::getsockopt(m_Socket,SOL_SOCKET,SO_ERROR,(char*)&err,&len)<0||err!=0) //error by connect
335  {
336  err = GET_NET_ERROR;
337  close();
338  SET_NET_ERROR(err);
339 
340  if (GET_NET_ERROR == EINPROGRESS)
341  {
342  return E_UNKNOWN;
343  }
344 
345  return E_SOCKET_CONNECT;
346  }
347  setNonBlocking(bWasNonBlocking);
348  return E_SUCCESS;
349  }
350 
352  {
353  SINT32 ret;
354 
356  {
357  return E_SUCCESS;
358  }
359 
360  ret = m_pcsClose->lock();
361  if (ret != E_SUCCESS)
362  {
363  CAMsg::printMsg(LOG_CRIT,
364  "Could not get lock for closing socket! Error code: %d\n", ret);
365  return ret;
366  }
367 
368  if (!m_bSocketIsClosed)
369  {
370  shutdown(m_Socket,SHUT_RDWR); //call shutdown here because some OSes seems to ned it to
371  //wakeup other threads which block in read() or write()
372  ret=::closesocket(m_Socket);
374  {
376  }
377  //CAMsg::printMsg(LOG_DEBUG,"Open Sockets: %d\n", m_u32NormalSocketsOpen);
378  //CAMsg::printMsg(LOG_DEBUG,"Closed socket: %d\n", m_Socket);
379  setSocket(0);
380  m_bSocketIsClosed=true;
381  }
382 
383  if (ret != E_SUCCESS)
384  {
385  ret = GET_NET_ERROR;
386  }
387 
388  m_pcsClose->unlock();
389  return ret;
390  }
391 
401  {
402  if(len==0)
403  return 0; //nothing to send
404  int ret;
405  SINT32 ef=0;
406  do
407  {
408  ret=::send(m_Socket,(char*)buff,len,MSG_NOSIGNAL);
409  #ifdef _DEBUG
410  if(ret==SOCKET_ERROR)
411  CAMsg::printMsg(LOG_DEBUG,"Fehler beim Socket-send: %i (Socket: %i)\n",GET_NET_ERROR,m_Socket);
412  #endif
413  }
414  while(ret==SOCKET_ERROR&&(ef=GET_NET_ERROR)==EINTR);
415  if(ret==SOCKET_ERROR)
416  {
417  if(ef==ERR_INTERN_WOULDBLOCK)
418  {
419  #ifdef _DEBUG
420  CAMsg::printMsg(LOG_DEBUG,"Fehler beim Socket-send: E_AGAIN\n");
421  #endif
422  return E_AGAIN;
423  }
424  #ifdef _DEBUG
425  CAMsg::printMsg(LOG_DEBUG,"Fehler beim Socket-send:E_UNKNOWN (ef=%i)\n",ef);
426  #endif
427  return E_UNKNOWN;
428  }
429  return ret;
430  }
431 
441 
443 {
444  SINT32 ret;
445  SINT32 aktTimeOut=0;
446  bool bWasNonBlocking;
447  getNonBlocking(&bWasNonBlocking);
448  if(bWasNonBlocking) //we are in non-blocking mode
449  {
450  ret=send(buff,len);
451  }
452  else
453  {
454  aktTimeOut=getSendTimeOut();
455  if(aktTimeOut>0&&(UINT32)aktTimeOut==msTimeOut) //we already have the right timeout
456  {
457  ret=send(buff,len);
458  }
459  else if(aktTimeOut<0||setSendTimeOut(msTimeOut)!=E_SUCCESS)
460  {//do it complicate but still to simple!!!! more work TODO
461  setNonBlocking(true);
462  ret=send(buff,len);
463  if(ret==E_AGAIN)
464  {
465  CAMsg::printMsg(LOG_DEBUG,"Send again...\n");
466  msSleep((UINT16)msTimeOut);
467  ret=send(buff,len);
468  }
469  setNonBlocking(bWasNonBlocking);
470  }
471  else
472  {
473  ret=send(buff,len);
474  setSendTimeOut(aktTimeOut);
475  }
476  }
477  return ret;
478 }
479 
480 
488 SINT32 CASocket::sendFullyTimeOut(const UINT8* buff,UINT32 len, UINT32 msTimeOut, UINT32 msTimeOutSingleSend)
489 {
490  if(len==0)
491  {
492  return E_SUCCESS; //nothing to send
493  }
494 
495  SINT32 ret;
496  SINT32 aktTimeOut=0;
497  UINT64 startupTime, currentMillis;
498  CASingleSocketGroup* pSingleSocketGroup = NULL;
499 
500  bool bWasNonBlocking;
501  getNonBlocking(&bWasNonBlocking);
502  aktTimeOut=getSendTimeOut();
503  getcurrentTimeMillis(startupTime);
504 
505  if(bWasNonBlocking)
506  {
507  //we are in non-blocking mode
508 #ifdef _DEBUG
509  CAMsg::printMsg(LOG_DEBUG, "CASocket::sendFullyTimeOut() -->non-blocking case\n");
510 #endif
511  return sendFully(buff, len);
512  }
513  else if (setSendTimeOut(msTimeOutSingleSend)!=E_SUCCESS)
514  {
515  // it is not possible to set the socket timeout
516  CAMsg::printMsg(LOG_ERR,"CASocket::sendFullyTimeOut() - could not set socket timeout!\n");
517  return sendFully(buff, len);
518  }
519  else
520  {
521  SINT32 retval = E_UNKNOWN;
522  for(;;)
523  {
524  getcurrentTimeMillis(currentMillis);
525  if (currentMillis >= (startupTime + msTimeOut))
526  {
527  #ifdef DEBUG
528  CAMsg::printMsg(LOG_DEBUG,"CASocket::sendFullyTimeOut() - timed out!\n");
529  #endif
530  setSendTimeOut(aktTimeOut);
532  retval=E_TIMEDOUT;
533  break;
534  }
535 
536  ret=send(buff,len);
537 #ifdef DEBUG
538  CAMsg::printMsg(LOG_DEBUG, "CASocket::sendFullyTimeOut() - send returned %i (expected: %u)!\n",ret,len);
539 #endif
540  if((UINT32)ret==len)
541  {
542  setSendTimeOut(aktTimeOut);
543  retval=E_SUCCESS;
544  break;
545  }
546  else if(ret==E_AGAIN)
547  {
548  if (pSingleSocketGroup == NULL)
549  {
550  pSingleSocketGroup = new CASingleSocketGroup(true);
551  pSingleSocketGroup->add(*this);
552  }
553  ret= pSingleSocketGroup->select(1000);
554  if(ret>=0||ret==E_TIMEDOUT)
555  continue;
556  #ifdef _DEBUG
557  CAMsg::printMsg(LOG_DEBUG,"CASocket::sendTimeOutFully() - error near select_once() ret=%i\n",ret);
558  #endif
559  setSendTimeOut(aktTimeOut);
560  retval=E_UNKNOWN;
561  break;
562  }
563  else if(ret<0)
564  {
565  #ifdef _DEBUG
566  CAMsg::printMsg(LOG_DEBUG,"CASocket::sendTimeOutFully() - send returned %i\n",ret);
567  #endif
568  setSendTimeOut(aktTimeOut);
569  retval=E_UNKNOWN;
570  break;
571  }
572  len-=ret;
573  buff+=ret;
574  }
575  if (pSingleSocketGroup != NULL)
576  delete pSingleSocketGroup;
577  return retval;
578  }
579 }
580 
588  {
589  if(len==0)
590  return E_SUCCESS; //nothing to send
591  SINT32 ret;
592  CASingleSocketGroup* pSingleSocketGroup = NULL;
593  SINT32 retval = E_UNKNOWN;
594  for(;;)
595  {
596  ret=send(buff,len);
597  if((UINT32)ret==len)
598  return E_SUCCESS;
599  else if(ret==E_AGAIN)
600  {
601  if (pSingleSocketGroup == NULL)
602  {
603  pSingleSocketGroup = new CASingleSocketGroup(true);
604  pSingleSocketGroup->add(*this);
605  }
606 
607  ret= pSingleSocketGroup->select(1000);
608  if(ret>=0||ret==E_TIMEDOUT)
609  continue;
610  #ifdef _DEBUG
611  CAMsg::printMsg(LOG_DEBUG,"CASocket::sendFully() - error near select_once() ret=%i\n",ret);
612  #endif
613  retval=E_UNKNOWN;
614  break;
615  }
616  else if(ret<0)
617  {
618  #ifdef _DEBUG
619  CAMsg::printMsg(LOG_DEBUG,"CASocket::sendFully() - send returned %i\n",ret);
620  #endif
621  retval=E_UNKNOWN;
622  break;
623  }
624  len-=ret;
625  buff+=ret;
626  }
627  if (pSingleSocketGroup != NULL)
628  delete pSingleSocketGroup;
629  return retval;
630 }
631 
646  {
647  int ret;
648  int ef=0;
649  do
650  {
651  ret=::recv(m_Socket,(char*)buff,len,MSG_NOSIGNAL);
652  }
653  while(ret==SOCKET_ERROR&&(ef=GET_NET_ERROR)==EINTR);
654  if(ret==SOCKET_ERROR)
655  {
656  if(ef==ERR_INTERN_WOULDBLOCK)
657  return E_AGAIN;
658  }
659 #ifdef _DEBUG
660  if(ret==SOCKET_ERROR)
661  CAMsg::printMsg(LOG_DEBUG,"CASocket Receive error %d (%s)\n",ef,GET_NET_ERROR_STR(ef));
662 #endif
663  return ret;
664  }
665 
678  {
679  SINT32 ret;
680  UINT32 pos=0;
681  UINT64 currentTime,endTime;
682  getcurrentTimeMillis(currentTime);
683  set64(endTime,currentTime);
684  add64(endTime,msTimeOut);
685 // CASingleSocketGroup oSG(false);
686 // oSG.add(*this);
687  for(;;)
688  {
689  ret = m_pSingleSocketGroupRead->select(msTimeOut);
690  if(ret==1)
691  {
692  ret=receive(buff+pos,len);
693  if(ret<=0)
694  return E_UNKNOWN;
695  pos+=ret;
696  len-=ret;
697  }
698  else if(ret==E_TIMEDOUT)
699  {
700  return E_TIMEDOUT;
701  }
702  if(len==0)
703  return E_SUCCESS;
704  getcurrentTimeMillis(currentTime);
705  if(!isLesser64(currentTime,endTime))
706  {
708  return E_TIMEDOUT;
709  }
710  msTimeOut=diff64(endTime,currentTime);
711  }
712  }
713 
714 SINT32 CASocket::receiveLine(UINT8* line, UINT32 maxLen, UINT32 msTimeOut)
715 {
716  UINT32 i = 0;
717  UINT8 byte = 0;
718  SINT32 ret = 0;
719  UINT64 currentTime, endTime;
720  getcurrentTimeMillis(currentTime);
721  set64(endTime,currentTime);
722  add64(endTime,msTimeOut);
723 // CASingleSocketGroup oSG(false);
724 // oSG.add(*this);
725  do
726  {
727  ret = m_pSingleSocketGroupRead->select(msTimeOut);
728  if(ret == 1)
729  {
730  ret = receive(&byte, 1);
731  if(byte == '\r' || byte == '\n')
732  {
733  line[i++] = 0;
734  }
735  else
736  {
737  line[i++] = byte;
738  }
739  }
740  else if(ret == E_TIMEDOUT)
741  {
742  return E_TIMEDOUT;
743  }
744  getcurrentTimeMillis(currentTime);
745  if(!isLesser64(currentTime,endTime))
746  {
748  return E_TIMEDOUT;
749  }
750  msTimeOut=diff64(endTime,currentTime);
751  }
752  while(byte != '\n' && i<maxLen && ret > 0);
753 
754  return ret;
755 }
756 
771  {
772  int ret;
773  int ef=0;
774  do
775  {
776  ret=::recv(m_Socket,(char*)buff,len,MSG_NOSIGNAL|MSG_PEEK);
777  }
778  while(ret==SOCKET_ERROR&&(ef=GET_NET_ERROR)==EINTR);
779  if(ret==SOCKET_ERROR)
780  {
781  if(ef==ERR_INTERN_WOULDBLOCK)
782  return E_AGAIN;
783  }
784 #ifdef _DEBUG
785  if(ret==SOCKET_ERROR)
786  CAMsg::printMsg(LOG_DEBUG,"CASocket peek() error %d (%s)\n",ef,GET_NET_ERROR_STR(ef));
787 #endif
788  return ret;
789  }
790 
791 
802 {
803  struct sockaddr_in addr;
804  socklen_t namelen=sizeof(struct sockaddr_in);
805  if(getsockname(m_Socket,(struct sockaddr*)&addr,&namelen)==SOCKET_ERROR)
806  return SOCKET_ERROR;
807  memcpy(r_Ip,&addr.sin_addr,4);
808  return E_SUCCESS;
809 }
810 
812  {
813  struct sockaddr_in addr;
814  socklen_t namelen=sizeof(struct sockaddr_in);
815  if(getsockname(m_Socket,(struct sockaddr*)&addr,&namelen)==SOCKET_ERROR)
816  return SOCKET_ERROR;
817  return ntohs(addr.sin_port);
818  }
819 
821  {
822  struct sockaddr_in addr;
823  socklen_t namelen=sizeof(struct sockaddr_in);
824  if(getpeername(m_Socket,(struct sockaddr*)&addr,&namelen)==SOCKET_ERROR)
825  return SOCKET_ERROR;
826  memcpy(ip,&addr.sin_addr,4);
827  return E_SUCCESS;
828  }
829 
831  {
832  struct sockaddr_in addr;
833  socklen_t namelen=sizeof(struct sockaddr_in);
834  if(getpeername(m_Socket,(struct sockaddr*)&addr,&namelen)==SOCKET_ERROR)
835  return SOCKET_ERROR;
836  return ntohs(addr.sin_port);
837  }
838 
840  {
841  int val=0;
842  if(b) val=1;
843  return setsockopt(m_Socket,SOL_SOCKET,SO_REUSEADDR,(char*)&val,sizeof(val));
844  }
845 
847  {
848  int val=r;
849  return setsockopt(m_Socket,SOL_SOCKET,SO_RCVBUF,(char*)&val,sizeof(val));
850  }
851 
853  {
854  int val;
855  socklen_t size=sizeof(val);
856  if(getsockopt(m_Socket,SOL_SOCKET,SO_RCVBUF,(char*)&val,&size)==SOCKET_ERROR)
857  return E_UNKNOWN;
858  else
859  return val;
860  }
863  {
864  if(r<0)
865  return E_UNKNOWN;
866  SINT32 val=r;
867  SINT32 ret=setsockopt(m_Socket,SOL_SOCKET,SO_SNDBUF,(char*)&val,sizeof(val));
868  if(ret!=0)
869  return E_UNKNOWN;
870  return getSendBuff();
871  }
872 
874  {
875  SINT32 val;
876  socklen_t size=sizeof(val);
877  if(getsockopt(m_Socket,SOL_SOCKET,SO_SNDBUF,(char*)&val,&size)==SOCKET_ERROR)
878  return E_UNKNOWN;
879  else
880  return val;
881  }
882 
884  {
885  timeval t;
886  t.tv_sec=msTimeOut/1000;
887  t.tv_usec=(msTimeOut%1000)*1000;
888  return setsockopt(m_Socket,SOL_SOCKET,SO_SNDTIMEO,(char*)&t,sizeof(t));
889  }
890 
892  {
893  timeval val;
894  socklen_t size=sizeof(val);
895  if(getsockopt(m_Socket,SOL_SOCKET,SO_SNDTIMEO,(char*)&val,&size)==SOCKET_ERROR)
896  return E_UNKNOWN;
897  else
898  return val.tv_sec*1000+val.tv_usec/1000;
899  }
900 
907  {
908  int val=0;
909  if(b) val=1;
910  if(setsockopt(m_Socket,SOL_SOCKET,SO_KEEPALIVE,(char*)&val,sizeof(val))==SOCKET_ERROR)
911  {
912  int errnum=GET_NET_ERROR;
913  CAMsg::printMsg(LOG_ERR, "Could not set KEEP_ALIVE options. Reason: %s (%i)\n", GET_NET_ERROR_STR(errnum), errnum);
914  return E_UNKNOWN;
915  }
916  return E_SUCCESS;
917  }
918 
925  {
926  if(setKeepAlive(true)!=E_SUCCESS)
927  {
928  return E_UNKNOWN;
929  }
930 
931 #ifdef HAVE_TCP_KEEPALIVE
932  int val=sec;
933  if(setsockopt(m_Socket,IPPROTO_TCP,TCP_KEEPALIVE,(char*)&val,sizeof(val))==SOCKET_ERROR)
934  {
935  CAMsg::printMsg(LOG_ERR,"Socket option TCP-KEEP-ALIVE was not set! Reason: %s (%i)\n",
937  return E_UNKNOWN;
938  }
939  return E_SUCCESS;
940 #else
941  CAMsg::printMsg(LOG_INFO,"Socket option TCP-KEEP-ALIVE was not set as it is not available on this machine.\n");
942  return E_UNKNOWN;
943 #endif
944  }
945 
946 
948  {
949  if(b)
950  {
951  #ifndef _WIN32
952  int flags=fcntl(m_Socket,F_GETFL,0);
953  fcntl(m_Socket,F_SETFL,flags|O_NONBLOCK);
954  #else
955  unsigned long flags=1;
956  ioctlsocket(m_Socket,FIONBIO,&flags);
957  #endif
958  }
959  else
960  {
961  #ifndef _WIN32
962  int flags=fcntl(m_Socket,F_GETFL,0);
963  fcntl(m_Socket,F_SETFL,flags&~O_NONBLOCK);
964  #else
965  unsigned long flags=0;
966  ioctlsocket(m_Socket,FIONBIO,&flags);
967  #endif
968  }
969  return E_SUCCESS;
970  }
971 
973  {
974  #ifndef _WIN32
975  int flags=fcntl(m_Socket,F_GETFL,0);
976  *b=((flags&O_NONBLOCK)==O_NONBLOCK);
977  return E_SUCCESS;
978  #else
979  return SOCKET_ERROR;
980  #endif
981  }
982 
984 {
985  CASocket* parSocket=new CASocket[10001];
986  UINT32 maxSocket=0;
987  for(UINT32 t=0;t<10001;t++)
988  {
989  if(parSocket[t].create(false)!=E_SUCCESS)
990  {
991  maxSocket=t;
992  break;
993  }
994  }
995  for(UINT32 t=0;t<maxSocket;t++)
996  {
997  parSocket[t].close();
998  }
999  delete []parSocket;
1000  parSocket = NULL;
1001  return maxSocket;
1002 }
1003 
SINT32 getcurrentTimeMillis(UINT64 &u64Time)
Gets the current Systemtime in milli seconds.
Definition: CAUtil.cpp:252
SINT32 sSleep(UINT32 sec)
Sleeps sec Seconds.
Definition: CAUtil.cpp:425
SINT32 msSleep(UINT32 ms)
Sleeps ms milliseconds.
Definition: CAUtil.cpp:406
UINT32 diff64(const UINT64 &bigop, const UINT64 &smallop)
Definition: CAUtil.hpp:398
void add64(UINT64 &op1, UINT32 op2)
Definition: CAUtil.hpp:375
bool isLesser64(UINT64 &smallOp1, UINT64 &bigOp2)
Definition: CAUtil.hpp:442
void set64(UINT64 &op1, UINT32 op2)
Definition: CAUtil.hpp:321
#define GET_NET_ERROR
Definition: StdAfx.h:469
#define INVALID_SOCKET
Definition: StdAfx.h:465
#define GET_NET_ERROR_STR(x)
Definition: StdAfx.h:471
SOCKADDR * LPSOCKADDR
Definition: StdAfx.h:459
#define ERR_INTERN_WOULDBLOCK
Definition: StdAfx.h:476
#define ERR_INTERN_CONNREFUSED
Definition: StdAfx.h:475
#define closesocket(s)
Definition: StdAfx.h:463
#define SOCKET_ERROR
Definition: StdAfx.h:464
int socklen_t
Definition: StdAfx.h:393
#define SET_NET_ERROR(x)
Definition: StdAfx.h:470
#define ERR_INTERN_SOCKET_CLOSED
Definition: StdAfx.h:477
#define MSG_NOSIGNAL
Definition: StdAfx.h:408
#define ERR_INTERN_TIMEDOUT
Definition: StdAfx.h:474
#define AF_LOCAL
Definition: StdAfx.h:482
struct sockaddr SOCKADDR
Definition: StdAfx.h:458
#define ioctlsocket(a, b, c)
Definition: StdAfx.h:462
#define SOCKET
Definition: StdAfx.h:460
unsigned short UINT16
Definition: basetypedefs.h:133
signed int SINT32
Definition: basetypedefs.h:132
unsigned char UINT8
Definition: basetypedefs.h:135
unsigned int UINT32
Definition: basetypedefs.h:131
static SINT32 printMsg(UINT32 typ, const char *format,...)
Writes a given message to the log.
Definition: CAMsg.cpp:251
SINT32 unlock()
Definition: CAMutex.hpp:52
SINT32 lock()
Definition: CAMutex.hpp:41
This is an abstract class for representing a socket address used in CASocket, CADatagramSocket and CA...
virtual SINT32 getType() const =0
The type (family) of socket for which this address is useful.
virtual const SOCKADDR * LPSOCKADDR() const =0
Casts to a SOCKADDR struct.
virtual SINT32 getSize() const =0
The size of the SOCKADDR struct needed by function of CASocket and other.
This class represents a socket address for Internet (IP) connections.
This is a class for Unix Domain Protocol Sockat Addresses.
SINT32 add(SOCKET &s)
CASocket(bool bIsReserved=false)
Definition: CASocket.cpp:49
virtual SINT32 receive(UINT8 *buff, UINT32 len)
Will receive some bytes from the socket.
Definition: CASocket.cpp:645
static CAMutex * m_pcsClose
Definition: CASocket.hpp:159
virtual SINT32 getPeerPort()
Definition: CASocket.cpp:830
virtual SINT32 listen(const CASocketAddr &psa)
Starts listening on address psa.
Definition: CASocket.cpp:142
virtual SINT32 send(const UINT8 *buff, UINT32 len)
Sends some data over the network.
Definition: CASocket.cpp:400
virtual SINT32 getNonBlocking(bool *b)
Definition: CASocket.cpp:972
bool m_bIsReservedSocket
Definition: CASocket.hpp:164
virtual SINT32 setKeepAlive(bool b)
Enables/disables the socket keep-alive option.
Definition: CASocket.cpp:906
static UINT32 m_u32MaxNormalSockets
Definition: CASocket.hpp:163
virtual SINT32 getSendTimeOut()
Definition: CASocket.cpp:891
virtual SINT32 setSendTimeOut(UINT32 msTimeOut)
Definition: CASocket.cpp:883
virtual SINT32 setRecvBuff(UINT32 r)
Definition: CASocket.cpp:846
virtual SINT32 receiveFullyT(UINT8 *buff, UINT32 len, UINT32 msTimeOut)
Trys to receive all bytes.
Definition: CASocket.cpp:677
virtual SINT32 getSendBuff()
Definition: CASocket.cpp:873
SOCKET m_Socket
Definition: CASocket.hpp:150
static SINT32 getMaxOpenSockets()
Tries to find out how many socket we can open by open as many socket as possible witthout errors.
Definition: CASocket.cpp:983
virtual SINT32 getPeerIP(UINT8 ip[4])
Definition: CASocket.cpp:820
volatile bool m_bSocketIsClosed
check
Definition: CASocket.hpp:145
CASingleSocketGroup * m_pSingleSocketGroupRead
Definition: CASocket.hpp:151
virtual SINT32 receiveLine(UINT8 *line, UINT32 maxLen, UINT32 msTimeOut)
Definition: CASocket.cpp:714
virtual SINT32 peek(UINT8 *buff, UINT32 len)
Will peek some bytes from the socket read queue.
Definition: CASocket.cpp:770
virtual SINT32 sendTimeOut(const UINT8 *buff, UINT32 len, UINT32 msTimeOut)
Sends some data over the network.
Definition: CASocket.cpp:442
virtual SINT32 setNonBlocking(bool b)
Definition: CASocket.cpp:947
virtual SINT32 setReuseAddr(bool b)
Definition: CASocket.cpp:839
virtual SINT32 sendFully(const UINT8 *buff, UINT32 len)
Sends all data over the network.
Definition: CASocket.cpp:587
virtual SINT32 setSendBuff(SINT32 r)
Returns < 0 on error, otherwise the new sendbuffersize (which may be less than r)
Definition: CASocket.cpp:862
virtual SINT32 accept(CASocket &s)
Accepts a new connection.
Definition: CASocket.cpp:192
virtual SINT32 getRecvBuff()
Definition: CASocket.cpp:852
virtual SINT32 sendFullyTimeOut(const UINT8 *buff, UINT32 len, UINT32 msTimeOut, UINT32 msTimeOutSingleSend)
Sends all data over the network.
Definition: CASocket.cpp:488
virtual SINT32 setSocket(SOCKET s)
Definition: CASocket.cpp:57
virtual SINT32 create()
Definition: CASocket.cpp:73
virtual SINT32 getLocalIP(UINT8 r_Ip[4])
LERNGRUPPE Returns the source address of the socket.
Definition: CASocket.cpp:801
virtual SINT32 close()
Definition: CASocket.cpp:351
virtual SINT32 connect(const CASocketAddr &psa)
Definition: CASocket.hpp:64
virtual SINT32 getLocalPort()
Definition: CASocket.cpp:811
static volatile UINT32 m_u32NormalSocketsOpen
The following two variables are use to realise "reserved" sockets.
Definition: CASocket.hpp:162
#define E_SOCKETCLOSED
Definition: errorcodes.hpp:11
#define E_SOCKET_LIMIT
Definition: errorcodes.hpp:16
const SINT32 E_SUCCESS
Definition: errorcodes.hpp:2
#define E_SOCKET_LISTEN
Definition: errorcodes.hpp:13
#define E_SOCKET_BIND
Definition: errorcodes.hpp:15
#define E_SOCKET_CREATE
Definition: errorcodes.hpp:12
#define E_AGAIN
Definition: errorcodes.hpp:9
#define E_UNKNOWN
Definition: errorcodes.hpp:3
#define E_TIMEDOUT
Definition: errorcodes.hpp:10
#define E_SOCKET_CONNECT
Definition: errorcodes.hpp:17
UINT16 flags
Definition: typedefs.hpp:1
UINT8 type
Definition: typedefs.hpp:1
UINT16 len
Definition: typedefs.hpp:0