00001
00002 #include "tao/IIOP_Connection_Handler.h"
00003
00004 #if defined (TAO_HAS_IIOP) && (TAO_HAS_IIOP != 0)
00005
00006 #include "tao/debug.h"
00007 #include "tao/ORB_Core.h"
00008 #include "tao/IIOP_Transport.h"
00009 #include "tao/IIOP_Endpoint.h"
00010 #include "tao/IIOPC.h"
00011 #include "tao/Thread_Lane_Resources.h"
00012 #include "tao/Base_Transport_Property.h"
00013 #include "tao/Protocols_Hooks.h"
00014 #include "tao/Wait_Strategy.h"
00015
00016 #include "ace/os_include/netinet/os_tcp.h"
00017 #include "ace/os_include/os_netdb.h"
00018
00019 ACE_RCSID (tao,
00020 IIOP_Connection_Handler,
00021 "$Id: IIOP_Connection_Handler.cpp 85817 2009-06-26 20:44:58Z mitza $")
00022
00023 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00024
00025
00026 #ifdef TAO_LOG_CH_REF_COUNTS
00027 ACE_Event_Handler::Reference_Count
00028 TAO_IIOP_Connection_Handler::add_reference (void)
00029 {
00030 Reference_Count rc = TAO_IIOP_SVC_HANDLER::add_reference ();
00031 if (TAO_debug_level > 9)
00032 {
00033 ACE_DEBUG ((LM_DEBUG,
00034 ACE_TEXT("TAO (%P|%t) - IIOP_Connection_Handler[%d]::")
00035 ACE_TEXT("add_reference, up to %d\n"),
00036 this->transport (), rc));
00037 }
00038 return rc;
00039
00040 }
00041
00042 ACE_Event_Handler::Reference_Count
00043 TAO_IIOP_Connection_Handler::remove_reference (void)
00044 {
00045 TAO_Transport *tport = this->transport ();
00046 Reference_Count rc = TAO_IIOP_SVC_HANDLER::remove_reference ();
00047 if (TAO_debug_level > 9)
00048 {
00049 ACE_DEBUG ((LM_DEBUG,
00050 ACE_TEXT("TAO (%P|%t) - IIOP_Connection_Handler[%d]::")
00051 ACE_TEXT("remove_reference, down to %d\n"), tport, rc));
00052 }
00053 return rc;
00054 }
00055 #endif
00056
00057
00058 TAO_IIOP_Connection_Handler::TAO_IIOP_Connection_Handler (ACE_Thread_Manager *t)
00059 : TAO_IIOP_SVC_HANDLER (t, 0 , 0),
00060 TAO_Connection_Handler (0),
00061 dscp_codepoint_ (IPDSFIELD_DSCP_DEFAULT << 2)
00062 {
00063
00064
00065
00066
00067
00068 ACE_ASSERT (0);
00069 }
00070
00071
00072 TAO_IIOP_Connection_Handler::TAO_IIOP_Connection_Handler (
00073 TAO_ORB_Core *orb_core)
00074 : TAO_IIOP_SVC_HANDLER (orb_core->thr_mgr (), 0, 0),
00075 TAO_Connection_Handler (orb_core),
00076 dscp_codepoint_ (IPDSFIELD_DSCP_DEFAULT << 2)
00077 {
00078 TAO_IIOP_Transport* specific_transport = 0;
00079 ACE_NEW (specific_transport,
00080 TAO_IIOP_Transport (this, orb_core));
00081
00082 if (TAO_debug_level > 9)
00083 {
00084 ACE_DEBUG ((LM_DEBUG,
00085 ACE_TEXT("TAO (%P|%t) - IIOP_Connection_Handler[%d] ctor, ")
00086 ACE_TEXT("this=%@\n"),
00087 static_cast<TAO_Transport *> (specific_transport), this));
00088 }
00089
00090
00091 this->transport (specific_transport);
00092 }
00093
00094 TAO_IIOP_Connection_Handler::~TAO_IIOP_Connection_Handler (void)
00095 {
00096 delete this->transport ();
00097 int const result =
00098 this->release_os_resources ();
00099
00100 if (result == -1 && TAO_debug_level)
00101 {
00102 ACE_ERROR ((LM_ERROR,
00103 ACE_TEXT("TAO (%P|%t) - IIOP_Connection_Handler::")
00104 ACE_TEXT("~IIOP_Connection_Handler, ")
00105 ACE_TEXT("release_os_resources() failed %m\n")));
00106 }
00107 }
00108
00109
00110
00111
00112
00113
00114
00115
00116 int
00117 TAO_IIOP_Connection_Handler::open_handler (void *v)
00118 {
00119 return this->open (v);
00120 }
00121
00122 int
00123 TAO_IIOP_Connection_Handler::open (void*)
00124 {
00125 if (this->shared_open() == -1)
00126 return -1;
00127
00128 TAO_IIOP_Protocol_Properties protocol_properties;
00129
00130
00131 protocol_properties.send_buffer_size_ =
00132 this->orb_core ()->orb_params ()->sock_sndbuf_size ();
00133 protocol_properties.recv_buffer_size_ =
00134 this->orb_core ()->orb_params ()->sock_rcvbuf_size ();
00135 protocol_properties.no_delay_ =
00136 this->orb_core ()->orb_params ()->nodelay ();
00137 protocol_properties.keep_alive_ =
00138 this->orb_core ()->orb_params ()->sock_keepalive ();
00139 protocol_properties.dont_route_ =
00140 this->orb_core ()->orb_params ()->sock_dontroute ();
00141 protocol_properties.hop_limit_ =
00142 this->orb_core ()->orb_params ()->ip_hoplimit ();
00143
00144 TAO_Protocols_Hooks *tph = this->orb_core ()->get_protocols_hooks ();
00145
00146 if (tph != 0)
00147 {
00148 try
00149 {
00150 if (this->transport ()->opened_as () == TAO::TAO_CLIENT_ROLE)
00151 {
00152 tph->client_protocol_properties_at_orb_level (protocol_properties);
00153 }
00154 else
00155 {
00156 tph->server_protocol_properties_at_orb_level (protocol_properties);
00157 }
00158 }
00159 catch (const ::CORBA::Exception&)
00160 {
00161 return -1;
00162 }
00163 }
00164
00165 if (this->set_socket_option (this->peer (),
00166 protocol_properties.send_buffer_size_,
00167 protocol_properties.recv_buffer_size_) == -1)
00168 {
00169 return -1;
00170 }
00171
00172 #if !defined (ACE_LACKS_TCP_NODELAY)
00173 if (this->peer ().set_option (ACE_IPPROTO_TCP,
00174 TCP_NODELAY,
00175 (void *) &protocol_properties.no_delay_,
00176 sizeof (protocol_properties.no_delay_)) == -1)
00177 return -1;
00178 #endif
00179
00180 if (protocol_properties.keep_alive_)
00181 {
00182 if (this->peer ().
00183 set_option (SOL_SOCKET,
00184 SO_KEEPALIVE,
00185 (void *) &protocol_properties.keep_alive_,
00186 sizeof (protocol_properties.keep_alive_)) == -1
00187 && errno != ENOTSUP)
00188 {
00189 return -1;
00190 }
00191 }
00192
00193 #if !defined (ACE_LACKS_SO_DONTROUTE)
00194 if (protocol_properties.dont_route_)
00195 {
00196 if (this->peer ().
00197 set_option (SOL_SOCKET,
00198 SO_DONTROUTE,
00199 (void *) &protocol_properties.dont_route_,
00200 sizeof (protocol_properties.dont_route_)) == -1
00201 && errno != ENOTSUP)
00202 {
00203 return -1;
00204 }
00205 }
00206 #endif
00207
00208 if (protocol_properties.hop_limit_ >= 0)
00209 {
00210 int result = 0;
00211 #if defined (ACE_HAS_IPV6)
00212 ACE_INET_Addr local_addr;
00213 if (this->peer ().get_local_addr (local_addr) == -1)
00214 {
00215 result = -1;
00216 }
00217 else if (local_addr.get_type () == AF_INET6)
00218 {
00219 #if defined (ACE_WIN32)
00220 DWORD hop_limit =
00221 static_cast<DWORD> (protocol_properties.hop_limit_);
00222 #else
00223 int hop_limit =
00224 static_cast<int> (protocol_properties.hop_limit_);
00225 #endif
00226 result = this->peer ().set_option (
00227 IPPROTO_IPV6,
00228 IPV6_UNICAST_HOPS,
00229 (void *) &hop_limit,
00230 sizeof (hop_limit));
00231 }
00232 else
00233 #endif
00234 {
00235 #if defined (ACE_WIN32)
00236 DWORD hop_limit =
00237 static_cast<DWORD> (protocol_properties.hop_limit_);
00238 #else
00239 int hop_limit =
00240 static_cast<int> (protocol_properties.hop_limit_);
00241 #endif
00242 result = this->peer ().set_option (
00243 IPPROTO_IP,
00244 IP_TTL,
00245 (void *) &hop_limit,
00246 sizeof (hop_limit));
00247 }
00248
00249 if (result != 0)
00250 {
00251 if (TAO_debug_level)
00252 {
00253 ACE_ERROR ((LM_ERROR,
00254 ACE_TEXT("TAO (%P|%t) - IIOP_Connection_Handler::open, ")
00255 ACE_TEXT("couldn't set hop limit\n\n")));
00256 }
00257 return -1;
00258 }
00259 }
00260
00261 if (this->transport ()->wait_strategy ()->non_blocking ()
00262 || this->transport ()->opened_as () == TAO::TAO_SERVER_ROLE)
00263 {
00264 if (this->peer ().enable (ACE_NONBLOCK) == -1)
00265 return -1;
00266 }
00267
00268
00269
00270
00271 ACE_INET_Addr remote_addr;
00272 if (this->peer ().get_remote_addr (remote_addr) == -1)
00273 return -1;
00274
00275 ACE_INET_Addr local_addr;
00276 if (this->peer ().get_local_addr (local_addr) == -1)
00277 return -1;
00278
00279 if (TAO_debug_level > 2)
00280 ACE_DEBUG ((LM_DEBUG,
00281 ACE_TEXT("TAO (%P|%t) - IIOP_Connection_Handler::open, ")
00282 ACE_TEXT("The local addr is <%C:%d>\n"),
00283 local_addr.get_host_addr (),
00284 local_addr.get_port_number()));
00285
00286 if (local_addr == remote_addr)
00287 {
00288 if (TAO_debug_level > 0)
00289 {
00290 ACE_TCHAR remote_as_string[MAXHOSTNAMELEN + 16];
00291 ACE_TCHAR local_as_string[MAXHOSTNAMELEN + 16];
00292
00293 (void) remote_addr.addr_to_string (remote_as_string,
00294 sizeof(remote_as_string));
00295 (void) local_addr.addr_to_string (local_as_string,
00296 sizeof(local_as_string));
00297 ACE_ERROR ((LM_ERROR,
00298 ACE_TEXT("TAO(%P|%t) - IIOP_Connection_Handler::open, ")
00299 ACE_TEXT("Holy Cow! The remote addr and ")
00300 ACE_TEXT("local addr are identical (%s == %s)\n"),
00301 remote_as_string, local_as_string));
00302 }
00303 return -1;
00304 }
00305
00306 #if defined (ACE_HAS_IPV6) && !defined (ACE_HAS_IPV6_V6ONLY)
00307
00308
00309 if (this->orb_core ()->orb_params ()->connect_ipv6_only () &&
00310 remote_addr.is_ipv4_mapped_ipv6 ())
00311 {
00312 if (TAO_debug_level > 0)
00313 {
00314 ACE_TCHAR remote_as_string[MAXHOSTNAMELEN + 16];
00315
00316 (void) remote_addr.addr_to_string (remote_as_string,
00317 sizeof(remote_as_string));
00318
00319 ACE_ERROR ((LM_ERROR,
00320 ACE_TEXT("TAO (%P|%t) - IIOP_Connection_Handler::open, ")
00321 ACE_TEXT("invalid connection from IPv4 mapped IPv6 interface <%s>!\n"),
00322 remote_as_string));
00323 }
00324 return -1;
00325 }
00326 #endif
00327
00328 if (TAO_debug_level > 0)
00329 {
00330 ACE_TCHAR client_addr[MAXHOSTNAMELEN + 16];
00331
00332
00333 if (remote_addr.addr_to_string (client_addr, sizeof (client_addr)) == -1)
00334 return -1;
00335
00336 ACE_DEBUG ((LM_DEBUG,
00337 ACE_TEXT ("TAO (%P|%t) - IIOP_Connection_Handler::open, IIOP ")
00338 ACE_TEXT ("connection to peer <%s> on %d\n"),
00339 client_addr, this->peer ().get_handle ()));
00340 }
00341
00342
00343
00344
00345 if (!this->transport ()->post_open ((size_t) this->get_handle ()))
00346 return -1;
00347 this->state_changed (TAO_LF_Event::LFS_SUCCESS,
00348 this->orb_core ()->leader_follower ());
00349
00350 return 0;
00351 }
00352
00353 int
00354 TAO_IIOP_Connection_Handler::resume_handler (void)
00355 {
00356 return ACE_Event_Handler::ACE_APPLICATION_RESUMES_HANDLER;
00357 }
00358
00359 int
00360 TAO_IIOP_Connection_Handler::close_connection (void)
00361 {
00362
00363
00364 int const linger = this->orb_core()->orb_params()->linger ();
00365 if (linger != -1)
00366 {
00367 struct linger lval;
00368 lval.l_onoff = 1;
00369 lval.l_linger = (u_short)linger;
00370 if (this->peer ().set_option(SOL_SOCKET,
00371 SO_LINGER,
00372 (void*) &lval,
00373 sizeof (lval)) == -1)
00374 {
00375 if (TAO_debug_level)
00376 {
00377 ACE_DEBUG ((LM_DEBUG,
00378 ACE_TEXT ("TAO (%P|%t) Unable to set ")
00379 ACE_TEXT ("SO_LINGER on %d\n"),
00380 this->peer ().get_handle ()));
00381 }
00382 }
00383 }
00384
00385 return this->close_connection_eh (this);
00386 }
00387
00388 int
00389 TAO_IIOP_Connection_Handler::handle_input (ACE_HANDLE h)
00390 {
00391 return this->handle_input_eh (h, this);
00392 }
00393
00394 int
00395 TAO_IIOP_Connection_Handler::handle_output (ACE_HANDLE handle)
00396 {
00397 int const result = this->handle_output_eh (handle, this);
00398
00399 if (result == -1)
00400 {
00401 this->close_connection ();
00402 return 0;
00403 }
00404
00405 return result;
00406 }
00407
00408
00409 int
00410 TAO_IIOP_Connection_Handler::handle_timeout (const ACE_Time_Value &,
00411 const void *)
00412 {
00413
00414
00415
00416
00417
00418
00419 TAO_Auto_Reference<TAO_IIOP_Connection_Handler> safeguard (*this);
00420
00421
00422
00423
00424
00425
00426
00427
00428 int const ret = this->close ();
00429 this->reset_state (TAO_LF_Event::LFS_TIMEOUT);
00430 if (TAO_debug_level > 9)
00431 {
00432 ACE_DEBUG ((LM_DEBUG, "TAO (%P|%t) - TAO_IIOP_Connection_Handler[%d]::"
00433 "handle_timeout reset state to LFS_TIMEOUT\n",
00434 this->transport ()-> id()));
00435 }
00436 return ret;
00437 }
00438
00439 int
00440 TAO_IIOP_Connection_Handler::handle_close (ACE_HANDLE, ACE_Reactor_Mask)
00441 {
00442 ACE_ASSERT (0);
00443 return 0;
00444 }
00445
00446 int
00447 TAO_IIOP_Connection_Handler::close (u_long flags)
00448 {
00449 return this->close_handler (flags);
00450 }
00451
00452 int
00453 TAO_IIOP_Connection_Handler::release_os_resources (void)
00454 {
00455 return this->peer ().close ();
00456 }
00457
00458 int
00459 TAO_IIOP_Connection_Handler::add_transport_to_cache (void)
00460 {
00461 ACE_INET_Addr addr;
00462
00463
00464 if (this->peer ().get_remote_addr (addr) == -1)
00465 return -1;
00466
00467
00468 TAO_IIOP_Endpoint endpoint (
00469 addr,
00470 this->orb_core()->orb_params()->cache_incoming_by_dotted_decimal_address ());
00471
00472
00473 TAO_Base_Transport_Property prop (&endpoint);
00474
00475 TAO::Transport_Cache_Manager &cache =
00476 this->orb_core ()->lane_resources ().transport_cache ();
00477
00478
00479 return cache.cache_transport (&prop, this->transport ());
00480 }
00481
00482 int
00483 TAO_IIOP_Connection_Handler::process_listen_point_list (
00484 IIOP::ListenPointList &listen_list)
00485 {
00486
00487 CORBA::ULong len = listen_list.length ();
00488
00489 if (TAO_debug_level > 0 && len == 0)
00490 {
00491 ACE_ERROR ((LM_ERROR,
00492 ACE_TEXT("TAO (%P|%t) - IIOP_Connection_Handler::")
00493 ACE_TEXT("process_listen_point_list, ")
00494 ACE_TEXT("Received list of size 0, check client config.\n")));
00495 }
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514 len = 1;
00515 for (CORBA::ULong i = 0; i < len; ++i)
00516 {
00517 IIOP::ListenPoint listen_point = listen_list[i];
00518
00519
00520
00521
00522
00523 ACE_INET_Addr addr;
00524 (void)addr.set(listen_point.port, listen_point.host.in ());
00525
00526 if (TAO_debug_level > 0)
00527 {
00528 ACE_DEBUG ((LM_DEBUG,
00529 ACE_TEXT("TAO (%P|%t) - IIOP_Connection_Handler::")
00530 ACE_TEXT("process_listen_point_list, ")
00531 ACE_TEXT("Listening port [%d] on [%C]\n"),
00532 listen_point.port,
00533 listen_point.host.in ()));
00534 }
00535
00536
00537
00538
00539
00540 TAO_IIOP_Endpoint endpoint (listen_point.host.in (),
00541 listen_point.port, addr);
00542
00543
00544 TAO_Base_Transport_Property prop (&endpoint);
00545
00546
00547 prop.set_bidir_flag (1);
00548
00549
00550
00551 if (this->transport ()->recache_transport (&prop) == -1)
00552 return -1;
00553
00554
00555 this->transport ()->make_idle ();
00556 }
00557
00558 return 0;
00559 }
00560
00561 int
00562 TAO_IIOP_Connection_Handler::set_tos (int tos)
00563 {
00564 if (tos != this->dscp_codepoint_)
00565 {
00566 int result = 0;
00567 #if defined (ACE_HAS_IPV6)
00568 ACE_INET_Addr local_addr;
00569 if (this->peer ().get_local_addr (local_addr) == -1)
00570 return -1;
00571 else if (local_addr.get_type () == AF_INET6)
00572 # if !defined (IPV6_TCLASS)
00573
00574
00575 {
00576 if (TAO_debug_level)
00577 {
00578 ACE_DEBUG ((LM_DEBUG,
00579 ACE_TEXT("TAO (%P|%t) - IIOP_Connection_Handler::")
00580 ACE_TEXT("set_dscp_codepoint -> IPV6_TCLASS not supported yet\n")));
00581 }
00582 return 0;
00583 }
00584 # else
00585 result = this->peer ().set_option (IPPROTO_IPV6,
00586 IPV6_TCLASS,
00587 (int *) &tos ,
00588 (int) sizeof (tos));
00589 else
00590 # endif
00591 #endif
00592 result = this->peer ().set_option (IPPROTO_IP,
00593 IP_TOS,
00594 (int *) &tos ,
00595 (int) sizeof (tos));
00596
00597 if (TAO_debug_level)
00598 {
00599 ACE_DEBUG ((LM_DEBUG,
00600 ACE_TEXT("TAO (%P|%t) - IIOP_Connection_Handler::")
00601 ACE_TEXT("set_dscp_codepoint -> dscp: %x; result: %d; %C\n"),
00602 tos,
00603 result,
00604 result == -1 ? "try running as superuser" : ""));
00605 }
00606
00607
00608 if (result == 0)
00609 this->dscp_codepoint_ = tos;
00610 }
00611 return 0;
00612 }
00613
00614 int
00615 TAO_IIOP_Connection_Handler::set_dscp_codepoint (CORBA::Long dscp_codepoint)
00616 {
00617 int tos = IPDSFIELD_DSCP_DEFAULT << 2;
00618
00619 CORBA::Long codepoint = dscp_codepoint;
00620
00621 tos = static_cast<int> (codepoint) << 2;
00622
00623 this->set_tos (tos);
00624
00625 return 0;
00626 }
00627
00628 int
00629 TAO_IIOP_Connection_Handler::set_dscp_codepoint (CORBA::Boolean set_network_priority)
00630 {
00631 int tos = IPDSFIELD_DSCP_DEFAULT << 2;
00632
00633 if (set_network_priority)
00634 {
00635 TAO_Protocols_Hooks *tph = this->orb_core ()->get_protocols_hooks ();
00636
00637 if (tph != 0)
00638 {
00639 CORBA::Long codepoint = tph->get_dscp_codepoint ();
00640
00641 tos = static_cast<int> (codepoint) << 2;
00642 this->set_tos (tos);
00643 }
00644 }
00645
00646 return 0;
00647 }
00648
00649 void
00650 TAO_IIOP_Connection_Handler::abort (void)
00651 {
00652 struct linger lval;
00653 lval.l_onoff = 1;
00654 lval.l_linger = 0;
00655
00656 if (this->peer ().set_option(SOL_SOCKET,
00657 SO_LINGER,
00658 (void*) &lval,
00659 sizeof (lval)) == -1)
00660 {
00661 if (TAO_debug_level)
00662 {
00663 ACE_DEBUG ((LM_DEBUG,
00664 ACE_TEXT ("TAO (%P|%t) Unable to set ")
00665 ACE_TEXT ("SO_LINGER on %d\n"),
00666 this->peer ().get_handle ()));
00667 }
00668 }
00669 }
00670
00671 int
00672 TAO_IIOP_Connection_Handler::handle_write_ready (const ACE_Time_Value *timeout)
00673 {
00674 return ACE::handle_write_ready (this->peer ().get_handle (), timeout);
00675 }
00676
00677
00678
00679
00680
00681
00682
00683 TAO_END_VERSIONED_NAMESPACE_DECL
00684
00685 #endif