1 #include "tao/Strategies/SCIOP_Acceptor.h"
2 #include "tao/Strategies/SCIOP_Profile.h"
6 #include "tao/MProfile.h"
8 #include "tao/Protocols_Hooks.h"
9 #include "tao/Codeset_Manager.h"
10 #include "tao/Transport.h"
12 #include "ace/os_include/os_netdb.h"
15 #if !defined(__ACE_INLINE__)
16 #include "tao/Strategies/SCIOP_Acceptor.inl"
17 #endif /* __ACE_INLINE__ */
19 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
21 TAO_SCIOP_Acceptor::TAO_SCIOP_Acceptor ()
22 : TAO_Acceptor (TAO_TAG_SCIOP_PROFILE
),
28 version_ (TAO_DEF_SCIOP_MAJOR
, TAO_DEF_SCIOP_MINOR
),
30 base_acceptor_ (this),
31 creation_strategy_ (0),
32 concurrency_strategy_ (0),
37 TAO_SCIOP_Acceptor::~TAO_SCIOP_Acceptor ()
39 // Make sure we are closed before we start destroying the
43 delete this->creation_strategy_
;
44 delete this->concurrency_strategy_
;
45 delete this->accept_strategy_
;
47 delete [] this->addrs_
;
49 for (CORBA::ULong i
= 0; i
< this->endpoint_count_
; ++i
)
50 CORBA::string_free (this->hosts_
[i
]);
52 delete [] this->hosts_
;
56 // 2) For V1.[1,2] there are tagged components
58 TAO_SCIOP_Acceptor::create_profile (const TAO::ObjectKey
&object_key
,
59 TAO_MProfile
&mprofile
,
60 CORBA::Short priority
)
63 if (this->endpoint_count_
== 0)
66 // Check if multiple endpoints should be put in one profile or
67 // if they should be spread across multiple profiles.
69 if (priority == TAO_INVALID_PRIORITY)
70 return this->create_new_profile (object_key,
75 return this->create_shared_profile (object_key
,
81 TAO_SCIOP_Acceptor::create_new_profile (const TAO::ObjectKey
&object_key
,
82 TAO_MProfile
&mprofile
,
83 CORBA::Short priority
)
85 // Adding this->endpoint_count_ to the TAO_MProfile.
86 int const count
= mprofile
.profile_count ();
87 if ((mprofile
.size () - count
) < this->endpoint_count_
88 && mprofile
.grow (count
+ this->endpoint_count_
) == -1)
91 // Create a profile for each acceptor endpoint.
92 for (CORBA::ULong i
= 0; i
< this->endpoint_count_
; ++i
)
94 TAO_SCIOP_Profile
*pfile
= 0;
95 ACE_NEW_RETURN (pfile
,
96 TAO_SCIOP_Profile (this->hosts_
[i
],
97 this->addrs_
[i
].get_port_number (),
103 pfile
->endpoint ()->priority (priority
);
105 if (mprofile
.give_profile (pfile
) == -1)
107 pfile
->_decr_refcnt ();
112 pfile
->tagged_components ().set_orb_type (TAO_ORB_TYPE
);
114 TAO_Codeset_Manager
*csm
= this->orb_core_
->codeset_manager();
116 csm
->set_codeset(pfile
->tagged_components());
123 TAO_SCIOP_Acceptor::create_shared_profile (const TAO::ObjectKey
&object_key
,
124 TAO_MProfile
&mprofile
,
125 CORBA::Short priority
)
127 CORBA::ULong index
= 0;
128 TAO_SCIOP_Profile
*sciop_profile
= 0;
130 // Do not check <mprofile> for the presence of an existing
131 // SCIOP_Profile. With SCIOP, there is a one-to-one relationship
132 // between Acceptors and Profiles.
134 ACE_NEW_RETURN (sciop_profile
,
135 TAO_SCIOP_Profile (this->hosts_
[0],
136 this->addrs_
[0].get_port_number (),
142 sciop_profile
->endpoint ()->priority (priority
);
144 if (mprofile
.give_profile (sciop_profile
) == -1)
146 sciop_profile
->_decr_refcnt ();
151 sciop_profile
->tagged_components ().set_orb_type (TAO_ORB_TYPE
);
153 TAO_Codeset_Manager
*csm
= this->orb_core_
->codeset_manager();
155 csm
->set_codeset(sciop_profile
->tagged_components());
160 // Add any remaining acceptor endpoints to the SCIOP_Profile.
162 index
< this->endpoint_count_
;
165 TAO_SCIOP_Endpoint
*endpoint
= 0;
166 ACE_NEW_RETURN (endpoint
,
167 TAO_SCIOP_Endpoint (this->hosts_
[index
],
168 this->addrs_
[index
].get_port_number (),
169 this->addrs_
[index
]),
171 endpoint
->priority (priority
);
172 sciop_profile
->add_endpoint (endpoint
);
179 TAO_SCIOP_Acceptor::is_collocated (const TAO_Endpoint
*endpoint
)
181 const TAO_SCIOP_Endpoint
*endp
=
182 dynamic_cast<const TAO_SCIOP_Endpoint
*> (endpoint
);
184 // Make sure the dynamically cast pointer is valid.
188 for (CORBA::ULong i
= 0; i
< this->endpoint_count_
; ++i
)
190 // compare the port and host name. Please do *NOT* optimize
191 // this code by comparing the IP address instead. That would
192 // trigger the following bug:
194 // http://bugzilla.dre.vanderbilt.edu/show_bug.cgi?id=1220
196 if (endp
->port() == this->addrs_
[i
].get_port_number()
197 && ACE_OS::strcmp(endp
->host(), this->hosts_
[i
]) == 0)
205 TAO_SCIOP_Acceptor::close ()
207 return this->base_acceptor_
.close ();
211 TAO_SCIOP_Acceptor::open (TAO_ORB_Core
*orb_core
,
212 ACE_Reactor
*reactor
,
218 this->orb_core_
= orb_core
;
220 if (this->hosts_
!= 0)
222 // The hostname cache has already been set!
223 // This is bad mojo, i.e. an internal TAO error.
224 TAOLIB_ERROR_RETURN ((LM_ERROR
,
225 ACE_TEXT ("TAO (%P|%t) - ")
226 ACE_TEXT ("SCIOP_Acceptor::open, ")
227 ACE_TEXT ("hostname already set\n\n")),
235 if (this->parse_options (options
) == -1)
238 ACE_Multihomed_INET_Addr addr
;
240 const char *port_separator_loc
= std::strchr (address
, ':');
241 std::unique_ptr
<char[]> tmp_host_auto
;
243 if (port_separator_loc
== address
)
245 // The address is a port number or port name. No hostname was
246 // specified. The hostname for each network interface and the
247 // fully qualified domain name must be obtained.
249 // Check for multiple network interfaces.
250 if (this->probe_interfaces (orb_core
) == -1)
253 // First convert the port into a usable form.
254 ACE_INET_Addr temp_addr
;
255 if (temp_addr
.set (address
+ sizeof (':')) != 0)
258 // Now reset the port and set the host.
259 if (addr
.set (temp_addr
.get_port_number (),
260 static_cast<ACE_UINT32
> (INADDR_ANY
),
264 return this->open_i (addr
,
268 // If we've reached this point, then the address consists of one or
269 // more hostnames, followed perhaps by a port.
271 u_short port_number
= 0;
273 size_t hostname_length
= 0;
275 if (port_separator_loc
!= 0) {
276 // Port separator was found. Check that the next character is
277 // not the terminator.
278 const char *port_loc
= port_separator_loc
;
281 TAOLIB_ERROR_RETURN ((LM_ERROR
,
282 ACE_TEXT ("TAO (%P|%t) ")
283 ACE_TEXT ("SCIOP_Acceptor::open - ")
284 ACE_TEXT ("no port number after the ")
285 ACE_TEXT ("colon in \"%C\"\n"),
290 // Read the port number
291 ACE_INET_Addr temp_addr
;
292 if (temp_addr
.string_to_addr(port_loc
) != 0)
294 port_number
= temp_addr
.get_port_number();
296 // Set the length of the hostname
297 hostname_length
= port_separator_loc
- address
;
299 // Port separator was not found. We allow port_number to retain
300 // the value of 0, which will cause the port to be chosen for us
303 // Set the length of the hostname
304 hostname_length
= std::strlen(address
);
307 ACE_NEW_RETURN(tmp_host
, char[hostname_length
+ 1], -1);
308 tmp_host_auto
.reset(tmp_host
);
309 ACE_OS::memcpy (tmp_host
, address
, hostname_length
);
310 tmp_host
[hostname_length
] = '\0';
312 // There may be multiple hostnames. Parse them.
313 ACE_Array
<ACE_CString
> hostnames
;
314 if (parse_multiple_hostnames(tmp_host
, hostnames
) != 0)
317 // Check that at least one hostname was obtained.
318 if (hostnames
.size() < 1) {
319 TAOLIB_ERROR_RETURN ((LM_ERROR
,
320 ACE_TEXT ("TAO (%P|%t) ")
321 ACE_TEXT ("SCIOP_Acceptor::open - ")
322 ACE_TEXT ("no hostnames in string \"%C\"\n"),
327 // Obtain the primary ip address.
328 ACE_UINT32 primary_ip_addr
= 0;
330 // Obtain a char* for the primary hostname.
331 ACE_CString
& primary_hostname_obj
= hostnames
[0];
332 std::unique_ptr
<char[]> primary_hostname_auto(primary_hostname_obj
.rep());
333 const char* primary_hostname
= primary_hostname_auto
.get();
335 // Convert the primary hostname to ACE_UINT32
336 ACE_INET_Addr temp_addr
;
337 if (temp_addr
.set((u_short
) 0, primary_hostname
) != 0)
340 primary_ip_addr
= temp_addr
.get_ip_address();
343 // Allocate an array of secondary ip addresses.
344 ACE_UINT32
*secondary_ip_addrs
= 0;
345 std::unique_ptr
<ACE_UINT32
[]> secondary_ip_addrs_auto
;
346 size_t num_secondary_ip_addrs
= hostnames
.size() - 1;
347 if (num_secondary_ip_addrs
> 0) {
348 ACE_NEW_RETURN(secondary_ip_addrs
,
349 ACE_UINT32
[num_secondary_ip_addrs
],
351 secondary_ip_addrs_auto
.reset(secondary_ip_addrs
);
354 // Populate the array of secondary ip addresses
356 ACE_INET_Addr temp_addr
;
357 while (i
< num_secondary_ip_addrs
) {
358 // Obtain a char* for a single secondary hostname.
359 ACE_CString
& hostname_obj
= hostnames
[i
+ 1];
360 std::unique_ptr
<char[]> hostname_auto(hostname_obj
.rep());
361 const char* hostname
= hostname_auto
.get();
363 // Obtain the ip address for this secondary hostname.
364 if (temp_addr
.set((u_short
) 0, hostname
) != 0)
367 // Put secondary ip address into the array
368 secondary_ip_addrs
[i
++] = temp_addr
.get_ip_address();
371 // Populate our ACE_Multihomed_INET_Addr with all the right
373 if (addr
.set(port_number
,
377 num_secondary_ip_addrs
) != 0)
382 // Number of endpoints equals the size of the hostname array.
383 this->endpoint_count_
= hostnames
.size();
385 ACE_NEW_RETURN (this->addrs_
,
386 ACE_INET_Addr
[this->endpoint_count_
],
389 ACE_NEW_RETURN (this->hosts_
,
390 char *[this->endpoint_count_
],
393 // Copy the primary address to the first slot of the
395 this->addrs_
[0].set (addr
);
397 // Copy secondary addresses to the remaining slots of the
399 ACE_INET_Addr
*secondary_addrs
= this->addrs_
;
401 addr
.get_secondary_addresses(secondary_addrs
, num_secondary_ip_addrs
);
403 // Set cached hostnames.
405 while (i
< hostnames
.size()) {
406 // The hostname_in_ior_ field may override the FIRST hostname only.
407 if (this->hostname_in_ior_
!= 0 && i
== 0)
409 if (TAO_debug_level
> 2)
411 TAOLIB_DEBUG ((LM_DEBUG
,
412 ACE_TEXT ("TAO (%P|%t) - ")
413 ACE_TEXT ("SCIOP_Acceptor::open, ")
414 ACE_TEXT ("overriding address in IOR with %C\n"),
415 this->hostname_in_ior_
));
417 if (this->hostname (orb_core
,
420 this->hostname_in_ior_
) != 0)
425 // Obtain a char* for the hostname.
426 ACE_CString
& hostname_obj
= hostnames
[i
];
427 std::unique_ptr
<char[]> hostname_auto(hostname_obj
.rep());
428 const char* hostname
= hostname_auto
.get();
430 if (this->hostname (orb_core
,
441 return this->open_i (addr
,
446 TAO_SCIOP_Acceptor::open_default (TAO_ORB_Core
*orb_core
,
447 ACE_Reactor
*reactor
,
452 this->orb_core_
= orb_core
;
454 if (this->hosts_
!= 0)
456 // The hostname cache has already been set!
457 // This is bad mojo, i.e. an internal TAO error.
458 TAOLIB_ERROR_RETURN ((LM_ERROR
,
459 ACE_TEXT ("TAO (%P|%t) ")
460 ACE_TEXT ("SCIOP_Acceptor::open_default - ")
461 ACE_TEXT ("hostname already set\n\n")),
466 if (this->parse_options (options
) == -1)
469 // Check for multiple network interfaces.
470 if (this->probe_interfaces (orb_core
) == -1)
473 // Now that each network interface's hostname has been cached, open
474 // an endpoint on each network interface using the INADDR_ANY
476 ACE_Multihomed_INET_Addr addr
;
478 if (addr
.set (static_cast<u_short
> (0),
479 static_cast<ACE_UINT32
> (INADDR_ANY
),
483 return this->open_i (addr
,
488 TAO_SCIOP_Acceptor::open_i (const ACE_Multihomed_INET_Addr
& addr
,
489 ACE_Reactor
*reactor
)
491 ACE_NEW_RETURN (this->creation_strategy_
,
492 TAO_SCIOP_CREATION_STRATEGY (this->orb_core_
),
495 ACE_NEW_RETURN (this->concurrency_strategy_
,
496 TAO_SCIOP_CONCURRENCY_STRATEGY (this->orb_core_
),
499 ACE_NEW_RETURN (this->accept_strategy_
,
500 TAO_SCIOP_ACCEPT_STRATEGY (this->orb_core_
),
503 u_short requested_port
= addr
.get_port_number ();
504 if (requested_port
== 0)
506 // don't care, i.e., let the OS choose an ephemeral port
507 if (this->base_acceptor_
.open (addr
,
509 this->creation_strategy_
,
510 this->accept_strategy_
,
511 this->concurrency_strategy_
) == -1)
513 if (TAO_debug_level
> 0)
514 TAOLIB_DEBUG ((LM_DEBUG
,
515 ACE_TEXT ("\n\nTAO (%P|%t) SCIOP_Acceptor::open_i ")
516 ACE_TEXT ("- %p\n\n"),
517 ACE_TEXT ("cannot open acceptor")));
523 ACE_Multihomed_INET_Addr
a(addr
);
525 bool found_a_port
= false;
526 ACE_UINT32
const last_port
= ACE_MIN (requested_port
+ this->port_span_
- 1,
527 ACE_MAX_DEFAULT_PORT
);
529 for (ACE_UINT32 p
= requested_port
; p
<= last_port
; p
++)
531 if (TAO_debug_level
> 5)
532 TAOLIB_DEBUG ((LM_DEBUG
,
533 ACE_TEXT ("TAO (%P|%t) SCIOP_Acceptor::open_i() ")
534 ACE_TEXT ("trying to listen on port %d\n"), p
));
536 // Now try to actually open on that port
537 a
.set_port_number ((u_short
)p
);
538 if (this->base_acceptor_
.open (a
,
540 this->creation_strategy_
,
541 this->accept_strategy_
,
542 this->concurrency_strategy_
) != -1)
549 // Now, if we couldn't locate a port, we punt
552 if (TAO_debug_level
> 0)
553 TAOLIB_DEBUG ((LM_DEBUG
,
554 ACE_TEXT ("\n\nTAO (%P|%t) SCIOP_Acceptor::open_i ")
555 ACE_TEXT ("cannot open acceptor in port range (%d,%d)")
556 ACE_TEXT ("- %p\n\n"),
557 requested_port
, last_port
, ACE_TEXT("")));
562 ACE_INET_Addr address
;
564 // We do this make sure the port number the endpoint is listening on
565 // gets set in the addr.
566 if (this->base_acceptor_
.acceptor ().get_local_addr (address
) != 0)
568 // @@ Should this be a catastrophic error???
569 if (TAO_debug_level
> 0)
570 TAOLIB_DEBUG ((LM_DEBUG
,
571 ACE_TEXT ("\n\nTAO (%P|%t) SCIOP_Acceptor::open_i ")
572 ACE_TEXT ("- %p\n\n"),
573 ACE_TEXT ("cannot get local addr")));
577 // Set the port for each addr. If there is more than one network
578 // interface then the endpoint created on each interface will be on
579 // the same port. This is how a wildcard socket bind() is supposed
581 u_short port
= address
.get_port_number ();
582 for (CORBA::ULong j
= 0; j
< this->endpoint_count_
; ++j
)
583 this->addrs_
[j
].set_port_number (port
, 1);
585 (void) this->base_acceptor_
.acceptor().enable (ACE_CLOEXEC
);
586 // This avoids having child processes acquire the listen socket thereby
587 // denying the server the opportunity to restart on a well-known endpoint.
588 // This does not affect the aberrent behavior on Win32 platforms.
590 if (TAO_debug_level
> 5)
592 for (CORBA::ULong i
= 0; i
< this->endpoint_count_
; ++i
)
594 TAOLIB_DEBUG ((LM_DEBUG
,
595 ACE_TEXT ("\nTAO (%P|%t) SCIOP_Acceptor::open_i - ")
596 ACE_TEXT ("listening on: <%C:%u>\n"),
598 this->addrs_
[i
].get_port_number ()));
602 // In the event that an accept() fails, we can examine the reason. If
603 // the reason warrants it, we can try accepting again at a later time.
604 // The amount of time we wait to accept again is governed by this orb
606 this->set_error_retry_delay (
607 this->orb_core_
->orb_params ()->accept_error_delay());
613 TAO_SCIOP_Acceptor::hostname (TAO_ORB_Core
*orb_core
,
616 const char *specified_hostname
)
618 if (orb_core
->orb_params ()->use_dotted_decimal_addresses ())
620 // If dotted decimal addresses are enabled,
622 return this->dotted_decimal_address (addr
, host
);
624 else if (specified_hostname
!= 0)
626 // If the user specified a hostname, pass it back
627 // blindly as it overrides our choice of hostname.
628 host
= CORBA::string_dup (specified_hostname
);
632 char tmp_host
[MAXHOSTNAMELEN
+ 1];
634 // Get the hostname associated with our address
635 if (addr
.get_host_name (tmp_host
, sizeof (tmp_host
)) != 0)
637 // On failure, just return the decimal address.
638 return this->dotted_decimal_address (addr
, host
);
642 host
= CORBA::string_dup (tmp_host
);
650 TAO_SCIOP_Acceptor::dotted_decimal_address (ACE_INET_Addr
&addr
,
656 // If the IP address in the INET_Addr is the INADDR_ANY address,
657 // then force the actual IP address to be used by initializing a new
658 // INET_Addr with the hostname from the original one. If that fails
659 // then something is seriously wrong with the systems networking
661 if (addr
.get_ip_address () == INADDR_ANY
)
663 ACE_INET_Addr new_addr
;
664 result
= new_addr
.set (addr
.get_port_number (),
665 addr
.get_host_name ());
666 tmp
= new_addr
.get_host_addr ();
669 tmp
= addr
.get_host_addr ();
671 if (tmp
== 0 || result
!= 0)
673 if (TAO_debug_level
> 0)
674 TAOLIB_DEBUG ((LM_DEBUG
,
675 ACE_TEXT ("\n\nTAO (%P|%t) ")
676 ACE_TEXT ("SCIOP_Acceptor::dotted_decimal_address ")
677 ACE_TEXT ("- %p\n\n"),
678 ACE_TEXT ("cannot determine hostname")));
682 host
= CORBA::string_dup (tmp
);
687 TAO_SCIOP_Acceptor::probe_interfaces (TAO_ORB_Core
*orb_core
)
689 // Extract the hostname for each network interface, and then cache
690 // it. The hostnames will then be used when creating a
691 // TAO_SCIOP_Profile for each endpoint setup on the probed
692 // network interfaces.
693 ACE_INET_Addr
*if_addrs
= 0;
696 if (ACE::get_ip_interfaces (if_cnt
,
700 // In the case where errno == ENOTSUP, if_cnt and if_addrs will
701 // not be modified, and will each remain equal to zero. This
702 // causes the default interface to be used.
706 if (if_cnt
== 0 || if_addrs
== 0)
708 if (TAO_debug_level
> 0)
710 TAOLIB_DEBUG ((LM_WARNING
,
711 ACE_TEXT ("TAO (%P|%t) Unable to probe network ")
712 ACE_TEXT ("interfaces. Using default.\n")));
715 if_cnt
= 1; // Force the network interface count to be one.
717 ACE_NEW_RETURN (if_addrs
,
718 ACE_INET_Addr
[if_cnt
],
722 // Scan for the loopback interface since it shouldn't be included in
723 // the list of cached hostnames unless it is the only interface.
724 size_t lo_cnt
= 0; // Loopback interface count
725 for (size_t j
= 0; j
< if_cnt
; ++j
)
726 if (if_addrs
[j
].is_loopback ())
729 // The instantiation for this template is in
730 // tao/SCIOP_Connector.cpp.
731 std::unique_ptr
<ACE_INET_Addr
[]> safe_if_addrs (if_addrs
);
733 // If the loopback interface is the only interface then include it
734 // in the list of interfaces to query for a hostname, otherwise
735 // exclude it from the list.
736 if (if_cnt
== lo_cnt
)
737 this->endpoint_count_
= static_cast<CORBA::ULong
> (if_cnt
);
739 this->endpoint_count_
= static_cast<CORBA::ULong
> (if_cnt
- lo_cnt
);
741 ACE_NEW_RETURN (this->addrs_
,
742 ACE_INET_Addr
[this->endpoint_count_
],
745 ACE_NEW_RETURN (this->hosts_
,
746 char *[this->endpoint_count_
],
749 ACE_OS::memset (this->hosts_
, 0, sizeof (char*) * this->endpoint_count_
);
751 // The number of hosts/interfaces we want to cache may not be the
752 // same as the number of detected interfaces so keep a separate
756 for (size_t i
= 0; i
< if_cnt
; ++i
)
758 // Ignore any loopback interface if there are other
759 // non-loopback interfaces.
760 if (if_cnt
!= lo_cnt
&&
761 if_addrs
[i
].is_loopback ())
764 if (this->hostname_in_ior_
!= 0)
766 if (TAO_debug_level
> 2)
768 TAOLIB_DEBUG ((LM_DEBUG
,
769 ACE_TEXT ("TAO (%P|%t) - ")
770 ACE_TEXT ("SCIOP_Acceptor::probe_interfaces, ")
771 ACE_TEXT ("overriding address in IOR with %C\n"),
772 this->hostname_in_ior_
));
774 if (this->hostname (orb_core
,
776 this->hosts_
[host_cnt
],
777 this->hostname_in_ior_
) != 0)
782 if (this->hostname (orb_core
,
784 this->hosts_
[host_cnt
]) != 0)
788 // Copy the addr. The port is (re)set in
789 // TAO_SCIOP_Acceptor::open_i().
790 if (this->addrs_
[host_cnt
].set (if_addrs
[i
]) != 0)
800 TAO_SCIOP_Acceptor::parse_multiple_hostnames (const char *hostnames
,
801 ACE_Array
<ACE_CString
> &hostnames_out
)
803 // Make a copy of hostnames string
804 int const hostnames_string_length
= std::strlen(hostnames
) + 1;
805 char* hostnames_copy
= 0;
806 ACE_NEW_RETURN (hostnames_copy
,
807 char[hostnames_string_length
],
809 std::unique_ptr
<char[]> hostnames_copy_auto(hostnames_copy
);
810 ACE_OS::strncpy(hostnames_copy
, hostnames
, hostnames_string_length
);
812 // Count the number of hostnames separated by "+"
813 size_t num_hostnames
= 0;
815 const char* hostname
= ACE_OS::strtok_r (hostnames_copy
, "+", &last
);
817 while (hostname
!= 0) {
819 hostname
= ACE_OS::strtok_r (0, "+", &last
);
822 // Set the size of the array to the number of hostnames
823 if (hostnames_out
.size(num_hostnames
) == -1) {
824 TAOLIB_ERROR_RETURN ((LM_ERROR
,
825 ACE_TEXT ("TAO (%P|%t) Could not allocate storage ")
826 ACE_TEXT ("for %d hostnames in SCIOP endpoint\n"),
831 // Refresh copy of hostnames string
832 ACE_NEW_RETURN (hostnames_copy
,
833 char[hostnames_string_length
],
835 hostnames_copy_auto
.reset(hostnames_copy
);
836 ACE_OS::strncpy(hostnames_copy
, hostnames
, hostnames_string_length
);
838 // Iterate over the hostnames and stuff them into the array
841 hostname
= ACE_OS::strtok_r (hostnames_copy
, "+", &last
);
843 while (index
< num_hostnames
) {
844 ACE_CString
hostname_object(hostname
);
845 hostnames_out
.set(hostname_object
, index
++);
847 hostname
= ACE_OS::strtok_r (0, "+", &last
);
854 TAO_SCIOP_Acceptor::endpoint_count ()
856 return this->endpoint_count_
;
860 TAO_SCIOP_Acceptor::object_key (IOP::TaggedProfile
&profile
,
861 TAO::ObjectKey
&object_key
)
863 // Create the decoding association from the encapsulation in the buffer,
864 #if (TAO_NO_COPY_OCTET_SEQUENCES == 1)
865 TAO_InputCDR
cdr (profile
.profile_data
.mb ());
867 TAO_InputCDR
cdr (reinterpret_cast<char*> (profile
.profile_data
.get_buffer ()),
868 profile
.profile_data
.length ());
869 #endif /* TAO_NO_COPY_OCTET_SEQUENCES == 1 */
871 CORBA::Octet major
= 0;
872 CORBA::Octet minor
= 0;
874 // Read the version. We just read it here. We don't*do any*
876 if (!(cdr
.read_octet (major
)
877 && cdr
.read_octet (minor
)))
879 if (TAO_debug_level
> 0)
881 TAOLIB_ERROR ((LM_ERROR
,
882 ACE_TEXT ("TAO (%P|%t) SCIOP_Profile::decode - v%d.%d\n"),
889 CORBA::String_var host
;
890 CORBA::UShort port
= 0;
892 // Get host and port. No processing here too..
893 if (cdr
.read_string (host
.out ()) == 0
894 || cdr
.read_ushort (port
) == 0)
896 if (TAO_debug_level
> 0)
898 TAOLIB_DEBUG ((LM_DEBUG
,
899 ACE_TEXT ("TAO (%P|%t) TAO_SCIOP_Acceptor::object_key - ")
900 ACE_TEXT ("error while decoding host/port")));
905 // ... and object key.
906 if (!(cdr
>> object_key
))
909 // We are NOT bothered about the rest.
915 TAO_SCIOP_Acceptor::parse_options (const char *str
)
918 return 0; // No options to parse. Not a problem.
920 // Use an option format similar to the one used for CGI scripts in
922 // e.g.: option1=foo&option2=bar
923 ACE_CString
options (str
);
925 size_t len
= options
.length ();
927 const char option_delimiter
= '&';
929 // Count the number of options.
931 CORBA::ULong option_count
= 1;
932 // Number of endpoints in the string (initialized to 1).
934 // Only check for endpoints after the protocol specification and
935 // before the object key.
936 for (size_t i
= 0; i
< len
; ++i
)
937 if (options
[i
] == option_delimiter
)
940 // The idea behind the following loop is to split the options into
941 // (option, name) pairs.
943 // `option1=foo&option2=bar'
944 // will be parsed into:
948 ACE_CString::size_type begin
= 0;
949 ACE_CString::size_type end
= 0;
951 for (CORBA::ULong j
= 0; j
< option_count
; ++j
)
953 if (j
< option_count
- 1)
954 end
= options
.find (option_delimiter
, begin
);
959 TAOLIB_ERROR_RETURN ((LM_ERROR
,
960 ACE_TEXT ("TAO (%P|%t) Zero length SCIOP option.\n")),
962 else if (end
!= ACE_CString::npos
)
964 ACE_CString opt
= options
.substring (begin
, end
- begin
);
966 ACE_CString::size_type slot
= opt
.find ("=");
969 || slot
== ACE_CString::npos
)
970 TAOLIB_ERROR_RETURN ((LM_ERROR
,
971 ACE_TEXT ("TAO (%P|%t) SCIOP option <%C> is ")
972 ACE_TEXT ("missing a value.\n"),
976 ACE_CString name
= opt
.substring (0, slot
);
977 ACE_CString value
= opt
.substring (slot
+ 1);
979 if (name
.length () == 0)
980 TAOLIB_ERROR_RETURN ((LM_ERROR
,
981 ACE_TEXT ("TAO (%P|%t) Zero length SCIOP ")
982 ACE_TEXT ("option name.\n")),
985 if (name
== "priority")
987 TAOLIB_ERROR_RETURN ((LM_ERROR
,
988 ACE_TEXT ("TAO (%P|%t) Invalid SCIOP endpoint format: ")
989 ACE_TEXT ("endpoint priorities no longer supported.\n")),
992 else if (name
== "portspan")
994 int const range
= ACE_OS::atoi (value
.c_str ());
995 // @@ What's the lower bound on the range? zero, or one?
996 if (range
< 1 || range
> ACE_MAX_DEFAULT_PORT
)
997 TAOLIB_ERROR_RETURN ((LM_ERROR
,
998 ACE_TEXT ("TAO (%P|%t) Invalid SCIOP endpoint ")
999 ACE_TEXT ("portspan: <%C>\n")
1000 ACE_TEXT ("Valid range 1 -- %d\n"),
1001 value
.c_str (), ACE_MAX_DEFAULT_PORT
),
1004 this->port_span_
= static_cast<u_short
> (range
);
1006 else if (name
== "hostname_in_ior")
1008 this->hostname_in_ior_
= value
.rep ();
1011 TAOLIB_ERROR_RETURN ((LM_ERROR
,
1012 ACE_TEXT ("TAO (%P|%t) Invalid SCIOP option: <%C>\n"),
1020 break; // No other options.
1027 TAO_END_VERSIONED_NAMESPACE_DECL
1029 #endif /* TAO_HAS_SCIOP == 1 */