Return TypeFunction nameArguments
voidhzIpServer::ServeX(void)

Declared in file: hzIpServer.h
Defined in file : hzIpServer.cpp

Function Logic:

0:START 1:pthread_attr_init pthread_attr_setdetachstate epoll_create1 s_epollSocket 2:s_epollSocket==-1 3:Fatal 4:hzLogger::Log I 5:I.Valid(); 6:hzList::Iter::Element pLS hzIpListen::GetSocket epEventNew epEventNew 7:epoll_ctl(s_epollSocket,EPOLL_CTL_ADD,pLS->GetSocket(),&epEventNew)<0 8:hzIpListen::GetSocket Fatal 9:hzIpListen::GetSocket hzLogger::Log hzIpListen::GetSocket hzMapS::Insert 10:nBannedAttempts nCliSeq m_nLoop 11:; 12:RealtimeNano nsThen epoll_wait nEpollEvents RealtimeNano nsNow nC 13:nC 14:_hzGlobal_Debug&HZ_DEBUG_SERVER 15:nSlot 16:hzLogger::Log 17:hzLogger::Log 18:m_arEvents[nSlot].events&EPOLLHUP 19:cSock pCC nError 20:!pCC 21:m_bShutdown hzLogger::Log 22:!pCC->CliSocket() 23:m_bShutdown hzLogger::Log 24:getsockopt(cSock,SOL_SOCKET,SO_ERROR,(void*)&nError,&cliLen)==0 25:strerror hzLogger::Log 26:hzLogger::Log 27:m_arEvents[nSlot].events&EPOLLERR 28:cSock pCC nError 29:!pCC 30:m_bShutdown hzLogger::Log 31:!pCC->CliSocket() 32:m_bShutdown hzLogger::Log 33:getsockopt(cSock,SOL_SOCKET,SO_ERROR,(void*)&nError,&cliLen)==0 34:strerror hzLogger::Log 35:hzLogger::Log 36:ls.Exists(m_arEvents[nC].data.fd) 37:pLS pSSL cliLen 38:(aSock=accept(pLS->GetSocket(),&cliAddr,&cliLen))<0 39:hzIpListen::GetPort hzLogger::Log 40:cSock fcntl flags 41:flags==-1 42:Fatal 43:flags 44:fcntl(cSock,F_SETFL,flags)==-1 45:Fatal 46:epEventNew epEventNew 47:epoll_ctl(s_epollSocket,EPOLL_CTL_ADD,cSock,&epEventNew)<0 48:Fatal 49:inet_ntop ipa 50:m_bShutdown||(pLS->GetCurConnections()>=pLS->GetMaxConnections()) 51:hzLogger::Log 52:close(cSock)<0 53:hzLogger::Log 54:tv tv 55:setsockopt(cSock,SOL_SOCKET,SO_SNDTIMEO,&tv,sizeof(tv))<0 56:hzLogger::Log 57:setsockopt(cSock,SOL_SOCKET,SO_RCVTIMEO,&tv,sizeof(tv))<0 58:hzLogger::Log 59:pLS->UseSSL() 60:SSL_new pSSL 61:!pSSL 62:hzIpListen::GetPort hzLogger::Log 63:hzIpListen::GetPort hzLogger::Log SSL_set_fd SSL_accept sys_rc 64:sys_rc<=0 65:hzIpListen::GetPort SSL_get_error hzLogger::Log SSL_free 66:close(cSock)<0 67:hzLogger::Log 68:hzLogger::Log 69:SSL_get_cipher hzLogger::Log 70:pCC 71:!pCC 72:pCC 73:!pCC 74:hzexit 75:hzMapS::Insert 76:hzLogger::Log hzIpConnex::Initialize 77:pCC->m_OnConnect 78:_hzGlobal_Debug&HZ_DEBUG_SERVER 79:hzIpConnex::EventNo hzIpConnex::CliSocket hzLogger::Log 80:items 81:m_arEvents[nC].events&EPOLLOUT 82:cSock hzLogger::Log 83:m_arEvents[nC].events&EPOLLIN 84:cSock pCC 85:!pCC 86:hzLogger::Log 87:pCC->IsCliTerm() 88:hzIpConnex::EventNo hzIpConnex::CliSocket hzLogger::Log 89:; 90:hzIpConnex::Recv nRecv hzIpConnex::EventNo hzIpConnex::CliSocket hzLogger::Log 91:nRecv<=0 92:!pCC->SizeIn() 93:hzIpConnex::EventNo hzIpConnex::CliSocket hzLogger::Log 94:nsNow>pCC->Expires() 95:hzIpConnex::EventNo hzIpConnex::CliSocket hzLogger::Log hzIpConnex::Terminate 96:hzDiode::Push pthread_cond_signal 97:(nsNow-nsThen)>100000000 98:_hzGlobal_Debug&HZ_DEBUG_SERVER 99:hzLogger::Log nX 100:nX 101:hzMapS::GetObj pCC 102:!pCC 103:!pCC->CliSocket() 104:pCC->_isxmit() 105:hzIpConnex::_xmit err 106:!pCC->SizeIn()&&(nsNow>pCC->Expires()) 107:hzIpConnex::EventNo hzIpConnex::CliSocket hzIpConnex::IsVirgin hzLogger::Log hzIpConnex::Terminate 108: No text

Function body:

void hzIpServer::ServeX (void)
{
   _hzfunc("hzIpServer::ServeX") ;
   hzMapS<uint32_t,hzIpListen*>    ls ;
   hzMapS<uint32_t,hzIpConnex*>    allCC ;
   hzMapS<uint32_t,hzIpConnex*>    duff ;
   hzList<hzIpListen*>::Iter       I ;
   struct epoll_event  epEventNew ;
   hzPacket        tbuf ;
   SOCKADDR        cliAddr ;
   SOCKADDRIN      cliAddrIn ;
   socklen_t       cliLen ;
   hzIpListen*     pLS ;
   hzIpConnex*     pCC ;
   SSL*            pSSL ;
   timeval         tv ;
   pthread_attr_t  tattr ;
   uint64_t        nsThen ;
   uint64_t        nsNow ;
   hzIpaddr        ipa ;
   uint32_t        nBannedAttempts ;
   uint32_t        nCliSeq = 1;
   uint32_t        nX ;
   uint32_t        nSlot ;
   uint32_t        nError ;
   uint32_t        cSock ;
   uint32_t        cPort ;
   int32_t         aSock ;
   int32_t         flags ;
   int32_t         nC ;
   int32_t         nRecv ;
   int32_t         nEpollEvents ;
   int32_t         sys_rc ;
   hzEcode         err ;
   char            ipbuf[44];
   pthread_attr_init(&tattr) ;
   pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED) ;
   s_epollSocket = epoll_create1(0);
   if (s_epollSocket == -1)
       Fatal("Could not create epoll socket\n") ;
   m_pLog->Log("Epoll socket is %d\n", s_epollSocket) ;
   for (I = m_LS ; I.Valid() ; I++)
   {
       pLS = I.Element() ;
       epEventNew.data.fd = pLS->GetSocket() ;
       epEventNew.events = EPOLLIN ;
       if (epoll_ctl(s_epollSocket, EPOLL_CTL_ADD, pLS->GetSocket(), &epEventNew) < 0)
           Fatal("Could not add listening socket %d to the epoll controller\n", pLS->GetSocket()) ;
       m_pLog->Log("Added listening socket is %d\n", pLS->GetSocket()) ;
       ls.Insert(pLS->GetSocket(), pLS) ;
   }
   m_nLoop = nCliSeq = nBannedAttempts = 0;
   for (;;)
   {
       nsThen = RealtimeNano() ;
       nEpollEvents = epoll_wait(s_epollSocket, m_arEvents, MAXEVENTS, 30000);
       nsNow = RealtimeNano() ;
       for (nC = 0; nC < nEpollEvents ; nC++)
       {
           if (_hzGlobal_Debug & HZ_DEBUG_SERVER)
           {
               if (nSlot)
                   m_pLog->Log("Loop %u slot %u: Event on socket %d\n", m_nLoop, nSlot, m_arEvents[nSlot].data.fd) ;
               else
                   m_pLog->Log("Loop %u: Waited %lu nanoseconds for %d events: 1st sock %u\n", m_nLoop, nsNow - nsThen, nEpollEvents, m_arEvents[0].data.fd);
           }
           if (m_arEvents[nSlot].events & EPOLLHUP)
           {
               cSock = m_arEvents[nSlot].data.fd ;
               pCC = currCC[cSock] ;
               nError = 0;
               if (!pCC)               { m_bShutdown = true ; m_pLog->Log("Loop %u slot %u: HANGUP CORRUPT Sock %d No connector\n", m_nLoop, nSlot, cSock) ; continue ; }
               if (!pCC->CliSocket())  { m_bShutdown = true ; m_pLog->Log("Loop %u slot %u: HANGUP CORRUPT Sock %d Connector defunct\n", m_nLoop, nSlot, cSock) ; continue ; }
               if (getsockopt(cSock, SOL_SOCKET, SO_ERROR, (void *)&nError, &cliLen) == 0)
                   m_pLog->Log("Loop %u slot %u: HANGUP on socket %d (%s)\n", m_nLoop, nSlot, cSock, strerror(nError)) ;
               else
                   m_pLog->Log("Loop %u slot %u: HANGUP on socket %d (no details)\n", m_nLoop, nSlot, cSock) ;
           }
           if (m_arEvents[nSlot].events & EPOLLERR)
           {
               cSock = m_arEvents[nSlot].data.fd ;
               pCC = currCC[cSock] ;
               nError = 0;
               if (!pCC)               { m_bShutdown = true ; m_pLog->Log("Loop %u slot %u: EPOLLERR CORRUPT Sock %d No connector\n", m_nLoop, nSlot, cSock) ; continue ; }
               if (!pCC->CliSocket())  { m_bShutdown = true ; m_pLog->Log("Loop %u slot %u: EPOLLERR CORRUPT Sock %d Connector defunct\n", m_nLoop, nSlot, cSock) ; continue ; }
               if (getsockopt(cSock, SOL_SOCKET, SO_ERROR, (void *)&nError, &cliLen) == 0)
                   m_pLog->Log("Loop %u slot %u: EPOLLERR on socket %d (%s)\n", m_nLoop, nSlot, cSock, strerror(nError)) ;
               else
                   m_pLog->Log("Loop %u slot %u: EPOLLERR on socket %d (no details)\n", m_nLoop, nSlot, cSock) ;
           }
           if (ls.Exists(m_arEvents[nC].data.fd))
           {
               pLS = ls[m_arEvents[nC].data.fd] ;
               pSSL = 0;
               cliLen = sizeof(SOCKADDRIN) ;
               if ((aSock = accept(pLS->GetSocket(), &cliAddr, &cliLen)) < 0)
               {
                   m_pLog->Log("Listening socket %d will not accept client on port %d\n", aSock, pLS->GetPort()) ;
                   continue ;
               }
               cSock = aSock ;
               flags = fcntl(cSock, F_GETFL, 0);
               if (flags == -1)
                   Fatal("Could not make client socket %d non blocking (case 1)\n", cSock) ;
               flags |= O_NONBLOCK ;
               if (fcntl(cSock, F_SETFL, flags) == -1)
                   Fatal("Could not make client socket %d non blocking (case 2)\n", cSock) ;
               epEventNew.data.fd = cSock ;
               epEventNew.events = EPOLLIN | EPOLLET ;
               if (epoll_ctl(s_epollSocket, EPOLL_CTL_ADD, cSock, &epEventNew) < 0)
                   Fatal("Could not add client socket %d to control\n", cSock) ;
               inet_ntop(AF_INET, &cliAddrIn.sin_addr, ipbuf, 16);
               ipa = ipbuf ;
               if (m_bShutdown || (pLS->GetCurConnections() >&eq; pLS->GetMaxConnections()))
               {
                   m_pLog->Log("NOTE: System too busy: Curr %d Max %d stat %d\n", m_nCurrentClients, m_nMaxClients, m_bShutdown ? 1: 0);
                   if (close(cSock) < 0)
                       m_pLog->Log("NOTE: Could not close socket %d after sys_too_busy\n", cSock) ;
                   continue ;
               }
               /*
               **  if (_ipcheck(ipbuf, pLS->GetPort()))
               **      {
               **       m_pLog->Log("Lorris Attack from IP %s port %d\n", ipbuf, pLS->GetPort()) ;
               **       if (close(cSock) < 0)
               **        m_pLog->Log("NOTE: Could not close socket %d after lorris_attack\n", cSock) ;
               **       continue ;
               **      }
               **                     */
               tv.tv_sec = 1;
               tv.tv_usec = 0;
               if (setsockopt(cSock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) < 0)
                   { m_pLog->Log("Could not set send socket options\n") ; continue ; }
               if (setsockopt(cSock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0)
                   { m_pLog->Log("Could not set recv socket options\n") ; continue ; }
               if (pLS->UseSSL())
               {
                   pSSL = SSL_new(s_SSL_svrRegime->m_svrCTX) ;
                   if (!pSSL)
                       { m_pLog->Log("Failed to allocate an SSL instance on port %d\n", pLS->GetPort()) ; continue ; }
                   m_pLog->Log("Allocated SSL instance on port %d\n", pLS->GetPort()) ;
                   SSL_set_fd(pSSL, cSock) ;
                   sys_rc = SSL_accept(pSSL) ;
                   if (sys_rc <&eq; 0)
                   {
                       m_pLog->Log("NOTE: Failed to accept SSL client on port %d socket %d (error=%d,%d)\n",
                           pLS->GetPort(), cSock, sys_rc, SSL_get_error(pSSL, sys_rc)) ;
                       SSL_free(pSSL) ;
                       if (close(cSock) < 0)
                           m_pLog->Log("NOTE: Could not close socket %d after SSL fail_accept\n", cSock) ;
                       m_pLog->Log("Closed socket\n") ;
                       continue ;
                   }
                   m_pLog->Log("SSL connection using %s\n", SSL_get_cipher(pSSL)) ;
                   /*
                   **  if (verify_callback)
                   **       {
                   **        // Get the client's certificate (optional)
                   **        client_cert = SSL_get_peer_certificate(pSSL);
                   **  
                   **        if (client_cert != NULL)
                   **        {
                   **         clicert_str = X509_NAME_oneline(X509_get_subject_name(client_cert), 0, 0);
                   **         if (!clicert_str)
                   **          { m_pLog->Log("No Client Certificate found\n") ; continue ; }
                   **         m_pLog->Log("Subject of Client Cert: %s\n", clicert_str) ;
                   **         free(clicert_str) ;
                   **  
                   **         clicert_str = X509_NAME_oneline(X509_get_issuer_name(client_cert), 0, 0);
                   **         if (!clicert_str)
                   **          { m_pLog->Log("No Client Cert Issuer found\n") ; continue ; }
                   **         m_pLog->Log("Issuer of Client Cert: %s\n", clicert_str) ;
                   **         free(clicert_str) ;
                   **  
                   **         X509_free(client_cert);
                   **        }
                   **        else
                   **         printf("The SSL client does not have certificate.\n");
                   **       }
                   **                          */
               }
               /*
               **  ** Allocate the connected client object
               **                     */
               pCC = allCC[cSock] ;
               if (!pCC)
               {
                   pCC = new hzIpConnex(m_pLog) ;
                   if (!pCC)
                       hzexit(E_MEMORY, "No memory for new client connection\n") ;
                   allCC.Insert(cSock, pCC) ;
               }
               m_pLog->Log("New client connection on socket %d\n", cSock) ;
               pCC->Initialize(pLS, pSSL, ipa, cSock, cPort, nCliSeq++) ;
               if (pCC->m_OnConnect)
               {
                   if (_hzGlobal_Debug & HZ_DEBUG_SERVER)
                       m_pLog->Log("Client %d (sock %d): Issuing server hello\n", pCC->EventNo(), pCC->CliSocket()) ;
                   pCC->m_OnConnect(pCC) ;
               }
               continue ;
           }
           if (m_arEvents[nC].events & EPOLLOUT)
           {
               cSock = m_arEvents[nC].data.fd ;
               m_pLog->Log("WHAT??? write event on socket %d\n", cSock) ;
               continue ;
           }
           if (m_arEvents[nC].events & EPOLLIN)
           {
               cSock = m_arEvents[nC].data.fd ;
               pCC = allCC[cSock] ;
               if (!pCC)
               {
                   m_pLog->Log("WHAT??? read event on socket %d but no connector!\n", cSock) ;
                   continue ;
               }
               if (pCC->IsCliTerm())
                   m_pLog->Log("NOTE: Client %d (sock %d) has a read event after sending 0 byte packet\n", pCC->EventNo(), pCC->CliSocket()) ;
               for (;;)
               {
                   nRecv = pCC->Recv(tbuf) ;
                   m_pLog->Log("Client %d (sock %d): Got %d bytes\n", pCC->EventNo(), pCC->CliSocket(), nRecv) ;
                   if (nRecv <&eq; 0)
                       break ;
               }
               if (!pCC->SizeIn())
               {
                   m_pLog->Log("Client %d (sock %d): Final read - NO DATA\n", pCC->EventNo(), pCC->CliSocket()) ;
                   if (nsNow > pCC->Expires())
                   {
                       m_pLog->Log("Client %d (sock %d): Final read - NO DATA deleted\n", pCC->EventNo(), pCC->CliSocket()) ;
                       pCC->Terminate() ;
                   }
               }
               else
               {
                   s_queRequests.Push(pCC) ;
                   pthread_cond_signal(&s_request_cond) ;
               }
           }
       }
       if ((nsNow - nsThen) > 100000000)
       {
           if (_hzGlobal_Debug & HZ_DEBUG_SERVER)
               m_pLog->Log("Purging ...\n") ;
           for (nX = 0; nX < allCC.Count() ; nX++)
           {
               pCC = allCC.GetObj(nX) ;
               if (!pCC)
                   continue ;
               if (!pCC->CliSocket())
                   continue ;
               if (pCC->_isxmit())
               {
                   err = pCC->_xmit(tbuf) ;
                   continue ;
               }
               /*
               **  if (pCC->State() == HZCONNEX_FAIL)
               **      {
               **       if (now < pCC->Expires())
               **        continue ;
               **       
               **       //pCC->StateDone() ;
               **       pCC->SetState(*_fn, HZCONNEX_DONE) ;
               **       if (m_pLog)
               **        m_pLog->Log("Client (ev %d sock %d state %d) vgn %d: Failed, removed\n",
               **         pCC->EventNo(), pCC->CliSocket(), pCC->State(), pCC->IsVirgin() ? 1 : 0) ;
               **       pCC->Terminate() ;
               **       continue ;
               **      }
               **                     */
               if (!pCC->SizeIn() && (nsNow > pCC->Expires()))
               {
                   m_pLog->Log("Client (ev %d sock %d) vgn %d: Inactive, removed\n", pCC->EventNo(), pCC->CliSocket(), pCC->IsVirgin() ? 1: 0);
                   pCC->Terminate() ;
               }
           }
       }
   }
   threadLog("Shutdown\n") ;
}