(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.81.8.12 and 1.138

version 1.81.8.12, 2006/10/18 04:24:42 version 1.138, 2015/06/10 12:36:01
Line 1 
Line 1 
 //%2006////////////////////////////////////////////////////////////////////////  //%LICENSE////////////////////////////////////////////////////////////////
 // //
 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development  // Licensed to The Open Group (TOG) under one or more contributor license
 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.  // agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;  // this work for additional information regarding copyright ownership.
 // IBM Corp.; EMC Corporation, The Open Group.  // Each contributor licenses this file to you under the OpenPegasus Open
 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;  // Source License; you may not use this file except in compliance with the
 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.  // License.
 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;  //
 // EMC Corporation; VERITAS Software Corporation; The Open Group.  // Permission is hereby granted, free of charge, to any person obtaining a
 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;  // copy of this software and associated documentation files (the "Software"),
 // EMC Corporation; Symantec Corporation; The Open Group.  // to deal in the Software without restriction, including without limitation
 //  // the rights to use, copy, modify, merge, publish, distribute, sublicense,
 // Permission is hereby granted, free of charge, to any person obtaining a copy  // and/or sell copies of the Software, and to permit persons to whom the
 // of this software and associated documentation files (the "Software"), to  // Software is furnished to do so, subject to the following conditions:
 // deal in the Software without restriction, including without limitation the  //
 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or  // The above copyright notice and this permission notice shall be included
 // sell copies of the Software, and to permit persons to whom the Software is  // in all copies or substantial portions of the Software.
 // furnished to do so, subject to the following conditions:  //
 //  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN  // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED  // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT  // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR  // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT  // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN  // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION  //
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  //////////////////////////////////////////////////////////////////////////
 //  
 //==============================================================================  
 //  
 // 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, Symantec Corp. (david_dillard@symantec.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_OS_TYPE_WINDOWS  
 # include <windows.h>  
 #else  
 # include <cctype>  
 # include <cstdlib>  
 # include <errno.h>  
 # include <fcntl.h>  
 # include <netdb.h>  
 # include <netinet/in.h>  
 # include <netinet/tcp.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_OS_PASE
 # include "OS400ConvertChar.h"  # include <as400_protos.h>
   # include <Pegasus/Common/PaseCcsid.h>
 #endif #endif
  
   
 PEGASUS_USING_STD; PEGASUS_USING_STD;
  
 PEGASUS_NAMESPACE_BEGIN PEGASUS_NAMESPACE_BEGIN
  
  
 static int MAX_CONNECTION_QUEUE_LENGTH = -1;  static int _maxConnectionQueueLength = -1;
   
   Uint32 HTTPAcceptor::_socketWriteTimeout =
       PEGASUS_DEFAULT_SOCKETWRITE_TIMEOUT_SECONDS;
   
   #ifndef PEGASUS_INTEGERS_BOUNDARY_ALIGNED
   Mutex HTTPAcceptor::_socketWriteTimeoutMutex;
   #endif
  
 //////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
 // //
Line 98 
Line 70 
 class HTTPAcceptorRep class HTTPAcceptorRep
 { {
 public: public:
     HTTPAcceptorRep(Boolean local)      HTTPAcceptorRep(Uint16 connectionType)
     {     {
         if (local)          if (connectionType == HTTPAcceptor::LOCAL_CONNECTION)
         {         {
   
 #ifndef PEGASUS_OS_TYPE_WINDOWS  
 # ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET # ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET
               address =
             address = reinterpret_cast<struct sockaddr*>(new struct sockaddr_un);                  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_UNREACHABLE(PEGASUS_ASSERT(false);)
 # endif # endif
           }
   #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 #endif
           else if (connectionType == HTTPAcceptor::IPV4_CONNECTION)
           {
               address =
                   reinterpret_cast<struct sockaddr*>(new struct sockaddr_in);
               address_size = sizeof(struct sockaddr_in);
         }         }
         else         else
         {         {
             address = reinterpret_cast<struct sockaddr*>(new struct sockaddr_in);              PEGASUS_UNREACHABLE(PEGASUS_ASSERT(false);)
             address_size = sizeof(struct sockaddr_in);  
         }         }
     }     }
   
     ~HTTPAcceptorRep()     ~HTTPAcceptorRep()
     {     {
           closeSocket();
         delete address;         delete address;
     }     }
   
       void closeSocket()
       {
           Socket::close(socket);
       }
   
     struct sockaddr* address;     struct sockaddr* address;
  
     PEGASUS_SOCKLEN_T address_size;      SocketLength address_size;
     Mutex _connection_mut;     Mutex _connection_mut;
  
     PEGASUS_SOCKET socket;      SocketHandle socket;
   
 // Added for NamedPipe implementation for windows  
 #if defined PEGASUS_OS_TYPE_WINDOWS && !defined(PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET)  
     NamedPipeServer* namedPipeServer;  
 #endif  
     Array<HTTPConnection*> connections;     Array<HTTPConnection*> connections;
 }; };
  
 //------------------------------------------------------------------------------  
 //  
 // _setTCPNoDelay()  
 //  
 //------------------------------------------------------------------------------  
   
 inline void _setTCPNoDelay(PEGASUS_SOCKET socket)  
 {  
     // This function disables "Nagle's Algorithm" also known as "the TCP delay  
     // algorithm", which causes read operations to obtain whatever data is  
     // already in the input queue and then wait a little longer to see if  
     // more data arrives. This algorithm optimizes the case in which data is  
     // sent in only one direction but severely impairs performance of round  
     // trip servers. Disabling TCP delay is a standard technique for round  
     // trip servers.  
   
    int opt = 1;  
    setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (char*)&opt, sizeof(opt));  
 }  
  
 //////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
 // //
Line 166 
Line 131 
  
 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)                             HostAddress *listenOn)
    : 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)      _listenAddress(listenOn)
 { {
      PEGASUS_ASSERT(!_sslcontext == !_sslContextObjectLock);
    Socket::initializeInterface();    Socket::initializeInterface();
  
    /*    /*
         Platforms interpret the value of MAX_CONNECTION_QUEUE_LENGTH differently.  Some platforms interpret          Platforms interpret the value of _maxConnectionQueueLength
         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
           _maxConnectionQueueLength = 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 _maxConnectionQueueLength = 15
  
 /* /*
    if(MAX_CONNECTION_QUEUE_LENGTH == -1){      if (_maxConnectionQueueLength == -1)
 #ifdef PEGASUS_PLATFORM_OS400_ISERIES_IBM      {
 #pragma convert(37)  
     const char* env = getenv("PEGASUS_MAX_BACKLOG_CONNECTION_QUEUE");  
     EtoA(env);  
 #pragma convert(0)  
 #else  
     const char* env = getenv("PEGASUS_MAX_BACKLOG_CONNECTION_QUEUE");     const char* env = getenv("PEGASUS_MAX_BACKLOG_CONNECTION_QUEUE");
 #endif          if (!env)
     if(!env){          {
         MAX_CONNECTION_QUEUE_LENGTH = 15;              _maxConnectionQueueLength = 15;
     }else{          }
           else
           {
         char *end = NULL;         char *end = NULL;
         MAX_CONNECTION_QUEUE_LENGTH = strtol(env, &end, 10);              _maxConnectionQueueLength = strtol(env, &end, 10);
         if(*end)         if(*end)
             MAX_CONNECTION_QUEUE_LENGTH = 15;                  _maxConnectionQueueLength = 15;
         cout << " MAX_CONNECTION_QUEUE_LENGTH = " << MAX_CONNECTION_QUEUE_LENGTH << endl;              cout << " _maxConnectionQueueLength = " <<
                   _maxConnectionQueueLength << endl;
     }     }
    }    }
 */ */
    MAX_CONNECTION_QUEUE_LENGTH = 15;  #ifdef PEGASUS_WMIMAPPER
       //The WMI Mapper can be used as a proxy to multiple WMI Servers.
       //If a client application simultaneously initiates connections
       //to many Windows systems, many of these connections may be routed
       //to a single WMI Mapper. A larger _maxConnectionQueueLength
       //value is required to allow these connections to be initiated
       //successfully.
       _maxConnectionQueueLength = 40;
   #else
       _maxConnectionQueueLength = 15;
   #endif
 } }
  
 HTTPAcceptor::~HTTPAcceptor() HTTPAcceptor::~HTTPAcceptor()
Line 238 
Line 215 
    {    {
       case SOCKET_MESSAGE:       case SOCKET_MESSAGE:
       {       {
           SocketMessage* socketMessage = (SocketMessage*)message;  
   
          // If this is a connection request:          // If this is a connection request:
               PEGASUS_ASSERT(((SocketMessage*)message)->socket == _rep->socket);
   
               PEGASUS_ASSERT(
                   ((SocketMessage*)message)->events & SocketMessage::READ);
  
          if (socketMessage->socket == _rep->socket &&  
              socketMessage->events & SocketMessage::READ)  
          {  
              _acceptConnection();              _acceptConnection();
          }  
          else  
          {  
             // ATTN! this can't happen!  
             Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2,  
               "HTTPAcceptor::handleEnqueue: Invalid SOCKET_MESSAGE received.");  
          }  
  
          break;          break;
       }       }
  
 // Added for NamedPipe implementation for windows  
 #if defined PEGASUS_OS_TYPE_WINDOWS && !defined(PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET)  
       case NAMEDPIPE_MESSAGE:  
       {  
          NamedPipeMessage* namedPipeMessage = (NamedPipeMessage*)message;  
   
          if (((namedPipeMessage->namedPipe.getPipe()) == ( _rep->namedPipeServer->getPipe())) &&  
              (namedPipeMessage->events & NamedPipeMessage::READ))  
          {  
              _acceptNamedPipeConnection();  
          }  
          else  
          {  
             // ATTN! this can't happen!  
             Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2,  
               "HTTPAcceptor::handleEnqueue: Invalid NAMEDPIPE_MESSAGE received.");  
          }  
          break;  
       }  
 #endif  
      // may Need to close connection for Named Pipe too.....??  
      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];
 // Added for NamedPipe implementation for windows                 SocketHandle socket = connection->getSocket();
 #if defined PEGASUS_OS_TYPE_WINDOWS && !defined(PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET)  
             if(!connection->isNamedPipeConnection())  
             {  
 #endif  
                 PEGASUS_SOCKET socket = connection->getSocket();  
  
                 if (socket == closeConnectionMessage->socket)                 if (socket == closeConnectionMessage->socket)
                 {                 {
Line 302 
Line 245 
                     delete connection;                     delete connection;
                     break;                     break;
                 }                 }
 // Added for NamedPipe implementation for windows  
 #if defined PEGASUS_OS_TYPE_WINDOWS && !defined(PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET)  
             }  
             else  
             {  
                 NamedPipe namedPipe = connection->getNamedPipe();  
                 //NamedPipeMessage* namedPipeMessage = (NamedPipeMessage*)message;  
   
                 if (namedPipe.getPipe() == closeConnectionMessage->namedPipe.getPipe())  
                 {  
                     _monitor->unsolicitPipeMessages(namedPipe);  
                     _rep->connections.remove(i);  
                     delete connection;  
                     break;  
                 }  
             }  
 #endif  
         }         }
  
         break;         break;
      }      }
  
       default:       default:
       // ATTN: need unexpected message error!             PEGASUS_UNREACHABLE(PEGASUS_ASSERT(false);)
       Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2,  
            "HTTPAcceptor::handleEnqueue: Invalid MESSAGE received.");  
       break;       break;
    };      }
  
    delete message;    delete message;
 } }
Line 338 
Line 262 
 void HTTPAcceptor::handleEnqueue() void HTTPAcceptor::handleEnqueue()
 { {
    Message* message = dequeue();    Message* message = dequeue();
   
    if (!message)  
    {  
       Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2,  
            "HTTPAcceptor::handleEnqueue(): No message on queue.");  
       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,  
            "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()
 { {
 #ifdef PEGASUS_LOCALDOMAINSOCKET_DEBUG  #ifdef PEGASUS_OS_PASE
     {      AutoPtr<PaseCcsid> ccsid;
         AutoMutex automut(Monitor::_cout_mut);  
         PEGASUS_STD(cout) << "in HTTPAcceptor::_bind at the begining" << PEGASUS_STD(endl);  
         PEGASUS_STD(cout) << "in HTTPAcceptor::_bind before ASSERT" << PEGASUS_STD(endl);  
     }  
 #endif #endif
   
    PEGASUS_ASSERT(_rep != 0);    PEGASUS_ASSERT(_rep != 0);
    // Create address:    // Create address:
 #ifdef PEGASUS_LOCALDOMAINSOCKET_DEBUG      memset(_rep->address, 0, _rep->address_size);
    {  
        AutoMutex automut(Monitor::_cout_mut);  
        PEGASUS_STD(cout) << "in HTTPAcceptor::_bind before memset" << PEGASUS_STD(endl);  
    }  
 #endif  
   
  
 #if defined PEGASUS_OS_TYPE_WINDOWS      if (_connectionType == LOCAL_CONNECTION)
    if (!_localConnection)  
    {    {
 #endif  #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET
        memset(_rep->address, 0, sizeof(*_rep->address));          //
 #if defined PEGASUS_OS_TYPE_WINDOWS          // Make sure the local domain socket can be owned by the cimserver
    }          // user.  Otherwise, the bind may fail with a vague "bind failed"
 #endif          // error.
           //
 #ifdef PEGASUS_LOCALDOMAINSOCKET_DEBUG  #ifdef PEGASUS_OS_PASE
           // PASE domain socket needs ccsid 819
           int orig_ccsid;
           orig_ccsid = _SETCCSID(-1);
           if (orig_ccsid == -1)
    {    {
        AutoMutex automut(Monitor::_cout_mut);              PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1,
        PEGASUS_STD(cout) << "in HTTPAcceptor::_bind After memset" << PEGASUS_STD(endl);                      "HTTPAcceptor::_bind: Can not get current PASE CCSID.");
               orig_ccsid = 1208;
    }    }
           ccsid.reset(new PaseCcsid(819, orig_ccsid));
 #endif #endif
           if (System::exists(PEGASUS_LOCAL_DOMAIN_SOCKET_PATH))
    if (_localConnection)  
    {    {
 // Added for NamedPipe implementation for windows              if (!System::removeFile(PEGASUS_LOCAL_DOMAIN_SOCKET_PATH))
 #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET  
   
 # ifdef PEGASUS_OS_TYPE_WINDOWS  
 #  ifdef PEGASUS_LOCALDOMAINSOCKET_DEBUG  
        {        {
            AutoMutex automut(Monitor::_cout_mut);                  throw CannotRemoveFile(PEGASUS_LOCAL_DOMAIN_SOCKET_PATH);
            PEGASUS_STD(cout) << "in HTTPAcceptor::_bind before calling _createNamedPipe() "  
                              << PEGASUS_STD(endl);  
        }        }
 #  endif  
        _createNamedPipe();  
 # ifdef PEGASUS_LOCALDOMAINSOCKET_DEBUG  
        {  
            AutoMutex automut(Monitor::_cout_mut);  
            PEGASUS_STD(cout) << "in HTTPAcceptor::_bind after calling _createNamedPipe() " << PEGASUS_STD(endl);  
        }        }
 # endif  
        return;  
 # else // Other than Windows platform  
        reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_family =        reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_family =
            AF_UNIX;            AF_UNIX;
        strcpy(          strcpy(reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path,
            reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path,  
            PEGASUS_LOCAL_DOMAIN_SOCKET_PATH);            PEGASUS_LOCAL_DOMAIN_SOCKET_PATH);
   #else
 #ifdef PEGASUS_PLATFORM_OS400_ISERIES_IBM          PEGASUS_UNREACHABLE(PEGASUS_ASSERT(false);)
        AtoE(reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path);  
 #endif  
        ::unlink(reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path);  
 # endif # endif
       }
   #ifdef PEGASUS_ENABLE_IPV6
       else if (_connectionType == IPV6_CONNECTION)
       {
           if(_listenAddress)
           {
               String hostAdd = _listenAddress->getHost();
               CString ip = hostAdd.getCString();
  
 #else              struct sockaddr_in6 in6addr;
        PEGASUS_ASSERT(false);              memset(&in6addr, 0, sizeof(sockaddr_in6));
               if(_listenAddress ->isHostAddLinkLocal())
               {
                   HostAddress::convertTextToBinary(AF_INET6,
                   (const char*)ip,
                   &in6addr.sin6_addr);
                   reinterpret_cast<struct sockaddr_in6*>(
                       _rep->address)->sin6_addr = in6addr.sin6_addr;
                   reinterpret_cast<struct sockaddr_in6*>(
                       _rep->address)->sin6_scope_id =
                           _listenAddress->getScopeID();
               }
               else
               {
                   HostAddress::convertTextToBinary(AF_INET6,
                   (const char*)ip,
                   &in6addr.sin6_addr);
                   reinterpret_cast<struct sockaddr_in6*>(
                       _rep->address)->sin6_addr = in6addr.sin6_addr;
               }
           }
           else
           {
           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 #endif
       else if(_connectionType == IPV4_CONNECTION)
       {
           if(_listenAddress)
           {
               String hostAdd = _listenAddress->getHost();
               CString ip = hostAdd.getCString();
               struct sockaddr_in addrs;
               HostAddress::convertTextToBinary(
                   AF_INET,
                   (const char*)ip,
                   &addrs.sin_addr);
               reinterpret_cast<struct sockaddr_in*>(
                   _rep->address)->sin_addr.s_addr = addrs.sin_addr.s_addr;
    }    }
    else    else
    {    {
        reinterpret_cast<struct sockaddr_in*>(_rep->address)->sin_addr.s_addr =              reinterpret_cast<struct sockaddr_in*>(
            INADDR_ANY;              _rep->address)->sin_addr.s_addr = INADDR_ANY;
           }
        reinterpret_cast<struct sockaddr_in*>(_rep->address)->sin_family =        reinterpret_cast<struct sockaddr_in*>(_rep->address)->sin_family =
            AF_INET;            AF_INET;
        reinterpret_cast<struct sockaddr_in*>(_rep->address)->sin_port =        reinterpret_cast<struct sockaddr_in*>(_rep->address)->sin_port =
            htons(_portNumber);            htons(_portNumber);
    }    }
       else
       {
           PEGASUS_UNREACHABLE(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::createSocket(PF_INET6, SOCK_STREAM, IPPROTO_TCP);
       }
   #endif
       else if (_connectionType == IPV4_CONNECTION)
    {    {
        _rep->socket = socket(AF_UNIX, SOCK_STREAM, 0);          _rep->socket = Socket::createSocket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    }    }
    else    else
    {    {
        _rep->socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);          PEGASUS_UNREACHABLE(PEGASUS_ASSERT(false);)
   
        _setTCPNoDelay(_rep->socket);  
    }    }
  
    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,  
            "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.
Line 492 
Line 440 
    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::LEVEL1,
                   "HTTPAcceptor::_bind: fcntl(F_GETFD) failed");                   "HTTPAcceptor::_bind: fcntl(F_GETFD) failed");
    }    }
    else    else
Line 500 
Line 448 
       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::LEVEL1,
                   "HTTPAcceptor::_bind: fcntl(F_SETFD) failed");                   "HTTPAcceptor::_bind: fcntl(F_SETFD) failed");
       }       }
    }    }
 #endif #endif
  
   
    //    //
    // Set the socket option SO_REUSEADDR to reuse the socket address so    // Set the socket option SO_REUSEADDR to reuse the socket address so
    // that we can rebind to a new socket using the same address when we    // that we can rebind to a new socket using the same address when we
Line 516 
Line 465 
    if (setsockopt(_rep->socket, SOL_SOCKET, SO_REUSEADDR,    if (setsockopt(_rep->socket, SOL_SOCKET, SO_REUSEADDR,
           (char *)&opt, sizeof(opt)) < 0)           (char *)&opt, sizeof(opt)) < 0)
    {    {
       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,  
                    "HTTPAcceptor::_bind: Failed to set socket option.");  
       throw BindFailedException(parms);       throw BindFailedException(parms);
    }    }
  
   
    //    //
    // Bind socket to port:    // Bind socket to port:
    //    //
    if (::bind(_rep->socket, _rep->address, _rep->address_size) < 0)    if (::bind(_rep->socket, _rep->address, _rep->address_size) < 0)
    {    {
       Socket::close(_rep->socket);          MessageLoaderParms parms(
               "Common.HTTPAcceptor.FAILED_BIND_SOCKET_DETAIL",
               "Failed to bind socket on port $0: $1.",
               _portNumber, PEGASUS_SYSTEM_NETWORK_ERRORMSG_NLS);
   
       delete _rep;       delete _rep;
       _rep = 0;       _rep = 0;
       //l10n  
       //throw BindFailedException("Failed to bind socket");  
       MessageLoaderParms parms("Common.HTTPAcceptor.FAILED_BIND_SOCKET",  
                    "Failed to bind socket");  
       PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,  
                         "HTTPAcceptor::_bind: Failed to bind socket.");  
       throw BindFailedException(parms);       throw BindFailedException(parms);
    }    }
  
   
    //    //
    // Get the actual port value used if the caller specified a port value of 0.    // Get the actual port value used if the caller specified a port value of 0.
    //    //
    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);
       }       }
    }    }
  
   
    //    //
    //  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_OS_ZOS) || \
         defined(PEGASUS_OS_PASE))
       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 |
                   S_IRGRP | S_IWGRP | S_IXGRP |                   S_IRGRP | S_IWGRP | S_IXGRP |
                   S_IROTH | S_IWOTH | S_IXOTH ) < 0 )                   S_IROTH | S_IWOTH | S_IXOTH ) < 0 )
      {      {
        Socket::close(_rep->socket);              MessageLoaderParms parms(
                   "Common.HTTPAcceptor.FAILED_SET_LDS_FILE_OPTION",
                   "Failed to set permission on local domain socket $0: $1.",
                   PEGASUS_LOCAL_DOMAIN_SOCKET_PATH,
                   PEGASUS_SYSTEM_ERRORMSG_NLS );
   
        delete _rep;        delete _rep;
        _rep = 0;        _rep = 0;
        //l10n  
        //throw BindFailedException("Failed to bind socket");  
        MessageLoaderParms parms("Common.HTTPAcceptor.FAILED_BIND_SOCKET",  
                    "Failed to bind socket");  
        PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,  
               "HTTPAcceptor::_bind: Failed to set domain socket permissions.");  
        throw BindFailedException(parms);        throw BindFailedException(parms);
      }      }
    }    }
 #endif #endif
  
    // Set up listening on the given socket:    // Set up listening on the given socket:
    //int const MAX_CONNECTION_QUEUE_LENGTH = 15;  
  
    if (listen(_rep->socket, MAX_CONNECTION_QUEUE_LENGTH) < 0)      //int const _maxConnectionQueueLength = 15;
   
       if (::listen(_rep->socket, _maxConnectionQueueLength) < 0)
    {    {
       Socket::close(_rep->socket);          MessageLoaderParms parms(
               "Common.HTTPAcceptor.FAILED_LISTEN_SOCKET",
               "Failed to listen on socket $0: $1.",
               (int)_rep->socket,PEGASUS_SYSTEM_NETWORK_ERRORMSG_NLS );
   
       delete _rep;       delete _rep;
       _rep = 0;       _rep = 0;
       //l10n  
       //throw BindFailedException("Failed to bind socket");  
       MessageLoaderParms parms("Common.HTTPAcceptor.FAILED_BIND_SOCKET",  
                    "Failed to bind socket");  
       PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,  
                   "HTTPAcceptor::_bind: Failed to bind socket(1).");  
       throw BindFailedException(parms);       throw BindFailedException(parms);
    }    }
  
Line 604 
Line 552 
  
    if ( -1 == ( _entry_index = _monitor->solicitSocketMessages(    if ( -1 == ( _entry_index = _monitor->solicitSocketMessages(
       _rep->socket,       _rep->socket,
       SocketMessage::READ | SocketMessage::EXCEPTION,  
       getQueueId(),       getQueueId(),
       Monitor::ACCEPTOR)))              MonitorEntry::TYPE_ACCEPTOR)))
    {    {
       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,  
                   "HTTPAcceptor::_bind: Failed to solicit socket messages(2).");  
       throw BindFailedException(parms);       throw BindFailedException(parms);
    }    }
 #ifdef PEGASUS_LOCALDOMAINSOCKET_DEBUG  
    {  
        AutoMutex automut(Monitor::_cout_mut);  
        PEGASUS_STD(cout) << "in HTTPAcceptor::_bind at the End" << PEGASUS_STD(endl);  
    }  
 #endif  
   
 } }
  
 /** /**
Line 642 
Line 578 
       //_monitor->unsolicitSocketMessages(_rep->socket);       //_monitor->unsolicitSocketMessages(_rep->socket);
  
       // close the socket       // close the socket
       Socket::close(_rep->socket);          _rep->closeSocket();
       // Unlink Local Domain Socket Bug# 3312       // Unlink Local Domain Socket Bug# 3312
       if (_localConnection)          if (_connectionType == LOCAL_CONNECTION)
       {       {
 #ifndef PEGASUS_OS_TYPE_WINDOWS  
 # ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET # ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET
           PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL2,              PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL3,
                         "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_UNREACHABLE(PEGASUS_ASSERT(false);)
 # endif  
 #endif #endif
       }       }
   
    }    }
    else    else
    {    {
       PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,          PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL2,
                         "HTTPAcceptor::closeConnectionSocket failure _rep is null." );                         "HTTPAcceptor::closeConnectionSocket failure _rep is null." );
    }    }
 } }
Line 677 
Line 612 
    }    }
    else    else
    {    {
       PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,          PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1,
                         "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
           _rep->closeSocket();
           // Unlink Local Domain Socket
           if (_connectionType == LOCAL_CONNECTION)
           {
   #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET
               PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL3,
                   "HTTPAcceptor::reconnectConnectionSocket Unlinking local "
                       "connection." );
               ::unlink(
                       reinterpret_cast<struct sockaddr_un*>(
                           _rep->address)->sun_path);
   #else
               PEGASUS_UNREACHABLE(PEGASUS_ASSERT(false);)
   #endif
           }
           // open the socket
           _bind();
       }
       else
       {
           PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1,
               "HTTPAcceptor::reconnectConnectionSocket failure _rep is null.");
       }
   }
   
 /** /**
    getOutstandingRequestCount - returns the number of outstanding requests.    getOutstandingRequestCount - returns the number of outstanding requests.
 */ */
Line 691 
Line 662 
    if (_rep)    if (_rep)
    {    {
       AutoMutex autoMut(_rep->_connection_mut);       AutoMutex autoMut(_rep->_connection_mut);
       if (_rep->connections.size() > 0)          for (Uint32 i = 0, n = _rep->connections.size(); i < n; i++)
       {       {
          HTTPConnection* connection = _rep->connections[0];              HTTPConnection* connection = _rep->connections[i];
          count = connection->getRequestCount();              if (connection->isResponsePending())
               {
                   count++;
               }
       }       }
    }    }
    return count;    return count;
 } }
  
   /**
       getListenAddress - Returns bind address
   */
   String HTTPAcceptor::getListenAddress() const
   {
       return _listenAddress ? _listenAddress->getHost() : String();
   }
  
 /** /**
     getPortNumber - returns the port number used for the connection     getPortNumber - returns the port number used for the connection
Line 709 
Line 690 
     return _portNumber;     return _portNumber;
 } }
  
   void HTTPAcceptor::setSocketWriteTimeout(Uint32 socketWriteTimeout)
   {
   #ifndef PEGASUS_INTEGERS_BOUNDARY_ALIGNED
       AutoMutex lock(_socketWriteTimeoutMutex);
   #endif
       _socketWriteTimeout = socketWriteTimeout;
   }
   
 void HTTPAcceptor::unbind() void HTTPAcceptor::unbind()
 { {
    if (_rep)    if (_rep)
    {    {
       _portNumber = 0;       _portNumber = 0;
       Socket::close(_rep->socket);          _rep->closeSocket();
  
       if (_localConnection)          if (_connectionType == LOCAL_CONNECTION)
       {       {
 #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET
 # ifndef PEGASUS_OS_TYPE_WINDOWS  
   
          ::unlink(          ::unlink(
              reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path);                      reinterpret_cast<struct sockaddr_un*>
 # endif                      (_rep->address)->sun_path);
 #else #else
          PEGASUS_ASSERT(false);              PEGASUS_UNREACHABLE(PEGASUS_ASSERT(false);)
 #endif #endif
       }       }
  
Line 734 
Line 721 
    }    }
    else    else
    {    {
       PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,          PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL1,
               "HTTPAcceptor::unbind failure _rep is null." );               "HTTPAcceptor::unbind failure _rep is null." );
    }    }
 } }
Line 749 
Line 736 
      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];
 // Added for NamedPipe implementation for windows              SocketHandle socket = connection->getSocket();
 #if defined PEGASUS_OS_TYPE_WINDOWS && !defined(PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET)  
         if(!connection->isNamedPipeConnection())  
         {  
 #endif  
             PEGASUS_SOCKET socket = connection->getSocket();  
  
            // Unsolicit SocketMessages:            // Unsolicit SocketMessages:
  
            _monitor->unsolicitSocketMessages(socket);            _monitor->unsolicitSocketMessages(socket);
  
 // Added for NamedPipe implementation for windows  
 // Destroy the connection (causing it to close): // Destroy the connection (causing it to close):
 #if defined PEGASUS_OS_TYPE_WINDOWS && !defined(PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET)  
         }  
         else  
         {  
             NamedPipe namedPipe = connection->getNamedPipe();  
             _monitor->unsolicitPipeMessages(namedPipe);  
         }  
 #endif  
         while (connection->refcount.get()) { }         while (connection->refcount.get()) { }
         delete connection;         delete connection;
      }      }
Line 784 
Line 758 
  
    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;
    PEGASUS_SOCKLEN_T address_size;      SocketLength address_size;
  
    if (_localConnection)      if (_connectionType == LOCAL_CONNECTION)
    {    {
 #ifndef PEGASUS_OS_TYPE_WINDOWS  
 # 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_UNREACHABLE(PEGASUS_ASSERT(false);)
 # endif  
 #endif #endif
    }    }
    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
    }    }
  
    PEGASUS_SOCKET 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::LEVEL1,
                   "Socket has an IO error. TCP/IP down. Try to reconnect.");
   
               reconnectConnectionSocket();
   
               return;
           }
           PEG_TRACE((
               TRC_DISCARDED_DATA,
               Tracer::LEVEL1,
               "HTTPAcceptor: accept() failed.  errno: %u",
               errno));
           return;
       }
   
       // Use an AutoPtr to ensure the socket handle is closed on exception
       AutoPtr<SocketHandle, CloseSocketHandle> socketPtr(&socket);
   
   #ifndef PEGASUS_OS_TYPE_WINDOWS
       // 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;
   
           PEG_TRACE(
               (TRC_DISCARDED_DATA,
                Tracer::LEVEL1,
                "HTTPAcceptor out of available sockets."
                    "accept() returned too large socket number %u."
                    "Closing connection to the new client.",
                socket));
   
           return;
       }
   #endif
  
        Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,      String ipAddress;
            "HTTPAcceptor - accept() failure.  errno: $0"  
            ,errno);  
  
        PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,      if (_connectionType == LOCAL_CONNECTION)
                         "HTTPAcceptor: accept() failed");      {
           ipAddress = "localhost";
       }
       else
       {
   #ifdef PEGASUS_ENABLE_IPV6
           char ipBuffer[PEGASUS_INET6_ADDRSTR_LEN];
           if (System::getNameInfo(accept_address,
                   address_size,
                   ipBuffer,
                   PEGASUS_INET6_ADDRSTR_LEN,
                   0,
                   0,
                   NI_NUMERICHOST))
           {
               delete accept_address;
       return;       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_OS_TYPE_WINDOWS) && !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::LEVEL1,
                         "HTTPAcceptor: fcntl(F_GETFD) failed");                         "HTTPAcceptor: fcntl(F_GETFD) failed");
    }    }
    else    else
Line 837 
Line 893 
       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::LEVEL1,
                         "HTTPAcceptor: fcntl(F_SETFD) failed");                         "HTTPAcceptor: fcntl(F_SETFD) failed");
       }       }
    }    }
 #endif #endif
  
  
    PEG_LOGGER_TRACE((Logger::STANDARD_LOG, System::CIMSERVER, 0,      PEG_TRACE((
        "HTTPAcceptor - accept() success.  Socket: $1" ,socket));          TRC_HTTP,
           Tracer::LEVEL3,
           "HTTPAcceptor - accept() success.  Socket: %u",
           socket));
   
       SharedPtr<MP_Socket> mp_socket(new MP_Socket(
           socket, _sslcontext, _sslContextObjectLock, ipAddress));
       // mp_socket now has responsibility for closing the socket handle
       socketPtr.release();
   
       mp_socket->disableBlocking();
  
    AutoPtr<MP_Socket> mp_socket(new MP_Socket(      {
        socket, _sslcontext, _sslContextObjectLock, _exportConnection));  #ifndef PEGASUS_INTEGERS_BOUNDARY_ALIGNED
           AutoMutex lock(_socketWriteTimeoutMutex);
   #endif
           mp_socket->setSocketWriteTimeout(_socketWriteTimeout);
       }
  
    // Perform the SSL handshake, if applicable.  Make the socket non-blocking      // Perform the SSL handshake, if applicable.
    // 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)
    {    {
        PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,          PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1,
                         "HTTPAcceptor: SSL_accept() failed");                         "HTTPAcceptor: SSL_accept() failed");
        mp_socket->close();  
        return;        return;
    }    }
  
    // Create a new connection and add it to the connection list:    // Create a new connection and add it to the connection list:
  
    HTTPConnection* connection = new HTTPConnection(_monitor, mp_socket,      AutoPtr<HTTPConnection> connection(new HTTPConnection(
        this, static_cast<MessageQueue *>(_outputMessageQueue), _exportConnection);          _monitor,
           mp_socket,
           ipAddress,
           this,
           _outputMessageQueue));
   
       if (HTTPConnection::getIdleConnectionTimeout())
       {
           Time::gettimeofday(&connection->_idleStartTime);
       }
  
    if (socketAcceptStatus == 0)    if (socketAcceptStatus == 0)
    {    {
        PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL2,          PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL1,
            "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:
Line 883 
Line 958 
  
    if (-1 ==  (index = _monitor->solicitSocketMessages(    if (-1 ==  (index = _monitor->solicitSocketMessages(
       connection->getSocket(),       connection->getSocket(),
       SocketMessage::READ | SocketMessage::EXCEPTION,              connection->getQueueId(), MonitorEntry::TYPE_CONNECTION)) )
       connection->getQueueId(), Monitor::CONNECTION)) )  
    {    {
       // ATTN-DE-P2-2003100503::TODO::Need to enhance code to return          PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1,
       // an error message to Client application.              "HTTPAcceptor::_acceptConnection: Attempt to allocate entry in "
       Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2,                  "_entries table failed.");
           "HTTPAcceptor::_acceptConnection: Attempt to allocate entry in _entries table failed.");  
       delete connection;  
       Socket::close(socket);  
       return;       return;
    }    }
  
    // Save the socket for cleanup later:  
    connection->_entry_index = index;    connection->_entry_index = index;
    AutoMutex autoMut(_rep->_connection_mut);    AutoMutex autoMut(_rep->_connection_mut);
    _rep->connections.append(connection);      _rep->connections.append(connection.get());
 }      connection.release();
   
 // Added for NamedPipe implementation for windows  
 #if defined PEGASUS_OS_TYPE_WINDOWS && !defined(PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET)  
 void HTTPAcceptor::_createNamedPipe()  
 {  
 #ifdef PEGASUS_LOCALDOMAINSOCKET_DEBUG  
     {  
         AutoMutex automut(Monitor::_cout_mut);  
         PEGASUS_STD(cout) << "Entering  HTTPAcceptor::_createNamedPipe()." << PEGASUS_STD(endl);  
     }     }
 #endif  
     _rep->namedPipeServer = new NamedPipeServer(PEGASUS_NAMEDPIPE_PATH);  
 #ifdef PEGASUS_LOCALDOMAINSOCKET_DEBUG  
     {  
         AutoMutex automut(Monitor::_cout_mut);  
         PEGASUS_STD(cout) << "in HTTPAcceptor::_createNamedPipe() after calling the pipe server constructor" << PEGASUS_STD(endl);  
     }  
   
     {  
         AutoMutex automut(Monitor::_cout_mut);  
         cout << "Named pipe...in _createNamedPipe..." << _rep->namedPipeServer->getPipe() << endl;  
     }  
 #endif  
     // Register to receive Messages on Connection pipe:  
   
    if ( -1 == ( _entry_index = _monitor->solicitPipeMessages(  
       *_rep->namedPipeServer,  
       NamedPipeMessage::READ | NamedPipeMessage::EXCEPTION,  
       getQueueId(),  
       Monitor::ACCEPTOR)))  
    {  
        ::CloseHandle(_rep->namedPipeServer->getPipe());  
        delete _rep;  
        _rep = 0;  
        //l10n  
        MessageLoaderParms parms("Common.HTTPAcceptor.FAILED_SOLICIT_SOCKET_MESSAGES",  
                     "Failed to solicit socket messaeges");  
        PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,  
                    "HTTPAcceptor::_bind: Failed to solicit pipe messages(2).");  
        throw BindFailedException(parms);  
 #ifdef PEGASUS_LOCALDOMAINSOCKET_DEBUG  
        {  
            AutoMutex automut(Monitor::_cout_mut); //added  
            PEGASUS_STD(cout) << "in HTTPAcceptor::_createNamedPipe() _monitor->solicitSocketMessages failed"  
                              << PEGASUS_STD(endl);  
        }  
 #endif  
    }  
 #ifdef PEGASUS_LOCALDOMAINSOCKET_DEBUG  
    {  
        AutoMutex automut(Monitor::_cout_mut);  
        PEGASUS_STD(cout) << "Leaving  HTTPAcceptor::_createNamedPipe()." << PEGASUS_STD(endl);  
    }  
 #endif  
    return;  
 }  
   
 void HTTPAcceptor::_acceptNamedPipeConnection()  
 {  
     PEGASUS_ASSERT(_rep != 0);  
   
     if (!_rep)  
        return;  
 #ifdef PEGASUS_LOCALDOMAINSOCKET_DEBUG  
     {  
         AutoMutex automut(Monitor::_cout_mut);  
         cout <<"In HTTPAcceptor::_acceptNamedPipeConnection " << endl;  
     }  
 #endif  
   
   
     NamedPipeServerEndPiont nPSEndPoint = _rep->namedPipeServer->accept();  
     // Register to receive Messages on Connection pipe:  
 #ifdef PEGASUS_LOCALDOMAINSOCKET_DEBUG  
     {  
         AutoMutex automut(Monitor::_cout_mut);  
         cout << " In _acceptNamedPipeConnection -- after calling namedPipeServer->accept()" << endl;  
     }  
 #endif  
     HTTPConnection* connection = new HTTPConnection(_monitor, nPSEndPoint,  
         this, static_cast<MessageQueue *>(_outputMessageQueue), _exportConnection);  
   
     // Solicit events on this new connection's socket:  
     int index;  
 #ifdef PEGASUS_LOCALDOMAINSOCKET_DEBUG  
     {  
         AutoMutex automut(Monitor::_cout_mut);  
         cout << endl << connection->getNamedPipe().getName() << " has a this as a QueueID " <<  
          connection->getQueueId() << endl;  
     }  
 #endif  
     if (-1 ==  (index = _monitor->solicitPipeMessages(  
        connection->getNamedPipe(),  
        NamedPipeMessage::READ | NamedPipeMessage::EXCEPTION,  
        connection->getQueueId(), Monitor::ACCEPTOR)) )  
     {  
        // ATTN-DE-P2-2003100503::TODO::Need to enhance code to return  
        // an error message to Client application.  
        Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2,  
            "HTTPAcceptor::_acceptPipeConnection: Attempt to allocate entry in _entries table failed.");  
        delete connection;  
        return;  
     }  
   
     // Save the socket for cleanup later:  
     connection->_entry_index = index;  
     AutoMutex autoMut(_rep->_connection_mut);  
     _rep->connections.append(connection);  
 #ifdef PEGASUS_LOCALDOMAINSOCKET_DEBUG  
   {  
       AutoMutex automut(Monitor::_cout_mut);  
       PEGASUS_STD(cout)  
        << "in HTTPAcceptor::_acceptNamedPipeConnection() at the end" << PEGASUS_STD(endl);  
   }  
 #endif  
 }  
 #endif  
  
 PEGASUS_NAMESPACE_END PEGASUS_NAMESPACE_END


Legend:
Removed from v.1.81.8.12  
changed lines
  Added in v.1.138

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2