1 #include "tao/Strategies/SCIOP_Endpoint.h"
5 #include "tao/ORB_Constants.h"
8 #include "ace/os_include/os_netdb.h"
9 #include "ace/Synch_Traits.h"
10 #include "ace/Thread_Mutex.h"
11 #include "ace/OS_NS_string.h"
12 #include "ace/Log_Msg.h"
13 #include "ace/Synch.h"
14 #include "ace/OS_NS_stdio.h"
15 #include "tao/ORB_Core.h"
18 #if !defined (__ACE_INLINE__)
19 # include "tao/Strategies/SCIOP_Endpoint.inl"
20 #endif /* __ACE_INLINE__ */
22 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
24 TAO_SCIOP_Endpoint::TAO_SCIOP_Endpoint (const ACE_INET_Addr
&addr
,
25 int use_dotted_decimal_addresses
)
26 : TAO_Endpoint (TAO_TAG_SCIOP_PROFILE
)
28 , port_ (683) // default port (IANA assigned)
30 , object_addr_set_ (0)
32 , is_encodable_ (true)
35 this->set (addr
, use_dotted_decimal_addresses
);
38 TAO_SCIOP_Endpoint::TAO_SCIOP_Endpoint (const char *host
,
40 const ACE_INET_Addr
&addr
,
41 CORBA::Short priority
)
42 : TAO_Endpoint (TAO_TAG_SCIOP_PROFILE
,
47 , object_addr_set_ (0)
49 , is_encodable_ (true)
54 TAO_SCIOP_Endpoint::TAO_SCIOP_Endpoint ()
55 : TAO_Endpoint (TAO_TAG_SCIOP_PROFILE
)
57 , port_ (683) // default port (IANA assigned)
59 , object_addr_set_ (0)
61 , is_encodable_ (true)
66 TAO_SCIOP_Endpoint::TAO_SCIOP_Endpoint (const char *host
,
68 CORBA::Short priority
)
69 : TAO_Endpoint (TAO_TAG_SCIOP_PROFILE
)
73 , object_addr_set_ (0)
75 , is_encodable_ (true)
78 this->priority (priority
);
81 TAO_SCIOP_Endpoint::TAO_SCIOP_Endpoint (const TAO_SCIOP_Endpoint
&rhs
)
82 : TAO_Endpoint (rhs
.tag_
,
86 , object_addr_ (rhs
.object_addr_
)
87 , object_addr_set_ (rhs
.object_addr_set_
)
88 , preferred_path_ (rhs
.preferred_path_
)
89 , is_encodable_ (rhs
.is_encodable_
)
95 TAO_SCIOP_Endpoint::set (const ACE_INET_Addr
&addr
,
96 int use_dotted_decimal_addresses
)
98 char tmp_host
[MAXHOSTNAMELEN
+ 1];
100 if (use_dotted_decimal_addresses
101 || addr
.get_host_name (tmp_host
, sizeof (tmp_host
)) != 0)
103 const char *tmp
= addr
.get_host_addr ();
106 if (TAO_debug_level
> 0)
107 TAOLIB_DEBUG ((LM_DEBUG
,
108 ACE_TEXT ("\n\nTAO (%P|%t) ")
109 ACE_TEXT ("SCIOP_Endpoint::set ")
110 ACE_TEXT ("- %p\n\n"),
111 ACE_TEXT ("cannot determine hostname")));
118 this->host_
= CORBA::string_dup (tmp_host
);
120 this->port_
= addr
.get_port_number();
126 TAO_SCIOP_Endpoint::addr_to_string (char *buffer
, size_t length
)
129 ACE_OS::strlen (this->host_
.in ()) // chars in host name
130 + sizeof (':') // delimiter
131 + std::strlen ("65536") // max port
134 if (length
< actual_len
)
137 ACE_OS::sprintf (buffer
, "%s:%d",
138 this->host_
.in (), this->port_
);
144 TAO_SCIOP_Endpoint::host (const char *h
)
148 return this->host_
.in ();
152 TAO_SCIOP_Endpoint::next ()
158 TAO_SCIOP_Endpoint::duplicate ()
160 TAO_SCIOP_Endpoint
*endpoint
= 0;
162 // @@NOTE: Not at all exception safe
163 ACE_NEW_RETURN (endpoint
,
164 TAO_SCIOP_Endpoint (*this),
171 TAO_SCIOP_Endpoint::is_equivalent (const TAO_Endpoint
*other_endpoint
)
173 TAO_Endpoint
*endpt
=
174 const_cast<TAO_Endpoint
*> (other_endpoint
);
176 TAO_SCIOP_Endpoint
*endpoint
=
177 dynamic_cast<TAO_SCIOP_Endpoint
*> (endpt
);
181 return (this->port_
== endpoint
->port_
182 && (ACE_OS::strcmp(this->host(), endpoint
->host()) == 0));
186 TAO_SCIOP_Endpoint::hash ()
188 if (this->hash_val_
!= 0)
189 return this->hash_val_
;
192 ACE_GUARD_RETURN (TAO_SYNCH_MUTEX
,
194 this->addr_lookup_lock_
,
197 if (this->hash_val_
!= 0)
198 return this->hash_val_
;
200 // A few comments about this optimization. The call below will
201 // deadlock if the object_addr_set is false. If you don't belive
203 if (!this->object_addr_set_
)
205 // Set the object_addr first
206 (void) this->object_addr_i ();
210 this->object_addr_
.get_ip_address () + this->port ();
213 return this->hash_val_
;
216 const ACE_INET_Addr
&
217 TAO_SCIOP_Endpoint::object_addr () const
219 // The object_addr_ is initialized here, rather than at IOR decode
220 // time for several reasons:
221 // 1. A request on the object may never be invoked.
222 // 2. The DNS setup may have changed dynamically.
225 // Double checked locking optimization.
226 if (!this->object_addr_set_
)
228 ACE_GUARD_RETURN (TAO_SYNCH_MUTEX
,
230 this->addr_lookup_lock_
,
233 if (!this->object_addr_set_
)
235 (void) this->object_addr_i ();
239 return this->object_addr_
;
243 TAO_SCIOP_Endpoint::object_addr_i () const
245 if (this->object_addr_
.set (this->port_
, this->host_
.in ()) == -1)
247 // If this call fails, it most likely due a hostname
248 // lookup failure caused by a DNS misconfiguration. If
249 // a request is made to the object at the given host and
250 // port, then a CORBA::TRANSIENT() exception should be
253 // Invalidate the ACE_INET_Addr. This is used as a flag
254 // to denote that ACE_INET_Addr initialization failed.
255 this->object_addr_
.set_type (-1);
259 this->object_addr_set_
= true;
264 TAO_SCIOP_Endpoint::preferred_interfaces (TAO_ORB_Core
*oc
)
267 oc
->orb_params ()->preferred_interfaces ());
269 ACE_CString::size_type pos
= 0;
271 pos
= tmp
.find (this->host_
.in ());
273 TAO_SCIOP_Endpoint
*latest
= this;
275 CORBA::ULong count
= 0;
277 while (pos
!= ACE_CString::npos
)
279 // Do we have a "," or an '\0'?
280 ACE_CString::size_type new_pos
= tmp
.find (",", pos
+ 1);
282 // Length of the preferred path
283 ACE_CString::size_type length
= 0;
285 if (new_pos
== ACE_CString::npos
)
286 length
= tmp
.length () - pos
;
288 length
= new_pos
- pos
;
290 ACE_CString rem_tmp
= tmp
.substr (pos
, length
);
292 // Search for the ":"
293 ACE_CString::size_type col_pos
= rem_tmp
.find (":");
295 if (col_pos
== ACE_CString::npos
)
297 pos
= tmp
.find (latest
->host_
.in (),
302 ACE_CString path
= rem_tmp
.substr (col_pos
+ 1);
304 latest
->preferred_path_
.host
=
305 CORBA::string_dup (path
.c_str ());
307 if (TAO_debug_level
> 3)
308 TAOLIB_DEBUG ((LM_DEBUG
,
309 "(%P|%t) Adding path [%C] "
310 " as preferred path for [%C]\n",
311 path
.c_str (), this->host_
.in ()));
313 pos
= tmp
.find (latest
->host_
.in (),
316 if (pos
!= ACE_CString::npos
)
318 TAO_Endpoint
*tmp_ep
=
319 latest
->duplicate ();
321 latest
->next_
= dynamic_cast<TAO_SCIOP_Endpoint
*> (tmp_ep
);
323 if (latest
->next_
== 0) return count
;
325 latest
= latest
->next_
;
330 if (tmp
.length () != 0 &&
331 !oc
->orb_params ()->enforce_pref_interfaces ())
333 TAO_Endpoint
*tmp_ep
= latest
->duplicate ();
336 dynamic_cast<TAO_SCIOP_Endpoint
*> (tmp_ep
);
338 if (latest
->next_
== 0) return count
;
340 latest
->next_
->preferred_path_
.host
= (const char *) 0;
348 TAO_SCIOP_Endpoint::is_preferred_network () const
350 return (this->preferred_path_
.host
.in () != 0);
354 TAO_SCIOP_Endpoint::preferred_network () const
356 return this->preferred_path_
.host
.in ();
359 TAO_END_VERSIONED_NAMESPACE_DECL
361 #endif /* TAO_HAS_SCIOP == 1 */