.pc/05_add_ssltimeout_option.patch/havp/sockethandler.cpp
changeset 1 70b0d05afad2
equal deleted inserted replaced
0:8baf084f58c5 1:70b0d05afad2
       
     1 /***************************************************************************
       
     2                           sockethandler.cpp  -  description
       
     3                              -------------------
       
     4     begin                : Sa Feb 12 2005
       
     5     copyright            : (C) 2005 by Christian Hilgers
       
     6     email                : christian@hilgers.ag
       
     7  ***************************************************************************/
       
     8 
       
     9 /***************************************************************************
       
    10  *                                                                         *
       
    11  *   This program is free software; you can redistribute it and/or modify  *
       
    12  *   it under the terms of the GNU General Public License as published by  *
       
    13  *   the Free Software Foundation; either version 2 of the License, or     *
       
    14  *   (at your option) any later version.                                   *
       
    15  *                                                                         *
       
    16  ***************************************************************************/
       
    17 
       
    18 #include "sockethandler.h"
       
    19 #include "logfile.h"
       
    20 #include "params.h"
       
    21 #include "utils.h"
       
    22 
       
    23 #include <netdb.h>
       
    24 #include <unistd.h>
       
    25 #include <fcntl.h>
       
    26 #include <errno.h>
       
    27 
       
    28 #ifndef INADDR_NONE
       
    29 #define INADDR_NONE ((unsigned long) -1)
       
    30 #endif
       
    31 #ifndef AF_LOCAL
       
    32 #define AF_LOCAL AF_UNIX
       
    33 #endif
       
    34 
       
    35 //Create Server Socket
       
    36 bool SocketHandler::CreateServer( int portT, in_addr_t bind_addrT )
       
    37 {
       
    38     int i = 1;
       
    39 
       
    40     my_s_addr.sin_addr.s_addr = bind_addrT;
       
    41     my_s_addr.sin_port = htons(portT);
       
    42 
       
    43     if ( (sock_fd = socket( AF_INET, SOCK_STREAM, 0 )) < 0 )
       
    44     {
       
    45         LogFile::ErrorMessage("socket() failed: %s\n", strerror(errno));
       
    46         return false;
       
    47     }
       
    48 
       
    49     // Enable re-use Socket
       
    50     if ( setsockopt( sock_fd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i) ) < 0 )
       
    51     {
       
    52         LogFile::ErrorMessage("setsockopt() failed: %s\n", strerror(errno));
       
    53         return false;
       
    54     }
       
    55 
       
    56     if ( ::bind( sock_fd, (struct sockaddr *) &my_s_addr, sizeof(my_s_addr) ) < 0 )
       
    57     {
       
    58         LogFile::ErrorMessage("bind() failed: %s\n", strerror(errno));
       
    59         return false;
       
    60     }
       
    61 
       
    62     if ( ::listen( sock_fd, MAXCONNECTIONS ) < 0 )
       
    63     {
       
    64         LogFile::ErrorMessage("listen() failed: %s\n", strerror(errno));
       
    65         return false;
       
    66     }
       
    67 
       
    68     return true;
       
    69 }
       
    70 
       
    71 
       
    72 //Create Server Socket, convert ASCII address representation into binary one
       
    73 bool SocketHandler::CreateServer( int portT, string bind_addrT )
       
    74 {
       
    75     if ( bind_addrT == "" )
       
    76     {
       
    77         return CreateServer( portT, INADDR_ANY );
       
    78     }
       
    79     else
       
    80     {
       
    81         return CreateServer( portT, inet_addr( Params::GetConfigString("BIND_ADDRESS").c_str() ) );
       
    82     } 
       
    83 }
       
    84 
       
    85 
       
    86 //Connect to Server
       
    87 bool SocketHandler::ConnectToServer()
       
    88 {
       
    89     if ( (sock_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
       
    90     {
       
    91         LogFile::ErrorMessage("ConnectToServer socket() failed: %s\n", strerror(errno));
       
    92         return false;
       
    93     }
       
    94 
       
    95     if ( source_address != "" )
       
    96     {
       
    97         if ( ::bind(sock_fd, (struct sockaddr *) &l_addr, sizeof(l_addr)) < 0 )
       
    98         {
       
    99             LogFile::ErrorMessage("ConnectoToServer bind() failed: %s\n", strerror(errno));
       
   100             Close();
       
   101             return false;
       
   102         }
       
   103     }
       
   104 
       
   105     int flags, ret;
       
   106 
       
   107     //Nonblocking connect to get a proper timeout
       
   108     while ( (flags = fcntl(sock_fd, F_GETFL, 0)) < 0 )
       
   109     {
       
   110         if (errno == EINTR) continue;
       
   111 
       
   112         LogFile::ErrorMessage("ConnectToServer fcntl() get failed: %s\n", strerror(errno));
       
   113         Close();
       
   114         return false;
       
   115     }
       
   116     while ( fcntl(sock_fd, F_SETFL, flags | O_NONBLOCK) < 0 )
       
   117     {
       
   118         if (errno == EINTR) continue;
       
   119 
       
   120         LogFile::ErrorMessage("ConnectToServer fcntl() O_NONBLOCK failed: %s\n", strerror(errno));
       
   121         Close();
       
   122         return false;
       
   123     }
       
   124 
       
   125     while ( (ret = ::connect(sock_fd, (struct sockaddr *) &my_s_addr, sizeof(my_s_addr))) < 0 )
       
   126     {
       
   127         if (errno == EINTR) continue;
       
   128 
       
   129         if (errno != EINPROGRESS)
       
   130         {
       
   131             if (errno != EINVAL) LogFile::ErrorMessage("connect() failed: %s\n", strerror(errno));
       
   132             Close();
       
   133             return false;
       
   134         }
       
   135 
       
   136         break;
       
   137     }
       
   138 
       
   139     if ( ret != 0 )
       
   140     {
       
   141         FD_ZERO(&checkfd);
       
   142         FD_SET(sock_fd,&checkfd);
       
   143         wset = checkfd;
       
   144 
       
   145         Timeout.tv_sec = CONNTIMEOUT;
       
   146         Timeout.tv_usec = 0;
       
   147 
       
   148         ret = select_eintr(sock_fd+1, &checkfd, &wset, NULL, &Timeout);
       
   149 
       
   150         if ( ret <= 0 )
       
   151         {
       
   152             Close();
       
   153             return false;
       
   154         }
       
   155 
       
   156         addr_len = sizeof(peer_addr);
       
   157 
       
   158         if ( getpeername(sock_fd, (struct sockaddr *) &peer_addr, (socklen_t *) &addr_len) < 0 )
       
   159         {
       
   160             Close();
       
   161             return false;
       
   162         }
       
   163     }
       
   164 
       
   165     while ( fcntl(sock_fd, F_SETFL, flags) < 0 )
       
   166     {
       
   167         if (errno == EINTR) continue;
       
   168 
       
   169         LogFile::ErrorMessage("ConnectToServer fcntl() set failed: %s\n", strerror(errno));
       
   170         Close();
       
   171         return false;
       
   172     }
       
   173 
       
   174     return true;
       
   175 }
       
   176 
       
   177 
       
   178 bool SocketHandler::ConnectToSocket( string SocketPath, int retry )
       
   179 {
       
   180     strncpy(my_u_addr.sun_path, SocketPath.c_str(), sizeof(my_u_addr.sun_path)-1);
       
   181 
       
   182     if ( (sock_fd = socket(AF_LOCAL, SOCK_STREAM, 0)) < 0 )
       
   183     {
       
   184         LogFile::ErrorMessage("ConnectToSocket socket() failed: %s\n", strerror(errno));
       
   185         return false;
       
   186     }
       
   187 
       
   188     int tries = 0;
       
   189     int ret;
       
   190 
       
   191     for(;;)
       
   192     {
       
   193         while ( (ret = ::connect(sock_fd, (struct sockaddr *) &my_u_addr, sizeof(my_u_addr))) < 0 )
       
   194         {
       
   195             if (errno == EINTR) continue;
       
   196 
       
   197             if (errno != ENOENT) LogFile::ErrorMessage("ConnectToSocket connect() failed: %s\n", strerror(errno));
       
   198             break;
       
   199         }
       
   200 
       
   201         //Success?
       
   202         if ( ret == 0 ) return true;
       
   203 
       
   204         //All retried?
       
   205         if ( ++tries > retry ) break;
       
   206 
       
   207         //Try again in one second
       
   208         sleep(1);
       
   209         continue;
       
   210     }
       
   211 
       
   212     Close();
       
   213     return false;
       
   214 }
       
   215 
       
   216 
       
   217 //Accept Client
       
   218 bool SocketHandler::AcceptClient( SocketHandler &accept_socketT )
       
   219 {
       
   220     addr_len = sizeof(my_s_addr);
       
   221 
       
   222     while ((accept_socketT.sock_fd = ::accept(sock_fd, (sockaddr *) &my_s_addr, (socklen_t *) &addr_len)) < 0)
       
   223     {
       
   224         if (errno == EINTR) continue;
       
   225 
       
   226         LogFile::ErrorMessage("accept() failed: %s\n", strerror(errno));
       
   227 
       
   228         return false;
       
   229     }
       
   230 
       
   231     //Save IP to ToBrowser
       
   232     accept_socketT.my_s_addr = my_s_addr;    
       
   233 
       
   234     return true;
       
   235 }
       
   236 
       
   237 //Send String
       
   238 bool SocketHandler::Send( const char *sock_outT, int len )
       
   239 {
       
   240     int total_sent = 0;
       
   241     int ret, buffer_count;
       
   242 
       
   243     do
       
   244     {
       
   245         Timeout.tv_sec = SENDTIMEOUT;
       
   246         Timeout.tv_usec = 0;
       
   247         FD_ZERO(&checkfd);
       
   248         FD_SET(sock_fd,&checkfd);
       
   249 
       
   250         ret = select_eintr(sock_fd+1, NULL, &checkfd, NULL, &Timeout);
       
   251 
       
   252         if (ret <= 0)
       
   253         {
       
   254             return false;
       
   255         }
       
   256 
       
   257         while ((buffer_count = ::send(sock_fd, sock_outT + total_sent, len - total_sent, 0)) < 0)
       
   258         {
       
   259             if (errno == EINTR) continue;
       
   260 
       
   261             return false;
       
   262         }
       
   263         if (buffer_count == 0)
       
   264         {
       
   265             return false;
       
   266         }
       
   267 
       
   268         total_sent += buffer_count;
       
   269     }
       
   270     while (total_sent < len);
       
   271         
       
   272     return true;
       
   273 }
       
   274 
       
   275 //Send String
       
   276 bool SocketHandler::Send( string &sock_outT )
       
   277 {
       
   278     int total_sent = 0;
       
   279     int len = sock_outT.size();
       
   280     int ret, buffer_count;
       
   281 
       
   282     do
       
   283     {
       
   284         Timeout.tv_sec = SENDTIMEOUT;
       
   285         Timeout.tv_usec = 0;
       
   286         FD_ZERO(&checkfd);
       
   287         FD_SET(sock_fd,&checkfd);
       
   288 
       
   289         ret = select_eintr(sock_fd+1, NULL, &checkfd, NULL, &Timeout);
       
   290 
       
   291         if (ret <= 0)
       
   292         {
       
   293             return false;
       
   294         }
       
   295 
       
   296         while ((buffer_count = ::send(sock_fd, sock_outT.substr(total_sent).c_str(), len - total_sent, 0)) < 0)
       
   297         {
       
   298             if (errno == EINTR) continue;
       
   299 
       
   300             return false;
       
   301         }
       
   302         if (buffer_count == 0)
       
   303         {
       
   304             return false;
       
   305         }
       
   306 
       
   307         total_sent += buffer_count;
       
   308     }
       
   309     while (total_sent < len);
       
   310         
       
   311     return true;
       
   312 }
       
   313 
       
   314 
       
   315 //Receive String - Maximal MAXRECV
       
   316 //sock_del = false : Do not delete Data from Socket
       
   317 ssize_t SocketHandler::Recv( string &sock_inT, bool sock_delT, int timeout )
       
   318 {
       
   319     if ( RecvBuf.size() > 0 )
       
   320     {
       
   321         sock_inT.append( RecvBuf );
       
   322 
       
   323         if ( sock_delT == true )
       
   324         {
       
   325             ssize_t tempsize = RecvBuf.size();
       
   326 
       
   327             RecvBuf = "";
       
   328 
       
   329             return tempsize;
       
   330         }
       
   331 
       
   332         return RecvBuf.size();
       
   333     }
       
   334 
       
   335     char buffer[MAXRECV+1];
       
   336     ssize_t buffer_count;
       
   337     int ret;
       
   338 
       
   339     if ( timeout != -1 )
       
   340     {
       
   341         Timeout.tv_sec = timeout;
       
   342     }
       
   343     else
       
   344     {
       
   345         Timeout.tv_sec = RECVTIMEOUT;
       
   346     }
       
   347     Timeout.tv_usec = 0;
       
   348 
       
   349     FD_ZERO(&checkfd);
       
   350     FD_SET(sock_fd,&checkfd);
       
   351 
       
   352     ret = select_eintr(sock_fd+1, &checkfd, NULL, NULL, &Timeout);
       
   353 
       
   354     if (ret <= 0)
       
   355     {
       
   356         return -1;
       
   357     }
       
   358 
       
   359     while ((buffer_count = ::recv(sock_fd, buffer, MAXRECV, 0)) < 0)
       
   360     {
       
   361         if (errno == EINTR) continue;
       
   362 
       
   363         return -1;
       
   364     }
       
   365 
       
   366     if ( sock_delT == false )
       
   367     {
       
   368         RecvBuf.append( buffer, buffer_count );
       
   369     }
       
   370 
       
   371     if ( buffer_count == 0 )
       
   372     {
       
   373         return 0;
       
   374     }
       
   375 
       
   376     sock_inT.append( buffer, buffer_count );
       
   377 
       
   378     return buffer_count;
       
   379 }
       
   380 
       
   381 
       
   382 //Receive String of length sock_length
       
   383 bool SocketHandler::RecvLength( string &sock_inT, unsigned int sock_lengthT )
       
   384 {
       
   385     if ( RecvBuf.size() >= sock_lengthT )
       
   386     {
       
   387         sock_inT.append( RecvBuf.substr( 0, sock_lengthT ) );
       
   388 
       
   389         RecvBuf.erase( 0, sock_lengthT );
       
   390 
       
   391         return true;
       
   392     }
       
   393 
       
   394     char buffer[MAXRECV+1];
       
   395     ssize_t buffer_count;
       
   396     unsigned int received = 0;
       
   397 
       
   398     if ( RecvBuf.size() > 0 )
       
   399     {
       
   400         sock_inT.append( RecvBuf );
       
   401         received += RecvBuf.size();
       
   402 
       
   403         RecvBuf = "";
       
   404     }
       
   405 
       
   406     for(;;)
       
   407     {
       
   408         Timeout.tv_sec = RECVTIMEOUT;
       
   409         Timeout.tv_usec = 0;
       
   410 
       
   411         FD_ZERO(&checkfd);
       
   412         FD_SET(sock_fd,&checkfd);
       
   413 
       
   414         int ret = select_eintr(sock_fd+1, &checkfd, NULL, NULL, &Timeout);
       
   415 
       
   416         if ( ret <= 0 )
       
   417         {
       
   418             return false;
       
   419         }
       
   420 
       
   421         while ((buffer_count = ::recv(sock_fd, buffer, MAXRECV, 0)) < 0 && errno == EINTR);
       
   422 
       
   423         if ( buffer_count < 1 )
       
   424         {
       
   425             return false;
       
   426         }
       
   427 
       
   428         if ( received + buffer_count >= sock_lengthT )
       
   429         {
       
   430             string Rest;
       
   431             Rest.append( buffer, buffer_count );
       
   432 
       
   433             unsigned int needed = sock_lengthT - received;
       
   434             
       
   435             sock_inT.append( Rest.substr( 0, needed ) );
       
   436             if ( Rest.size() > needed ) RecvBuf.append( Rest.substr( needed ) );
       
   437 
       
   438             return true;
       
   439         }
       
   440 
       
   441         sock_inT.append( buffer, buffer_count );
       
   442         received += buffer_count;
       
   443     }
       
   444 
       
   445     return true;
       
   446 }
       
   447 
       
   448 
       
   449 //Wait and get something from socket until separator
       
   450 bool SocketHandler::GetLine( string &lineT, string separator, int timeout )
       
   451 {
       
   452     lineT = "";
       
   453 
       
   454     string TempLine;
       
   455     string::size_type Position;
       
   456 
       
   457     do
       
   458     {
       
   459         if ( Recv( TempLine, false, timeout ) == false )
       
   460         {
       
   461             return false;
       
   462         }
       
   463     }
       
   464     while ( (Position = TempLine.find( separator )) == string::npos );
       
   465 
       
   466     TempLine = "";
       
   467 
       
   468     if ( RecvLength( TempLine, Position + separator.size() ) == false )
       
   469     {
       
   470         return false;
       
   471     }
       
   472 
       
   473     lineT = TempLine.erase( Position );
       
   474 
       
   475     return true;
       
   476 }
       
   477 
       
   478 
       
   479 //Resolve and set hostname/port for connecting
       
   480 bool SocketHandler::SetDomainAndPort( string domainT, int portT )
       
   481 {
       
   482     if ( domainT == "" ) return false;
       
   483     if ( portT < 1 || portT > 65536 ) return false;
       
   484 
       
   485     int domlen = domainT.length();
       
   486 
       
   487     if (domlen > 250) domainT = domainT.substr(0, 250);
       
   488     my_s_addr.sin_port = htons(portT);
       
   489 
       
   490     //IP?
       
   491     if ( domlen >= 7 && domlen <= 15 && domainT.find_first_not_of("0123456789.") == string::npos )
       
   492     {
       
   493         LastHost = "";
       
   494         if ( inet_aton( domainT.c_str(), &my_s_addr.sin_addr ) != 0 ) return true;
       
   495         return false;
       
   496     }
       
   497 
       
   498     //Same host as last time, use next IP
       
   499     if ( server && LastHost == domainT )
       
   500     {
       
   501         if ( ips == 1 ) return true;
       
   502 
       
   503         if ( ++ip_count == ips ) ip_count = 0;
       
   504         memcpy((char *) &my_s_addr.sin_addr.s_addr, server->h_addr_list[ip_count], server->h_length);
       
   505 
       
   506         return true;
       
   507     }
       
   508 
       
   509     //Resolve host
       
   510     if ( (server = gethostbyname( domainT.c_str() )) )
       
   511     {
       
   512         //Count IPs
       
   513         for ( ips = 0; server->h_addr_list[ips] != NULL && server->h_addrtype == AF_INET && ips != 16; ips++ );
       
   514 
       
   515         if ( !ips ) return false;
       
   516 
       
   517         memcpy((char *) &my_s_addr.sin_addr.s_addr, server->h_addr_list[0], server->h_length);
       
   518 
       
   519         ip_count = 0;
       
   520         LastHost = domainT;
       
   521 
       
   522         return true;
       
   523     }
       
   524 
       
   525     LastHost = "";
       
   526     return false;
       
   527 }
       
   528 
       
   529 int SocketHandler::IPCount()
       
   530 {
       
   531     return ips;
       
   532 }
       
   533 
       
   534 string SocketHandler::GetIP()
       
   535 {
       
   536     string ip = inet_ntoa(my_s_addr.sin_addr);
       
   537     return ip;
       
   538 }
       
   539 
       
   540 bool SocketHandler::CheckForData( int timeout )
       
   541 {
       
   542     if ( RecvBuf.size() > 0 )
       
   543     {
       
   544         return true;
       
   545     }
       
   546 
       
   547     int ret;
       
   548 
       
   549     Timeout.tv_sec = timeout;
       
   550     Timeout.tv_usec = 0;
       
   551 
       
   552     FD_ZERO(&checkfd);
       
   553     FD_SET(sock_fd,&checkfd);
       
   554 
       
   555     ret = select_eintr(sock_fd+1, &checkfd, NULL, NULL, &Timeout);
       
   556 
       
   557     if (ret <= 0)
       
   558     {
       
   559         return false;
       
   560     }
       
   561 
       
   562     return true;
       
   563 }
       
   564 
       
   565 
       
   566 #ifdef SSLTUNNEL
       
   567 int SocketHandler::CheckForSSLData( int sockBrowser, int sockServer )
       
   568 {
       
   569     fd_set readfd;
       
   570     int fds;
       
   571 
       
   572     FD_ZERO(&readfd);
       
   573     FD_SET(sockBrowser,&readfd);
       
   574     FD_SET(sockServer,&readfd);
       
   575 
       
   576     if ( sockBrowser > sockServer )
       
   577     {
       
   578         fds = sockBrowser;
       
   579     }
       
   580     else
       
   581     {
       
   582         fds = sockServer;
       
   583     }
       
   584 
       
   585     Timeout.tv_sec = 20;
       
   586     Timeout.tv_usec = 0;
       
   587 
       
   588     int ret = select_eintr(fds+1, &readfd, NULL, NULL, &Timeout);
       
   589 
       
   590     if (ret <= 0) return 0;
       
   591 
       
   592     if (FD_ISSET(sockBrowser,&readfd)) return 1;
       
   593 
       
   594     return 2;
       
   595 }
       
   596 #endif
       
   597 
       
   598 
       
   599 void SocketHandler::Close()
       
   600 {
       
   601     //Clear receive buffer
       
   602     RecvBuf = "";
       
   603 
       
   604     //Check that we have a real fd
       
   605     if ( sock_fd > -1 )
       
   606     {
       
   607         while ( ::close(sock_fd) < 0 )
       
   608         {
       
   609             if (errno == EINTR) continue;
       
   610             if (errno == EBADF) break;
       
   611 
       
   612             //IO error?
       
   613             LogFile::ErrorMessage("close() failed: %s\n", strerror(errno));
       
   614         }
       
   615 
       
   616         //Mark socket unused
       
   617         sock_fd = -1;
       
   618     }
       
   619 }
       
   620 
       
   621 
       
   622 //Constructor
       
   623 SocketHandler::SocketHandler()
       
   624 {
       
   625     memset(&my_s_addr, 0, sizeof(my_s_addr));
       
   626     my_s_addr.sin_family = AF_INET;
       
   627 
       
   628     memset(&my_u_addr, 0, sizeof(my_u_addr));
       
   629     my_u_addr.sun_family = AF_LOCAL;
       
   630 
       
   631     ip_count = 0;
       
   632     ips = 0;
       
   633 
       
   634     //No socket exists yet
       
   635     sock_fd = -1;
       
   636 
       
   637     source_address = Params::GetConfigString("SOURCE_ADDRESS");
       
   638 
       
   639     if ( source_address != "" )
       
   640     {
       
   641         l_addr.sin_family = AF_INET;
       
   642         l_addr.sin_port = htons(0);
       
   643         l_addr.sin_addr.s_addr = inet_addr( source_address.c_str() );
       
   644     }
       
   645 
       
   646     RecvBuf.reserve(1500);
       
   647     RecvBuf = "";
       
   648 }
       
   649 
       
   650 
       
   651 //Destructor
       
   652 SocketHandler::~SocketHandler()
       
   653 {
       
   654 }