Merge pull request #2218 from jwillemsen/jwi-pthreadsigmask
[ACE_TAO.git] / TAO / tao / Strategies / DIOP_Connection_Handler.cpp
blobd87bb6ab8edd910212f65fce645fd054e66012fa
1 #include "tao/Strategies/DIOP_Connection_Handler.h"
3 #if defined (TAO_HAS_DIOP) && (TAO_HAS_DIOP != 0)
5 #include "tao/Timeprobe.h"
6 #include "tao/debug.h"
7 #include "tao/ORB_Core.h"
8 #include "tao/ORB.h"
9 #include "tao/CDR.h"
10 #include "tao/Server_Strategy_Factory.h"
11 #include "tao/Transport_Cache_Manager.h"
12 #include "tao/Thread_Lane_Resources.h"
13 #include "tao/Base_Transport_Property.h"
14 #include "tao/Protocols_Hooks.h"
15 #include "tao/Resume_Handle.h"
17 #include "tao/Strategies/DIOP_Transport.h"
18 #include "tao/Strategies/DIOP_Endpoint.h"
20 #include "ace/os_include/netinet/os_tcp.h"
21 #include "ace/os_include/os_netdb.h"
23 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
25 TAO_DIOP_Connection_Handler::TAO_DIOP_Connection_Handler (ACE_Thread_Manager *t)
26 : TAO_DIOP_SVC_HANDLER (t, 0 , 0),
27 TAO_Connection_Handler (0),
28 dscp_codepoint_ (IPDSFIELD_DSCP_DEFAULT << 2)
30 // This constructor should *never* get called, it is just here to
31 // make the compiler happy: the default implementation of the
32 // Creation_Strategy requires a constructor with that signature, we
33 // don't use that implementation, but some (most?) compilers
34 // instantiate it anyway.
35 ACE_ASSERT (0);
38 TAO_DIOP_Connection_Handler::TAO_DIOP_Connection_Handler (TAO_ORB_Core *orb_core)
39 : TAO_DIOP_SVC_HANDLER (orb_core->thr_mgr (), 0, 0),
40 TAO_Connection_Handler (orb_core),
41 dscp_codepoint_ (IPDSFIELD_DSCP_DEFAULT << 2)
43 TAO_DIOP_Transport* specific_transport = 0;
44 ACE_NEW (specific_transport,
45 TAO_DIOP_Transport (this, orb_core));
47 // store this pointer (indirectly increment ref count)
48 this->transport (specific_transport);
51 TAO_DIOP_Connection_Handler::~TAO_DIOP_Connection_Handler ()
53 delete this->transport ();
54 int const result =
55 this->release_os_resources ();
57 if (result == -1 && TAO_debug_level)
59 TAOLIB_ERROR ((LM_ERROR,
60 ACE_TEXT ("TAO (%P|%t) - DIOP_Connection_Handler::")
61 ACE_TEXT ("~DIOP_Connection_Handler, ")
62 ACE_TEXT ("release_os_resources() failed %m\n")));
66 // DIOP Additions - Begin
67 const ACE_INET_Addr &
68 TAO_DIOP_Connection_Handler::addr ()
70 return this->addr_;
73 void
74 TAO_DIOP_Connection_Handler::addr (const ACE_INET_Addr &addr)
76 this->addr_ = addr;
79 const ACE_INET_Addr &
80 TAO_DIOP_Connection_Handler::local_addr ()
82 return this->local_addr_;
85 void
86 TAO_DIOP_Connection_Handler::local_addr (const ACE_INET_Addr &addr)
88 this->local_addr_ = addr;
90 // DIOP Additions - End
92 int
93 TAO_DIOP_Connection_Handler::open_handler (void *v)
95 return this->open (v);
98 int
99 TAO_DIOP_Connection_Handler::open (void*)
101 TAO_DIOP_Protocol_Properties protocol_properties;
103 // Initialize values from ORB params.
104 protocol_properties.send_buffer_size_ =
105 this->orb_core ()->orb_params ()->sock_sndbuf_size ();
106 protocol_properties.recv_buffer_size_ =
107 this->orb_core ()->orb_params ()->sock_rcvbuf_size ();
108 protocol_properties.hop_limit_ =
109 this->orb_core ()->orb_params ()->ip_hoplimit ();
111 TAO_Protocols_Hooks *tph = this->orb_core ()->get_protocols_hooks ();
113 if (tph != 0)
117 if (this->transport ()->opened_as () == TAO::TAO_CLIENT_ROLE)
119 tph->client_protocol_properties_at_orb_level (protocol_properties);
121 else
123 tph->server_protocol_properties_at_orb_level (protocol_properties);
126 catch (const ::CORBA::Exception&)
128 return -1;
132 this->peer ().open (this->local_addr_);
134 if (this->set_socket_option (this->peer (),
135 protocol_properties.send_buffer_size_,
136 protocol_properties.recv_buffer_size_) == -1)
137 return -1;
139 if (protocol_properties.hop_limit_ >= 0)
141 int result = 0;
142 #if defined (ACE_HAS_IPV6)
143 if (this->local_addr_.get_type () == AF_INET6)
145 #if defined (ACE_WIN32)
146 DWORD hop_limit =
147 static_cast<DWORD> (protocol_properties.hop_limit_);
148 #else
149 int hop_limit =
150 static_cast<int> (protocol_properties.hop_limit_);
151 #endif
152 result = this->peer ().set_option (
153 IPPROTO_IPV6,
154 IPV6_UNICAST_HOPS,
155 (void *) &hop_limit,
156 sizeof (hop_limit));
158 else
159 #endif /* ACE_HAS_IPV6 */
161 #if defined (ACE_WIN32)
162 DWORD hop_limit =
163 static_cast<DWORD> (protocol_properties.hop_limit_);
164 #else
165 int hop_limit =
166 static_cast<int> (protocol_properties.hop_limit_);
167 #endif
168 result = this->peer ().set_option (
169 IPPROTO_IP,
170 IP_TTL,
171 (void *) &hop_limit,
172 sizeof (hop_limit));
175 if (result != 0)
177 if (TAO_debug_level)
179 TAOLIB_ERROR ((LM_ERROR,
180 ACE_TEXT("TAO (%P|%t) - DIOP_Connection_Handler::open, ")
181 ACE_TEXT("couldn't set hop limit\n\n")));
183 return -1;
187 if (TAO_debug_level > 5)
189 TAOLIB_DEBUG ((LM_DEBUG,
190 ACE_TEXT("TAO (%P|%t) - DIOP_Connection_Handler::open, ")
191 ACE_TEXT("listening on: <%C:%u>\n"),
192 this->local_addr_.get_host_name (),
193 this->local_addr_.get_port_number ()));
196 // Set that the transport is now connected, if fails we return -1
197 // Use C-style cast b/c otherwise we get warnings on lots of
198 // compilers
199 if (!this->transport ()->post_open ((size_t) this->peer ().get_handle ()))
200 return -1;
202 this->state_changed (TAO_LF_Event::LFS_SUCCESS,
203 this->orb_core ()->leader_follower ());
205 return 0;
209 TAO_DIOP_Connection_Handler::open_server ()
211 TAO_DIOP_Protocol_Properties protocol_properties;
213 // Initialize values from ORB params.
214 protocol_properties.send_buffer_size_ =
215 this->orb_core ()->orb_params ()->sock_sndbuf_size ();
216 protocol_properties.recv_buffer_size_ =
217 this->orb_core ()->orb_params ()->sock_rcvbuf_size ();
219 TAO_Protocols_Hooks *tph = this->orb_core ()->get_protocols_hooks ();
221 if (tph != 0)
225 if (this->transport ()->opened_as () == TAO::TAO_CLIENT_ROLE)
227 tph->client_protocol_properties_at_orb_level (protocol_properties);
229 else
231 tph->server_protocol_properties_at_orb_level (protocol_properties);
234 catch (const ::CORBA::Exception&)
236 return -1;
240 this->peer ().open (this->local_addr_);
242 if (this->set_socket_option (this->peer (),
243 protocol_properties.send_buffer_size_,
244 protocol_properties.recv_buffer_size_) == -1)
245 return -1;
247 if (TAO_debug_level > 5)
249 TAOLIB_DEBUG ((LM_DEBUG,
250 ACE_TEXT("TAO (%P|%t) - DIOP_Connection_Handler::open_server, ")
251 ACE_TEXT("listening on %C:%d\n"),
252 this->local_addr_.get_host_name (),
253 this->local_addr_.get_port_number ()));
256 this->transport ()->id ((size_t) this->peer ().get_handle ());
258 return 0;
262 TAO_DIOP_Connection_Handler::resume_handler ()
264 return ACE_Event_Handler::ACE_APPLICATION_RESUMES_HANDLER;
268 TAO_DIOP_Connection_Handler::close_connection ()
270 return this->close_connection_eh (this);
274 TAO_DIOP_Connection_Handler::handle_input (ACE_HANDLE h)
276 return this->handle_input_eh (h, this);
280 TAO_DIOP_Connection_Handler::handle_output (ACE_HANDLE handle)
282 int const result =
283 this->handle_output_eh (handle, this);
285 if (result == -1)
287 this->close_connection ();
288 return 0;
291 return result;
295 TAO_DIOP_Connection_Handler::handle_timeout (const ACE_Time_Value &,
296 const void *)
298 // We don't use this upcall from the Reactor. However, we should
299 // override this since the base class returns -1 which will result
300 // in handle_close() getting called.
301 return 0;
305 TAO_DIOP_Connection_Handler::handle_close (ACE_HANDLE, ACE_Reactor_Mask)
307 // No asserts here since the handler is registered with the Reactor
308 // and the handler ownership is given to the Reactor. When the
309 // Reactor closes, it will call handle_close() on the handler. It
310 // is however important to overwrite handle_close() to do nothing
311 // since the base class does too much.
312 return 0;
316 TAO_DIOP_Connection_Handler::close (u_long flags)
318 return this->close_handler (flags);
322 TAO_DIOP_Connection_Handler::release_os_resources ()
324 return this->peer ().close ();
328 TAO_DIOP_Connection_Handler::add_transport_to_cache ()
330 ACE_INET_Addr addr;
332 // This function is called by the acceptor to add this
333 // transport to the transport cache. This is really
334 // important for proper shutdown. The address used
335 // is irrelevent, since DIOP is connectionless.
337 // Construct a DIOP_Endpoint object.
338 TAO_DIOP_Endpoint endpoint (
339 addr,
340 this->orb_core ()->orb_params ()->cache_incoming_by_dotted_decimal_address ());
342 // Construct a property object
343 TAO_Base_Transport_Property prop (&endpoint);
345 // Add the handler to Cache
346 return this->orb_core ()->lane_resources ()
347 .transport_cache ().cache_transport (&prop, this->transport ());
351 TAO_DIOP_Connection_Handler::set_tos (int tos)
353 if (tos != this->dscp_codepoint_)
355 int result = 0;
356 #if defined (ACE_HAS_IPV6)
357 ACE_INET_Addr local_addr;
358 if (this->peer ().get_local_addr (local_addr) == -1)
359 return -1;
360 else if (local_addr.get_type () == AF_INET6)
361 # if !defined (IPV6_TCLASS)
362 // IPv6 defines option IPV6_TCLASS for specifying traffic class/priority
363 // but not many implementations yet (very new;-).
365 if (TAO_debug_level)
367 TAOLIB_DEBUG ((LM_DEBUG,
368 "TAO (%P|%t) - DIOP_Connection_Handler::"
369 "set_dscp_codepoint -> IPV6_TCLASS not supported yet\n"));
371 return 0;
373 # else /* !IPV6_TCLASS */
374 result = this->peer ().set_option (IPPROTO_IPV6,
375 IPV6_TCLASS,
376 (int *) &tos ,
377 (int) sizeof (tos));
378 else
379 # endif /* IPV6_TCLASS */
380 #endif /* ACE_HAS_IPV6 */
381 result = this->peer ().set_option (IPPROTO_IP,
382 IP_TOS,
383 (int *) &tos ,
384 (int) sizeof (tos));
386 if (TAO_debug_level)
388 TAOLIB_DEBUG ((LM_DEBUG,
389 "TAO (%P|%t) - DIOP_Connection_Handler::"
390 "set_dscp_codepoint, dscp: %x; result: %d; %C\n",
391 tos,
392 result,
393 result == -1 ? "try running as superuser" : ""));
396 // On successful setting of TOS field.
397 if (result == 0)
398 this->dscp_codepoint_ = tos;
400 return 0;
404 TAO_DIOP_Connection_Handler::set_dscp_codepoint (CORBA::Long dscp)
406 int tos = IPDSFIELD_DSCP_DEFAULT << 2;
407 tos = (int)(dscp) << 2;
408 this->set_tos (tos);
409 return 0;
413 TAO_DIOP_Connection_Handler::set_dscp_codepoint (CORBA::Boolean set_network_priority)
415 int tos = IPDSFIELD_DSCP_DEFAULT << 2;
417 if (set_network_priority)
419 TAO_Protocols_Hooks *tph = this->orb_core ()->get_protocols_hooks ();
421 if (tph != 0)
423 CORBA::Long codepoint = tph->get_dscp_codepoint ();
425 tos = (int)(codepoint) << 2;
426 this->set_tos (tos);
429 return 0;
433 TAO_DIOP_Connection_Handler::handle_write_ready (const ACE_Time_Value *t)
435 return ACE::handle_write_ready (this->peer ().get_handle (), t);
438 TAO_END_VERSIONED_NAMESPACE_DECL
440 #endif /* TAO_HAS_DIOP && TAO_HAS_DIOP != 0 */