Logo Search packages:      
Sourcecode: nepenthes version File versions  Download package

bool SocketManager::doLoop ( uint32_t  polltimeout  ) 

checks all sockets, and polls, handles the send and receive, socket timeouts, accepting new sockets, deleting dead sockets

Parameters:
polltimeout the polltimeout we want to use in milliseconds
Returns:
returns true if something was polled else false poll the sockets
Parameters:
polltimeout the polltimeout
Returns:
returns true

Definition at line 593 of file SocketManager.cpp.

Referenced by nepenthes::Nepenthes::doLoop().

{// FIXME ..




      list <Socket *>::iterator itSocket;

//    check socket timeouts and remove dead sockets
      for (itSocket = m_Sockets.begin();itSocket != m_Sockets.end(); itSocket++)
      {
            (*itSocket)->checkTimeout();
            if ((*itSocket)->getStatus() == SS_TIMEOUT )
            {
                  logDebug("Deleting Socket %s due to timeout \n",(*itSocket)->getDescription().c_str());
                  Socket *delsocket = *itSocket;
                  m_Sockets.erase(itSocket);
                  delete delsocket;

                  itSocket = m_Sockets.begin(); // FIXME ?
                  if(m_Sockets.size() == 0)
                  return false;
                  

            }

            if ( (*itSocket)->getStatus() == SS_CLOSED )
            {
                  logDebug("Deleting %s due to closed connection \n",(*itSocket)->getDescription().c_str());
                  Socket *delsocket = *itSocket;
                  m_Sockets.erase(itSocket);
                  delete delsocket;
                  itSocket = m_Sockets.begin(); // FIXME ?
            }
      }

      pollfd *polls = (pollfd *) malloc( (m_Sockets.size())* sizeof(pollfd));
      memset(polls,0,(m_Sockets.size())* sizeof(pollfd));
      int32_t i=0;
      for (itSocket = m_Sockets.begin();itSocket != m_Sockets.end(); itSocket++)
      {
            int32_t iError = 0;
            int32_t iSize = sizeof(iError);
            if((*itSocket)->getType() & ST_FILE)
            {
                  (*itSocket)->setPolled();
            }else
            if ((*itSocket)->getsockOpt(SOL_SOCKET, SO_ERROR, &iError,(socklen_t *) &iSize) != 0 )
            {
                  // socket is dead
                  logSpam("Socket %s is Dead\n",(*itSocket)->getDescription().c_str());
                  (*itSocket)->unsetPolled();

            } else
            {
                  switch (iError)
                  {
                  case 0:     // der socket is soweit okay
                  case EISCONN:
//                      logSpam("EISCONN State %i \n",(*itSocket)->getStatus());
                        if ((*itSocket)->getStatus() == SS_CONNECTING)
                        {
                              (*itSocket)->setStatus(SS_CONNECTED);
                        }
                        (*itSocket)->setPolled();     // der socket ist am start
                        break;

                  case EINPROGRESS: // der socket versuchts
                        (*itSocket)->unsetPolled();
                        break;


                  default:
                        (*itSocket)->unsetPolled();         // der is defekt
                  }
            }
      }

      i=0;
      for (itSocket = m_Sockets.begin();itSocket != m_Sockets.end(); itSocket++)
      {
            polls[i].events = 0;
            if ((*itSocket)->isPolled() == true )
            {
                  polls[i].fd = (*itSocket)->getSocket();

                  polls[i].events = POLLIN;

                  

                  if ((*itSocket)->wantSend() == true)
                  {
//                      logSpam("polling %s read|write\n",(*itSocket)->getDescription().c_str());
                              
                        polls[i].events |= POLLOUT;
                  }/*else
                        logSpam("polling %s readonly\n",(*itSocket)->getDescription().c_str());*/
                  i++;
            }
      }

      int32_t iPollRet = poll(polls,i,50);

      if (iPollRet != 0)
      {
            // read sockets
            i=0;
            for (itSocket = m_Sockets.begin();itSocket != m_Sockets.end(); itSocket++)
            {
                  if ( (*itSocket)->isPolled() == true )
                  {
                        if ( 
                           ( (*itSocket)->isAccept()  || (*itSocket)->isConnect() ) ||
                           (  (*itSocket)->isBind() && (*itSocket)->getType() & ST_UDP)     // bound udp sockets dont accept, they recvfrom
                           )
                        {
                              if ( iPollRet == 0 )
                                    continue;

                              if ( polls[i].revents & POLLIN && polls[i].events & POLLIN )
                              {
                                    (*itSocket)->doRecv();
                                    iPollRet--;
                              }
                        }
                        i++;
                  }
            }

            // write sockets
            i=0;
            for (itSocket = m_Sockets.begin();itSocket != m_Sockets.end(); itSocket++)
            {
                  if ( (*itSocket)->isPolled() == true )
                  {
//                      logSpam(" COuld write #%i\n",1);
                        // doRecv() can close sockets
                        // we need a valid way to verify we dont try to send on a closed socket, 
                        // i think wantSend() is a good option here
                        // getStatus i just a cheap fix
//                      logDebug("SSS %s \n",(*itSocket)->getDescription().c_str());
                        if (
                    ( (*itSocket)->getStatus() == SS_CONNECTED || (*itSocket)->getStatus() == SS_CLEANQUIT ) &&  
                            (
                             (*itSocket)->isAccept() ||
                             (*itSocket)->isConnect() || 
                             (
                              (*itSocket)->isBind() && (*itSocket)->getType() & ST_UDP
                             )
                            )  
                           )
                        {
//                            if ( iPollRet == 0 )
//                                  continue;
//                            logSpam(" COuld write #%i\n",2);
                              if ( polls[i].revents & POLLOUT && polls[i].events & POLLOUT )
                              {
//                                  logSpam(" COuld write #%i\n",3);
                                    (*itSocket)->doSend();
                                    iPollRet--;
                              }
                        }
                        i++;
                  }
            }


            // accept new, non udp clients as udp does not accept()
            i=0;
            for (itSocket = m_Sockets.begin();itSocket != m_Sockets.end(); itSocket++)
            {
                        

                  if ( (*itSocket)->isPolled() == true )
                  {
                        if ( (*itSocket)->isBind() )
                        {
                              if ( iPollRet == 0 )
                                    continue;

                              if ( !((*itSocket)->getType() & ST_UDP) ) // bound udp sockets dont accept, they recvfrom
                              {
                                    if ( polls[i].revents & POLLIN && polls[i].events & POLLIN )
                                    {
                                          logDebug("%s could Accept a Connection\n",(*itSocket)->getDescription().c_str());
                                          Socket * socket = (*itSocket)->acceptConnection();
                                          if ( socket == NULL )
                                          {
                                                logCrit("%s","Accept returned NULL ptr \n");
                                          } else
                                          {
                                                m_Sockets.push_back(socket);
                                                logDebug("Accepted Connection %s \n%i Sockets in list\n",socket->getDescription().c_str(), m_Sockets.size());
                                          }
                                          iPollRet--;
                                    }
                              }
                        }
                        i++;
                  }
            }
      }
      free(polls);
//    sleep(1);
      return true;
}


Generated by  Doxygen 1.6.0   Back to index