version 1.91, 2006/10/25 19:48:12
|
version 1.92, 2006/11/08 22:24:00
|
|
|
if (local) | if (local) |
{ | { |
#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); |
|
|
} | } |
else | else |
{ | { |
address = reinterpret_cast<struct sockaddr*>(new struct sockaddr_in); |
address = |
|
reinterpret_cast<struct sockaddr*>(new struct sockaddr_in); |
address_size = sizeof(struct sockaddr_in); | address_size = sizeof(struct sockaddr_in); |
} | } |
} | } |
|
|
Socket::initializeInterface(); | Socket::initializeInterface(); |
| |
/* | /* |
Platforms interpret the value of MAX_CONNECTION_QUEUE_LENGTH differently. Some platforms interpret |
Platforms interpret the value of MAX_CONNECTION_QUEUE_LENGTH |
the value literally, while others multiply a fudge factor. When the server is under |
differently. Some platforms interpret the value literally, while |
stress from multiple clients with multiple requests, toggling this number may prevent clients from |
others multiply a fudge factor. When the server is under stress from |
being dropped. Instead of hard coding the value, we allow an environment variable to be set which |
multiple clients with multiple requests, toggling this number may |
specifies a number greater than the maximum concurrent client connections possible. If this environment |
prevent clients from being dropped. Instead of hard coding the |
var is not specified, then MAX_CONNECTION_QUEUE_LENGTH = 15. |
value, we allow an environment variable to be set which specifies a |
|
number greater than the maximum concurrent client connections |
|
possible. If this environment var is not specified, then |
|
MAX_CONNECTION_QUEUE_LENGTH = 15. |
*/ | */ |
| |
//To engage runtime backlog queue length: uncomment the following block AND comment out the line MAX_CONNECTION_QUEUE_LENGTH = 15 |
//To engage runtime backlog queue length: uncomment the following block AND |
|
//comment out the line MAX_CONNECTION_QUEUE_LENGTH = 15 |
| |
/* | /* |
if(MAX_CONNECTION_QUEUE_LENGTH == -1){ |
if (MAX_CONNECTION_QUEUE_LENGTH == -1) |
|
{ |
#ifdef PEGASUS_PLATFORM_OS400_ISERIES_IBM | #ifdef PEGASUS_PLATFORM_OS400_ISERIES_IBM |
#pragma convert(37) | #pragma convert(37) |
const char* env = getenv("PEGASUS_MAX_BACKLOG_CONNECTION_QUEUE"); | const char* env = getenv("PEGASUS_MAX_BACKLOG_CONNECTION_QUEUE"); |
|
|
#else | #else |
const char* env = getenv("PEGASUS_MAX_BACKLOG_CONNECTION_QUEUE"); | const char* env = getenv("PEGASUS_MAX_BACKLOG_CONNECTION_QUEUE"); |
#endif | #endif |
if(!env){ |
if (!env) |
|
{ |
MAX_CONNECTION_QUEUE_LENGTH = 15; | MAX_CONNECTION_QUEUE_LENGTH = 15; |
}else{ |
} |
|
else |
|
{ |
char *end = NULL; | char *end = NULL; |
MAX_CONNECTION_QUEUE_LENGTH = strtol(env, &end, 10); | MAX_CONNECTION_QUEUE_LENGTH = strtol(env, &end, 10); |
if(*end) | if(*end) |
MAX_CONNECTION_QUEUE_LENGTH = 15; | MAX_CONNECTION_QUEUE_LENGTH = 15; |
cout << " MAX_CONNECTION_QUEUE_LENGTH = " << MAX_CONNECTION_QUEUE_LENGTH << endl; |
cout << " MAX_CONNECTION_QUEUE_LENGTH = " << |
|
MAX_CONNECTION_QUEUE_LENGTH << endl; |
} | } |
} | } |
*/ | */ |
MAX_CONNECTION_QUEUE_LENGTH = 15; | MAX_CONNECTION_QUEUE_LENGTH = 15; |
|
|
} | } |
| |
HTTPAcceptor::~HTTPAcceptor() | HTTPAcceptor::~HTTPAcceptor() |
|
|
{ | { |
// ATTN! this can't happen! | // ATTN! this can't happen! |
Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2, | Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
"HTTPAcceptor::handleEnqueue: Invalid SOCKET_MESSAGE received."); |
"HTTPAcceptor::handleEnqueue: Invalid SOCKET_MESSAGE " |
|
"received."); |
} | } |
| |
break; | break; |
|
|
| |
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); |
| |
|
|
Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2, | Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
"HTTPAcceptor::handleEnqueue: Invalid MESSAGE received."); | "HTTPAcceptor::handleEnqueue: Invalid MESSAGE received."); |
break; | break; |
}; |
} |
| |
delete message; | delete message; |
} | } |
|
|
} | } |
| |
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"); |
| |
|
|
| |
// bind address | // bind address |
_bind(); | _bind(); |
|
|
return; |
|
} | } |
| |
/** | /** |
_bind - creates a new server socket and bind socket to the port address. | _bind - creates a new server socket and bind socket to the port address. |
If PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET is not defined, the port number is ignored and |
If PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET is not defined, the port number is |
a domain socket is bound. |
ignored and a domain socket is bound. |
*/ | */ |
void HTTPAcceptor::_bind() | void HTTPAcceptor::_bind() |
{ | { |
|
|
PEGASUS_ASSERT(_rep != 0); | PEGASUS_ASSERT(_rep != 0); |
// Create address: | // Create address: |
| |
|
|
#ifdef PEGASUS_PLATFORM_OS400_ISERIES_IBM | #ifdef PEGASUS_PLATFORM_OS400_ISERIES_IBM |
AtoE(reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path); | AtoE(reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path); |
#endif | #endif |
::unlink(reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path); |
::unlink( |
|
reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path); |
#else | #else |
PEGASUS_ASSERT(false); | PEGASUS_ASSERT(false); |
#endif | #endif |
|
|
else | else |
{ | { |
_rep->socket = Socket::createSocket(PF_INET, SOCK_STREAM, IPPROTO_TCP); | _rep->socket = Socket::createSocket(PF_INET, SOCK_STREAM, IPPROTO_TCP); |
|
|
} | } |
| |
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, | Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
|
|
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_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
|
|
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_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
|
|
{ | { |
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) && \ | #if !defined(PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET) && \ |
( defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) || \ | ( defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) || \ |
|
|
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_STRING(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); |
} | } |
} | } |
|
|
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_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
|
|
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_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
"HTTPAcceptor::_bind: Failed to solicit socket messages(2)."); | "HTTPAcceptor::_bind: Failed to solicit socket messages(2)."); |
|
|
{ | { |
#ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET | #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET |
PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL2, | PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL2, |
"HTTPAcceptor::closeConnectionSocket Unlinking local connection." ); |
"HTTPAcceptor::closeConnectionSocket Unlinking local " |
|
"connection."); |
::unlink( | ::unlink( |
reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path); | reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path); |
#else | #else |
PEGASUS_ASSERT(false); | PEGASUS_ASSERT(false); |
#endif | #endif |
} | } |
|
|
} | } |
else | else |
{ | { |
|
|
{ | { |
#ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET | #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET |
PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL2, | PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL2, |
"HTTPAcceptor::reconnectConnectionSocket Unlinking local connection." ); |
"HTTPAcceptor::reconnectConnectionSocket 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 |
|
|
if (_localConnection) | if (_localConnection) |
{ | { |
#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); |
|
|
} | } |
else | else |
{ | { |
accept_address = reinterpret_cast<struct sockaddr*>(new struct sockaddr_in); |
accept_address = |
|
reinterpret_cast<struct sockaddr*>(new struct sockaddr_in); |
address_size = sizeof(struct sockaddr_in); | address_size = sizeof(struct sockaddr_in); |
} | } |
| |
|
|
// 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_STRING(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." ); |
| |
|
|
| |
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_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
"HTTPAcceptor: accept() failed"); | "HTTPAcceptor: accept() failed"); |
|
|
// 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, | Tracer::trace(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; |