(file) Return to HTTPAcceptor.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Common

Diff for /pegasus/src/Pegasus/Common/HTTPAcceptor.cpp between version 1.93.4.5 and 1.100

version 1.93.4.5, 2008/01/23 10:09:50 version 1.100, 2007/06/08 18:00:04
Line 40 
Line 40 
 #include "TLS.h" #include "TLS.h"
 #include "HTTPAcceptor.h" #include "HTTPAcceptor.h"
 #include "HTTPConnection.h" #include "HTTPConnection.h"
 #include "HostAddress.h"  
 #include "Tracer.h" #include "Tracer.h"
 #include <Pegasus/Common/MessageLoader.h> #include <Pegasus/Common/MessageLoader.h>
  
 #ifdef PEGASUS_PLATFORM_OS400_ISERIES_IBM  
 #include "EBCDIC_OS400.h"  
 #endif  
   
   
 PEGASUS_USING_STD; PEGASUS_USING_STD;
  
 PEGASUS_NAMESPACE_BEGIN PEGASUS_NAMESPACE_BEGIN
Line 65 
Line 59 
 class HTTPAcceptorRep class HTTPAcceptorRep
 { {
 public: public:
     HTTPAcceptorRep(Uint16 connectionType)      HTTPAcceptorRep(Boolean local)
     {     {
         if (connectionType == HTTPAcceptor::LOCAL_CONNECTION)          if (local)
         {         {
 #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET
             address =             address =
Line 77 
Line 71 
             PEGASUS_ASSERT(false);             PEGASUS_ASSERT(false);
 #endif #endif
         }         }
 #ifdef PEGASUS_ENABLE_IPV6          else
         else if (connectionType == HTTPAcceptor::IPV6_CONNECTION)  
         {  
             address =  
                 reinterpret_cast<struct sockaddr*>(new struct sockaddr_in6);  
             address_size = sizeof(struct sockaddr_in6);  
         }  
 #endif  
         else if (connectionType == HTTPAcceptor::IPV4_CONNECTION)  
         {         {
             address =             address =
                 reinterpret_cast<struct sockaddr*>(new struct sockaddr_in);                 reinterpret_cast<struct sockaddr*>(new struct sockaddr_in);
             address_size = sizeof(struct sockaddr_in);             address_size = sizeof(struct sockaddr_in);
         }         }
         else  
         {  
             PEGASUS_ASSERT(false);  
     }     }
     }  
   
     ~HTTPAcceptorRep()     ~HTTPAcceptorRep()
     {     {
         delete address;         delete address;
Line 119 
Line 100 
  
 HTTPAcceptor::HTTPAcceptor(Monitor* monitor, HTTPAcceptor::HTTPAcceptor(Monitor* monitor,
                            MessageQueue* outputMessageQueue,                            MessageQueue* outputMessageQueue,
                            Uint16 connectionType,                             Boolean localConnection,
                            Uint32 portNumber,                            Uint32 portNumber,
                            SSLContext * sslcontext,                            SSLContext * sslcontext,
                            ReadWriteSem* sslContextObjectLock)                            ReadWriteSem* sslContextObjectLock)
Line 128 
Line 109 
      _outputMessageQueue(outputMessageQueue),      _outputMessageQueue(outputMessageQueue),
      _rep(0),      _rep(0),
      _entry_index(-1),      _entry_index(-1),
      _connectionType(connectionType),       _localConnection(localConnection),
      _portNumber(portNumber),      _portNumber(portNumber),
      _sslcontext(sslcontext),      _sslcontext(sslcontext),
      _sslContextObjectLock(sslContextObjectLock),       _sslContextObjectLock(sslContextObjectLock)
      _idleConnectionTimeoutSeconds(0)  
 { {
    Socket::initializeInterface();    Socket::initializeInterface();
  
Line 154 
Line 134 
 /* /*
     if (MAX_CONNECTION_QUEUE_LENGTH == -1)     if (MAX_CONNECTION_QUEUE_LENGTH == -1)
     {     {
 #ifdef PEGASUS_PLATFORM_OS400_ISERIES_IBM  
 #pragma convert(37)  
         const char* env = getenv("PEGASUS_MAX_BACKLOG_CONNECTION_QUEUE");         const char* env = getenv("PEGASUS_MAX_BACKLOG_CONNECTION_QUEUE");
         EtoA(env);  
 #pragma convert(0)  
 #else  
         const char* env = getenv("PEGASUS_MAX_BACKLOG_CONNECTION_QUEUE");  
 #endif  
         if (!env)         if (!env)
         {         {
             MAX_CONNECTION_QUEUE_LENGTH = 15;             MAX_CONNECTION_QUEUE_LENGTH = 15;
Line 279 
Line 252 
         throw BindFailedException(parms);         throw BindFailedException(parms);
     }     }
  
     _rep = new HTTPAcceptorRep(_connectionType);      _rep = new HTTPAcceptorRep(_localConnection);
  
     // bind address     // bind address
     _bind();     _bind();
Line 294 
Line 267 
 { {
     PEGASUS_ASSERT(_rep != 0);     PEGASUS_ASSERT(_rep != 0);
     // Create address:     // Create address:
     memset(_rep->address, 0, _rep->address_size);  
  
     if (_connectionType == LOCAL_CONNECTION)      memset(_rep->address, 0, sizeof(*_rep->address));
   
       if (_localConnection)
     {     {
 #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET
           //
           // Make sure the local domain socket can be owned by the cimserver
           // user.  Otherwise, the bind may fail with a vague "bind failed"
           // error.
           //
           if (System::exists(PEGASUS_LOCAL_DOMAIN_SOCKET_PATH))
           {
               if (!System::removeFile(PEGASUS_LOCAL_DOMAIN_SOCKET_PATH))
               {
                   throw CannotRemoveFile(PEGASUS_LOCAL_DOMAIN_SOCKET_PATH);
               }
           }
   
         reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_family =         reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_family =
             AF_UNIX;             AF_UNIX;
         strcpy(reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path,         strcpy(reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path,
             PEGASUS_LOCAL_DOMAIN_SOCKET_PATH);             PEGASUS_LOCAL_DOMAIN_SOCKET_PATH);
 #ifdef PEGASUS_PLATFORM_OS400_ISERIES_IBM  
         AtoE(reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path);  
 #endif  
         ::unlink(  
             reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path);  
 #else #else
         PEGASUS_ASSERT(false);         PEGASUS_ASSERT(false);
 #endif #endif
     }     }
 #ifdef PEGASUS_ENABLE_IPV6      else
     else if (_connectionType == IPV6_CONNECTION)  
     {  
         reinterpret_cast<struct sockaddr_in6*>(_rep->address)->sin6_addr =  
             in6addr_any;  
         reinterpret_cast<struct sockaddr_in6*>(_rep->address)->sin6_family =  
             AF_INET6;  
         reinterpret_cast<struct sockaddr_in6*>(_rep->address)->sin6_port =  
             htons(_portNumber);  
     }  
 #endif  
     else if(_connectionType == IPV4_CONNECTION)  
     {     {
         reinterpret_cast<struct sockaddr_in*>(_rep->address)->sin_addr.s_addr =         reinterpret_cast<struct sockaddr_in*>(_rep->address)->sin_addr.s_addr =
             INADDR_ANY;             INADDR_ANY;
Line 332 
Line 303 
         reinterpret_cast<struct sockaddr_in*>(_rep->address)->sin_port =         reinterpret_cast<struct sockaddr_in*>(_rep->address)->sin_port =
             htons(_portNumber);             htons(_portNumber);
     }     }
     else  
     {  
         PEGASUS_ASSERT(false);  
     }  
  
     // Create socket:     // Create socket:
  
     if (_connectionType == LOCAL_CONNECTION)      if (_localConnection)
     {     {
         _rep->socket = Socket::createSocket(AF_UNIX, SOCK_STREAM, 0);         _rep->socket = Socket::createSocket(AF_UNIX, SOCK_STREAM, 0);
     }     }
 #ifdef PEGASUS_ENABLE_IPV6  
     else if (_connectionType == IPV6_CONNECTION)  
     {  
         _rep->socket = Socket::createSocket(PF_INET6, SOCK_STREAM, IPPROTO_TCP);  
     }  
 #endif  
     else if (_connectionType == IPV4_CONNECTION)  
     {  
         _rep->socket = Socket::createSocket(PF_INET, SOCK_STREAM, IPPROTO_TCP);  
     }  
     else     else
     {     {
         PEGASUS_ASSERT(false);          _rep->socket = Socket::createSocket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
     }     }
  
     if (_rep->socket < 0)     if (_rep->socket < 0)
Line 369 
Line 326 
         throw BindFailedException(parms);         throw BindFailedException(parms);
     }     }
  
     Socket::disableBlocking(_rep->socket);  
  
 // set the close-on-exec bit for this file handle. // set the close-on-exec bit for this file handle.
 // any unix that forks needs this bit set. // any unix that forks needs this bit set.
Line 451 
Line 407 
 #if !defined(PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET) && \ #if !defined(PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET) && \
      (defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) || \      (defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) || \
       defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM))       defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM))
     if (_connectionType == LOCAL_CONNECTION)      if (_localConnection)
     {     {
         if (::chmod(PEGASUS_LOCAL_DOMAIN_SOCKET_PATH,         if (::chmod(PEGASUS_LOCAL_DOMAIN_SOCKET_PATH,
                 S_IRUSR | S_IWUSR | S_IXUSR |                 S_IRUSR | S_IWUSR | S_IXUSR |
Line 523 
Line 479 
         // close the socket         // close the socket
         Socket::close(_rep->socket);         Socket::close(_rep->socket);
         // Unlink Local Domain Socket Bug# 3312         // Unlink Local Domain Socket Bug# 3312
         if (_connectionType == LOCAL_CONNECTION)          if (_localConnection)
         {         {
 #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET
             PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL2,             PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL2,
Line 572 
Line 528 
         // close the socket         // close the socket
         Socket::close(_rep->socket);         Socket::close(_rep->socket);
         // Unlink Local Domain Socket Bug# 3312         // Unlink Local Domain Socket Bug# 3312
         if (_connectionType == LOCAL_CONNECTION)          if (_localConnection)
         {         {
 #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET
             PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL2,             PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL2,
Line 626 
Line 582 
     _socketWriteTimeout = socketWriteTimeout;     _socketWriteTimeout = socketWriteTimeout;
 } }
  
 void HTTPAcceptor::setIdleConnectionTimeout(Uint32 idleConnectionTimeoutSeconds)  
 {  
     _idleConnectionTimeoutSeconds = idleConnectionTimeoutSeconds;  
 }  
   
 void HTTPAcceptor::unbind() void HTTPAcceptor::unbind()
 { {
     if (_rep)     if (_rep)
Line 638 
Line 589 
         _portNumber = 0;         _portNumber = 0;
         Socket::close(_rep->socket);         Socket::close(_rep->socket);
  
         if (_connectionType == LOCAL_CONNECTION)          if (_localConnection)
         {         {
 #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET
             ::unlink(             ::unlink(
Line 695 
Line 646 
     struct sockaddr* accept_address;     struct sockaddr* accept_address;
     SocketLength address_size;     SocketLength address_size;
  
     if (_connectionType == LOCAL_CONNECTION)      if (_localConnection)
     {     {
 #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET
         accept_address =         accept_address =
Line 707 
Line 658 
     }     }
     else     else
     {     {
 #ifdef PEGASUS_ENABLE_IPV6  
         accept_address =  
            reinterpret_cast<struct sockaddr*>  
            (new struct sockaddr_storage);  
         address_size = sizeof(struct sockaddr_storage);  
 #else  
         accept_address =         accept_address =
             reinterpret_cast<struct sockaddr*>(new struct sockaddr_in);             reinterpret_cast<struct sockaddr*>(new struct sockaddr_in);
         address_size = sizeof(struct sockaddr_in);         address_size = sizeof(struct sockaddr_in);
 #endif  
     }     }
  
     // It is not necessary to handle EINTR errors from this accept() call.      SocketHandle socket;
     // An EINTR error should not occur on a non-blocking socket.  If the  #ifdef PEGASUS_OS_TYPE_WINDOWS
     // listen socket is blocking and EINTR occurs, the new socket connection      socket = accept(_rep->socket, accept_address, &address_size);
     // is not accepted here.  #else
       while (
     // EAGAIN errors are also not handled here.  An EAGAIN error should not          ((socket = accept(_rep->socket, accept_address, &address_size)) == -1)
     // occur after select() indicates that the listen socket is available for          && (errno == EINTR))
     // reading.  If the accept() fails with an EAGAIN error code, a new          ;
     // connection is not accepted here.  #endif
   
     SocketHandle socket = accept(_rep->socket, accept_address, &address_size);  
  
     if (socket == PEGASUS_SOCKET_ERROR)     if (socket == PEGASUS_SOCKET_ERROR)
     {     {
Line 754 
Line 696 
             "HTTPAcceptor: accept() failed");             "HTTPAcceptor: accept() failed");
         return;         return;
     }     }
     // We need to ensure that the socket number is not higher than  
     // what fits into FD_SETSIZE, because we else won't be able to select on it  
     // and won't ever communicate correct on that socket.  
     if (socket >= FD_SETSIZE)  
     {  
         // the remote connection is invalid, destroy client address.  
         delete accept_address;  
   
         Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,  
             "HTTPAcceptor out of available sockets. "  
                 "Closing connection to the new client.");  
   
         PEG_TRACE(  
             (TRC_DISCARDED_DATA,  
              Tracer::LEVEL2,  
              "accept() returned too large socket number %d.",  
              socket));  
   
         // close the connection  
         Socket::close(socket);  
         return;  
     }  
   
  
     String ipAddress;     String ipAddress;
  
     if (_connectionType == LOCAL_CONNECTION)      if (_localConnection)
     {     {
         ipAddress = "localhost";         ipAddress = "localhost";
     }     }
     else     else
     {     {
 #ifdef PEGASUS_ENABLE_IPV6  
         char ipBuffer[PEGASUS_INET6_ADDRSTR_LEN];  
         int rc;  
         while ((rc = getnameinfo(accept_address, address_size, ipBuffer,  
             PEGASUS_INET6_ADDRSTR_LEN, 0, 0, NI_NUMERICHOST)) == EAI_AGAIN)  
             ;  
         if (rc)  
         {  
             Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,  
                 "HTTPAcceptor - getnameinfo() failure.  rc: $0", rc);  
   
             PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,  
                 "HTTPAcceptor: getnameinfo() failed");  
             delete accept_address;  
             Socket::close(socket);  
             return;  
         }  
         ipAddress = ipBuffer;  
 #else  
         unsigned char* sa = reinterpret_cast<unsigned char*>(         unsigned char* sa = reinterpret_cast<unsigned char*>(
             &reinterpret_cast<struct sockaddr_in*>(             &reinterpret_cast<struct sockaddr_in*>(
                 accept_address)->sin_addr.s_addr);                 accept_address)->sin_addr.s_addr);
         char ipBuffer[32];         char ipBuffer[32];
         sprintf(ipBuffer, "%u.%u.%u.%u", sa[0], sa[1], sa[2], sa[3]);         sprintf(ipBuffer, "%u.%u.%u.%u", sa[0], sa[1], sa[2], sa[3]);
         ipAddress = ipBuffer;         ipAddress = ipBuffer;
 #endif  
     }     }
  
     delete accept_address;     delete accept_address;
Line 839 
Line 738 
     PEG_LOGGER_TRACE((Logger::STANDARD_LOG, System::CIMSERVER, 0,     PEG_LOGGER_TRACE((Logger::STANDARD_LOG, System::CIMSERVER, 0,
         "HTTPAcceptor - accept() success.  Socket: $1" ,socket));         "HTTPAcceptor - accept() success.  Socket: $1" ,socket));
  
     AutoPtr<MP_Socket> mp_socket(new MP_Socket(      SharedPtr<MP_Socket> mp_socket(new MP_Socket(
         socket, _sslcontext, _sslContextObjectLock));          socket, _sslcontext, _sslContextObjectLock, ipAddress));
  
     mp_socket->disableBlocking();  
     mp_socket->setSocketWriteTimeout(_socketWriteTimeout);     mp_socket->setSocketWriteTimeout(_socketWriteTimeout);
  
     // Perform the SSL handshake, if applicable.      // Perform the SSL handshake, if applicable.  Make the socket non-blocking
       // for this operation so we can send it back to the Monitor's select() loop
       // if it takes a while.
  
       mp_socket->disableBlocking();
     Sint32 socketAcceptStatus = mp_socket->accept();     Sint32 socketAcceptStatus = mp_socket->accept();
       mp_socket->enableBlocking();
  
     if (socketAcceptStatus < 0)     if (socketAcceptStatus < 0)
     {     {
Line 862 
Line 764 
     HTTPConnection* connection = new HTTPConnection(_monitor, mp_socket,     HTTPConnection* connection = new HTTPConnection(_monitor, mp_socket,
         ipAddress, this, static_cast<MessageQueue *>(_outputMessageQueue));         ipAddress, this, static_cast<MessageQueue *>(_outputMessageQueue));
  
     if (_idleConnectionTimeoutSeconds)  
     {  
         connection->_idleConnectionTimeoutSeconds =  
             _idleConnectionTimeoutSeconds;  
         Time::gettimeofday(&connection->_idleStartTime);  
     }  
   
     if (socketAcceptStatus == 0)     if (socketAcceptStatus == 0)
     {     {
         PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL2,         PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL2,
             "HTTPAcceptor: SSL_accept() pending");             "HTTPAcceptor: SSL_accept() pending");
         connection->_acceptPending = true;         connection->_acceptPending = true;
         Time::gettimeofday(&connection->_acceptPendingStartTime);  
     }     }
  
     // Solicit events on this new connection's socket:     // Solicit events on this new connection's socket:


Legend:
Removed from v.1.93.4.5  
changed lines
  Added in v.1.100

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2