version 1.93.4.1, 2007/04/04 11:04:44
|
version 1.93.4.2, 2007/07/03 21:50:04
|
|
|
#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> | #include <Pegasus/Common/MessageLoader.h> |
| |
|
|
class HTTPAcceptorRep | class HTTPAcceptorRep |
{ | { |
public: | public: |
HTTPAcceptorRep(Boolean local) |
HTTPAcceptorRep(Uint16 connectionType) |
{ | { |
if (local) |
if (connectionType == HTTPAcceptor::LOCAL_CONNECTION) |
{ | { |
#ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET | #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET |
address = | address = |
|
|
PEGASUS_ASSERT(false); | PEGASUS_ASSERT(false); |
#endif | #endif |
} | } |
else |
#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 |
|
else if (connectionType == HTTPAcceptor::IPV4_CONNECTION) |
{ | { |
address = | address = |
reinterpret_cast<struct sockaddr*>(new struct sockaddr_in); | reinterpret_cast<struct sockaddr*>(new struct sockaddr_in); |
address_size = sizeof(struct sockaddr_in); | address_size = sizeof(struct sockaddr_in); |
} | } |
|
else |
|
{ |
|
PEGASUS_ASSERT(false); |
|
} |
} | } |
|
|
~HTTPAcceptorRep() | ~HTTPAcceptorRep() |
{ | { |
delete address; | delete address; |
|
|
| |
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) |
|
|
throw BindFailedException(parms); | throw BindFailedException(parms); |
} | } |
| |
_rep = new HTTPAcceptorRep(_localConnection); |
_rep = new HTTPAcceptorRep(_connectionType); |
| |
// bind address | // bind address |
_bind(); | _bind(); |
|
|
{ | { |
PEGASUS_ASSERT(_rep != 0); | PEGASUS_ASSERT(_rep != 0); |
// Create address: | // Create address: |
|
memset(_rep->address, 0, _rep->address_size); |
| |
memset(_rep->address, 0, sizeof(*_rep->address)); |
if (_connectionType == LOCAL_CONNECTION) |
|
|
if (_localConnection) |
|
{ | { |
#ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET | #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET |
reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_family = | reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_family = |
|
|
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) |
{ | { |
|
|
#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) || \ |
defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)) | defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)) |
if (_localConnection) |
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 | |
|
|
// 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_DISABLE_LOCAL_DOMAIN_SOCKET |
PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL2, | PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL2, |
|
|
// 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_DISABLE_LOCAL_DOMAIN_SOCKET |
PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL2, | PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL2, |
|
|
_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 |
::unlink( | ::unlink( |
|
|
struct sockaddr* accept_address; | struct sockaddr* accept_address; |
SocketLength address_size; | SocketLength address_size; |
| |
if (_localConnection) |
if (_connectionType == LOCAL_CONNECTION) |
{ | { |
#ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET | #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET |
accept_address = | accept_address = |
|
|
} | } |
else | else |
{ | { |
|
#ifdef PEGASUS_ENABLE_IPV6 |
|
accept_address = |
|
reinterpret_cast<struct sockaddr*> |
|
(new struct sockaddr_storage); |
|
address_size = sizeof(struct sockaddr_storage); |
|
#else |
accept_address = | accept_address = |
reinterpret_cast<struct sockaddr*>(new struct sockaddr_in); | 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 = accept(_rep->socket, accept_address, &address_size); |
|
|
| |
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; |