diff options
Diffstat (limited to 'trunk/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ServerRequestInterceptor.cpp')
-rw-r--r-- | trunk/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ServerRequestInterceptor.cpp | 182 |
1 files changed, 182 insertions, 0 deletions
diff --git a/trunk/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ServerRequestInterceptor.cpp b/trunk/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ServerRequestInterceptor.cpp new file mode 100644 index 00000000000..10bb3303a39 --- /dev/null +++ b/trunk/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ServerRequestInterceptor.cpp @@ -0,0 +1,182 @@ +#include "orbsvcs/LoadBalancing/LB_ServerRequestInterceptor.h" +#include "orbsvcs/LoadBalancing/LB_LoadAlert.h" + +#include "tao/debug.h" + +#include "ace/OS_NS_string.h" + + +ACE_RCSID (LoadBalancing, + LB_ServerRequestInterceptor, + "$Id$") + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +TAO_LB_ServerRequestInterceptor::TAO_LB_ServerRequestInterceptor ( + TAO_LB_LoadAlert & load_alert) + : load_alert_ (load_alert) +{ +} + +TAO_LB_ServerRequestInterceptor::~TAO_LB_ServerRequestInterceptor (void) +{ +} + +char * +TAO_LB_ServerRequestInterceptor::name (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + return CORBA::string_dup ("TAO_LB_ServerRequestInterceptor"); +} + +void +TAO_LB_ServerRequestInterceptor::destroy (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ +} + +void +TAO_LB_ServerRequestInterceptor::receive_request_service_contexts ( + PortableInterceptor::ServerRequestInfo_ptr ri + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)) +{ + if (this->load_alert_.alerted ()) + { + CORBA::String_var op = ri->operation (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + if (ACE_OS::strcmp (op.in (), "_get_loads") == 0 // LoadMonitor + || ACE_OS::strcmp (op.in (), "disable_alert") == 0 // LoadAlert + || ACE_OS::strcmp (op.in (), "enable_alert") == 0) // LoadAlert + return; // Do not redirect. + +#if 0 + ACE_TRY + { + IOP::ServiceContext_var service_context = + ri->get_request_service_context (CosLoadBalancing::LOAD_MANAGED + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + /* + // Use TAO-specific "compiled marshaling" instead of + // standard interpretive marshaling via a CDR encapsulation + // Codec for efficiency reasons. + const char * buf = + reinterpret_cast<const char *> (service_context->context_data.get_buffer ()); + TAO_InputCDR cdr (buf, + service_context->context_data.length ()); + + CORBA::Boolean byte_order; + if ((cdr >> ACE_InputCDR::to_boolean (byte_order)) == 0) + ACE_TRY_THROW (CORBA::BAD_PARAM ()); + + cdr.reset_byte_order (static_cast<int> (byte_order)); + + CORBA::Object_var object_group; + if (cdr >> object_group.out ()) + ACE_TRY_THROW (PortableInterceptor::ForwardRequest (object_group.in (), + 0)); + else + ACE_TRY_THROW (CORBA::BAD_PARAM ()); + */ + + // A ServiceContext of the given ServiceId exists. This + // means that the target is load balanced. Force the client + // to try another profile since this location is currently + // overloaded. + ACE_TRY_THROW (CORBA::TRANSIENT ()); + } + ACE_CATCH (CORBA::BAD_PARAM, ex) + { + // No CosLoadBalancing::LB_GROUP_REF ServiceContext. This + // probably means that the target object is not + // LoadBalanced. + + // There is a huge DoS attack vulnerability with this load + // shedding model. The model relies on the client behaving + // correctly. In particular, it relies on the client to + // send the forward object group reference in the + // ServiceContextList. Any "misbehaving" client can avoid + // that, in which case no load will ever be shed! + + + // Make sure we get a CORBA::BAD_PARAM for the right + // reason. + if (ex.minor () != (CORBA::OMGVMCID | 26)) + ACE_RE_THROW; + } + ACE_ENDTRY; + ACE_CHECK; +#else + // Force the client to try another profile since this location + // is currently overloaded. + // + // NOTE: This applies to both load balanced and non-load + // balanced targets. + ACE_THROW (CORBA::TRANSIENT ()); +#endif /* 0 */ + } +} + +void +TAO_LB_ServerRequestInterceptor::receive_request ( + PortableInterceptor::ServerRequestInfo_ptr + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)) +{ +} + +void +TAO_LB_ServerRequestInterceptor::send_reply ( + PortableInterceptor::ServerRequestInfo_ptr /* ri */ + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ +} + +void +TAO_LB_ServerRequestInterceptor::send_exception ( + PortableInterceptor::ServerRequestInfo_ptr + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)) +{ + if (TAO_debug_level > 0) + { + // A CORBA::TRANSIENT is thrown when the LoadManager informs the + // LoadAlert object that its member is overloaded, for example. + + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("TAO_LB_ServerRequestInterceptor -- ") + ACE_TEXT ("Exception thrown.\n"))); + } +} + +void +TAO_LB_ServerRequestInterceptor::send_other ( + PortableInterceptor::ServerRequestInfo_ptr ri + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)) +{ + if (TAO_debug_level > 0) + { + // A location forward occurs when the LoadManager informs the + // LoadAlert object that its member is overloaded, for example. + + const PortableInterceptor::ReplyStatus status = + ri->reply_status (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + if (status == PortableInterceptor::LOCATION_FORWARD) + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("TAO_LB_ServerRequestInterceptor -- ") + ACE_TEXT ("LOCATION FORWARDED\n"))); + } +} + +TAO_END_VERSIONED_NAMESPACE_DECL |