version 1.93.4.4, 2008/01/02 21:05:03
|
version 1.99.2.3, 2007/06/20 09:56:26
|
|
|
#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"); | const char* env = getenv("PEGASUS_MAX_BACKLOG_CONNECTION_QUEUE"); |
EtoA(env); |
|
#pragma convert(0) |
|
#else |
|
const char* env = getenv("PEGASUS_MAX_BACKLOG_CONNECTION_QUEUE"); |
|
#endif |
|
if (!env) | if (!env) |
{ | { |
MAX_CONNECTION_QUEUE_LENGTH = 15; | MAX_CONNECTION_QUEUE_LENGTH = 15; |
|
|
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( | ::unlink( |
reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path); | reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path); |
#else | #else |
|
|
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) |
{ | { |
|
|
#ifdef PEGASUS_ENABLE_IPV6 | #ifdef PEGASUS_ENABLE_IPV6 |
char ipBuffer[PEGASUS_INET6_ADDRSTR_LEN]; | char ipBuffer[PEGASUS_INET6_ADDRSTR_LEN]; |
int rc; | int rc; |
while ((rc = getnameinfo(accept_address, address_size, ipBuffer, |
if ((rc = getnameinfo(accept_address, address_size, ipBuffer, |
PEGASUS_INET6_ADDRSTR_LEN, 0, 0, NI_NUMERICHOST)) == EAI_AGAIN) |
PEGASUS_INET6_ADDRSTR_LEN, 0, 0, NI_NUMERICHOST))) |
; |
|
if (rc) |
|
{ | { |
Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE, | Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE, |
"HTTPAcceptor - getnameinfo() failure. rc: $0", rc); | "HTTPAcceptor - getnameinfo() failure. rc: $0", rc); |
|
|
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: |