version 1.88.6.1, 2006/11/03 05:04:20
|
version 1.105.2.1, 2008/09/25 18:26:38
|
|
|
#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 "EBCDIC_OS400.h" |
# include <as400_protos.h> |
|
# include <Pegasus/Common/PaseCcsid.h> |
#endif | #endif |
| |
|
#if defined(PEGASUS_OS_VXWORKS) |
|
# define HTTP_ACCEPTOR_MAX_CONNECTIONS 2 |
|
#else |
|
//# define HTTP_ACCEPTOR_MAX_CONNECTIONS Uint32(0xFFFFFFFF) |
|
# define HTTP_ACCEPTOR_MAX_CONNECTIONS 2 |
|
#endif |
| |
PEGASUS_USING_STD; | PEGASUS_USING_STD; |
| |
PEGASUS_NAMESPACE_BEGIN | PEGASUS_NAMESPACE_BEGIN |
| |
| |
static int MAX_CONNECTION_QUEUE_LENGTH = -1; |
static int _maxConnectionQueueLength = -1; |
| |
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// |
// | // |
|
|
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 = 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 |
|
} |
|
#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_ASSERT(false); |
address_size = sizeof(struct sockaddr_in); |
|
} | } |
} | } |
|
|
~HTTPAcceptorRep() | ~HTTPAcceptorRep() |
{ | { |
delete address; | delete address; |
|
|
Mutex _connection_mut; | Mutex _connection_mut; |
| |
SocketHandle 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; |
}; | }; |
| |
|
|
| |
HTTPAcceptor::HTTPAcceptor(Monitor* monitor, | HTTPAcceptor::HTTPAcceptor(Monitor* monitor, |
MessageQueue* outputMessageQueue, | MessageQueue* outputMessageQueue, |
Boolean localConnection, |
Uint16 connectionType, |
Uint32 portNumber, | Uint32 portNumber, |
SSLContext * sslcontext, | SSLContext * sslcontext, |
ReadWriteSem* sslContextObjectLock) | ReadWriteSem* sslContextObjectLock) |
|
|
_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), |
_sslContextObjectLock(sslContextObjectLock) | _sslContextObjectLock(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() |
|
|
| |
void HTTPAcceptor::handleEnqueue(Message *message) | void HTTPAcceptor::handleEnqueue(Message *message) |
{ | { |
|
Uint32 numConnections = HTTP_ACCEPTOR_MAX_CONNECTIONS; |
|
|
if (! message) | if (! message) |
return; | return; |
| |
|
|
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; |
} | } |
| |
// 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 |
|
|
|
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 |
|
#if defined PEGASUS_OS_TYPE_WINDOWS && !defined(PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET) |
|
if(!connection->isNamedPipeConnection()) |
|
{ |
|
#endif |
|
|
|
SocketHandle socket = connection->getSocket(); | SocketHandle socket = connection->getSocket(); |
| |
if (socket == closeConnectionMessage->socket) | if (socket == closeConnectionMessage->socket) |
{ | { |
_monitor->unsolicitSocketMessages(socket); | _monitor->unsolicitSocketMessages(socket); |
_rep->connections.remove(i); | _rep->connections.remove(i); |
|
numConnections = _rep->connections.size(); |
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! | // 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; |
} |
|
| |
|
// Re-enable connections if connection count falls below maximum. |
|
|
|
if (_entry_index == -1 && numConnections < HTTP_ACCEPTOR_MAX_CONNECTIONS) |
|
{ |
|
startAcceptingConnections(); |
|
} |
|
} |
| |
void HTTPAcceptor::handleEnqueue() | void HTTPAcceptor::handleEnqueue() |
{ | { |
|
|
| |
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() |
{ | { |
|
#ifdef PEGASUS_OS_PASE |
|
// bind need ccsid is 819 |
|
int orig_ccsid; |
|
orig_ccsid = _SETCCSID(-1); |
|
if (orig_ccsid == -1) |
|
{ |
|
PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
|
String("HTTPAcceptor::_bind: Can not get current PASE CCSID.")); |
|
orig_ccsid = 1208; |
|
} |
|
PaseCcsid ccsid(819, orig_ccsid); |
|
#endif |
| |
PEGASUS_ASSERT(_rep != 0); | PEGASUS_ASSERT(_rep != 0); |
// Create address: | // Create address: |
|
memset(_rep->address, 0, _rep->address_size); |
| |
#if defined PEGASUS_OS_TYPE_WINDOWS |
if (_connectionType == LOCAL_CONNECTION) |
if (!_localConnection) |
|
{ | { |
#endif |
|
|
|
memset(_rep->address, 0, sizeof(*_rep->address)); |
|
#if defined PEGASUS_OS_TYPE_WINDOWS |
|
} |
|
#endif |
|
if (_localConnection) |
|
{ |
|
// Added for NamedPipe implementation for windows |
|
#ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET | #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET |
# ifdef PEGASUS_OS_TYPE_WINDOWS |
// |
# ifdef PEGASUS_LOCALDOMAINSOCKET_DEBUG |
// Make sure the local domain socket can be owned by the cimserver |
|
// user. Otherwise, the bind may fail with a vague "bind failed" |
|
// error. |
|
// |
|
if (System::exists(PEGASUS_LOCAL_DOMAIN_SOCKET_PATH)) |
{ | { |
AutoMutex automut(Monitor::_cout_mut); |
if (!System::removeFile(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); |
throw CannotRemoveFile(PEGASUS_LOCAL_DOMAIN_SOCKET_PATH); |
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(reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path, | strcpy(reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path, |
PEGASUS_LOCAL_DOMAIN_SOCKET_PATH); | PEGASUS_LOCAL_DOMAIN_SOCKET_PATH); |
#ifdef PEGASUS_PLATFORM_OS400_ISERIES_IBM |
|
AtoE(reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path); |
|
#endif |
|
::unlink(reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path); |
|
# endif |
|
#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; |
|
|
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); | _rep->socket = Socket::createSocket(AF_UNIX, SOCK_STREAM, 0); |
} | } |
else |
#ifdef PEGASUS_ENABLE_IPV6 |
|
else if (_connectionType == IPV6_CONNECTION) |
|
{ |
|
_rep->socket = Socket::createSocket(PF_INET6, SOCK_STREAM, IPPROTO_TCP); |
|
} |
|
#endif |
|
else if (_connectionType == IPV4_CONNECTION) |
{ | { |
_rep->socket = Socket::createSocket(PF_INET, SOCK_STREAM, IPPROTO_TCP); | _rep->socket = Socket::createSocket(PF_INET, SOCK_STREAM, IPPROTO_TCP); |
|
} |
|
else |
|
{ |
|
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); |
} | } |
|
|
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 |
|
|
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"); |
} | } |
} | } |
|
|
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); |
} | } |
|
|
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); |
} | } |
|
|
{ | { |
sockaddr_in buf; | sockaddr_in buf; |
SocketLength 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_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 | |
|
|
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); |
} | } |
} | } |
|
|
| |
// Set up listening on the given socket: | // Set up listening on the given socket: |
| |
//int const MAX_CONNECTION_QUEUE_LENGTH = 15; |
//int const _maxConnectionQueueLength = 15; |
| |
if (listen(_rep->socket, MAX_CONNECTION_QUEUE_LENGTH) < 0) |
if (listen(_rep->socket, _maxConnectionQueueLength) < 0) |
{ | { |
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); |
} | } |
|
|
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); |
} | } |
|
|
// 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_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::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 |
#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." ); |
} | } |
} | } |
|
|
} | } |
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." ); |
} | } |
} | } |
|
|
// 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_OS_TYPE_WINDOWS && !defined(PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET) |
PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL2, |
PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL2, |
"HTTPAcceptor::reconnectConnectionSocket Unlinking local " |
"HTTPAcceptor::reconnectConnectionSocket Unlinking local connection." ); |
"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 |
|
|
} | } |
// open the socket | // open the socket |
_bind(); | _bind(); |
} | } |
else | else |
{ | { |
PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
"HTTPAcceptor::reconnectConnectionSocket failure _rep is null." ); | "HTTPAcceptor::reconnectConnectionSocket failure _rep is null." ); |
} | } |
} | } |
|
|
_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 |
# ifndef PEGASUS_OS_TYPE_WINDOWS |
|
::unlink( | ::unlink( |
reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path); | reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path); |
# endif |
|
#else | #else |
PEGASUS_ASSERT(false); | PEGASUS_ASSERT(false); |
#endif | #endif |
} | } |
#if defined PEGASUS_OS_TYPE_WINDOWS && !defined(PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET) |
|
if (!_localConnection) |
|
{ |
|
#endif |
|
delete _rep; | delete _rep; |
#if defined PEGASUS_OS_TYPE_WINDOWS && !defined(PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET) |
|
} |
|
#endif |
|
_rep = 0; | _rep = 0; |
} | } |
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." ); |
} | } |
} | } |
|
|
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 |
|
#if defined PEGASUS_OS_TYPE_WINDOWS && !defined(PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET) |
|
if(!connection->isNamedPipeConnection()) |
|
{ |
|
#endif |
|
SocketHandle socket = connection->getSocket(); | SocketHandle 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; |
} | } |
|
|
| |
// Accept the connection (populate the address): | // Accept the connection (populate the address): |
| |
struct sockaddr* accept_address; |
struct sockaddr* accept_address = 0; |
SocketLength 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_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 |
} | } |
| |
SocketHandle socket = accept(_rep->socket, accept_address, &address_size); |
SocketHandle socket; |
|
#ifdef PEGASUS_OS_TYPE_WINDOWS |
|
socket = accept(_rep->socket, accept_address, &address_size); |
|
#else |
|
while ( |
|
((socket = accept(_rep->socket, accept_address, &address_size)) == -1) |
|
&& (errno == EINTR)) |
|
; |
|
#endif |
| |
if (socket == PEGASUS_SOCKET_ERROR) | if (socket == PEGASUS_SOCKET_ERROR) |
{ | { |
|
|
// TCPIP is down reconnect this acceptor | // TCPIP is down reconnect this acceptor |
if(getSocketError() == PEGASUS_NETWORK_TCPIP_STOPPED) | if(getSocketError() == PEGASUS_NETWORK_TCPIP_STOPPED) |
{ | { |
|
PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
|
"Socket has an IO error. TCP/IP down. Try to reconnect." ); | "Socket has an IO error. TCP/IP down. Try to reconnect." ); |
| |
reconnectConnectionSocket(); | reconnectConnectionSocket(); |
| |
return; | 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; | String ipAddress; |
| |
if (_localConnection) |
if (_connectionType == LOCAL_CONNECTION) |
{ | { |
ipAddress = "localhost"; | ipAddress = "localhost"; |
} | } |
else | else |
{ | { |
|
#ifdef PEGASUS_ENABLE_IPV6 |
|
char ipBuffer[PEGASUS_INET6_ADDRSTR_LEN]; |
|
int rc; |
|
while ((rc = getnameinfo(accept_address, address_size, ipBuffer, |
|
PEGASUS_INET6_ADDRSTR_LEN, 0, 0, NI_NUMERICHOST)) == EAI_AGAIN) |
|
; |
|
if (rc) |
|
{ |
|
Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE, |
|
"HTTPAcceptor - getnameinfo() failure. rc: $0", rc); |
|
|
|
PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
|
"HTTPAcceptor: getnameinfo() failed"); |
|
delete accept_address; |
|
Socket::close(socket); |
|
return; |
|
} |
|
ipAddress = ipBuffer; |
|
#else |
unsigned char* sa = reinterpret_cast<unsigned char*>( | unsigned char* sa = reinterpret_cast<unsigned char*>( |
&reinterpret_cast<struct sockaddr_in*>( | &reinterpret_cast<struct sockaddr_in*>( |
accept_address)->sin_addr.s_addr); | accept_address)->sin_addr.s_addr); |
char ipBuffer[32]; | char ipBuffer[32]; |
sprintf(ipBuffer, "%u.%u.%u.%u", sa[0], sa[1], sa[2], sa[3]); | sprintf(ipBuffer, "%u.%u.%u.%u", sa[0], sa[1], sa[2], sa[3]); |
ipAddress = ipBuffer; | ipAddress = ipBuffer; |
|
#endif |
} | } |
| |
delete accept_address; | delete accept_address; |
|
|
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 |
|
|
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"); |
} | } |
} | } |
|
|
PEG_LOGGER_TRACE((Logger::STANDARD_LOG, System::CIMSERVER, 0, | PEG_LOGGER_TRACE((Logger::STANDARD_LOG, System::CIMSERVER, 0, |
"HTTPAcceptor - accept() success. Socket: $1" ,socket)); | "HTTPAcceptor - accept() success. Socket: $1" ,socket)); |
| |
AutoPtr<MP_Socket> mp_socket(new MP_Socket( |
SharedPtr<MP_Socket> mp_socket(new MP_Socket( |
socket, _sslcontext, _sslContextObjectLock)); |
socket, _sslcontext, _sslContextObjectLock, ipAddress)); |
| |
mp_socket->setSocketWriteTimeout(_socketWriteTimeout); | mp_socket->setSocketWriteTimeout(_socketWriteTimeout); |
| |
|
|
| |
if (socketAcceptStatus < 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; |
|
|
| |
if (socketAcceptStatus == 0) | if (socketAcceptStatus == 0) |
{ | { |
PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL2, |
PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL2, |
"HTTPAcceptor: SSL_accept() pending"); | "HTTPAcceptor: SSL_accept() pending"); |
connection->_acceptPending = true; | connection->_acceptPending = true; |
} | } |
|
|
{ | { |
// 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; |
|
|
| |
// Save the socket for cleanup later: | // Save the socket for cleanup later: |
connection->_entry_index = index; | connection->_entry_index = index; |
|
Uint32 numConnections; |
|
{ |
AutoMutex autoMut(_rep->_connection_mut); | AutoMutex autoMut(_rep->_connection_mut); |
_rep->connections.append(connection); | _rep->connections.append(connection); |
} |
numConnections = _rep->connections.size(); |
// 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); |
|
} | } |
| |
{ |
// Start accepting new connections when we exceeded maximum connections. |
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( |
if (numConnections >= HTTP_ACCEPTOR_MAX_CONNECTIONS) |
*_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 |
stopAcceptingConnections(); |
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) |
int HTTPAcceptor::startAcceptingConnections() |
return; |
|
#ifdef PEGASUS_LOCALDOMAINSOCKET_DEBUG |
|
{ | { |
AutoMutex automut(Monitor::_cout_mut); |
if ((_entry_index = _monitor->solicitSocketMessages( |
cout <<"In HTTPAcceptor::_acceptNamedPipeConnection " << endl; |
_rep->socket, |
} |
SocketMessage::READ | SocketMessage::EXCEPTION, |
#endif |
getQueueId(), |
|
Monitor::ACCEPTOR)) == -1) |
|
|
NamedPipeServerEndPiont nPSEndPoint = _rep->namedPipeServer->accept(); |
|
// Register to receive Messages on Connection pipe: |
|
#ifdef PEGASUS_LOCALDOMAINSOCKET_DEBUG |
|
{ | { |
AutoMutex automut(Monitor::_cout_mut); |
return false; |
cout << " In _acceptNamedPipeConnection -- after calling namedPipeServer->accept()" << endl; |
|
} | } |
#endif |
|
HTTPConnection* connection = new HTTPConnection(_monitor, nPSEndPoint, |
|
this, static_cast<MessageQueue *>(_outputMessageQueue),false); |
|
| |
// Solicit events on this new connection's socket: |
return true; |
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: |
void HTTPAcceptor::stopAcceptingConnections() |
connection->_entry_index = index; |
|
AutoMutex autoMut(_rep->_connection_mut); |
|
_rep->connections.append(connection); |
|
#ifdef PEGASUS_LOCALDOMAINSOCKET_DEBUG |
|
{ | { |
AutoMutex automut(Monitor::_cout_mut); |
_monitor->unsolicitSocketMessages(_rep->socket); |
PEGASUS_STD(cout) |
_entry_index = -1; |
<< "in HTTPAcceptor::_acceptNamedPipeConnection() at the end" << PEGASUS_STD(endl); |
|
} |
|
#endif |
|
} | } |
#endif |
|
| |
PEGASUS_NAMESPACE_END | PEGASUS_NAMESPACE_END |