(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.67 and 1.93.4.4

version 1.67, 2005/05/16 15:22:15 version 1.93.4.4, 2008/01/02 21:05:03
Line 1 
Line 1 
 //%2005////////////////////////////////////////////////////////////////////////  //%2006////////////////////////////////////////////////////////////////////////
 // //
 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems. // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
Line 8 
Line 8 
 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group. // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.; // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 // EMC Corporation; VERITAS Software Corporation; The Open Group. // EMC Corporation; VERITAS Software Corporation; The Open Group.
   // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
   // EMC Corporation; Symantec Corporation; The Open Group.
 // //
 // Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
 // of this software and associated documentation files (the "Software"), to // of this software and associated documentation files (the "Software"), to
Line 27 
Line 29 
 // //
 //============================================================================== //==============================================================================
 // //
 // Author: Mike Brasher (mbrasher@bmc.com)  
 //  
 // Modified By:  
 //          Jenny Yu, Hewlett-Packard Company (jenny_yu@hp.com)  
 //          Nag Boranna, Hewlett-Packard Company (nagaraja_boranna@hp.com)  
 //          Dave Rosckes (rosckes@us.ibm.com)  
 //          Denise Eckstein (denise.eckstein@hp.com)  
 //          Alagaraja Ramasubramanian (alags_raj@in.ibm.com) for Bug#1090  
 //          Amit Arora, IBM (amita@in.ibm.com) for Bug#2541  
 //          Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com)  
 //          Sean Keenan, Hewlett-Packard Company (sean.keenan@hp.com)  
 //          Josephine Eskaline Joyce, IBM (jojustin@in.ibm.com) for Bug#2065  
 //          David Dillard, VERITAS Software Corp.  
 //              (david.dillard@veritas.com)  
 //          John Alex, IBM (johnalex@us.ibm.com) for Bug#3312  
 //  
 //%///////////////////////////////////////////////////////////////////////////// //%/////////////////////////////////////////////////////////////////////////////
  
 #include "Config.h" #include "Config.h"
 #include "Constants.h" #include "Constants.h"
 #include <iostream> #include <iostream>
 #include "Socket.h"  
   
 #ifdef PEGASUS_PLATFORM_WIN32_IX86_MSVC  
 #include <windows.h>  
 #else  
 # include <cctype>  
 # include <cstdlib>  
 # include <errno.h>  
 # include <fcntl.h>  
 # include <netdb.h>  
 # include <netinet/in.h>  
 # include <arpa/inet.h>  
 # include <sys/socket.h>  
 # ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET  
 # include <unistd.h>  
 #  include <sys/un.h>  
 # endif  
 #endif  
  
   #include "Network.h"
 #include "Socket.h" #include "Socket.h"
 #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> //l10n  #include <Pegasus/Common/MessageLoader.h>
  
 #ifdef PEGASUS_PLATFORM_OS400_ISERIES_IBM #ifdef PEGASUS_PLATFORM_OS400_ISERIES_IBM
 #include "OS400ConvertChar.h"  #include "EBCDIC_OS400.h"
 #endif #endif
  
   
 PEGASUS_USING_STD; PEGASUS_USING_STD;
  
 PEGASUS_NAMESPACE_BEGIN PEGASUS_NAMESPACE_BEGIN
  
  
 //  
 // Determine the correct type to use for the length passed to getsockname().  
 // The default is to use the 'socklen_t'.  
 //  
   
 #if defined(PEGASUS_OS_TYPE_WINDOWS) || defined(PEGASUS_OS_OS400)  
 #define PEGASUS_SOCKLEN_T   int  
 #endif  
   
 #if defined(PEGASUS_OS_HPUX) && !defined(_XOPEN_SOURCE_EXTENDED)  
 #define PEGASUS_SOCKLEN_T   int  
 #endif  
   
   
 #if defined(PEGASUS_OS_VMS) || defined(PEGASUS_OS_ZOS)  
 #define PEGASUS_SOCKLEN_T   unsigned  
 #endif  
   
 #ifndef PEGASUS_SOCKLEN_T  
 #define PEGASUS_SOCKLEN_T   socklen_t  
 #endif  
   
 static int MAX_CONNECTION_QUEUE_LENGTH = -1; static int MAX_CONNECTION_QUEUE_LENGTH = -1;
  
   
 //////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
 // //
 // HTTPAcceptorRep // HTTPAcceptorRep
Line 117 
Line 65 
 class HTTPAcceptorRep class HTTPAcceptorRep
 { {
 public: public:
     HTTPAcceptorRep(Boolean local)      HTTPAcceptorRep(Uint16 connectionType)
     {     {
         if (local)          if (connectionType == HTTPAcceptor::LOCAL_CONNECTION)
         {         {
 #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET
             address = reinterpret_cast<struct sockaddr*>(new struct sockaddr_un);              address =
                   reinterpret_cast<struct sockaddr*>(new struct sockaddr_un);
             address_size = sizeof(struct sockaddr_un);             address_size = sizeof(struct sockaddr_un);
 #else #else
             PEGASUS_ASSERT(false);             PEGASUS_ASSERT(false);
 #endif #endif
         }         }
         else  #ifdef PEGASUS_ENABLE_IPV6
           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 = reinterpret_cast<struct sockaddr*>(new struct sockaddr_in);              address =
                   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()
       {
           delete address;
       }
     struct sockaddr* address;     struct sockaddr* address;
  
 #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM) || defined(PEGASUS_OS_VMS)      SocketLength address_size;
    size_t address_size;  
 #elif defined(PEGASUS_PLATFORM_AIX_RS_IBMCXX) || defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) || (defined(PEGASUS_PLATFORM_SOLARIS_SPARC_CC) && !defined(SUNOS_5_6))  
    socklen_t address_size;  
 #else  
    int address_size;  
 #endif  
       Mutex _connection_mut;       Mutex _connection_mut;
  
       Sint32 socket;      SocketHandle socket;
       Array<HTTPConnection*> connections;       Array<HTTPConnection*> connections;
 }; };
  
   
 //////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
 // //
 // HTTPAcceptor // HTTPAcceptor
Line 158 
Line 119 
  
 HTTPAcceptor::HTTPAcceptor(Monitor* monitor, HTTPAcceptor::HTTPAcceptor(Monitor* monitor,
                            MessageQueue* outputMessageQueue,                            MessageQueue* outputMessageQueue,
                            Boolean localConnection,                             Uint16 connectionType,
                            Uint32 portNumber,                            Uint32 portNumber,
                            SSLContext * sslcontext,                            SSLContext * sslcontext,
                            Boolean exportConnection,  
                            ReadWriteSem* sslContextObjectLock)                            ReadWriteSem* sslContextObjectLock)
    : Base(PEGASUS_QUEUENAME_HTTPACCEPTOR),  // ATTN: Need unique names?    : Base(PEGASUS_QUEUENAME_HTTPACCEPTOR),  // ATTN: Need unique names?
      _monitor(monitor),      _monitor(monitor),
      _outputMessageQueue(outputMessageQueue),      _outputMessageQueue(outputMessageQueue),
      _rep(0),      _rep(0),
      _entry_index(-1),      _entry_index(-1),
      _localConnection(localConnection),       _connectionType(connectionType),
      _portNumber(portNumber),      _portNumber(portNumber),
      _sslcontext(sslcontext),      _sslcontext(sslcontext),
      _exportConnection(exportConnection),       _sslContextObjectLock(sslContextObjectLock),
      _sslContextObjectLock(sslContextObjectLock)       _idleConnectionTimeoutSeconds(0)
 { {
    Socket::initializeInterface();    Socket::initializeInterface();
  
    /*    /*
         Platforms interpret the value of MAX_CONNECTION_QUEUE_LENGTH differently.  Some platforms interpret          Platforms interpret the value of MAX_CONNECTION_QUEUE_LENGTH
         the value literally, while others multiply a fudge factor. When the server is under          differently.  Some platforms interpret the value literally, while
         stress from multiple clients with multiple requests, toggling this number may prevent clients from          others multiply a fudge factor. When the server is under stress from
         being dropped.  Instead of hard coding the value, we allow an environment variable to be set which          multiple clients with multiple requests, toggling this number may
         specifies a number greater than the maximum concurrent client connections possible.  If this environment          prevent clients from being dropped.  Instead of hard coding the
         var is not specified, then MAX_CONNECTION_QUEUE_LENGTH = 15.          value, we allow an environment variable to be set which specifies a
           number greater than the maximum concurrent client connections
           possible.  If this environment var is not specified, then
           MAX_CONNECTION_QUEUE_LENGTH = 15.
    */    */
  
 //To engage runtime backlog queue length: uncomment the following block AND comment out the line MAX_CONNECTION_QUEUE_LENGTH = 15  //To engage runtime backlog queue length: uncomment the following block AND
   //comment out the line MAX_CONNECTION_QUEUE_LENGTH = 15
  
 /* /*
    if(MAX_CONNECTION_QUEUE_LENGTH == -1){      if (MAX_CONNECTION_QUEUE_LENGTH == -1)
       {
 #ifdef PEGASUS_PLATFORM_OS400_ISERIES_IBM #ifdef PEGASUS_PLATFORM_OS400_ISERIES_IBM
 #pragma convert(37) #pragma convert(37)
     const char* env = getenv("PEGASUS_MAX_BACKLOG_CONNECTION_QUEUE");     const char* env = getenv("PEGASUS_MAX_BACKLOG_CONNECTION_QUEUE");
Line 197 
Line 162 
 #else #else
     const char* env = getenv("PEGASUS_MAX_BACKLOG_CONNECTION_QUEUE");     const char* env = getenv("PEGASUS_MAX_BACKLOG_CONNECTION_QUEUE");
 #endif #endif
     if(!env){          if (!env)
           {
         MAX_CONNECTION_QUEUE_LENGTH = 15;         MAX_CONNECTION_QUEUE_LENGTH = 15;
     }else{          }
           else
           {
         char *end = NULL;         char *end = NULL;
         MAX_CONNECTION_QUEUE_LENGTH = strtol(env, &end, 10);         MAX_CONNECTION_QUEUE_LENGTH = strtol(env, &end, 10);
         if(*end)         if(*end)
             MAX_CONNECTION_QUEUE_LENGTH = 15;             MAX_CONNECTION_QUEUE_LENGTH = 15;
         cout << " MAX_CONNECTION_QUEUE_LENGTH = " << MAX_CONNECTION_QUEUE_LENGTH << endl;              cout << " MAX_CONNECTION_QUEUE_LENGTH = " <<
                   MAX_CONNECTION_QUEUE_LENGTH << endl;
     }     }
    }    }
 */ */
    MAX_CONNECTION_QUEUE_LENGTH = 15;    MAX_CONNECTION_QUEUE_LENGTH = 15;
   
 } }
  
 HTTPAcceptor::~HTTPAcceptor() HTTPAcceptor::~HTTPAcceptor()
 { {
       destroyConnections();
    unbind();    unbind();
    // ATTN: Is this correct in a multi-HTTPAcceptor server?    // ATTN: Is this correct in a multi-HTTPAcceptor server?
    Socket::uninitializeInterface();    Socket::uninitializeInterface();
Line 224 
Line 193 
    if (! message)    if (! message)
       return;       return;
  
       PEGASUS_ASSERT(_rep != 0);
    switch (message->getType())    switch (message->getType())
    {    {
       case SOCKET_MESSAGE:       case SOCKET_MESSAGE:
Line 240 
Line 210 
      else      else
      {      {
         // ATTN! this can't happen!         // ATTN! this can't happen!
             Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2,                  PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
               "HTTPAcceptor::handleEnqueue: Invalid SOCKET_MESSAGE received.");                      "HTTPAcceptor::handleEnqueue: Invalid SOCKET_MESSAGE "
                           "received.");
      }      }
  
      break;      break;
Line 249 
Line 220 
  
       case CLOSE_CONNECTION_MESSAGE:       case CLOSE_CONNECTION_MESSAGE:
       {       {
      CloseConnectionMessage* closeConnectionMessage             CloseConnectionMessage* closeConnectionMessage =
         = (CloseConnectionMessage*)message;                 (CloseConnectionMessage*)message;
  
      AutoMutex autoMut(_rep->_connection_mut);      AutoMutex autoMut(_rep->_connection_mut);
  
      for (Uint32 i = 0, n = _rep->connections.size(); i < n; i++)      for (Uint32 i = 0, n = _rep->connections.size(); i < n; i++)
      {      {
         HTTPConnection* connection = _rep->connections[i];         HTTPConnection* connection = _rep->connections[i];
         Sint32 socket = connection->getSocket();                 SocketHandle socket = connection->getSocket();
  
         if (socket == closeConnectionMessage->socket)         if (socket == closeConnectionMessage->socket)
         {         {
Line 273 
Line 244 
  
       default:       default:
       // ATTN: need unexpected message error!       // ATTN: need unexpected message error!
       Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2,             PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
            "HTTPAcceptor::handleEnqueue: Invalid MESSAGE received.");            "HTTPAcceptor::handleEnqueue: Invalid MESSAGE received.");
       break;       break;
    };      }
  
    delete message;    delete message;
 } }
Line 288 
Line 259 
  
    if (!message)    if (!message)
    {    {
       Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2,          PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
            "HTTPAcceptor::handleEnqueue(): No message on queue.");            "HTTPAcceptor::handleEnqueue(): No message on queue.");
       return;       return;
    }    }
  
    handleEnqueue(message);    handleEnqueue(message);
   
 } }
  
 void HTTPAcceptor::bind() void HTTPAcceptor::bind()
 { {
    if (_rep){      if (_rep)
     //l10n      {
       //throw BindFailedException("HTTPAcceptor already bound");  
   
       MessageLoaderParms parms("Common.HTTPAcceptor.ALREADY_BOUND",       MessageLoaderParms parms("Common.HTTPAcceptor.ALREADY_BOUND",
                    "HTTPAcceptor already bound");                    "HTTPAcceptor already bound");
  
       Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2,          PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
            "HTTPAcceptor::bind: HTTPAcceptor already bound.");            "HTTPAcceptor::bind: HTTPAcceptor already bound.");
       throw BindFailedException(parms);       throw BindFailedException(parms);
    }    }
  
    _rep = new HTTPAcceptorRep(_localConnection);      _rep = new HTTPAcceptorRep(_connectionType);
  
    // bind address    // bind address
    _bind();    _bind();
   
    return;  
 } }
  
 /** /**
    _bind - creates a new server socket and bind socket to the port address.    _bind - creates a new server socket and bind socket to the port address.
    If PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET is not defined, the port number is ignored and      If PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET is not defined, the port number is
    a domain socket is bound.      ignored and a domain socket is bound.
 */ */
 void HTTPAcceptor::_bind() void HTTPAcceptor::_bind()
 { {
       PEGASUS_ASSERT(_rep != 0);
    // Create address:    // Create address:
       memset(_rep->address, 0, _rep->address_size);
  
    memset(_rep->address, 0, sizeof(*_rep->address));      if (_connectionType == LOCAL_CONNECTION)
   
    if (_localConnection)  
    {    {
 #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET
        reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_family =        reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_family =
Line 341 
Line 306 
 #ifdef PEGASUS_PLATFORM_OS400_ISERIES_IBM #ifdef PEGASUS_PLATFORM_OS400_ISERIES_IBM
        AtoE(reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path);        AtoE(reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path);
 #endif #endif
        ::unlink(reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path);          ::unlink(
               reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path);
 #else #else
        PEGASUS_ASSERT(false);        PEGASUS_ASSERT(false);
 #endif #endif
    }    }
    else  #ifdef PEGASUS_ENABLE_IPV6
       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 355 
Line 332 
        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 (_localConnection)      if (_connectionType == LOCAL_CONNECTION)
       {
           _rep->socket = Socket::createSocket(AF_UNIX, SOCK_STREAM, 0);
       }
   #ifdef PEGASUS_ENABLE_IPV6
       else if (_connectionType == IPV6_CONNECTION)
    {    {
        _rep->socket = socket(AF_UNIX, SOCK_STREAM, 0);          _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
    {    {
        _rep->socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);          PEGASUS_ASSERT(false);
    }    }
  
    if (_rep->socket < 0)    if (_rep->socket < 0)
    {    {
       delete _rep;       delete _rep;
       _rep = 0;       _rep = 0;
       //l10n  
       //throw BindFailedException("Failed to create socket");  
       MessageLoaderParms parms("Common.HTTPAcceptor.FAILED_CREATE_SOCKET",       MessageLoaderParms parms("Common.HTTPAcceptor.FAILED_CREATE_SOCKET",
                    "Failed to create socket");                    "Failed to create socket");
       Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2,          PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
            "HTTPAcceptor::_bind _rep->socket < 0");            "HTTPAcceptor::_bind _rep->socket < 0");
       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.
 #if !defined PEGASUS_PLATFORM_WIN32_IX86_MSVC && !defined(PEGASUS_OS_VMS)  #if !defined PEGASUS_OS_TYPE_WINDOWS && !defined(PEGASUS_OS_VMS)
    int sock_flags;    int sock_flags;
  if( (sock_flags = fcntl(_rep->socket, F_GETFD, 0)) < 0)  if( (sock_flags = fcntl(_rep->socket, F_GETFD, 0)) < 0)
    {    {
        PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,          PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
                   "HTTPAcceptor::_bind: fcntl(F_GETFD) failed");                   "HTTPAcceptor::_bind: fcntl(F_GETFD) failed");
    }    }
    else    else
Line 395 
Line 385 
       sock_flags |= FD_CLOEXEC;       sock_flags |= FD_CLOEXEC;
       if (fcntl(_rep->socket, F_SETFD, sock_flags) < 0)       if (fcntl(_rep->socket, F_SETFD, sock_flags) < 0)
       {       {
        PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,              PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
                   "HTTPAcceptor::_bind: fcntl(F_SETFD) failed");                   "HTTPAcceptor::_bind: fcntl(F_SETFD) failed");
       }       }
    }    }
Line 415 
Line 405 
       Socket::close(_rep->socket);       Socket::close(_rep->socket);
       delete _rep;       delete _rep;
       _rep = 0;       _rep = 0;
       //l10n  
       //throw BindFailedException("Failed to set socket option");  
       MessageLoaderParms parms("Common.HTTPAcceptor.FAILED_SET_SOCKET_OPTION",       MessageLoaderParms parms("Common.HTTPAcceptor.FAILED_SET_SOCKET_OPTION",
                    "Failed to set socket option");                    "Failed to set socket option");
       PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,          PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
                    "HTTPAcceptor::_bind: Failed to set socket option.");                    "HTTPAcceptor::_bind: Failed to set socket option.");
       throw BindFailedException(parms);       throw BindFailedException(parms);
    }    }
Line 433 
Line 421 
       Socket::close(_rep->socket);       Socket::close(_rep->socket);
       delete _rep;       delete _rep;
       _rep = 0;       _rep = 0;
       //l10n  
       //throw BindFailedException("Failed to bind socket");  
       MessageLoaderParms parms("Common.HTTPAcceptor.FAILED_BIND_SOCKET",       MessageLoaderParms parms("Common.HTTPAcceptor.FAILED_BIND_SOCKET",
                    "Failed to bind socket");                    "Failed to bind socket");
       PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,          PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
                         "HTTPAcceptor::_bind: Failed to bind socket.");                         "HTTPAcceptor::_bind: Failed to bind socket.");
       throw BindFailedException(parms);       throw BindFailedException(parms);
    }    }
Line 449 
Line 435 
    if ( _portNumber == 0 )    if ( _portNumber == 0 )
    {    {
       sockaddr_in buf;       sockaddr_in buf;
       PEGASUS_SOCKLEN_T bufSize = sizeof(buf);          SocketLength bufSize = sizeof(buf);
       if ( getsockname(_rep->socket, reinterpret_cast<sockaddr *>(&buf), &bufSize) == 0 )          if (getsockname(_rep->socket, reinterpret_cast<sockaddr *>(&buf),
                   &bufSize) == 0 )
       {       {
           _portNumber = ntohs(buf.sin_port);           _portNumber = ntohs(buf.sin_port);
       }       }
Line 458 
Line 445 
  
  
    //    //
    //  Change permissions on Linux local domain socket to allow writes by others.      // Change permissions on Linux local domain socket to allow writes by
       // others.
    //    //
 #if !defined(PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET) && defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU)  #if !defined(PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET) && \
    if (_localConnection)       (defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) || \
         defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM))
       if (_connectionType == LOCAL_CONNECTION)
    {    {
      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 471 
Line 461 
        Socket::close(_rep->socket);        Socket::close(_rep->socket);
        delete _rep;        delete _rep;
        _rep = 0;        _rep = 0;
        //l10n  
        //throw BindFailedException("Failed to bind socket");  
        MessageLoaderParms parms("Common.HTTPAcceptor.FAILED_BIND_SOCKET",        MessageLoaderParms parms("Common.HTTPAcceptor.FAILED_BIND_SOCKET",
                    "Failed to bind socket");                    "Failed to bind socket");
        PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,              PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
               "HTTPAcceptor::_bind: Failed to set domain socket permissions.");                  "HTTPAcceptor::_bind: Failed to set domain socket "
                       "permissions.");
        throw BindFailedException(parms);        throw BindFailedException(parms);
      }      }
    }    }
Line 491 
Line 480 
       Socket::close(_rep->socket);       Socket::close(_rep->socket);
       delete _rep;       delete _rep;
       _rep = 0;       _rep = 0;
       //l10n  
       //throw BindFailedException("Failed to bind socket");  
       MessageLoaderParms parms("Common.HTTPAcceptor.FAILED_BIND_SOCKET",       MessageLoaderParms parms("Common.HTTPAcceptor.FAILED_BIND_SOCKET",
                    "Failed to bind socket");                    "Failed to bind socket");
       PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,          PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
                   "HTTPAcceptor::_bind: Failed to bind socket(1).");                   "HTTPAcceptor::_bind: Failed to bind socket(1).");
       throw BindFailedException(parms);       throw BindFailedException(parms);
    }    }
Line 511 
Line 498 
       Socket::close(_rep->socket);       Socket::close(_rep->socket);
       delete _rep;       delete _rep;
       _rep = 0;       _rep = 0;
       //l10n          MessageLoaderParms parms(
       //throw BindFailedException("Failed to solicit socket messaeges");              "Common.HTTPAcceptor.FAILED_SOLICIT_SOCKET_MESSAGES",
       MessageLoaderParms parms("Common.HTTPAcceptor.FAILED_SOLICIT_SOCKET_MESSAGES",  
                    "Failed to solicit socket messaeges");                    "Failed to solicit socket messaeges");
       PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,          PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
                   "HTTPAcceptor::_bind: Failed to solicit socket messages(2).");                   "HTTPAcceptor::_bind: Failed to solicit socket messages(2).");
       throw BindFailedException(parms);       throw BindFailedException(parms);
    }    }
Line 537 
Line 523 
       // 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 (_localConnection)          if (_connectionType == LOCAL_CONNECTION)
       {       {
 #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET
           PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,              PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL2,
                         "HTTPAcceptor::closeConnectionSocket Unlinking local connection." );                  "HTTPAcceptor::closeConnectionSocket Unlinking local "
                       "connection.");
          ::unlink(          ::unlink(
              reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path);              reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path);
 #else #else
          PEGASUS_ASSERT(false);          PEGASUS_ASSERT(false);
 #endif #endif
       }       }
   
    }    }
    else    else
    {    {
       PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,          PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
                         "HTTPAcceptor::closeConnectionSocket failure _rep is null." );                         "HTTPAcceptor::closeConnectionSocket failure _rep is null." );
    }    }
 } }
Line 568 
Line 554 
    }    }
    else    else
    {    {
       PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,          PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
                         "HTTPAcceptor::reopenConnectionSocket failure _rep is null." );                         "HTTPAcceptor::reopenConnectionSocket failure _rep is null." );
    }    }
 } }
  
   
   /**
      reconnectConnectionSocket - creates a new server socket.
   */
   void HTTPAcceptor::reconnectConnectionSocket()
   {
       if (_rep)
       {
           // unregister the socket
           _monitor->unsolicitSocketMessages(_rep->socket);
           // close the socket
           Socket::close(_rep->socket);
           // Unlink Local Domain Socket Bug# 3312
           if (_connectionType == LOCAL_CONNECTION)
           {
   #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET
               PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL2,
                   "HTTPAcceptor::reconnectConnectionSocket Unlinking local "
                       "connection." );
               ::unlink(
                   reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path);
   #else
               PEGASUS_ASSERT(false);
   #endif
           }
           // open the socket
           _bind();
       }
       else
       {
           PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
               "HTTPAcceptor::reconnectConnectionSocket failure _rep is null.");
       }
   }
   
 /** /**
    getOutstandingRequestCount - returns the number of outstanding requests.    getOutstandingRequestCount - returns the number of outstanding requests.
 */ */
 Uint32 HTTPAcceptor::getOutstandingRequestCount() const Uint32 HTTPAcceptor::getOutstandingRequestCount() const
 { {
    Uint32 count = 0;    Uint32 count = 0;
       if (_rep)
       {
    AutoMutex autoMut(_rep->_connection_mut);    AutoMutex autoMut(_rep->_connection_mut);
    if (_rep->connections.size() > 0)    if (_rep->connections.size() > 0)
    {    {
       HTTPConnection* connection = _rep->connections[0];       HTTPConnection* connection = _rep->connections[0];
       count = connection->getRequestCount();       count = connection->getRequestCount();
    }    }
       }
    return count;    return count;
 } }
  
Line 599 
Line 621 
     return _portNumber;     return _portNumber;
 } }
  
   void HTTPAcceptor::setSocketWriteTimeout(Uint32 socketWriteTimeout)
   {
       _socketWriteTimeout = socketWriteTimeout;
   }
   
   void HTTPAcceptor::setIdleConnectionTimeout(Uint32 idleConnectionTimeoutSeconds)
   {
       _idleConnectionTimeoutSeconds = idleConnectionTimeoutSeconds;
   }
   
 void HTTPAcceptor::unbind() void HTTPAcceptor::unbind()
 { {
    if (_rep)    if (_rep)
Line 606 
Line 638 
       _portNumber = 0;       _portNumber = 0;
       Socket::close(_rep->socket);       Socket::close(_rep->socket);
  
       if (_localConnection)          if (_connectionType == LOCAL_CONNECTION)
       {       {
 #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET
          ::unlink(          ::unlink(
Line 621 
Line 653 
    }    }
    else    else
    {    {
       PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,          PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
               "HTTPAcceptor::unbind failure _rep is null." );               "HTTPAcceptor::unbind failure _rep is null." );
    }    }
 } }
  
 void HTTPAcceptor::destroyConnections() void HTTPAcceptor::destroyConnections()
 { {
       if (_rep)
       {
    // For each connection created by this object:    // For each connection created by this object:
  
    AutoMutex autoMut(_rep->_connection_mut);    AutoMutex autoMut(_rep->_connection_mut);
    for (Uint32 i = 0, n = _rep->connections.size(); i < n; i++)    for (Uint32 i = 0, n = _rep->connections.size(); i < n; i++)
    {    {
       HTTPConnection* connection = _rep->connections[i];       HTTPConnection* connection = _rep->connections[i];
       Sint32 socket = connection->getSocket();              SocketHandle socket = connection->getSocket();
  
       // Unsolicit SocketMessages:       // Unsolicit SocketMessages:
  
Line 644 
Line 676 
  
       // Destroy the connection (causing it to close):       // Destroy the connection (causing it to close):
  
       while (connection->refcount.value()) { }              while (connection->refcount.get()) { }
       delete connection;       delete connection;
    }    }
  
    _rep->connections.clear();    _rep->connections.clear();
       }
 } }
  
 void HTTPAcceptor::_acceptConnection() void HTTPAcceptor::_acceptConnection()
Line 658 
Line 690 
  
    PEGASUS_ASSERT(_rep != 0);    PEGASUS_ASSERT(_rep != 0);
  
    if (!_rep)  
       return;  
   
    // Accept the connection (populate the address):    // Accept the connection (populate the address):
  
    struct sockaddr* accept_address;    struct sockaddr* accept_address;
 #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM) || defined(PEGASUS_OS_VMS)      SocketLength address_size;
    size_t address_size;  
 #elif defined(PEGASUS_PLATFORM_AIX_RS_IBMCXX) || defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) || (defined(PEGASUS_OS_SOLARIS) && !defined(SUNOS_5_6))  
    socklen_t address_size;  
 #else  
    int address_size;  
 #endif  
  
    if (_localConnection)      if (_connectionType == LOCAL_CONNECTION)
    {    {
 #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET
        accept_address = reinterpret_cast<struct sockaddr*>(new struct sockaddr_un);          accept_address =
               reinterpret_cast<struct sockaddr*>(new struct sockaddr_un);
        address_size = sizeof(struct sockaddr_un);        address_size = sizeof(struct sockaddr_un);
 #else #else
        PEGASUS_ASSERT(false);        PEGASUS_ASSERT(false);
Line 683 
Line 707 
    }    }
    else    else
    {    {
        accept_address = reinterpret_cast<struct sockaddr*>(new struct sockaddr_in);  #ifdef PEGASUS_ENABLE_IPV6
           accept_address =
              reinterpret_cast<struct sockaddr*>
              (new struct sockaddr_storage);
           address_size = sizeof(struct sockaddr_storage);
   #else
           accept_address =
               reinterpret_cast<struct sockaddr*>(new struct sockaddr_in);
        address_size = sizeof(struct sockaddr_in);        address_size = sizeof(struct sockaddr_in);
   #endif
    }    }
  
    Sint32 socket = accept(_rep->socket, accept_address, &address_size);      // It is not necessary to handle EINTR errors from this accept() call.
       // An EINTR error should not occur on a non-blocking socket.  If the
       // listen socket is blocking and EINTR occurs, the new socket connection
       // is not accepted here.
   
       // EAGAIN errors are also not handled here.  An EAGAIN error should not
       // occur after select() indicates that the listen socket is available for
       // reading.  If the accept() fails with an EAGAIN error code, a new
       // connection is not accepted here.
  
       SocketHandle socket = accept(_rep->socket, accept_address, &address_size);
   
       if (socket == PEGASUS_SOCKET_ERROR)
       {
           // the remote connection is invalid, destroy client address.
    delete accept_address;    delete accept_address;
  
    if (socket < 0)          // TCPIP is down reconnect this acceptor
           if (getSocketError() == PEGASUS_NETWORK_TCPIP_STOPPED)
    {    {
               PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
                   "Socket has an IO error. TCP/IP down. Try to reconnect.");
   
               reconnectConnectionSocket();
   
               return;
           }
  
        Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,        Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,
            "HTTPAcceptor - accept() failure.  errno: $0"              "HTTPAcceptor - accept() failure.  errno: $0", errno);
            ,errno);  
  
        PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,          PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
                         "HTTPAcceptor: accept() failed");                         "HTTPAcceptor: accept() failed");
       return;       return;
    }    }
  
       String ipAddress;
   
       if (_connectionType == LOCAL_CONNECTION)
       {
           ipAddress = "localhost";
       }
       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*>(
               &reinterpret_cast<struct sockaddr_in*>(
                   accept_address)->sin_addr.s_addr);
           char ipBuffer[32];
           sprintf(ipBuffer, "%u.%u.%u.%u", sa[0], sa[1], sa[2], sa[3]);
           ipAddress = ipBuffer;
   #endif
       }
   
       delete accept_address;
   
 // set the close on exec flag // set the close on exec flag
 #if !defined PEGASUS_PLATFORM_WIN32_IX86_MSVC && !defined(PEGASUS_OS_VMS)  #if !defined(PEGASUS_OS_TYPE_WINDOWS) && !defined(PEGASUS_OS_VMS)
    int sock_flags;    int sock_flags;
  if( (sock_flags = fcntl(socket, F_GETFD, 0)) < 0)  if( (sock_flags = fcntl(socket, F_GETFD, 0)) < 0)
    {    {
        PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,          PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
                         "HTTPAcceptor: fcntl(F_GETFD) failed");                         "HTTPAcceptor: fcntl(F_GETFD) failed");
    }    }
    else    else
Line 716 
Line 806 
       sock_flags |= FD_CLOEXEC;       sock_flags |= FD_CLOEXEC;
       if (fcntl(socket, F_SETFD, sock_flags) < 0)       if (fcntl(socket, F_SETFD, sock_flags) < 0)
       {       {
        PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,              PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
                         "HTTPAcceptor: fcntl(F_SETFD) failed");                         "HTTPAcceptor: fcntl(F_SETFD) failed");
       }       }
    }    }
 #endif #endif
  
  
    Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,      PEG_LOGGER_TRACE((Logger::STANDARD_LOG, System::CIMSERVER, 0,
            "HTTPAcceptor - accept() success.  Socket: $1"          "HTTPAcceptor - accept() success.  Socket: $1" ,socket));
            ,socket);  
  
    // Create a new conection and add it to the connection list:      AutoPtr<MP_Socket> mp_socket(new MP_Socket(
           socket, _sslcontext, _sslContextObjectLock));
  
    AutoPtr<MP_Socket> mp_socket(new MP_Socket(socket, _sslcontext, _exportConnection));      mp_socket->disableBlocking();
       mp_socket->setSocketWriteTimeout(_socketWriteTimeout);
  
    Sint32 retVal;      // Perform the SSL handshake, if applicable.
  
    if (_sslcontext)      Sint32 socketAcceptStatus = mp_socket->accept();
    {  
        //  
        // For SSL connections, obtain read lock to SSLContext object before  
        // calling the accept() method of MP_Socket.  
        //  
        ReadLock rlock(*_sslContextObjectLock);  
        retVal = mp_socket->accept();  
    }  
    else  
    {  
        retVal = mp_socket->accept();  
    }  
  
    if (retVal < 0)      if (socketAcceptStatus < 0)
    {    {
        PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,          PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
                         "HTTPAcceptor: SSL_accept() failed");                         "HTTPAcceptor: SSL_accept() failed");
        mp_socket->close();        mp_socket->close();
        return;        return;
    }    }
  
       // Create a new connection and add it to the connection list:
   
    HTTPConnection* connection = new HTTPConnection(_monitor, mp_socket,    HTTPConnection* connection = new HTTPConnection(_monitor, mp_socket,
        this, static_cast<MessageQueue *>(_outputMessageQueue), _exportConnection);          ipAddress, this, static_cast<MessageQueue *>(_outputMessageQueue));
   
       if (_idleConnectionTimeoutSeconds)
       {
           connection->_idleConnectionTimeoutSeconds =
               _idleConnectionTimeoutSeconds;
           Time::gettimeofday(&connection->_idleStartTime);
       }
   
       if (socketAcceptStatus == 0)
       {
           PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL2,
               "HTTPAcceptor: SSL_accept() pending");
           connection->_acceptPending = true;
           Time::gettimeofday(&connection->_acceptPendingStartTime);
       }
  
    // Solicit events on this new connection's socket:    // Solicit events on this new connection's socket:
    int index;    int index;
Line 768 
Line 864 
    {    {
       // ATTN-DE-P2-2003100503::TODO::Need to enhance code to return       // ATTN-DE-P2-2003100503::TODO::Need to enhance code to return
       // an error message to Client application.       // an error message to Client application.
       Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2,          PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
           "HTTPAcceptor::_acceptConnection: Attempt to allocate entry in _entries table failed.");              "HTTPAcceptor::_acceptConnection: Attempt to allocate entry in "
                   "_entries table failed.");
       delete connection;       delete connection;
       Socket::close(socket);       Socket::close(socket);
       return;       return;


Legend:
Removed from v.1.67  
changed lines
  Added in v.1.93.4.4

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2