00001
00002
00003
00004
00005
00006 #include "orbsvcs/PortableGroup/UIPMC_Connection_Handler.h"
00007 #include "orbsvcs/PortableGroup/UIPMC_Endpoint.h"
00008
00009 #include "tao/Timeprobe.h"
00010 #include "tao/debug.h"
00011 #include "tao/ORB_Core.h"
00012 #include "tao/ORB.h"
00013 #include "tao/CDR.h"
00014 #include "tao/Server_Strategy_Factory.h"
00015 #include "tao/Transport_Cache_Manager.h"
00016 #include "tao/Thread_Lane_Resources.h"
00017 #include "tao/Base_Transport_Property.h"
00018 #include "tao/Resume_Handle.h"
00019 #include "tao/Protocols_Hooks.h"
00020
00021
00022 ACE_RCSID(PortableGroup,
00023 UIPMC_Connection_Handler,
00024 "$Id: UIPMC_Connection_Handler.cpp 85817 2009-06-26 20:44:58Z mitza $")
00025
00026 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00027
00028 TAO_UIPMC_Connection_Handler::TAO_UIPMC_Connection_Handler (ACE_Thread_Manager *t)
00029 : TAO_UIPMC_SVC_HANDLER (t, 0 , 0),
00030 TAO_Connection_Handler (0),
00031 dscp_codepoint_ (IPDSFIELD_DSCP_DEFAULT << 2)
00032 {
00033
00034
00035
00036
00037
00038 ACE_ASSERT (0);
00039 }
00040
00041 TAO_UIPMC_Connection_Handler::TAO_UIPMC_Connection_Handler (TAO_ORB_Core *orb_core)
00042 : TAO_UIPMC_SVC_HANDLER (orb_core->thr_mgr (), 0, 0),
00043 TAO_Connection_Handler (orb_core),
00044 dscp_codepoint_ (IPDSFIELD_DSCP_DEFAULT << 2)
00045 {
00046 UIPMC_TRANSPORT* specific_transport = 0;
00047 ACE_NEW(specific_transport,
00048 UIPMC_TRANSPORT (this, orb_core));
00049
00050
00051 this->transport (specific_transport);
00052 }
00053
00054 TAO_UIPMC_Connection_Handler::~TAO_UIPMC_Connection_Handler (void)
00055 {
00056 delete this->transport ();
00057 int const result =
00058 this->release_os_resources ();
00059
00060 if (result == -1 && TAO_debug_level)
00061 {
00062 ACE_ERROR ((LM_ERROR,
00063 ACE_TEXT("TAO (%P|%t) - UIPMC_Connection_Handler::")
00064 ACE_TEXT("~UIPMC_Connection_Handler, ")
00065 ACE_TEXT("release_os_resources() failed %m\n")));
00066 }
00067 }
00068
00069 const ACE_INET_Addr &
00070 TAO_UIPMC_Connection_Handler::addr (void)
00071 {
00072 return this->addr_;
00073 }
00074
00075 void
00076 TAO_UIPMC_Connection_Handler::addr (const ACE_INET_Addr &addr)
00077 {
00078 this->addr_ = addr;
00079 }
00080
00081 const ACE_INET_Addr &
00082 TAO_UIPMC_Connection_Handler::local_addr (void)
00083 {
00084 return local_addr_;
00085 }
00086
00087 void
00088 TAO_UIPMC_Connection_Handler::local_addr (const ACE_INET_Addr &addr)
00089 {
00090 local_addr_ = addr;
00091 }
00092
00093 ssize_t
00094 TAO_UIPMC_Connection_Handler::send (const iovec iov[],
00095 int n,
00096 const ACE_Addr &addr,
00097 int flags) const
00098 {
00099 return this->peer ().send (iov, n, addr, flags);
00100 }
00101
00102 int
00103 TAO_UIPMC_Connection_Handler::open_handler (void *v)
00104 {
00105 return this->open (v);
00106 }
00107
00108 int
00109 TAO_UIPMC_Connection_Handler::open (void*)
00110 {
00111
00112
00113
00114 TAO_DIOP_Protocol_Properties protocol_properties;
00115
00116
00117 protocol_properties.hop_limit_ =
00118 this->orb_core ()->orb_params ()->ip_hoplimit ();
00119 protocol_properties.enable_multicast_loop_ =
00120 this->orb_core ()->orb_params ()->ip_multicastloop ();
00121
00122 TAO_Protocols_Hooks *tph =
00123 this->orb_core ()->get_protocols_hooks ();
00124
00125 if (tph != 0)
00126 {
00127 try
00128 {
00129 tph->client_protocol_properties_at_orb_level (protocol_properties);
00130 }
00131 catch (const ::CORBA::Exception&)
00132 {
00133 return -1;
00134 }
00135 }
00136
00137 this->peer ().open (this->local_addr_);
00138
00139 if (TAO_debug_level > 5)
00140 {
00141 ACE_DEBUG ((LM_DEBUG,
00142 ACE_TEXT("TAO (%P|%t) - UIPMC_Connection_Handler::open, ")
00143 ACE_TEXT("listening on: <%s:%u>\n"),
00144 this->local_addr_.get_host_addr (),
00145 this->local_addr_.get_port_number ()));
00146 }
00147
00148 if (protocol_properties.hop_limit_ >= 0)
00149 {
00150 int result = 0;
00151 #if defined (ACE_HAS_IPV6)
00152 if (this->local_addr_.get_type () == AF_INET6)
00153 {
00154 #if defined (ACE_WIN32)
00155 DWORD hop_limit =
00156 static_cast<DWORD> (protocol_properties.hop_limit_);
00157 #else
00158 int hop_limit =
00159 static_cast<int> (protocol_properties.hop_limit_);
00160 #endif
00161 result = this->peer ().set_option (
00162 IPPROTO_IPV6,
00163 IPV6_MULTICAST_HOPS,
00164 (void *) &hop_limit,
00165 sizeof (hop_limit));
00166 }
00167 else
00168 #endif
00169 {
00170 #if defined (ACE_WIN32)
00171 DWORD hop_limit =
00172 static_cast<DWORD> (protocol_properties.hop_limit_);
00173 #elif defined (ACE_HAS_IP_MULTICAST_TTL_AS_INT)
00174 int hop_limit =
00175 static_cast<int> (protocol_properties.hop_limit_);
00176 #else
00177 unsigned char hop_limit =
00178 static_cast<unsigned char> (protocol_properties.hop_limit_);
00179 #endif
00180 result = this->peer ().set_option (
00181 IPPROTO_IP,
00182 IP_MULTICAST_TTL,
00183 (void *) &hop_limit,
00184 sizeof (hop_limit));
00185 }
00186
00187 if (result != 0)
00188 {
00189 if (TAO_debug_level)
00190 {
00191 ACE_ERROR ((LM_ERROR,
00192 ACE_TEXT("TAO (%P|%t) - UIPMC_Connection_Handler::open, ")
00193 ACE_TEXT("couldn't set hop limit\n\n")));
00194 }
00195 return -1;
00196 }
00197 }
00198
00199 int result = 0;
00200 #if defined (ACE_HAS_IPV6)
00201 if (this->local_addr_.get_type () == AF_INET6)
00202 {
00203 #if defined (ACE_WIN32)
00204 DWORD enable_loop =
00205 static_cast<DWORD> (protocol_properties.enable_multicast_loop_);
00206 #elif defined (ACE_HAS_IPV6_MULTICAST_LOOP_AS_BOOL)
00207 bool enable_loop =
00208 static_cast<bool> (protocol_properties.enable_multicast_loop_);
00209 #else
00210 unsigned int enable_loop =
00211 static_cast<unsigned int> (protocol_properties.enable_multicast_loop_);
00212 #endif
00213 result = this->peer ().set_option (
00214 IPPROTO_IPV6,
00215 IPV6_MULTICAST_LOOP,
00216 (void *) &enable_loop,
00217 sizeof (enable_loop));
00218 }
00219 else
00220 #endif
00221 {
00222 #if defined (ACE_WIN32)
00223 DWORD enable_loop =
00224 static_cast<DWORD> (protocol_properties.enable_multicast_loop_);
00225 #elif defined (ACE_HAS_IP_MULTICAST_LOOP_AS_INT)
00226 int enable_loop =
00227 static_cast<int> (protocol_properties.enable_multicast_loop_);
00228 #else
00229 unsigned char enable_loop =
00230 static_cast<unsigned char> (protocol_properties.enable_multicast_loop_);
00231 #endif
00232 result = this->peer ().set_option (
00233 IPPROTO_IP,
00234 IP_MULTICAST_LOOP,
00235 (void *) &enable_loop,
00236 sizeof (enable_loop));
00237 }
00238
00239 if (result != 0)
00240 {
00241 if (TAO_debug_level)
00242 {
00243 ACE_ERROR ((LM_ERROR,
00244 ACE_TEXT("TAO (%P|%t) - UIPMC_Connection_Handler::open, ")
00245 ACE_TEXT("couldn't %s multicast packets looping\n\n"),
00246 protocol_properties.enable_multicast_loop_ ?
00247 ACE_TEXT("enable") : ACE_TEXT("disable")));
00248 }
00249 return -1;
00250 }
00251
00252
00253
00254
00255 if (!this->transport ()->post_open ((size_t) this->peer ().get_handle ()))
00256 return -1;
00257
00258 this->state_changed (TAO_LF_Event::LFS_SUCCESS,
00259 this->orb_core ()->leader_follower ());
00260
00261 return 0;
00262 }
00263
00264 int
00265 TAO_UIPMC_Connection_Handler::resume_handler (void)
00266 {
00267 return ACE_Event_Handler::ACE_APPLICATION_RESUMES_HANDLER;
00268 }
00269
00270 int
00271 TAO_UIPMC_Connection_Handler::close_connection (void)
00272 {
00273 return this->close_connection_eh (this);
00274 }
00275
00276 int
00277 TAO_UIPMC_Connection_Handler::handle_input (ACE_HANDLE h)
00278 {
00279 return this->handle_input_eh (h, this);
00280 }
00281
00282 int
00283 TAO_UIPMC_Connection_Handler::handle_output (ACE_HANDLE handle)
00284 {
00285 int result =
00286 this->handle_output_eh (handle, this);
00287
00288 if (result == -1)
00289 {
00290 this->close_connection ();
00291 return 0;
00292 }
00293
00294 return result;
00295 }
00296
00297 int
00298 TAO_UIPMC_Connection_Handler::handle_timeout (const ACE_Time_Value &,
00299 const void *)
00300 {
00301
00302
00303
00304
00305
00306
00307 TAO_Auto_Reference<TAO_UIPMC_Connection_Handler> safeguard (*this);
00308
00309
00310
00311
00312
00313
00314
00315 int ret = this->close ();
00316 this->reset_state (TAO_LF_Event::LFS_TIMEOUT);
00317 return ret;
00318 }
00319
00320 int
00321 TAO_UIPMC_Connection_Handler::handle_close (ACE_HANDLE,
00322 ACE_Reactor_Mask)
00323 {
00324
00325
00326
00327
00328
00329 return 0;
00330 }
00331
00332 int
00333 TAO_UIPMC_Connection_Handler::close (u_long flags)
00334 {
00335 return this->close_handler (flags);
00336 }
00337
00338 int
00339 TAO_UIPMC_Connection_Handler::release_os_resources (void)
00340 {
00341 return this->peer ().close ();
00342 }
00343
00344 int
00345 TAO_UIPMC_Connection_Handler::add_transport_to_cache (void)
00346 {
00347 ACE_INET_Addr addr;
00348
00349
00350
00351
00352
00353
00354
00355 TAO_UIPMC_Endpoint endpoint (addr);
00356
00357
00358 TAO_Base_Transport_Property prop (&endpoint);
00359
00360
00361 return this->orb_core ()->lane_resources ()
00362 .transport_cache ().cache_transport (&prop,
00363 this->transport ());
00364 }
00365
00366 int
00367 TAO_UIPMC_Connection_Handler::set_tos (int tos)
00368 {
00369
00370
00371 if (tos != this->dscp_codepoint_)
00372 {
00373 int result = 0;
00374 #if defined (ACE_HAS_IPV6)
00375 ACE_INET_Addr local_addr;
00376 if (this->peer ().get_local_addr (local_addr) == -1)
00377 return -1;
00378 else if (local_addr.get_type () == AF_INET6)
00379 # if !defined (IPV6_TCLASS)
00380
00381
00382 {
00383 if (TAO_debug_level)
00384 {
00385 ACE_DEBUG ((LM_DEBUG,
00386 "TAO (%P|%t) - UIPMC_Connection_Handler::"
00387 "set_dscp_codepoint -> IPV6_TCLASS not supported yet\n"));
00388 }
00389 return 0;
00390 }
00391 # else
00392 result = this->peer ().set_option (IPPROTO_IPV6,
00393 IPV6_TCLASS,
00394 (int *) &tos,
00395 (int) sizeof (tos));
00396 else
00397 # endif
00398 #endif
00399 result = this->peer ().set_option (IPPROTO_IP,
00400 IP_TOS,
00401 (int *) &tos,
00402 (int) sizeof (tos));
00403
00404 if (TAO_debug_level)
00405 {
00406 ACE_DEBUG ((LM_DEBUG,
00407 "TAO (%P|%t) - UIPMC_Connection_Handler::"
00408 "set_dscp_codepoint -> dscp: %x; result: %d; %s\n",
00409 tos,
00410 result,
00411 result == -1 ? "try running as superuser" : ""));
00412 }
00413
00414
00415 if (result == 0)
00416 this->dscp_codepoint_ = tos;
00417 }
00418
00419 return 0;
00420 }
00421
00422 int
00423 TAO_UIPMC_Connection_Handler::set_dscp_codepoint (CORBA::Long dscp_codepoint)
00424 {
00425 int tos = IPDSFIELD_DSCP_DEFAULT << 2;
00426
00427 CORBA::Long codepoint = dscp_codepoint;
00428
00429 tos = static_cast<int> (codepoint) << 2;
00430
00431 this->set_tos (tos);
00432
00433 return 0;
00434 }
00435
00436 int
00437 TAO_UIPMC_Connection_Handler::set_dscp_codepoint (CORBA::Boolean set_network_priority)
00438 {
00439 int tos = IPDSFIELD_DSCP_DEFAULT << 2;
00440
00441 if (set_network_priority)
00442 {
00443 TAO_Protocols_Hooks *tph =
00444 this->orb_core ()->get_protocols_hooks ();
00445
00446 if (tph != 0 )
00447 {
00448 CORBA::Long codepoint =
00449 tph->get_dscp_codepoint ();
00450
00451 tos = static_cast<int> (codepoint) << 2;
00452 this->set_tos (tos);
00453 }
00454 }
00455
00456 return 0;
00457 }
00458
00459 int
00460 TAO_UIPMC_Connection_Handler::handle_write_ready (const ACE_Time_Value *t)
00461 {
00462 return ACE::handle_write_ready (this->peer ().get_handle (), t);
00463 }
00464
00465 TAO_END_VERSIONED_NAMESPACE_DECL