00001 #include "tao/Strategies/SCIOP_Connection_Handler.h"
00002
00003 #if TAO_HAS_SCIOP == 1
00004
00005
00006
00007
00008 #ifndef IPPROTO_SCTP
00009 # include "netinet/sctp.h"
00010 #else // !IPPROTO_SCTP
00011 # ifndef SCTP_NODELAY
00012 # define SCTP_NODELAY 1
00013 # endif // !SCTP_NODELAY
00014 #endif
00015
00016 #include "tao/Timeprobe.h"
00017 #include "tao/debug.h"
00018 #include "tao/ORB_Core.h"
00019 #include "tao/ORB.h"
00020 #include "tao/CDR.h"
00021 #include "tao/Server_Strategy_Factory.h"
00022 #include "tao/Strategies/SCIOP_Transport.h"
00023 #include "tao/Strategies/SCIOP_Endpoint.h"
00024 #include "tao/Transport_Cache_Manager.h"
00025 #include "tao/Thread_Lane_Resources.h"
00026 #include "tao/Base_Transport_Property.h"
00027 #include "tao/Resume_Handle.h"
00028 #include "tao/Protocols_Hooks.h"
00029 #include "tao/Wait_Strategy.h"
00030
00031 ACE_RCSID (tao,
00032 SCIOP_Connection_Handler,
00033 "SCIOP_Connection_Handler.cpp,v 1.23 2006/04/19 11:38:50 jwillemsen Exp")
00034
00035 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00036
00037 TAO_SCIOP_Connection_Handler::TAO_SCIOP_Connection_Handler (ACE_Thread_Manager *t)
00038 : TAO_SCIOP_SVC_HANDLER (t, 0 , 0),
00039 TAO_Connection_Handler (0),
00040 dscp_codepoint_ (IPDSFIELD_DSCP_DEFAULT << 2)
00041 {
00042
00043
00044
00045
00046
00047 ACE_ASSERT (0);
00048 }
00049
00050
00051 TAO_SCIOP_Connection_Handler::TAO_SCIOP_Connection_Handler (TAO_ORB_Core *orb_core,
00052 CORBA::Boolean flag)
00053 : TAO_SCIOP_SVC_HANDLER (orb_core->thr_mgr (), 0, 0),
00054 TAO_Connection_Handler (orb_core),
00055 dscp_codepoint_ (IPDSFIELD_DSCP_DEFAULT << 2)
00056 {
00057 TAO_SCIOP_Transport* specific_transport = 0;
00058 ACE_NEW (specific_transport,
00059 TAO_SCIOP_Transport (this, orb_core, flag));
00060
00061
00062 this->transport (specific_transport);
00063 }
00064
00065 TAO_SCIOP_Connection_Handler::TAO_SCIOP_Connection_Handler (TAO_ORB_Core *orb_core)
00066 : TAO_SCIOP_SVC_HANDLER (orb_core->thr_mgr (), 0, 0),
00067 TAO_Connection_Handler (orb_core),
00068 dscp_codepoint_ (IPDSFIELD_DSCP_DEFAULT << 2)
00069 {
00070 }
00071
00072
00073 TAO_SCIOP_Connection_Handler::~TAO_SCIOP_Connection_Handler (void)
00074 {
00075 delete this->transport ();
00076 }
00077
00078 int
00079 TAO_SCIOP_Connection_Handler::open_handler (void *v)
00080 {
00081 return this->open (v);
00082 }
00083
00084 int
00085 TAO_SCIOP_Connection_Handler::open (void*)
00086 {
00087 TAO_SCIOP_Protocol_Properties protocol_properties;
00088
00089
00090 protocol_properties.send_buffer_size_ =
00091 this->orb_core ()->orb_params ()->sock_sndbuf_size ();
00092 protocol_properties.recv_buffer_size_ =
00093 this->orb_core ()->orb_params ()->sock_rcvbuf_size ();
00094 protocol_properties.no_delay_ =
00095 this->orb_core ()->orb_params ()->nodelay ();
00096
00097 TAO_Protocols_Hooks *tph =
00098 this->orb_core ()->get_protocols_hooks ();
00099
00100 bool client =
00101 this->transport ()->opened_as () == TAO::TAO_CLIENT_ROLE;;
00102
00103 ACE_DECLARE_NEW_CORBA_ENV;
00104
00105 ACE_TRY
00106 {
00107 if (client)
00108 {
00109 tph->client_protocol_properties_at_orb_level (
00110 protocol_properties
00111 ACE_ENV_ARG_PARAMETER);
00112 ACE_TRY_CHECK;
00113 }
00114 else
00115 {
00116 tph->server_protocol_properties_at_orb_level (
00117 protocol_properties
00118 ACE_ENV_ARG_PARAMETER);
00119 ACE_TRY_CHECK;
00120 }
00121 }
00122 ACE_CATCHANY
00123 {
00124 return -1;
00125 }
00126 ACE_ENDTRY;
00127 ACE_CHECK_RETURN (-1);
00128
00129 if (this->set_socket_option (this->peer (),
00130 protocol_properties.send_buffer_size_,
00131 protocol_properties.recv_buffer_size_) == -1)
00132 return -1;
00133
00134 #if !defined (ACE_LACKS_TCP_NODELAY)
00135 if (this->peer ().set_option (IPPROTO_SCTP,
00136 SCTP_NODELAY,
00137 (void *) &protocol_properties.no_delay_,
00138 sizeof (protocol_properties.no_delay_)) == -1)
00139 return -1;
00140 #endif
00141
00142 if (this->transport ()->wait_strategy ()->non_blocking ())
00143 {
00144 if (this->peer ().enable (ACE_NONBLOCK) == -1)
00145 return -1;
00146 }
00147
00148
00149
00150
00151 ACE_INET_Addr remote_addr;
00152 if (this->peer ().get_remote_addr (remote_addr) == -1)
00153 return -1;
00154
00155 ACE_INET_Addr local_addr;
00156 if (this->peer ().get_local_addr (local_addr) == -1)
00157 return -1;
00158
00159
00160 if (TAO_debug_level > 2)
00161 ACE_DEBUG ((LM_DEBUG,
00162 ACE_TEXT("TAO(%P|%t) - SCIOP_Connection_Handler::open, ")
00163 ACE_TEXT("The local addr is (%s) \n"),
00164 local_addr. get_host_addr ()));
00165
00166 if (local_addr.get_ip_address () == remote_addr.get_ip_address ()
00167 && local_addr.get_port_number () == remote_addr.get_port_number ())
00168 {
00169 if (TAO_debug_level > 0)
00170 {
00171 ACE_TCHAR remote_as_string[MAXHOSTNAMELEN + 16];
00172 ACE_TCHAR local_as_string[MAXHOSTNAMELEN + 16];
00173
00174 (void) remote_addr.addr_to_string (remote_as_string,
00175 sizeof(remote_as_string));
00176 (void) local_addr.addr_to_string (local_as_string,
00177 sizeof(local_as_string));
00178 ACE_ERROR ((LM_ERROR,
00179 ACE_TEXT("TAO(%P|%t) - TAO_SCIOP_Connection_Handler::open, ")
00180 ACE_TEXT("Holy Cow! The remote addr and ")
00181 ACE_TEXT("local addr are identical (%s == %s)\n"),
00182 remote_as_string, local_as_string));
00183 }
00184 return -1;
00185 }
00186
00187 if (TAO_debug_level > 0)
00188 {
00189 ACE_TCHAR client[MAXHOSTNAMELEN + 16];
00190
00191
00192 if (remote_addr.addr_to_string (client, sizeof (client)) == -1)
00193 return -1;
00194
00195 ACE_DEBUG ((LM_DEBUG,
00196 ACE_TEXT ("TAO (%P|%t) - SCIOP_Connection_Handler::open, SCIOP ")
00197 ACE_TEXT ("connection to peer <%s> on %d\n"),
00198 client, this->peer ().get_handle ()));
00199 }
00200
00201
00202
00203
00204 if (!this->transport ()->post_open ((size_t) this->get_handle ()))
00205 return -1;
00206
00207 this->state_changed (TAO_LF_Event::LFS_SUCCESS,
00208 this->orb_core ()->leader_follower ());
00209
00210 return 0;
00211 }
00212
00213 int
00214 TAO_SCIOP_Connection_Handler::resume_handler (void)
00215 {
00216 return ACE_Event_Handler::ACE_APPLICATION_RESUMES_HANDLER;
00217 }
00218
00219 int
00220 TAO_SCIOP_Connection_Handler::close_connection (void)
00221 {
00222 return this->close_connection_eh (this);
00223 }
00224
00225 int
00226 TAO_SCIOP_Connection_Handler::handle_input (ACE_HANDLE h)
00227 {
00228 return this->handle_input_eh (h, this);
00229 }
00230
00231 int
00232 TAO_SCIOP_Connection_Handler::handle_output (ACE_HANDLE handle)
00233 {
00234 int const result =
00235 this->handle_output_eh (handle, this);
00236
00237 if (result == -1)
00238 {
00239 this->close_connection ();
00240 return 0;
00241 }
00242
00243 return result;
00244 }
00245
00246 int
00247 TAO_SCIOP_Connection_Handler::handle_timeout (const ACE_Time_Value &,
00248 const void *)
00249 {
00250
00251
00252
00253 return this->close ();
00254 }
00255
00256 int
00257 TAO_SCIOP_Connection_Handler::handle_close (ACE_HANDLE,
00258 ACE_Reactor_Mask)
00259 {
00260 ACE_ASSERT (0);
00261 return 0;
00262 }
00263
00264 int
00265 TAO_SCIOP_Connection_Handler::close (u_long)
00266 {
00267 return this->close_handler ();
00268 }
00269
00270 int
00271 TAO_SCIOP_Connection_Handler::release_os_resources (void)
00272 {
00273 return this->peer().close ();
00274 }
00275
00276 int
00277 TAO_SCIOP_Connection_Handler::add_transport_to_cache (void)
00278 {
00279 ACE_INET_Addr addr;
00280
00281
00282 if (this->peer ().get_remote_addr (addr) == -1)
00283 return -1;
00284
00285
00286 TAO_SCIOP_Endpoint endpoint (
00287 addr,
00288 this->orb_core()->orb_params()->use_dotted_decimal_addresses ());
00289
00290
00291 TAO_Base_Transport_Property prop (&endpoint);
00292
00293 TAO::Transport_Cache_Manager &cache =
00294 this->orb_core ()->lane_resources ().transport_cache ();
00295
00296
00297 return cache.cache_idle_transport (&prop,
00298 this->transport ());
00299
00300 }
00301
00302 int
00303 TAO_SCIOP_Connection_Handler::process_listen_point_list (
00304 IIOP::ListenPointList &listen_list)
00305 {
00306
00307 CORBA::ULong const len = listen_list.length ();
00308
00309 for (CORBA::ULong i = 0; i < len; ++ i)
00310 {
00311 IIOP::ListenPoint listen_point = listen_list[i];
00312 ACE_INET_Addr addr (listen_point.port,
00313 listen_point.host.in ());
00314
00315 if (TAO_debug_level > 0)
00316 {
00317 ACE_DEBUG ((LM_DEBUG,
00318 ACE_TEXT("(%P|%t) Listening port [%d] on [%s]\n"),
00319 listen_point.port,
00320 ACE_TEXT_CHAR_TO_TCHAR(listen_point.host.in ())));
00321 }
00322
00323
00324 TAO_SCIOP_Endpoint endpoint (addr,
00325 this->orb_core()->orb_params()->use_dotted_decimal_addresses ());
00326
00327
00328 TAO_Base_Transport_Property prop (&endpoint);
00329
00330
00331 prop.set_bidir_flag (1);
00332
00333
00334
00335 int const retval = this->transport ()->recache_transport (&prop);
00336 if (retval == -1)
00337 return retval;
00338
00339
00340 this->transport ()->make_idle ();
00341 }
00342
00343 return 0;
00344 }
00345
00346 int
00347 TAO_SCIOP_Connection_Handler::set_dscp_codepoint (CORBA::Boolean set_network_priority)
00348 {
00349 int tos = IPDSFIELD_DSCP_DEFAULT << 2;
00350
00351 if (set_network_priority)
00352 {
00353 TAO_Protocols_Hooks *tph =
00354 this->orb_core ()->get_protocols_hooks ();
00355
00356 CORBA::Long codepoint =
00357 tph->get_dscp_codepoint ();
00358
00359 tos = (int)(codepoint) << 2;
00360 }
00361
00362 if (tos != this->dscp_codepoint_)
00363 {
00364 int const result = this->peer ().set_option (IPPROTO_IP,
00365 IP_TOS,
00366 (int *) &tos ,
00367 (int) sizeof (tos));
00368
00369 if (TAO_debug_level)
00370 {
00371 ACE_DEBUG ((LM_DEBUG,
00372 "TAO (%P|%t) - SCIOP_Connection_Handler::"
00373 "set_dscp_codepoint -> dscp: %x; result: %d; %s\n",
00374 tos,
00375 result,
00376 result == -1 ? "try running as superuser" : ""));
00377 }
00378
00379
00380 if (result == 0)
00381 this->dscp_codepoint_ = tos;
00382
00383 }
00384
00385 return 0;
00386 }
00387
00388 TAO_END_VERSIONED_NAMESPACE_DECL
00389
00390 #endif