summaryrefslogtreecommitdiff
path: root/TAO/tao/Invocation_Endpoint_Selectors.cpp
blob: bdb493bd648cc98719b1c63d980e5c521c74c5ae (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
//$Id$
#include "tao/Invocation_Endpoint_Selectors.h"
#include "tao/Stub.h"
#include "tao/Profile.h"
#include "tao/ORB_Core.h"
#include "tao/IIOP_Endpoint.h"
#include "tao/Base_Transport_Property.h"
#include "tao/Profile_Transport_Resolver.h"
#include "tao/ORB_Constants.h"
#include "tao/SystemException.h"

ACE_RCSID (tao,
           Invocation_Endpoint_Selectors,
           "$Id$")


TAO_BEGIN_VERSIONED_NAMESPACE_DECL

TAO_Invocation_Endpoint_Selector::~TAO_Invocation_Endpoint_Selector (void)
{
}

// ****************************************************************

TAO_Default_Endpoint_Selector::~TAO_Default_Endpoint_Selector (void)
{
}

void
TAO_Default_Endpoint_Selector::select_endpoint (
    TAO::Profile_Transport_Resolver *r,
    ACE_Time_Value *max_wait_time
    ACE_ENV_ARG_DECL)
{
#if defined (ACE_HAS_IPV6)
  // See if we have IIOP selector preference parameters set.
  // If so we need to walk a different path in selecting an endpoint.
  if (r->stub ()->orb_core ()->orb_params ()->prefer_ipv6_interfaces () ||
      r->stub ()->orb_core ()->orb_params ()->connect_ipv6_only ())
    {
      bool test_ipv6 = true;  // first round try IPv6

      for (unsigned test_count = 2; test_count > 0 ;--test_count)
        {
          do
            {
              r->profile (r->stub ()->profile_in_use ());

              // Check whether we need to do a blocked wait or we have a
              // non-blocked wait and we support that.  If this is not the
              // case we can't use this profile so try the next.
              if (r->blocked_connect () ||
                 (!r->blocked_connect () &&
                    r->profile ()->supports_non_blocking_oneways ()))
                {
                  const size_t endpoint_count =
                    r->profile ()->endpoint_count ();

                  TAO_Endpoint *ep =
                    r->profile ()->endpoint ();

                  for (size_t i = 0; i < endpoint_count; ++i)
                    {
                      // in case we're running the first round:
                      //   try this endpoint if it either *not* an IIOP endpoint OR
                      //   if it is an IIOP IPv6 endpoint.
                      // else
                      //   only try when it's an IPv4 IIOP endpoint
                      bool try_ep = test_ipv6;

                      if (r->profile ()->tag () == IOP::TAG_INTERNET_IOP)
                        {
                          TAO_IIOP_Endpoint *iep =
                            dynamic_cast<TAO_IIOP_Endpoint *> (ep);
                          if (!iep->is_ipv6_decimal ())
                            {
                              const ACE_INET_Addr &addr = iep->object_addr ();

                              if (test_ipv6)
                                try_ep =
                                  addr.get_type () == AF_INET6 &&
                                    !addr.is_ipv4_mapped_ipv6();
                              else
                                try_ep =
                                  addr.get_type () == AF_INET ||
                                    (addr.get_type () == AF_INET6 &&
                                      addr.is_ipv4_mapped_ipv6());
                            }
                        }

                      if (try_ep)
                        {
                          TAO_Base_Transport_Property desc (ep);
                          const bool retval =
                            r->try_connect (&desc,
                                            max_wait_time
                                            ACE_ENV_ARG_PARAMETER);
                          ACE_CHECK;

                          // Check if the connect has completed.
                          if (retval)
                            return;
                        }

                      // Go to the next endpoint in this profile.
                      ep = ep->next ();
                    }
                }
            }
          while (r->stub ()->next_profile_retry () != 0);

          // If we get here we did not find any suitable non-IPv4 endpoint so
          // now try those if allowed
          if (!r->stub ()->orb_core ()->orb_params ()->connect_ipv6_only ())
            test_ipv6 = false;
          else
            break;  // Do not test remaining (if any) IPv4 endpoints
        }
    }
  else
#endif /* ACE_HAS_IPV6 */
  do
    {
      r->profile (r->stub ()->profile_in_use ());

      // Check whether we need to do a blocked wait or we have a
      // non-blocked wait and we support that.  If this is not the
      // case we can't use this profile so try the next.
      if (r->blocked_connect () ||
         (!r->blocked_connect () && r->profile ()->supports_non_blocking_oneways ()))
        {
          size_t const endpoint_count =
            r->profile ()->endpoint_count ();

          TAO_Endpoint * ep =
            r->profile ()->endpoint ();

          for (size_t i = 0; i < endpoint_count; ++i)
            {
              TAO_Base_Transport_Property desc (ep);
              bool const retval =
                r->try_connect (&desc,
                                max_wait_time
                                ACE_ENV_ARG_PARAMETER);
              ACE_CHECK;

              // Check if the connect has completed.
              if (retval)
                return;

              // Go to the next endpoint in this profile.
              ep = ep->next ();
            }
        }
    }
  while (r->stub ()->next_profile_retry () != 0);

  // If we get here, we completely failed to find an endpoint selector
  // that we know how to use, so throw an exception.
  ACE_THROW (CORBA::TRANSIENT (CORBA::OMGVMCID | 2,
                               CORBA::COMPLETED_NO));
}

TAO_END_VERSIONED_NAMESPACE_DECL