00001 #include "tao/IIOP_Connection_Handler.h"
00002
00003 #if defined (TAO_HAS_IIOP) && (TAO_HAS_IIOP != 0)
00004
00005 #include "tao/debug.h"
00006 #include "tao/ORB_Core.h"
00007 #include "tao/IIOP_Transport.h"
00008 #include "tao/IIOP_Endpoint.h"
00009 #include "tao/IIOPC.h"
00010 #include "tao/Thread_Lane_Resources.h"
00011 #include "tao/Base_Transport_Property.h"
00012 #include "tao/Protocols_Hooks.h"
00013 #include "tao/Wait_Strategy.h"
00014
00015 #include "ace/os_include/netinet/os_tcp.h"
00016 #include "ace/os_include/os_netdb.h"
00017
00018 ACE_RCSID (tao,
00019 IIOP_Connection_Handler,
00020 "IIOP_Connection_Handler.cpp,v 1.113 2006/05/16 06:10:47 mesnier_p Exp")
00021
00022 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00023
00024 TAO_IIOP_Connection_Handler::TAO_IIOP_Connection_Handler (ACE_Thread_Manager *t)
00025 : TAO_IIOP_SVC_HANDLER (t, 0 , 0),
00026 TAO_Connection_Handler (0),
00027 dscp_codepoint_ (IPDSFIELD_DSCP_DEFAULT << 2)
00028 {
00029
00030
00031
00032
00033
00034 ACE_ASSERT (0);
00035 }
00036
00037
00038 TAO_IIOP_Connection_Handler::TAO_IIOP_Connection_Handler (
00039 TAO_ORB_Core *orb_core,
00040 CORBA::Boolean flag)
00041 : TAO_IIOP_SVC_HANDLER (orb_core->thr_mgr (), 0, 0),
00042 TAO_Connection_Handler (orb_core),
00043 dscp_codepoint_ (IPDSFIELD_DSCP_DEFAULT << 2)
00044 {
00045 TAO_IIOP_Transport* specific_transport = 0;
00046 ACE_NEW (specific_transport,
00047 TAO_IIOP_Transport (this, orb_core, flag));
00048
00049
00050 this->transport (specific_transport);
00051 }
00052
00053 TAO_IIOP_Connection_Handler::TAO_IIOP_Connection_Handler (TAO_ORB_Core *orb_core)
00054 : TAO_IIOP_SVC_HANDLER (orb_core->thr_mgr (), 0, 0),
00055 TAO_Connection_Handler (orb_core),
00056 dscp_codepoint_ (IPDSFIELD_DSCP_DEFAULT << 2)
00057 {
00058 }
00059
00060 TAO_IIOP_Connection_Handler::~TAO_IIOP_Connection_Handler (void)
00061 {
00062 delete this->transport ();
00063 }
00064
00065
00066
00067
00068
00069
00070
00071
00072 int
00073 TAO_IIOP_Connection_Handler::open_handler (void *v)
00074 {
00075 return this->open (v);
00076 }
00077
00078 int
00079 TAO_IIOP_Connection_Handler::open (void*)
00080 {
00081 TAO_IIOP_Protocol_Properties protocol_properties;
00082
00083
00084 protocol_properties.send_buffer_size_ =
00085 this->orb_core ()->orb_params ()->sock_sndbuf_size ();
00086 protocol_properties.recv_buffer_size_ =
00087 this->orb_core ()->orb_params ()->sock_rcvbuf_size ();
00088 protocol_properties.no_delay_ =
00089 this->orb_core ()->orb_params ()->nodelay ();
00090 protocol_properties.keep_alive_ =
00091 this->orb_core ()->orb_params ()->sock_keepalive ();
00092 protocol_properties.dont_route_ =
00093 this->orb_core ()->orb_params ()->sock_dontroute ();
00094
00095 TAO_Protocols_Hooks *tph =
00096 this->orb_core ()->get_protocols_hooks ();
00097
00098 bool const client =
00099 this->transport ()->opened_as () == TAO::TAO_CLIENT_ROLE;
00100
00101 ACE_DECLARE_NEW_CORBA_ENV;
00102
00103 ACE_TRY
00104 {
00105 if (client)
00106 {
00107 tph->client_protocol_properties_at_orb_level (
00108 protocol_properties
00109 ACE_ENV_ARG_PARAMETER);
00110 ACE_TRY_CHECK;
00111 }
00112 else
00113 {
00114 tph->server_protocol_properties_at_orb_level (
00115 protocol_properties
00116 ACE_ENV_ARG_PARAMETER);
00117 ACE_TRY_CHECK;
00118 }
00119 }
00120 ACE_CATCHANY
00121 {
00122 return -1;
00123 }
00124 ACE_ENDTRY;
00125 ACE_CHECK_RETURN (-1);
00126
00127 if (this->set_socket_option (this->peer (),
00128 protocol_properties.send_buffer_size_,
00129 protocol_properties.recv_buffer_size_) == -1)
00130 return -1;
00131
00132 #if !defined (ACE_LACKS_TCP_NODELAY)
00133 if (this->peer ().set_option (ACE_IPPROTO_TCP,
00134 TCP_NODELAY,
00135 (void *) &protocol_properties.no_delay_,
00136 sizeof (protocol_properties.no_delay_)) == -1)
00137 return -1;
00138 #endif
00139
00140 if (protocol_properties.keep_alive_)
00141 {
00142 if (this->peer ().
00143 set_option (SOL_SOCKET,
00144 SO_KEEPALIVE,
00145 (void *) &protocol_properties.keep_alive_,
00146 sizeof (protocol_properties.keep_alive_)) == -1
00147 && errno != ENOTSUP)
00148 {
00149 return -1;
00150 }
00151 }
00152
00153 #if !defined (ACE_LACKS_SO_DONTROUTE)
00154 if (protocol_properties.dont_route_)
00155 {
00156 if (this->peer ().
00157 set_option (SOL_SOCKET,
00158 SO_DONTROUTE,
00159 (void *) &protocol_properties.dont_route_,
00160 sizeof (protocol_properties.dont_route_)) == -1
00161 && errno != ENOTSUP)
00162 {
00163 return -1;
00164 }
00165 }
00166 #endif
00167
00168 if (this->transport ()->wait_strategy ()->non_blocking ()
00169 || this->transport ()->opened_as () == TAO::TAO_SERVER_ROLE)
00170 {
00171 if (this->peer ().enable (ACE_NONBLOCK) == -1)
00172 return -1;
00173 }
00174
00175
00176
00177
00178 ACE_INET_Addr remote_addr;
00179 if (this->peer ().get_remote_addr (remote_addr) == -1)
00180 return -1;
00181
00182 ACE_INET_Addr local_addr;
00183 if (this->peer ().get_local_addr (local_addr) == -1)
00184 return -1;
00185
00186 if (TAO_debug_level > 2)
00187 ACE_DEBUG ((LM_DEBUG,
00188 ACE_TEXT("TAO (%P|%t) - IIOP_Connection_Handler::open, ")
00189 ACE_TEXT("The local addr is <%s:%d> \n"),
00190 local_addr.get_host_addr (),
00191 local_addr.get_port_number()));
00192
00193 if (local_addr == remote_addr)
00194 {
00195 if (TAO_debug_level > 0)
00196 {
00197 ACE_TCHAR remote_as_string[MAXHOSTNAMELEN + 16];
00198 ACE_TCHAR local_as_string[MAXHOSTNAMELEN + 16];
00199
00200 (void) remote_addr.addr_to_string (remote_as_string,
00201 sizeof(remote_as_string));
00202 (void) local_addr.addr_to_string (local_as_string,
00203 sizeof(local_as_string));
00204 ACE_ERROR ((LM_ERROR,
00205 ACE_TEXT("TAO(%P|%t) - IIOP_Connection_Handler::open, ")
00206 ACE_TEXT("Holy Cow! The remote addr and ")
00207 ACE_TEXT("local addr are identical (%s == %s)\n"),
00208 remote_as_string, local_as_string));
00209 }
00210 return -1;
00211 }
00212
00213 #if defined (ACE_HAS_IPV6) && !defined (ACE_HAS_IPV6_V6ONLY)
00214
00215
00216 if (this->orb_core ()->orb_params ()->connect_ipv6_only () &&
00217 remote_addr.is_ipv4_mapped_ipv6 ())
00218 {
00219 if (TAO_debug_level > 0)
00220 {
00221 ACE_TCHAR remote_as_string[MAXHOSTNAMELEN + 16];
00222
00223 (void) remote_addr.addr_to_string (remote_as_string,
00224 sizeof(remote_as_string));
00225
00226 ACE_ERROR ((LM_WARNING,
00227 ACE_TEXT("TAO (%P|%t) - IIOP_Connection_Handler::open, ")
00228 ACE_TEXT("invalid connection from IPv4 mapped IPv6 interface <%s>!\n"),
00229 remote_as_string));
00230 }
00231 return -1;
00232 }
00233 #endif
00234
00235 if (TAO_debug_level > 0)
00236 {
00237 ACE_TCHAR client_addr[MAXHOSTNAMELEN + 16];
00238
00239
00240 if (remote_addr.addr_to_string (client_addr, sizeof (client_addr)) == -1)
00241 return -1;
00242
00243 ACE_DEBUG ((LM_DEBUG,
00244 ACE_TEXT ("TAO (%P|%t) - IIOP_Connection_Handler::open, IIOP ")
00245 ACE_TEXT ("connection to peer <%s> on %d\n"),
00246 client_addr, 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_IIOP_Connection_Handler::resume_handler (void)
00263 {
00264 return ACE_Event_Handler::ACE_APPLICATION_RESUMES_HANDLER;
00265 }
00266
00267 int
00268 TAO_IIOP_Connection_Handler::close_connection (void)
00269 {
00270
00271
00272 int linger = this->orb_core()->orb_params()->linger ();
00273 if (linger != -1)
00274 {
00275 struct linger lval;
00276 lval.l_onoff = 1;
00277 lval.l_linger = (u_short)linger;
00278
00279 if (this->peer ().set_option(SOL_SOCKET,
00280 SO_LINGER,
00281 (void*) &lval,
00282 sizeof (lval)) == -1)
00283 {
00284 if (TAO_debug_level)
00285 {
00286 ACE_DEBUG ((LM_DEBUG,
00287 ACE_TEXT ("TAO (%P|%t) Unable to set ")
00288 ACE_TEXT ("SO_LINGER on %d\n"),
00289 this->peer ().get_handle ()));
00290 }
00291 }
00292 }
00293
00294 return this->close_connection_eh (this);
00295 }
00296
00297 int
00298 TAO_IIOP_Connection_Handler::handle_input (ACE_HANDLE h)
00299 {
00300 return this->handle_input_eh (h, this);
00301 }
00302
00303 int
00304 TAO_IIOP_Connection_Handler::handle_output (ACE_HANDLE handle)
00305 {
00306 const int result =
00307 this->handle_output_eh (handle, this);
00308
00309 if (result == -1)
00310 {
00311 this->close_connection ();
00312 return 0;
00313 }
00314
00315 return result;
00316 }
00317
00318 int
00319 TAO_IIOP_Connection_Handler::handle_timeout (const ACE_Time_Value &,
00320 const void *)
00321 {
00322
00323
00324
00325 return this->close ();
00326 }
00327
00328 int
00329 TAO_IIOP_Connection_Handler::handle_close (ACE_HANDLE,
00330 ACE_Reactor_Mask)
00331 {
00332 ACE_ASSERT (0);
00333 return 0;
00334 }
00335
00336 int
00337 TAO_IIOP_Connection_Handler::close (u_long)
00338 {
00339 return this->close_handler ();
00340 }
00341
00342 int
00343 TAO_IIOP_Connection_Handler::release_os_resources (void)
00344 {
00345 return this->peer ().close ();
00346 }
00347
00348 int
00349 TAO_IIOP_Connection_Handler::add_transport_to_cache (void)
00350 {
00351 ACE_INET_Addr addr;
00352
00353
00354 if (this->peer ().get_remote_addr (addr) == -1)
00355 return -1;
00356
00357
00358 TAO_IIOP_Endpoint endpoint (
00359 addr,
00360 this->orb_core()->orb_params()->cache_incoming_by_dotted_decimal_address ());
00361
00362
00363 TAO_Base_Transport_Property prop (&endpoint);
00364
00365 TAO::Transport_Cache_Manager &cache =
00366 this->orb_core ()->lane_resources ().transport_cache ();
00367
00368
00369 return cache.cache_idle_transport (&prop,
00370 this->transport ());
00371 }
00372
00373 int
00374 TAO_IIOP_Connection_Handler::process_listen_point_list (
00375 IIOP::ListenPointList &listen_list)
00376 {
00377
00378 const CORBA::ULong len = listen_list.length ();
00379
00380 if (TAO_debug_level > 0 && len == 0)
00381 {
00382 ACE_ERROR ((LM_ERROR,
00383 ACE_TEXT("TAO (%P|%t) - IIOP_Connection_Handler::")
00384 ACE_TEXT("process_listen_point_list, ")
00385 ACE_TEXT("Received list of size 0, check client config.\n")));
00386 }
00387
00388 for (CORBA::ULong i = 0; i < len; ++i)
00389 {
00390 IIOP::ListenPoint listen_point = listen_list[i];
00391 ACE_INET_Addr addr (listen_point.port,
00392 listen_point.host.in ());
00393
00394 if (TAO_debug_level > 0)
00395 {
00396 ACE_DEBUG ((LM_DEBUG,
00397 ACE_TEXT("TAO (%P|%t) - IIOP_Connection_Handler::")
00398 ACE_TEXT("process_listen_point_list, ")
00399 ACE_TEXT("Listening port [%d] on [%s]\n"),
00400 listen_point.port,
00401 ACE_TEXT_CHAR_TO_TCHAR(listen_point.host.in ())));
00402 }
00403
00404
00405
00406
00407
00408 TAO_IIOP_Endpoint endpoint (listen_point.host.in (),
00409 listen_point.port, addr);
00410
00411
00412 TAO_Base_Transport_Property prop (&endpoint);
00413
00414
00415 prop.set_bidir_flag (1);
00416
00417
00418
00419 int retval =
00420 this->transport ()->recache_transport (&prop);
00421
00422 if (retval == -1)
00423 return retval;
00424
00425
00426 this->transport ()->make_idle ();
00427 }
00428
00429 return 0;
00430 }
00431
00432 int
00433 TAO_IIOP_Connection_Handler::set_dscp_codepoint (CORBA::Boolean set_network_priority)
00434 {
00435 int tos = IPDSFIELD_DSCP_DEFAULT << 2;
00436
00437 if (set_network_priority)
00438 {
00439 TAO_Protocols_Hooks *tph =
00440 this->orb_core ()->get_protocols_hooks ();
00441
00442 CORBA::Long codepoint =
00443 tph->get_dscp_codepoint ();
00444
00445 tos = static_cast<int> (codepoint) << 2;
00446 }
00447
00448 if (tos != this->dscp_codepoint_)
00449 {
00450 int result = 0;
00451 #if defined (ACE_HAS_IPV6)
00452 ACE_INET_Addr local_addr;
00453 if (this->peer ().get_local_addr (local_addr) == -1)
00454 return -1;
00455 else if (local_addr.get_type () == AF_INET6)
00456 # if !defined (IPV6_TCLASS)
00457
00458
00459 {
00460 if (TAO_debug_level)
00461 {
00462 ACE_DEBUG ((LM_DEBUG,
00463 "TAO (%P|%t) - IIOP_Connection_Handler::"
00464 "set_dscp_codepoint -> IPV6_TCLASS not supported yet\n"));
00465 }
00466 return 0;
00467 }
00468 # else
00469 result = this->peer ().set_option (IPPROTO_IPV6,
00470 IPV6_TCLASS,
00471 (int *) &tos ,
00472 (int) sizeof (tos));
00473 else
00474 # endif
00475 #endif
00476 result = this->peer ().set_option (IPPROTO_IP,
00477 IP_TOS,
00478 (int *) &tos ,
00479 (int) sizeof (tos));
00480
00481 if (TAO_debug_level)
00482 {
00483 ACE_DEBUG ((LM_DEBUG,
00484 "TAO (%P|%t) - IIOP_Connection_Handler::"
00485 "set_dscp_codepoint -> dscp: %x; result: %d; %s\n",
00486 tos,
00487 result,
00488 result == -1 ? "try running as superuser" : ""));
00489 }
00490
00491
00492 if (result == 0)
00493 this->dscp_codepoint_ = tos;
00494
00495 }
00496
00497 return 0;
00498 }
00499
00500 void
00501 TAO_IIOP_Connection_Handler::abort (void)
00502 {
00503 struct linger lval;
00504 lval.l_onoff = 1;
00505 lval.l_linger = 0;
00506
00507 if (this->peer ().set_option(SOL_SOCKET,
00508 SO_LINGER,
00509 (void*) &lval,
00510 sizeof (lval)) == -1)
00511 {
00512 if (TAO_debug_level)
00513 {
00514 ACE_DEBUG ((LM_DEBUG,
00515 ACE_TEXT ("TAO (%P|%t) Unable to set ")
00516 ACE_TEXT ("SO_LINGER on %d\n"),
00517 this->peer ().get_handle ()));
00518 }
00519 }
00520 }
00521
00522
00523
00524
00525
00526
00527
00528
00529 TAO_END_VERSIONED_NAMESPACE_DECL
00530
00531 #endif