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

Generated on Thu Nov 9 11:54:12 2006 for TAO by doxygen 1.3.6