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 #include "ace/os_include/os_netdb.h"
00031
00032 ACE_RCSID (tao,
00033 SCIOP_Connection_Handler,
00034 "$Id: SCIOP_Connection_Handler.cpp 85817 2009-06-26 20:44:58Z mitza $")
00035
00036 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00037
00038 TAO_SCIOP_Connection_Handler::TAO_SCIOP_Connection_Handler (ACE_Thread_Manager *t)
00039 : TAO_SCIOP_SVC_HANDLER (t, 0 , 0),
00040 TAO_Connection_Handler (0),
00041 dscp_codepoint_ (IPDSFIELD_DSCP_DEFAULT << 2)
00042 {
00043
00044
00045
00046
00047
00048 ACE_ASSERT (0);
00049 }
00050
00051
00052 TAO_SCIOP_Connection_Handler::TAO_SCIOP_Connection_Handler (TAO_ORB_Core *orb_core)
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));
00060
00061
00062 this->transport (specific_transport);
00063 }
00064
00065 TAO_SCIOP_Connection_Handler::~TAO_SCIOP_Connection_Handler (void)
00066 {
00067 delete this->transport ();
00068 int const result =
00069 this->release_os_resources ();
00070
00071 if (result == -1 && TAO_debug_level)
00072 {
00073 ACE_ERROR ((LM_ERROR,
00074 ACE_TEXT("TAO (%P|%t) - SCIOP_Connection_Handler::")
00075 ACE_TEXT("~scIOP_Connection_Handler, ")
00076 ACE_TEXT("release_os_resources() failed %m\n")));
00077 }
00078 }
00079
00080 int
00081 TAO_SCIOP_Connection_Handler::open_handler (void *v)
00082 {
00083 return this->open (v);
00084 }
00085
00086 int
00087 TAO_SCIOP_Connection_Handler::open (void*)
00088 {
00089 if (this->shared_open() == -1)
00090 return -1;
00091
00092 TAO_SCIOP_Protocol_Properties protocol_properties;
00093
00094
00095 protocol_properties.send_buffer_size_ =
00096 this->orb_core ()->orb_params ()->sock_sndbuf_size ();
00097 protocol_properties.recv_buffer_size_ =
00098 this->orb_core ()->orb_params ()->sock_rcvbuf_size ();
00099 protocol_properties.no_delay_ =
00100 this->orb_core ()->orb_params ()->nodelay ();
00101 protocol_properties.hop_limit_ =
00102 this->orb_core ()->orb_params ()->ip_hoplimit ();
00103
00104 TAO_Protocols_Hooks *tph = this->orb_core ()->get_protocols_hooks ();
00105
00106 if (tph != 0)
00107 {
00108 try
00109 {
00110 if (this->transport ()->opened_as () == TAO::TAO_CLIENT_ROLE)
00111 {
00112 tph->client_protocol_properties_at_orb_level (protocol_properties);
00113 }
00114 else
00115 {
00116 tph->server_protocol_properties_at_orb_level (protocol_properties);
00117 }
00118 }
00119 catch (const ::CORBA::Exception& ex)
00120 {
00121 return -1;
00122 }
00123 }
00124
00125 if (this->set_socket_option (this->peer (),
00126 protocol_properties.send_buffer_size_,
00127 protocol_properties.recv_buffer_size_) == -1)
00128 return -1;
00129
00130 #if !defined (ACE_LACKS_TCP_NODELAY)
00131 if (this->peer ().set_option (IPPROTO_SCTP,
00132 SCTP_NODELAY,
00133 (void *) &protocol_properties.no_delay_,
00134 sizeof (protocol_properties.no_delay_)) == -1)
00135 return -1;
00136 #endif
00137
00138 if (protocol_properties.hop_limit_ >= 0)
00139 {
00140 int result = 0;
00141 #if defined (ACE_HAS_IPV6)
00142 ACE_INET_Addr local_addr;
00143 if (this->peer ().get_local_addr (local_addr) == -1)
00144 {
00145 result = -1;
00146 }
00147 else if (local_addr.get_type () == AF_INET6)
00148 {
00149 #if defined (ACE_WIN32)
00150 DWORD hop_limit =
00151 static_cast<DWORD> (protocol_properties.hop_limit_);
00152 #else
00153 int hop_limit =
00154 static_cast<int> (protocol_properties.hop_limit_);
00155 #endif
00156 result = this->peer ().set_option (
00157 IPPROTO_IPV6,
00158 IPV6_UNICAST_HOPS,
00159 (void *) &hop_limit,
00160 sizeof (hop_limit));
00161 }
00162 else
00163 #endif
00164 {
00165 #if defined (ACE_WIN32)
00166 DWORD hop_limit =
00167 static_cast<DWORD> (protocol_properties.hop_limit_);
00168 #else
00169 int hop_limit =
00170 static_cast<int> (protocol_properties.hop_limit_);
00171 #endif
00172 result = this->peer ().set_option (
00173 IPPROTO_IP,
00174 IP_TTL,
00175 (void *) &hop_limit,
00176 sizeof (hop_limit));
00177 }
00178
00179 if (result != 0)
00180 {
00181 if (TAO_debug_level)
00182 {
00183 ACE_ERROR ((LM_ERROR,
00184 ACE_TEXT("TAO (%P|%t) - SCIOP_Connection_Handler::open, ")
00185 ACE_TEXT("couldn't set hop limit\n\n")));
00186 }
00187 return -1;
00188 }
00189 }
00190
00191 if (this->transport ()->wait_strategy ()->non_blocking ())
00192 {
00193 if (this->peer ().enable (ACE_NONBLOCK) == -1)
00194 return -1;
00195 }
00196
00197
00198
00199
00200 ACE_INET_Addr remote_addr;
00201 if (this->peer ().get_remote_addr (remote_addr) == -1)
00202 return -1;
00203
00204 ACE_INET_Addr local_addr;
00205 if (this->peer ().get_local_addr (local_addr) == -1)
00206 return -1;
00207
00208 if (TAO_debug_level > 2)
00209 ACE_DEBUG ((LM_DEBUG,
00210 ACE_TEXT("TAO(%P|%t) - SCIOP_Connection_Handler::open, ")
00211 ACE_TEXT("The local addr is (%C)\n"),
00212 local_addr.get_host_addr ()));
00213
00214 if (local_addr.get_ip_address () == remote_addr.get_ip_address ()
00215 && local_addr.get_port_number () == remote_addr.get_port_number ())
00216 {
00217 if (TAO_debug_level > 0)
00218 {
00219 ACE_TCHAR remote_as_string[MAXHOSTNAMELEN + 16];
00220 ACE_TCHAR local_as_string[MAXHOSTNAMELEN + 16];
00221
00222 (void) remote_addr.addr_to_string (remote_as_string,
00223 sizeof(remote_as_string));
00224 (void) local_addr.addr_to_string (local_as_string,
00225 sizeof(local_as_string));
00226 ACE_ERROR ((LM_ERROR,
00227 ACE_TEXT("TAO(%P|%t) - TAO_SCIOP_Connection_Handler::open, ")
00228 ACE_TEXT("Holy Cow! The remote addr and ")
00229 ACE_TEXT("local addr are identical (%s == %s)\n"),
00230 remote_as_string, local_as_string));
00231 }
00232 return -1;
00233 }
00234
00235 if (TAO_debug_level > 0)
00236 {
00237 ACE_TCHAR client[MAXHOSTNAMELEN + 16];
00238
00239
00240 if (remote_addr.addr_to_string (client, sizeof (client)) == -1)
00241 return -1;
00242
00243 ACE_DEBUG ((LM_DEBUG,
00244 ACE_TEXT ("TAO (%P|%t) - SCIOP_Connection_Handler::open, SCIOP ")
00245 ACE_TEXT ("connection to peer <%s> on %d\n"),
00246 client, this->peer ().get_handle ()));
00247 }
00248
00249
00250
00251
00252 if (!this->transport ()->post_open ((size_t) this->get_handle ()))
00253 return -1;
00254
00255 this->state_changed (TAO_LF_Event::LFS_SUCCESS,
00256 this->orb_core ()->leader_follower ());
00257
00258 return 0;
00259 }
00260
00261 int
00262 TAO_SCIOP_Connection_Handler::resume_handler (void)
00263 {
00264 return ACE_Event_Handler::ACE_APPLICATION_RESUMES_HANDLER;
00265 }
00266
00267 int
00268 TAO_SCIOP_Connection_Handler::close_connection (void)
00269 {
00270 return this->close_connection_eh (this);
00271 }
00272
00273 int
00274 TAO_SCIOP_Connection_Handler::handle_input (ACE_HANDLE h)
00275 {
00276 return this->handle_input_eh (h, this);
00277 }
00278
00279 int
00280 TAO_SCIOP_Connection_Handler::handle_output (ACE_HANDLE handle)
00281 {
00282 int const result =
00283 this->handle_output_eh (handle, this);
00284
00285 if (result == -1)
00286 {
00287 this->close_connection ();
00288 return 0;
00289 }
00290
00291 return result;
00292 }
00293
00294 int
00295 TAO_SCIOP_Connection_Handler::handle_timeout (const ACE_Time_Value &,
00296 const void *)
00297 {
00298
00299
00300
00301
00302
00303
00304 TAO_Auto_Reference<TAO_SCIOP_Connection_Handler> safeguard (*this);
00305
00306
00307
00308
00309
00310
00311
00312 int ret = this->close ();
00313 this->reset_state (TAO_LF_Event::LFS_TIMEOUT);
00314 return ret;
00315 }
00316
00317 int
00318 TAO_SCIOP_Connection_Handler::handle_close (ACE_HANDLE,
00319 ACE_Reactor_Mask)
00320 {
00321 ACE_ASSERT (0);
00322 return 0;
00323 }
00324
00325 int
00326 TAO_SCIOP_Connection_Handler::close (u_long flags)
00327 {
00328 return this->close_handler (flags);
00329 }
00330
00331 int
00332 TAO_SCIOP_Connection_Handler::release_os_resources (void)
00333 {
00334 return this->peer().close ();
00335 }
00336
00337 int
00338 TAO_SCIOP_Connection_Handler::add_transport_to_cache (void)
00339 {
00340 ACE_INET_Addr addr;
00341
00342
00343 if (this->peer ().get_remote_addr (addr) == -1)
00344 return -1;
00345
00346
00347 TAO_SCIOP_Endpoint endpoint (
00348 addr,
00349 this->orb_core()->orb_params()->use_dotted_decimal_addresses ());
00350
00351
00352 TAO_Base_Transport_Property prop (&endpoint);
00353
00354 TAO::Transport_Cache_Manager &cache =
00355 this->orb_core ()->lane_resources ().transport_cache ();
00356
00357
00358 return cache.cache_transport (&prop, this->transport ());
00359 }
00360
00361 int
00362 TAO_SCIOP_Connection_Handler::process_listen_point_list (
00363 IIOP::ListenPointList &listen_list)
00364 {
00365
00366 CORBA::ULong const len = listen_list.length ();
00367
00368 for (CORBA::ULong i = 0; i < len; ++ i)
00369 {
00370 IIOP::ListenPoint listen_point = listen_list[i];
00371 ACE_INET_Addr addr (listen_point.port,
00372 listen_point.host.in ());
00373
00374 if (TAO_debug_level > 0)
00375 {
00376 ACE_DEBUG ((LM_DEBUG,
00377 ACE_TEXT("(%P|%t) Listening port [%d] on [%C]\n"),
00378 listen_point.port,
00379 listen_point.host.in ()));
00380 }
00381
00382
00383 TAO_SCIOP_Endpoint endpoint (addr,
00384 this->orb_core()->orb_params()->use_dotted_decimal_addresses ());
00385
00386
00387 TAO_Base_Transport_Property prop (&endpoint);
00388
00389
00390 prop.set_bidir_flag (1);
00391
00392
00393
00394 int const retval = this->transport ()->recache_transport (&prop);
00395 if (retval == -1)
00396 return retval;
00397
00398
00399 this->transport ()->make_idle ();
00400 }
00401
00402 return 0;
00403 }
00404
00405 int
00406 TAO_SCIOP_Connection_Handler::set_tos (int tos)
00407 {
00408 if (tos != this->dscp_codepoint_)
00409 {
00410 int const result = this->peer ().set_option (IPPROTO_IP,
00411 IP_TOS,
00412 (int *) &tos ,
00413 (int) sizeof (tos));
00414
00415 if (TAO_debug_level)
00416 {
00417 ACE_DEBUG ((LM_DEBUG,
00418 ACE_TEXT("TAO (%P|%t) - SCIOP_Connection_Handler::")
00419 ACE_TEXT("set_dscp_codepoint -> dscp: %x; result: %d; %C\n"),
00420 tos,
00421 result,
00422 result == -1 ? "try running as superuser" : ""));
00423 }
00424
00425
00426 if (result == 0)
00427 this->dscp_codepoint_ = tos;
00428
00429 }
00430
00431 return 0;
00432 }
00433
00434 int
00435 TAO_SCIOP_Connection_Handler::set_dscp_codepoint (CORBA::Long dscp)
00436 {
00437 int tos = IPDSFIELD_DSCP_DEFAULT << 2;
00438 tos = (int)(dscp) << 2;
00439 this->set_tos (tos);
00440 return 0;
00441 }
00442
00443 int
00444 TAO_SCIOP_Connection_Handler::set_dscp_codepoint (CORBA::Boolean set_network_priority)
00445 {
00446 int tos = IPDSFIELD_DSCP_DEFAULT << 2;
00447
00448 if (set_network_priority)
00449 {
00450 TAO_Protocols_Hooks *tph = this->orb_core ()->get_protocols_hooks ();
00451
00452 if (tph != 0)
00453 {
00454 CORBA::Long codepoint = tph->get_dscp_codepoint ();
00455 tos = (int)(codepoint) << 2;
00456 this->set_tos (tos);
00457 }
00458 }
00459
00460 return 0;
00461 }
00462
00463 int
00464 TAO_SCIOP_Connection_Handler::handle_write_ready (const ACE_Time_Value *t)
00465 {
00466 return ACE::handle_write_ready (this->peer ().get_handle (), t);
00467 }
00468
00469 TAO_END_VERSIONED_NAMESPACE_DECL
00470
00471 #endif