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 "$Id: SCIOP_Connection_Handler.cpp 78950 2007-07-19 11:53:18Z johnnyw $")
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 : TAO_SCIOP_SVC_HANDLER (orb_core->thr_mgr (), 0, 0),
00053 TAO_Connection_Handler (orb_core),
00054 dscp_codepoint_ (IPDSFIELD_DSCP_DEFAULT << 2)
00055 {
00056 TAO_SCIOP_Transport* specific_transport = 0;
00057 ACE_NEW (specific_transport,
00058 TAO_SCIOP_Transport (this, orb_core));
00059
00060
00061 this->transport (specific_transport);
00062 }
00063
00064 TAO_SCIOP_Connection_Handler::~TAO_SCIOP_Connection_Handler (void)
00065 {
00066 delete this->transport ();
00067 int const result =
00068 this->release_os_resources ();
00069
00070 if (result == -1 && TAO_debug_level)
00071 {
00072 ACE_ERROR ((LM_ERROR,
00073 ACE_TEXT("TAO (%P|%t) - SCIOP_Connection_Handler::")
00074 ACE_TEXT("~scIOP_Connection_Handler, ")
00075 ACE_TEXT("release_os_resources() failed %m\n")));
00076 }
00077 }
00078
00079 int
00080 TAO_SCIOP_Connection_Handler::open_handler (void *v)
00081 {
00082 return this->open (v);
00083 }
00084
00085 int
00086 TAO_SCIOP_Connection_Handler::open (void*)
00087 {
00088 if (this->shared_open() == -1)
00089 return -1;
00090
00091 TAO_SCIOP_Protocol_Properties protocol_properties;
00092
00093
00094 protocol_properties.send_buffer_size_ =
00095 this->orb_core ()->orb_params ()->sock_sndbuf_size ();
00096 protocol_properties.recv_buffer_size_ =
00097 this->orb_core ()->orb_params ()->sock_rcvbuf_size ();
00098 protocol_properties.no_delay_ =
00099 this->orb_core ()->orb_params ()->nodelay ();
00100
00101 TAO_Protocols_Hooks *tph = this->orb_core ()->get_protocols_hooks ();
00102
00103 if (tph != 0)
00104 {
00105 try
00106 {
00107 if (this->transport ()->opened_as () == TAO::TAO_CLIENT_ROLE)
00108 {
00109 tph->client_protocol_properties_at_orb_level (protocol_properties);
00110 }
00111 else
00112 {
00113 tph->server_protocol_properties_at_orb_level (protocol_properties);
00114 }
00115 }
00116 catch (const ::CORBA::Exception& ex)
00117 {
00118 return -1;
00119 }
00120 }
00121
00122 if (this->set_socket_option (this->peer (),
00123 protocol_properties.send_buffer_size_,
00124 protocol_properties.recv_buffer_size_) == -1)
00125 return -1;
00126
00127 #if !defined (ACE_LACKS_TCP_NODELAY)
00128 if (this->peer ().set_option (IPPROTO_SCTP,
00129 SCTP_NODELAY,
00130 (void *) &protocol_properties.no_delay_,
00131 sizeof (protocol_properties.no_delay_)) == -1)
00132 return -1;
00133 #endif
00134
00135 if (this->transport ()->wait_strategy ()->non_blocking ())
00136 {
00137 if (this->peer ().enable (ACE_NONBLOCK) == -1)
00138 return -1;
00139 }
00140
00141
00142
00143
00144 ACE_INET_Addr remote_addr;
00145 if (this->peer ().get_remote_addr (remote_addr) == -1)
00146 return -1;
00147
00148 ACE_INET_Addr local_addr;
00149 if (this->peer ().get_local_addr (local_addr) == -1)
00150 return -1;
00151
00152 if (TAO_debug_level > 2)
00153 ACE_DEBUG ((LM_DEBUG,
00154 ACE_TEXT("TAO(%P|%t) - SCIOP_Connection_Handler::open, ")
00155 ACE_TEXT("The local addr is (%s) \n"),
00156 local_addr. get_host_addr ()));
00157
00158 if (local_addr.get_ip_address () == remote_addr.get_ip_address ()
00159 && local_addr.get_port_number () == remote_addr.get_port_number ())
00160 {
00161 if (TAO_debug_level > 0)
00162 {
00163 ACE_TCHAR remote_as_string[MAXHOSTNAMELEN + 16];
00164 ACE_TCHAR local_as_string[MAXHOSTNAMELEN + 16];
00165
00166 (void) remote_addr.addr_to_string (remote_as_string,
00167 sizeof(remote_as_string));
00168 (void) local_addr.addr_to_string (local_as_string,
00169 sizeof(local_as_string));
00170 ACE_ERROR ((LM_ERROR,
00171 ACE_TEXT("TAO(%P|%t) - TAO_SCIOP_Connection_Handler::open, ")
00172 ACE_TEXT("Holy Cow! The remote addr and ")
00173 ACE_TEXT("local addr are identical (%s == %s)\n"),
00174 remote_as_string, local_as_string));
00175 }
00176 return -1;
00177 }
00178
00179 if (TAO_debug_level > 0)
00180 {
00181 ACE_TCHAR client[MAXHOSTNAMELEN + 16];
00182
00183
00184 if (remote_addr.addr_to_string (client, sizeof (client)) == -1)
00185 return -1;
00186
00187 ACE_DEBUG ((LM_DEBUG,
00188 ACE_TEXT ("TAO (%P|%t) - SCIOP_Connection_Handler::open, SCIOP ")
00189 ACE_TEXT ("connection to peer <%s> on %d\n"),
00190 client, this->peer ().get_handle ()));
00191 }
00192
00193
00194
00195
00196 if (!this->transport ()->post_open ((size_t) this->get_handle ()))
00197 return -1;
00198
00199 this->state_changed (TAO_LF_Event::LFS_SUCCESS,
00200 this->orb_core ()->leader_follower ());
00201
00202 return 0;
00203 }
00204
00205 int
00206 TAO_SCIOP_Connection_Handler::resume_handler (void)
00207 {
00208 return ACE_Event_Handler::ACE_APPLICATION_RESUMES_HANDLER;
00209 }
00210
00211 int
00212 TAO_SCIOP_Connection_Handler::close_connection (void)
00213 {
00214 return this->close_connection_eh (this);
00215 }
00216
00217 int
00218 TAO_SCIOP_Connection_Handler::handle_input (ACE_HANDLE h)
00219 {
00220 return this->handle_input_eh (h, this);
00221 }
00222
00223 int
00224 TAO_SCIOP_Connection_Handler::handle_output (ACE_HANDLE handle)
00225 {
00226 int const result =
00227 this->handle_output_eh (handle, this);
00228
00229 if (result == -1)
00230 {
00231 this->close_connection ();
00232 return 0;
00233 }
00234
00235 return result;
00236 }
00237
00238 int
00239 TAO_SCIOP_Connection_Handler::handle_timeout (const ACE_Time_Value &,
00240 const void *)
00241 {
00242
00243
00244
00245
00246
00247
00248 TAO_Auto_Reference<TAO_SCIOP_Connection_Handler> safeguard (*this);
00249
00250
00251
00252
00253
00254
00255
00256 int ret = this->close ();
00257 this->reset_state (TAO_LF_Event::LFS_TIMEOUT);
00258 return ret;
00259 }
00260
00261 int
00262 TAO_SCIOP_Connection_Handler::handle_close (ACE_HANDLE,
00263 ACE_Reactor_Mask)
00264 {
00265 ACE_ASSERT (0);
00266 return 0;
00267 }
00268
00269 int
00270 TAO_SCIOP_Connection_Handler::close (u_long)
00271 {
00272 return this->close_handler ();
00273 }
00274
00275 int
00276 TAO_SCIOP_Connection_Handler::release_os_resources (void)
00277 {
00278 return this->peer().close ();
00279 }
00280
00281 int
00282 TAO_SCIOP_Connection_Handler::add_transport_to_cache (void)
00283 {
00284 ACE_INET_Addr addr;
00285
00286
00287 if (this->peer ().get_remote_addr (addr) == -1)
00288 return -1;
00289
00290
00291 TAO_SCIOP_Endpoint endpoint (
00292 addr,
00293 this->orb_core()->orb_params()->use_dotted_decimal_addresses ());
00294
00295
00296 TAO_Base_Transport_Property prop (&endpoint);
00297
00298 TAO::Transport_Cache_Manager &cache =
00299 this->orb_core ()->lane_resources ().transport_cache ();
00300
00301
00302 return cache.cache_idle_transport (&prop,
00303 this->transport ());
00304
00305 }
00306
00307 int
00308 TAO_SCIOP_Connection_Handler::process_listen_point_list (
00309 IIOP::ListenPointList &listen_list)
00310 {
00311
00312 CORBA::ULong const len = listen_list.length ();
00313
00314 for (CORBA::ULong i = 0; i < len; ++ i)
00315 {
00316 IIOP::ListenPoint listen_point = listen_list[i];
00317 ACE_INET_Addr addr (listen_point.port,
00318 listen_point.host.in ());
00319
00320 if (TAO_debug_level > 0)
00321 {
00322 ACE_DEBUG ((LM_DEBUG,
00323 ACE_TEXT("(%P|%t) Listening port [%d] on [%s]\n"),
00324 listen_point.port,
00325 ACE_TEXT_CHAR_TO_TCHAR(listen_point.host.in ())));
00326 }
00327
00328
00329 TAO_SCIOP_Endpoint endpoint (addr,
00330 this->orb_core()->orb_params()->use_dotted_decimal_addresses ());
00331
00332
00333 TAO_Base_Transport_Property prop (&endpoint);
00334
00335
00336 prop.set_bidir_flag (1);
00337
00338
00339
00340 int const retval = this->transport ()->recache_transport (&prop);
00341 if (retval == -1)
00342 return retval;
00343
00344
00345 this->transport ()->make_idle ();
00346 }
00347
00348 return 0;
00349 }
00350
00351 int
00352 TAO_SCIOP_Connection_Handler::set_tos (int tos)
00353 {
00354 if (tos != this->dscp_codepoint_)
00355 {
00356 int const result = this->peer ().set_option (IPPROTO_IP,
00357 IP_TOS,
00358 (int *) &tos ,
00359 (int) sizeof (tos));
00360
00361 if (TAO_debug_level)
00362 {
00363 ACE_DEBUG ((LM_DEBUG,
00364 "TAO (%P|%t) - SCIOP_Connection_Handler::"
00365 "set_dscp_codepoint -> dscp: %x; result: %d; %s\n",
00366 tos,
00367 result,
00368 result == -1 ? "try running as superuser" : ""));
00369 }
00370
00371
00372 if (result == 0)
00373 this->dscp_codepoint_ = tos;
00374
00375 }
00376
00377 return 0;
00378 }
00379
00380 int
00381 TAO_SCIOP_Connection_Handler::set_dscp_codepoint (CORBA::Long dscp)
00382 {
00383 int tos = IPDSFIELD_DSCP_DEFAULT << 2;
00384 tos = (int)(dscp) << 2;
00385 this->set_tos (tos);
00386 return 0;
00387 }
00388
00389 int
00390 TAO_SCIOP_Connection_Handler::set_dscp_codepoint (CORBA::Boolean set_network_priority)
00391 {
00392 int tos = IPDSFIELD_DSCP_DEFAULT << 2;
00393
00394 if (set_network_priority)
00395 {
00396 TAO_Protocols_Hooks *tph = this->orb_core ()->get_protocols_hooks ();
00397
00398 if (tph != 0)
00399 {
00400 CORBA::Long codepoint = tph->get_dscp_codepoint ();
00401 tos = (int)(codepoint) << 2;
00402 this->set_tos (tos);
00403 }
00404 }
00405
00406 return 0;
00407 }
00408
00409 TAO_END_VERSIONED_NAMESPACE_DECL
00410
00411 #endif