version 1.93.4.4, 2008/01/02 21:05:03
|
version 1.101, 2007/06/26 20:26:13
|
|
|
#include "Tracer.h" | #include "Tracer.h" |
#include <Pegasus/Common/MessageLoader.h> | #include <Pegasus/Common/MessageLoader.h> |
| |
#ifdef PEGASUS_PLATFORM_OS400_ISERIES_IBM |
|
#include "EBCDIC_OS400.h" |
|
#endif |
|
|
|
|
|
PEGASUS_USING_STD; | PEGASUS_USING_STD; |
| |
PEGASUS_NAMESPACE_BEGIN | PEGASUS_NAMESPACE_BEGIN |
|
|
_connectionType(connectionType), | _connectionType(connectionType), |
_portNumber(portNumber), | _portNumber(portNumber), |
_sslcontext(sslcontext), | _sslcontext(sslcontext), |
_sslContextObjectLock(sslContextObjectLock), |
_sslContextObjectLock(sslContextObjectLock) |
_idleConnectionTimeoutSeconds(0) |
|
{ | { |
Socket::initializeInterface(); | Socket::initializeInterface(); |
| |
|
|
/* | /* |
if (MAX_CONNECTION_QUEUE_LENGTH == -1) | if (MAX_CONNECTION_QUEUE_LENGTH == -1) |
{ | { |
#ifdef PEGASUS_PLATFORM_OS400_ISERIES_IBM |
|
#pragma convert(37) |
|
const char* env = getenv("PEGASUS_MAX_BACKLOG_CONNECTION_QUEUE"); |
|
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; | MAX_CONNECTION_QUEUE_LENGTH = 15; |
|
|
if (_connectionType == LOCAL_CONNECTION) | if (_connectionType == LOCAL_CONNECTION) |
{ | { |
#ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET | #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET |
|
// |
|
// Make sure the local domain socket can be owned by the cimserver |
|
// user. Otherwise, the bind may fail with a vague "bind failed" |
|
// error. |
|
// |
|
if (System::exists(PEGASUS_LOCAL_DOMAIN_SOCKET_PATH)) |
|
{ |
|
if (!System::removeFile(PEGASUS_LOCAL_DOMAIN_SOCKET_PATH)) |
|
{ |
|
throw CannotRemoveFile(PEGASUS_LOCAL_DOMAIN_SOCKET_PATH); |
|
} |
|
} |
|
|
reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_family = | reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_family = |
AF_UNIX; | AF_UNIX; |
strcpy(reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path, | strcpy(reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path, |
PEGASUS_LOCAL_DOMAIN_SOCKET_PATH); | PEGASUS_LOCAL_DOMAIN_SOCKET_PATH); |
#ifdef PEGASUS_PLATFORM_OS400_ISERIES_IBM |
|
AtoE(reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path); |
|
#endif |
|
::unlink( |
|
reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path); |
|
#else | #else |
PEGASUS_ASSERT(false); | PEGASUS_ASSERT(false); |
#endif | #endif |
|
|
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. |
|
|
_socketWriteTimeout = socketWriteTimeout; | _socketWriteTimeout = socketWriteTimeout; |
} | } |
| |
void HTTPAcceptor::setIdleConnectionTimeout(Uint32 idleConnectionTimeoutSeconds) |
|
{ |
|
_idleConnectionTimeoutSeconds = idleConnectionTimeoutSeconds; |
|
} |
|
|
|
void HTTPAcceptor::unbind() | void HTTPAcceptor::unbind() |
{ | { |
if (_rep) | if (_rep) |
|
|
#endif | #endif |
} | } |
| |
// It is not necessary to handle EINTR errors from this accept() call. |
SocketHandle socket; |
// An EINTR error should not occur on a non-blocking socket. If the |
#ifdef PEGASUS_OS_TYPE_WINDOWS |
// listen socket is blocking and EINTR occurs, the new socket connection |
socket = accept(_rep->socket, accept_address, &address_size); |
// is not accepted here. |
#else |
|
while ( |
// EAGAIN errors are also not handled here. An EAGAIN error should not |
((socket = accept(_rep->socket, accept_address, &address_size)) == -1) |
// occur after select() indicates that the listen socket is available for |
&& (errno == EINTR)) |
// reading. If the accept() fails with an EAGAIN error code, a new |
; |
// connection is not accepted here. |
#endif |
|
|
SocketHandle socket = accept(_rep->socket, accept_address, &address_size); |
|
| |
if (socket == PEGASUS_SOCKET_ERROR) | if (socket == PEGASUS_SOCKET_ERROR) |
{ | { |
|
|
PEG_LOGGER_TRACE((Logger::STANDARD_LOG, System::CIMSERVER, 0, | PEG_LOGGER_TRACE((Logger::STANDARD_LOG, System::CIMSERVER, 0, |
"HTTPAcceptor - accept() success. Socket: $1" ,socket)); | "HTTPAcceptor - accept() success. Socket: $1" ,socket)); |
| |
AutoPtr<MP_Socket> mp_socket(new MP_Socket( |
SharedPtr<MP_Socket> mp_socket(new MP_Socket( |
socket, _sslcontext, _sslContextObjectLock)); |
socket, _sslcontext, _sslContextObjectLock, ipAddress)); |
| |
mp_socket->disableBlocking(); |
|
mp_socket->setSocketWriteTimeout(_socketWriteTimeout); | mp_socket->setSocketWriteTimeout(_socketWriteTimeout); |
| |
// Perform the SSL handshake, if applicable. |
// Perform the SSL handshake, if applicable. Make the socket non-blocking |
|
// for this operation so we can send it back to the Monitor's select() loop |
|
// if it takes a while. |
| |
|
mp_socket->disableBlocking(); |
Sint32 socketAcceptStatus = mp_socket->accept(); | Sint32 socketAcceptStatus = mp_socket->accept(); |
|
mp_socket->enableBlocking(); |
| |
if (socketAcceptStatus < 0) | if (socketAcceptStatus < 0) |
{ | { |
|
|
HTTPConnection* connection = new HTTPConnection(_monitor, mp_socket, | HTTPConnection* connection = new HTTPConnection(_monitor, mp_socket, |
ipAddress, this, static_cast<MessageQueue *>(_outputMessageQueue)); | ipAddress, this, static_cast<MessageQueue *>(_outputMessageQueue)); |
| |
if (_idleConnectionTimeoutSeconds) |
|
{ |
|
connection->_idleConnectionTimeoutSeconds = |
|
_idleConnectionTimeoutSeconds; |
|
Time::gettimeofday(&connection->_idleStartTime); |
|
} |
|
|
|
if (socketAcceptStatus == 0) | if (socketAcceptStatus == 0) |
{ | { |
PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL2, | PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL2, |
"HTTPAcceptor: SSL_accept() pending"); | "HTTPAcceptor: SSL_accept() pending"); |
connection->_acceptPending = true; | connection->_acceptPending = true; |
Time::gettimeofday(&connection->_acceptPendingStartTime); |
|
} | } |
| |
// Solicit events on this new connection's socket: | // Solicit events on this new connection's socket: |