diff options
Diffstat (limited to 'TAO/tao/GIOP_Message_Factory.cpp')
-rw-r--r-- | TAO/tao/GIOP_Message_Factory.cpp | 446 |
1 files changed, 344 insertions, 102 deletions
diff --git a/TAO/tao/GIOP_Message_Factory.cpp b/TAO/tao/GIOP_Message_Factory.cpp index 2b62bc0b6be..d61251fa1a0 100644 --- a/TAO/tao/GIOP_Message_Factory.cpp +++ b/TAO/tao/GIOP_Message_Factory.cpp @@ -42,55 +42,129 @@ // reported. #include "tao/GIOP_Message_Factory.h" +#include "tao/GIOP_Utils.h" #include "tao/Any.h" +#include "tao/ORB_Core.h" #if !defined (__ACE_INLINE__) # include "tao/GIOP_Message_Factory.i" #endif /* __ACE_INLINE__ */ -TAO_GIOP_Message_Factory::TAO_GIOP_Message_Factory (void) + + +// +// Client Side Message Factory Methods +// + +TAO_GIOP_Client_Message_Factory::TAO_GIOP_Client_Message_Factory (void) { } -TAO_GIOP_Message_Factory::~TAO_GIOP_Message_Factory (void) +TAO_GIOP_Client_Message_Factory::~TAO_GIOP_Client_Message_Factory (void) { } -/*CORBA::Boolean -TAO_GIOP_Message_Factory::start_message (const TAO_GIOP_Version &version, - TAO_GIOP_Message_Factory::Message_Type t, - TAO_OutputCDR &msg) +int +TAO_GIOP_Client_Message_Factory::handle_input (TAO_Transport *transport, + TAO_ORB_Core */*orb_core*/, + TAO_Message_State_Factory &mesg_state, + ACE_Time_Value *max_wait_time) { - msg.reset (); - - static CORBA::Octet magic[] = - { - // The following works on non-ASCII platforms, such as MVS (which - // uses EBCDIC). - 0x47, // 'G' - 0x49, // 'I' - 0x4f, // 'O' - 0x50, // 'P' - }; - - static int magic_size = sizeof (magic)/sizeof (magic[0]); - msg.write_octet_array (magic, magic_size); - msg.write_octet (version.major); - msg.write_octet (version.minor); - msg.write_octet (TAO_ENCAP_BYTE_ORDER); - msg.write_octet ((CORBA::Octet) type); - - // Write a dummy <size> later it is set to the right value... - CORBA::ULong size = 0; - msg.write_ulong (size); + TAO_GIOP_Message_State *state = + ACE_dynamic_cast (TAO_GIOP_Message_State *, + &mesg_state); - return 1; + if (state->header_received () == 0) + { + if (TAO_GIOP_Utils::read_bytes_input (transport, + state->cdr, + TAO_GIOP_HEADER_LEN, + max_wait_time) == -1) + { + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) - %p\n" + "TAO_GIOP_Client_Message_Factory::handle_input")); + return -1; + } + + + if (this->parse_magic_bytes (state->cdr) == -1) + { + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) - %p\n" + "TAO_GIOP_Client_Message_Factory::handle_input, parse_bytes")); + return -1; + } + + // Read the rest of the stuff. That should be read by the + // corresponding states + if (this->parse_header (state) == -1) + { + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) - %p\n" + "TAO_GIOP_Client_Message_Factory::handle_input")); + return -1; + } + } + + size_t missing_data = + state->message_size - state->current_offset; + + + ssize_t n = + TAO_GIOP_Utils::read_buffer (transport, + state->cdr.rd_ptr () + state->current_offset, + missing_data, + max_wait_time); + if (n == -1) + { + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) - %p\n", + "TAO_GIOP_Client_Message_Factory::handle_input, read_buffer[1]")); + return -1; + } + else if (n == 0) + { + if (errno == EWOULDBLOCK) + return 0; + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) - %p\n", + "TAO_GIOP_Client_Message::handle_input, read_buffer[2]")); + return -1; + } + + state->current_offset += n; + + if (state->current_offset == state->message_size) + { + if (TAO_debug_level >= 4) + { + size_t header_len = TAO_GIOP_HEADER_LEN; + + // Need to include GIOPlite too. + + char *buf = state->cdr.rd_ptr (); + buf -= header_len; + size_t msg_len = state->cdr.length () + header_len; + TAO_GIOP_Utils::dump_msg ("recv", + ACE_reinterpret_cast (u_char *, + buf), + msg_len); + } + } + + return state->is_complete (); } -*/ + CORBA::Boolean -TAO_GIOP_Message_Factory::write_request_header (const IOP::ServiceContextList& /*svc_ctx*/, +TAO_GIOP_Client_Message_Factory::write_request_header (const IOP::ServiceContextList& /*svc_ctx*/, CORBA::ULong request_id, CORBA::Octet response_flags, TAO_Stub */*stub*/, @@ -105,7 +179,7 @@ TAO_GIOP_Message_Factory::write_request_header (const IOP::ServiceContextList& / // First the request id msg << request_id; - + // Second the response flags switch (response_flags) { @@ -134,9 +208,7 @@ TAO_GIOP_Message_Factory::write_request_header (const IOP::ServiceContextList& / // specific to GIOP 1.2. So some of the services would start // using this at some point of time and we will have them here // naturally out of a need. - default: - // Until more flags are defined by the OMG. return 0; } @@ -145,97 +217,267 @@ TAO_GIOP_Message_Factory::write_request_header (const IOP::ServiceContextList& / - -TAO_GIOP_Message_Factory::send_message (TAO_Transport *transport, - TAO_OutputCDR &stream, - ACE_Time_Value *max_wait_time = 0, - TAO_Stub *stub = 0) +int +TAO_GIOP_Client_Message_Factory::send_message (TAO_Transport *transport, + TAO_OutputCDR &stream, + ACE_Time_Value *max_wait_time, + TAO_Stub *stub) { - // TAO_FUNCTION_PP_TIMEPROBE (TAO_GIOP_SEND_MESSAGE_START); - - // Ptr to first buffer. - char *buf = (char *) stream.buffer (); - - // Length of all buffers. - size_t total_len = - stream.total_length (); - - // NOTE: Here would also be a fine place to calculate a digital - // signature for the message and place it into a preallocated slot - // in the "ServiceContext". Similarly, this is a good spot to - // encrypt messages (or just the message bodies) if that's needed in - // this particular environment and that isn't handled by the - // networking infrastructure (e.g., IPSEC). - // Get the header length size_t header_len = this->get_header_len (); // Get the message size offset size_t offset = this->get_message_size_offset (); + + return TAO_GIOP_Utils::send_message (transport, + stream, + header_len, + offset, + max_wait_time, + stub); +} + + + +// +// Server Side Message Factory Methods +// + + +TAO_GIOP_Message_Acceptor::TAO_GIOP_Message_Acceptor (void) +{ + // Initialised... + this->accept_states_ = &(this->available_states_.giop_1_1_); + +} + +TAO_GIOP_Message_Acceptor::~TAO_GIOP_Message_Acceptor (void) +{ + //no-op +} + +int +TAO_GIOP_Message_Acceptor::handle_input (TAO_Transport *transport, + TAO_ORB_Core */*orb_core*/, + TAO_Message_State_Factory &mesg_state, + ACE_Time_Value *max_wait_time) +{ + TAO_GIOP_Message_State *state = + ACE_dynamic_cast (TAO_GIOP_Message_State *, + &mesg_state); - CORBA::ULong bodylen = total_len - header_len; - -#if !defined (ACE_ENABLE_SWAP_ON_WRITE) - *ACE_reinterpret_cast (CORBA::ULong *, buf + offset) = bodylen; -#else - if (!stream->do_byte_swap ()) - *ACE_reinterpret_cast (CORBA::ULong *, - buf + offset) = bodylen; - else - ACE_CDR::swap_4 (ACE_reinterpret_cast (char *, - &bodylen), - buf + offset); -#endif /* ACE_ENABLE_SWAP_ON_WRITE */ - - // Strictly speaking, should not need to loop here because the - // socket never gets set to a nonblocking mode ... some Linux - // versions seem to need it though. Leaving it costs little. - this->dump_msg ("send", - ACE_reinterpret_cast (u_char *, - buf), - stream.length ()); - - // This guarantees to send all data (bytes) or return an error. - ssize_t n = transport->send (stub, - stream.begin (), - max_wait_time); + if (state->header_received () == 0) + { + if (TAO_GIOP_Utils::read_bytes_input (transport, + state->cdr, + TAO_GIOP_HEADER_LEN, + max_wait_time) == -1) + { + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) - %p\n" + "TAO_GIOP_Message_Acceptor::handle_input")); + return -1; + } + + if (this->parse_magic_bytes (state->cdr, + state) == -1) + { + this->accept_states_->send_error (transport); + + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) - %p\n" + "TAO_GIOP_Message_Acceptor::handle_input, parse_bytes")); + return -1; + } + + // Read the rest of the stuff. That should be read by the + // corresponding states + if (this->accept_states_->parse_header (state) == -1) + { + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) - %p\n" + "TAO_GIOP_Message_Acceptor::handle_input")); + return -1; + } + } + + size_t missing_data = + state->message_size - state->current_offset; + ssize_t n = + TAO_GIOP_Utils::read_buffer (transport, + state->cdr.rd_ptr () + state->current_offset, + missing_data, + max_wait_time); if (n == -1) { - if (TAO_orbdebug) + if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG, - "TAO: (%P|%t) closing conn %d after fault %p\n", - transport->handle (), - "GIOP_Message_Factory::send_message ()")); - + "TAO (%P|%t) - %p\n", + "TAO_GIOP_Message_Acceptor::handle_input, read_buffer[1]")); return -1; } - - // EOF. - if (n == 0) + else if (n == 0) { - if (TAO_orbdebug) + if (errno == EWOULDBLOCK) + return 0; + if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG, - "TAO: (%P|%t) GIOP::send_message () " - "EOF, closing conn %d\n", - transport->handle())); + "TAO (%P|%t) - %p\n", + "TAO_GIOP_Message_Acceptor::handle_input, read_buffer[2]")); return -1; } - return 1; + state->current_offset += n; + + if (state->current_offset == state->message_size) + { + if (TAO_debug_level >= 4) + { + size_t header_len = TAO_GIOP_HEADER_LEN; + + // Need to include GIOPlite too. + + char *buf = state->cdr.rd_ptr (); + buf -= header_len; + size_t msg_len = state->cdr.length () + header_len; + TAO_GIOP_Utils::dump_msg ("recv", + ACE_reinterpret_cast (u_char *, + buf), + msg_len); + } + } + + return state->is_complete (); } -void -TAO_GIOP_Message_Factory::dump_msg (const char */*label*/, - const u_char */*ptr*/, - size_t /*len*/) + +int +TAO_GIOP_Message_Acceptor:: +process_connector_messages (TAO_Transport *transport, + TAO_ORB_Core *orb_core, + TAO_InputCDR &input, + CORBA::Octet message_type) { - if (TAO_debug_level >= 5) + char repbuf[ACE_CDR::DEFAULT_BUFSIZE]; + +#if defined(ACE_HAS_PURIFY) + (void) ACE_OS::memset (repbuf, + '\0', + sizeof repbuf); +#endif /* ACE_HAS_PURIFY */ + + TAO_OutputCDR output (repbuf, + sizeof repbuf, + TAO_ENCAP_BYTE_ORDER, + orb_core->output_cdr_buffer_allocator (), + orb_core->output_cdr_dblock_allocator (), + orb_core->orb_params ()->cdr_memcpy_tradeoff (), + orb_core->to_iso8859 (), + orb_core->to_unicode ()); + + switch (message_type) { - // I will have to print out all the relevant debug messages!! - // Let me not wory about that now. I will get back to that at a - // later date!! + case TAO_GIOP_REQUEST: + // Should be taken care by the state specific invocations. They + // could raise an exception or write things in the output CDR + // stream + this->accept_states_->process_connector_request (transport, + orb_core, + input, + output); + break; + case TAO_GIOP_LOCATEREQUEST: + this->accept_states_->process_connector_locate (transport, + orb_core, + input, + output); + break; + case TAO_GIOP_MESSAGERROR: + case TAO_GIOP_REPLY: + case TAO_GIOP_LOCATEREPLY: + case TAO_GIOP_CLOSECONNECTION: + default: + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) Illegal message received by server\n")); + return this->accept_states_->send_error (transport); + break; } + + return 0; } +int +TAO_GIOP_Message_Acceptor::parse_magic_bytes (TAO_InputCDR &input, + TAO_GIOP_Message_State *state) +{ + // Grab the read pointer + char *buf = input.rd_ptr (); + + // The values are hard-coded to support non-ASCII platforms. + if (!(buf [0] == 0x47 // 'G' + && buf [1] == 0x49 // 'I' + && buf [2] == 0x4f // 'O' + && buf [3] == 0x50)) // 'P' + { + // Could be GIOPlite.. + //... + + // For the present... + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) bad header, magic word [%c%c%c%c]\n", + buf[0], + buf[1], + buf[2], + buf[3])); + return -1; + } + state->giop_version.major = buf[TAO_GIOP_VERSION_MAJOR_OFFSET]; + state->giop_version.minor = buf[TAO_GIOP_VERSION_MINOR_OFFSET]; + + // An extra variable?? Huh?? Can be removed?? + CORBA::Octet major = state->giop_version.major; + CORBA::Octet minor = state->giop_version.minor; + + if ((this->available_states_.check_major (major) == -1) || + (this->available_states_.check_minor (minor) == -1)) + { + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) bad version <%d.%d>\n", + major, minor)); + return -1; + } + + // Set the appropriate state + if (this->set_state (state) == -1) + { + if (TAO_debug_level > 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "(%P|%t|%N|%l) Failure <error> in set_state ()\n"), + -1); + } + } + + return 0; +} + + +int +TAO_GIOP_Message_Acceptor::set_state (TAO_GIOP_Message_State * /*state*/) + +{ + // Logic for selecting from a registry set should be here. Let me go + // first with normal stuff. + this->accept_states_ = &(this->available_states_.giop_1_1_); + + return 1; +} + |