GIOP_Message_Generator_Parser_10.cpp

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 #include "tao/GIOP_Message_Generator_Parser_10.h"
00004 #include "tao/GIOP_Utils.h"
00005 #include "tao/GIOP_Message_Locate_Header.h"
00006 #include "tao/operation_details.h"
00007 #include "tao/debug.h"
00008 #include "tao/Pluggable_Messaging_Utils.h"
00009 #include "tao/TAO_Server_Request.h"
00010 #include "tao/ORB_Constants.h"
00011 #include "tao/CDR.h"
00012 #include "tao/SystemException.h"
00013 
00014 #include "ace/Log_Msg.h"
00015 
00016 ACE_RCSID (tao,
00017            GIOP_Message_Generator_Parser_10,
00018            "$Id: GIOP_Message_Generator_Parser_10.cpp 80861 2008-03-07 13:48:34Z johnnyw $")
00019 
00020 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00021 
00022 bool
00023 TAO_GIOP_Message_Generator_Parser_10::write_request_header (
00024     const TAO_Operation_Details &opdetails,
00025     TAO_Target_Specification &spec,
00026     TAO_OutputCDR &msg)
00027 {
00028   // Write the service context list
00029   if (!(msg << opdetails.request_service_info ()))
00030     return false;
00031 
00032   // The request ID
00033   if (!(msg << opdetails.request_id ()))
00034     return false;
00035 
00036   CORBA::Octet const response_flags = opdetails.response_flags ();
00037 
00038   // Write the response flags
00039   if (response_flags == TAO_TWOWAY_RESPONSE_FLAG)
00040     {
00041       msg << ACE_OutputCDR::from_octet (1);
00042     }
00043   else
00044     {
00045       msg << ACE_OutputCDR::from_octet (0);
00046     }
00047 
00048   // In this case we cannot recognise anything other than the Object
00049   // key as the address disposition variable. But we do a sanity check
00050   // anyway.
00051   const TAO::ObjectKey *key = spec.object_key ();
00052 
00053   if (key)
00054     {
00055       // Put in the object key
00056       msg << *key;
00057     }
00058   else
00059     {
00060       if (TAO_debug_level)
00061         {
00062           ACE_ERROR ((LM_ERROR,
00063                       ACE_TEXT ("(%N |%l) Unable to handle this request \n")));
00064         }
00065       return false;
00066     }
00067 
00068   msg.write_string (opdetails.opname_len (), opdetails.opname ());
00069 
00070   // Last element of request header is the principal; no portable way
00071   // to get it, we just pass empty principal (convention: indicates
00072   // "anybody").  Steps upward in security include passing an
00073   // unverified user ID, and then verifying the message (i.e. a dummy
00074   // service context entry is set up to hold a digital signature for
00075   // this message, then patched shortly before it's sent).
00076 
00077   /***** This has been deprecated in the 2.4 spec ******/
00078 
00079 #if defined (TAO_PEER_REQUIRES_PRINCIPAL)
00080 
00081   char username[BUFSIZ];
00082   char *result =
00083     ACE_OS::cuserid (username,
00084                      BUFSIZ);
00085 
00086   if (result != 0)
00087     {
00088       const CORBA::ULong username_size =
00089         static_cast<CORBA::ULong> (ACE_OS::strlen (username));
00090 
00091       CORBA::Octet *buffer =
00092         CORBA::OctetSeq::allocbuf (username_size + 1);
00093 
00094       ACE_OS::memcpy (buffer,
00095                       username,
00096                       username_size + 1);
00097 
00098       req_principal.replace (username_size + 1,
00099                              username_size + 1,
00100                              buffer,
00101                              1);
00102     }
00103 
00104 #else
00105 
00106   CORBA::OctetSeq req_principal (0);
00107   req_principal.length (0);
00108 
00109 #endif /* TAO_PEER_REQUIRES_PRINCIPAL */
00110 
00111   msg << req_principal;
00112 
00113   return true;
00114 }
00115 
00116 bool
00117 TAO_GIOP_Message_Generator_Parser_10::write_locate_request_header (
00118     CORBA::ULong request_id,
00119     TAO_Target_Specification  &spec,
00120     TAO_OutputCDR &msg)
00121 {
00122   msg << request_id;
00123 
00124   // In this case we cannot recognise anything other than the Object
00125   // key as the address disposition variable. But we do a sanity check
00126   // anyway.
00127   const TAO::ObjectKey *key = spec.object_key ();
00128 
00129   if (key)
00130     {
00131       // Everything is fine
00132       msg << *key;
00133     }
00134   else
00135     {
00136       if (TAO_debug_level)
00137         {
00138           ACE_ERROR ((LM_ERROR,
00139                       ACE_TEXT ("(%N | %l) Unable to handle this request\n")));
00140         }
00141       return false;
00142     }
00143 
00144   return true;
00145 }
00146 
00147 bool
00148 TAO_GIOP_Message_Generator_Parser_10::write_reply_header (
00149     TAO_OutputCDR &output,
00150     TAO_Pluggable_Reply_Params_Base &reply)
00151 {
00152   // Write the service context list.
00153 #if (TAO_HAS_MINIMUM_CORBA == 1)
00154   if (!(output << reply.service_context_notowned ()))
00155     return false;
00156 #else
00157   if (reply.is_dsi_ == false)
00158     {
00159       if (!(output << reply.service_context_notowned ()))
00160         return false;
00161     }
00162   else
00163     {
00164       // If lazy evaluation is enabled then we are going to insert an
00165       // extra node at the end of the service context list, just to
00166       // force the appropriate padding.
00167       // But first we take it out any of them..
00168       CORBA::ULong count = 0;
00169       IOP::ServiceContextList &svc_ctx = reply.service_context_notowned ();
00170       CORBA::ULong const l = svc_ctx.length ();
00171       CORBA::ULong i;
00172 
00173       for (i = 0; i != l; ++i)
00174         {
00175           if (svc_ctx[i].context_id == TAO_SVC_CONTEXT_ALIGN)
00176             {
00177               continue;
00178             }
00179 
00180           ++count;
00181         }
00182 
00183       // Now increment it to account for the last dummy one...
00184       ++count;
00185 
00186       // Now marshal the rest of the service context objects
00187       if (!(output << count))
00188         return false;
00189 
00190       for (i = 0; i != l; ++i)
00191         {
00192           if (svc_ctx[i].context_id == TAO_SVC_CONTEXT_ALIGN)
00193             {
00194               continue;
00195             }
00196 
00197           if (!(output << svc_ctx[i]))
00198             return false;
00199         }
00200 
00201     }
00202 
00203   if (reply.is_dsi_ == true)
00204     {
00205       // @@ Much of this code is GIOP 1.1 specific and should be
00206       ptrdiff_t target = reply.dsi_nvlist_align_;
00207 
00208       ptrdiff_t const current =
00209         ptrdiff_t (output.current_alignment ()) % ACE_CDR::MAX_ALIGNMENT;
00210 
00211       CORBA::ULong pad = 0;
00212 
00213       if (target == 0)
00214         {
00215           // We want to generate adequate padding to start the request
00216           // id on a 8 byte boundary, two cases:
00217           // - If the dummy tag starts on a 4 byte boundary and the
00218           //   dummy sequence has 0 elements then we have:
00219           //   4:tag 8:sequence_length 4:sequence_body 4:request_id
00220           //   8:payload
00221           // - If the dummy tag starts on an 8 byte boundary, with 4
00222           //   elements we get:
00223           //   8:tag 4:sequence_length 8:sequence_body 4:request_id
00224           //   8:payload
00225           if (current != 0 && current <= ACE_CDR::LONG_ALIGN)
00226             {
00227               pad = 4;
00228             }
00229         }
00230       else if (target != ACE_CDR::LONG_ALIGN)
00231         {
00232           // The situation reverses, we want to generate adequate
00233           // padding to start the request id on a 4 byte boundary, two
00234           // cases:
00235           // - If the dummy tag starts on a 4 byte boundary and the
00236           //   dummy sequence has 4 elements then we have:
00237           //   4:tag 8:sequence_length 4:sequence_body 8:request_id
00238           //   4:payload
00239           // - If the dummy tag starts on an 8 byte boundary, with 0
00240           //   elements we get:
00241           //   8:tag 4:sequence_length 8:sequence_body 8:request_id
00242           //   4:payload
00243           if (current > ACE_CDR::LONG_ALIGN)
00244             {
00245               pad = 4;
00246             }
00247         }
00248       else if (target == ACE_CDR::MAX_ALIGNMENT)
00249         {
00250           pad = 0;
00251         }
00252       else
00253         {
00254           // <target> can only have the values above
00255           throw ::CORBA::MARSHAL ();
00256         }
00257 
00258       output << CORBA::ULong (TAO_SVC_CONTEXT_ALIGN);
00259       output << pad;
00260 
00261       for (CORBA::ULong j = 0; j != pad; ++j)
00262         {
00263           output << ACE_OutputCDR::from_octet(0);
00264         }
00265     }
00266 #endif /* TAO_HAS_MINIMUM_CORBA */
00267 
00268   // Write the request ID
00269   output.write_ulong (reply.request_id_);
00270 
00271   // Write the reply status
00272   output.write_ulong (reply.reply_status ());
00273 
00274   return true;
00275 }
00276 
00277 
00278 bool
00279 TAO_GIOP_Message_Generator_Parser_10::write_locate_reply_mesg (
00280     TAO_OutputCDR &output,
00281     CORBA::ULong request_id,
00282     TAO_GIOP_Locate_Status_Msg &status_info)
00283 {
00284   // Make the header for the locate request
00285   output.write_ulong (request_id);
00286   output.write_ulong (status_info.status);
00287 
00288   if (status_info.status == GIOP::OBJECT_FORWARD)
00289     {
00290       CORBA::Object_ptr object_ptr =
00291         status_info.forward_location_var.in ();
00292 
00293       if ((output << object_ptr) == false)
00294         {
00295           if (TAO_debug_level > 0)
00296             {
00297               ACE_ERROR ((
00298                   LM_ERROR,
00299                   ACE_TEXT ("TAO (%P|%t|%N|%l) write_locate_reply_mesg-")
00300                   ACE_TEXT (" cannot marshal object reference\n")
00301                 ));
00302             }
00303           return false;
00304         }
00305     }
00306 
00307   return true;
00308 }
00309 
00310 bool
00311 TAO_GIOP_Message_Generator_Parser_10::write_fragment_header (
00312   TAO_OutputCDR & /* cdr */,
00313   CORBA::ULong /* request_id */)
00314 {
00315   // GIOP fragments are not supported in GIOP 1.0.
00316   return false;
00317 }
00318 
00319 
00320 int
00321 TAO_GIOP_Message_Generator_Parser_10::parse_request_header (
00322     TAO_ServerRequest &request)
00323 {
00324   // Tear out the service context ... we currently ignore it, but it
00325   // should probably be passed to each ORB service as appropriate
00326   // (e.g. transactions, security).
00327   //
00328   // NOTE: As security support kicks in, this is a good place to
00329   // verify a digital signature, if that is required in this security
00330   // environment.  It may be required even when using IPSEC security
00331   // infrastructure.
00332 
00333   // Get the input CDR in the request class
00334   TAO_InputCDR & input = *request.incoming ();
00335 
00336   IOP::ServiceContextList &service_info = request.request_service_info ();
00337 
00338   if (!(input >> service_info))
00339     return -1;
00340 
00341   CORBA::Boolean hdr_status = (CORBA::Boolean) input.good_bit ();
00342 
00343   CORBA::ULong req_id = 0;
00344 
00345   // Get the rest of the request header ...
00346   hdr_status = hdr_status && input.read_ulong (req_id);
00347 
00348   request.request_id (req_id);
00349 
00350   CORBA::Octet response_flags = CORBA::Octet();
00351   hdr_status = hdr_status && input.read_octet (response_flags);
00352   request.response_expected ((response_flags != 0));
00353 
00354   // This is not supported now in GIOP 1.1
00355   request.sync_with_server (0);
00356 
00357   // We use ad-hoc demarshalling here: there is no need to increase
00358   // the reference count on the CDR message block, because this key
00359   // will not outlive the request (or the message block).
00360 
00361   hdr_status =
00362     hdr_status && request.profile ().unmarshall_object_key (input);
00363 
00364   // According to the CORBA 2.6.1 (and older) specification, the operation
00365   // name is an IDL Identifier. Identifiers must be composed of ASCII letters,
00366   // numbers, and underscores, starting with a letter. Based on this, and
00367   // the fact that I could find no text explicitly requiring operation name
00368   // translation, nor could others in the CORBA community, the operation name
00369   // will not be translated regardless of the translation of other strings.
00370   //
00371   CORBA::ULong length = 0;
00372   hdr_status = hdr_status && input.read_ulong (length);
00373 
00374   if (hdr_status)
00375     {
00376       // Do not include NULL character at the end.
00377       // @@ This is not getting demarshaled using the codeset
00378       //    translators!
00379 
00380       // Notice that there are no memory allocations involved
00381       // here!
00382       request.operation (input.rd_ptr (),
00383                          length - 1,
00384                          0 /* TAO_ServerRequest does NOT own string */);
00385       hdr_status = input.skip_bytes (length);
00386     }
00387 
00388   if (hdr_status)
00389     {
00390       /**** This has been deprecated in 2.4 ****/
00391       /*CORBA::Principal_var principal;
00392 
00393       input >> principal.out ();
00394 
00395       request.requesting_principal (principal.in ()); */
00396 
00397       CORBA::OctetSeq oct_seq;
00398       input >> oct_seq;
00399       request.requesting_principal (oct_seq);
00400       hdr_status = (CORBA::Boolean) input.good_bit ();
00401     }
00402 
00403 
00404   return hdr_status ? 0 : -1;
00405 }
00406 
00407 int
00408 TAO_GIOP_Message_Generator_Parser_10::parse_locate_header (
00409     TAO_GIOP_Locate_Request_Header &request)
00410 {
00411   // Get the stream
00412   TAO_InputCDR &msg = request.incoming_stream ();
00413 
00414   // Get the request id
00415   CORBA::ULong req_id = 0;
00416   CORBA::Boolean hdr_status = msg.read_ulong (req_id);
00417 
00418   // Store it in the Locate request classes
00419   request.request_id (req_id);
00420 
00421   // Get the object key
00422   hdr_status = hdr_status && request.profile ().unmarshall_object_key (msg);
00423 
00424   return hdr_status ? 0 : -1;
00425 }
00426 
00427 int
00428 TAO_GIOP_Message_Generator_Parser_10::parse_reply (
00429     TAO_InputCDR &cdr,
00430     TAO_Pluggable_Reply_Params &params)
00431 {
00432   // Read the service context list first
00433   if (!(cdr >> params.svc_ctx_))
00434     {
00435       if (TAO_debug_level > 0)
00436         {
00437           ACE_ERROR ((LM_ERROR,
00438                       ACE_TEXT ("TAO (%P|%t) parse_reply, ")
00439                       ACE_TEXT ("extracting context\n")));
00440         }
00441       return -1;
00442     }
00443 
00444   // Call the base class for further processing
00445   if (TAO_GIOP_Message_Generator_Parser::parse_reply (cdr, params) == -1)
00446     return -1;
00447 
00448   return 0;
00449 }
00450 
00451 
00452 int
00453 TAO_GIOP_Message_Generator_Parser_10::parse_locate_reply (
00454     TAO_InputCDR &cdr,
00455     TAO_Pluggable_Reply_Params &params)
00456 {
00457   if (TAO_GIOP_Message_Generator_Parser::parse_locate_reply (cdr,
00458                                                              params) == -1)
00459 
00460     return -1;
00461 
00462   return 0;
00463 }
00464 
00465 CORBA::Octet
00466 TAO_GIOP_Message_Generator_Parser_10::major_version (void) const
00467 {
00468   // Any harm in hardcoding??
00469   return static_cast<CORBA::Octet> (1);
00470 }
00471 
00472 CORBA::Octet
00473 TAO_GIOP_Message_Generator_Parser_10::minor_version (void) const
00474 {
00475   // Any harm in hardcoding??
00476   return 0;
00477 }
00478 
00479 size_t
00480 TAO_GIOP_Message_Generator_Parser_10::fragment_header_length (void) const
00481 {
00482   return 0;
00483 }
00484 
00485 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Tue Feb 2 17:37:52 2010 for TAO by  doxygen 1.4.7