1 //
2 // Copyright (c) ZeroC, Inc. All rights reserved.
3 //
4 
5 package IceInternal;
6 
7 public abstract class IPEndpointI extends EndpointI
8 {
IPEndpointI(ProtocolInstance instance, String host, int port, java.net.InetSocketAddress sourceAddr, String connectionId)9     protected IPEndpointI(ProtocolInstance instance, String host, int port, java.net.InetSocketAddress sourceAddr,
10                           String connectionId)
11     {
12         _instance = instance;
13         _host = host;
14         _port = port;
15         _sourceAddr = sourceAddr;
16         _connectionId = connectionId;
17         _hashInitialized = false;
18     }
19 
IPEndpointI(ProtocolInstance instance)20     protected IPEndpointI(ProtocolInstance instance)
21     {
22         _instance = instance;
23         _host = null;
24         _port = 0;
25         _sourceAddr = null;
26         _connectionId = "";
27         _hashInitialized = false;
28     }
29 
IPEndpointI(ProtocolInstance instance, Ice.InputStream s)30     protected IPEndpointI(ProtocolInstance instance, Ice.InputStream s)
31     {
32         _instance = instance;
33         _host = s.readString();
34         _port = s.readInt();
35         _sourceAddr = null;
36         _connectionId = "";
37         _hashInitialized = false;
38     }
39 
40     @Override
getInfo()41     public Ice.EndpointInfo getInfo()
42     {
43         Ice.IPEndpointInfo info = new Ice.IPEndpointInfo()
44             {
45                 @Override
46                 public short type()
47                 {
48                     return IPEndpointI.this.type();
49                 }
50 
51                 @Override
52                 public boolean datagram()
53                 {
54                     return IPEndpointI.this.datagram();
55                 }
56 
57                 @Override
58                 public boolean secure()
59                 {
60                     return IPEndpointI.this.secure();
61                 }
62         };
63         fillEndpointInfo(info);
64         return info;
65     }
66 
67     @Override
type()68     public short type()
69     {
70         return _instance.type();
71     }
72 
73     @Override
protocol()74     public String protocol()
75     {
76         return _instance.protocol();
77     }
78 
79     @Override
secure()80     public boolean secure()
81     {
82         return _instance.secure();
83     }
84 
85     @Override
connectionId()86     public String connectionId()
87     {
88         return _connectionId;
89     }
90 
91     @Override
connectionId(String connectionId)92     public EndpointI connectionId(String connectionId)
93     {
94         if(connectionId.equals(_connectionId))
95         {
96             return this;
97         }
98         else
99         {
100             return createEndpoint(_host, _port, connectionId);
101         }
102     }
103 
104     @Override
connectors_async(Ice.EndpointSelectionType selType, EndpointI_connectors callback)105     public void connectors_async(Ice.EndpointSelectionType selType, EndpointI_connectors callback)
106     {
107         _instance.resolve(_host, _port, selType, this, callback);
108     }
109 
110     @Override
expandIfWildcard()111     public java.util.List<EndpointI> expandIfWildcard()
112     {
113         java.util.List<EndpointI> endps = new java.util.ArrayList<EndpointI>();
114         java.util.List<String> hosts = Network.getHostsForEndpointExpand(_host, _instance.protocolSupport(), false);
115         if(hosts == null || hosts.isEmpty())
116         {
117             endps.add(this);
118         }
119         else
120         {
121             for(String h : hosts)
122             {
123                 endps.add(createEndpoint(h, _port, _connectionId));
124             }
125         }
126         return endps;
127     }
128 
129     @Override
expandHost(Ice.Holder<EndpointI> publishedEndpoint)130     public java.util.List<EndpointI> expandHost(Ice.Holder<EndpointI> publishedEndpoint)
131     {
132         //
133         // If this endpoint has an empty host (wildcard address), don't expand, just return
134         // this endpoint.
135         //
136         if(_host.isEmpty())
137         {
138             java.util.ArrayList<EndpointI> endpoints = new java.util.ArrayList<>();
139             endpoints.add(this);
140             return endpoints;
141         }
142 
143         //
144         // If using a fixed port, this endpoint can be used as the published endpoint to
145         // access the returned endpoints. Otherwise, we'll publish each individual expanded
146         // endpoint.
147         //
148         publishedEndpoint.value = _port > 0 ? this : null;
149 
150         java.util.List<java.net.InetSocketAddress> addresses = Network.getAddresses(_host,
151                                                                                     _port,
152                                                                                     _instance.protocolSupport(),
153                                                                                     Ice.EndpointSelectionType.Ordered,
154                                                                                     _instance.preferIPv6(),
155                                                                                     true);
156 
157         java.util.ArrayList<EndpointI> endpoints = new java.util.ArrayList<>();
158         if(addresses.size() == 1)
159         {
160             endpoints.add(this);
161         }
162         else
163         {
164             for(java.net.InetSocketAddress addr : addresses)
165             {
166                 endpoints.add(createEndpoint(addr.getAddress().getHostAddress(), addr.getPort(), _connectionId));
167             }
168         }
169         return endpoints;
170     }
171 
172     @Override
equivalent(EndpointI endpoint)173     public boolean equivalent(EndpointI endpoint)
174     {
175         if(!(endpoint instanceof IPEndpointI))
176         {
177             return false;
178         }
179         IPEndpointI ipEndpointI = (IPEndpointI)endpoint;
180         return ipEndpointI.type() == type() && ipEndpointI._host.equals(_host) && ipEndpointI._port == _port &&
181             Network.compareAddress(ipEndpointI._sourceAddr, _sourceAddr) == 0;
182     }
183 
connectors(java.util.List<java.net.InetSocketAddress> addresses, NetworkProxy proxy)184     public java.util.List<Connector> connectors(java.util.List<java.net.InetSocketAddress> addresses,
185                                                 NetworkProxy proxy)
186     {
187         java.util.List<Connector> connectors = new java.util.ArrayList<Connector>();
188         for(java.net.InetSocketAddress p : addresses)
189         {
190             connectors.add(createConnector(p, proxy));
191         }
192         return connectors;
193     }
194 
195     @Override
hashCode()196     synchronized public int hashCode()
197     {
198         if(!_hashInitialized)
199         {
200             _hashValue = 5381;
201             _hashValue = HashUtil.hashAdd(_hashValue, type());
202             _hashValue = hashInit(_hashValue);
203             _hashInitialized = true;
204         }
205         return _hashValue;
206     }
207 
208     @Override
options()209     public String options()
210     {
211         //
212         // WARNING: Certain features, such as proxy validation in Glacier2,
213         // depend on the format of proxy strings. Changes to toString() and
214         // methods called to generate parts of the reference string could break
215         // these features. Please review for all features that depend on the
216         // format of proxyToString() before changing this and related code.
217         //
218         String s = "";
219 
220         if(_host != null && _host.length() > 0)
221         {
222             s += " -h ";
223             boolean addQuote = _host.indexOf(':') != -1;
224             if(addQuote)
225             {
226                 s += "\"";
227             }
228             s += _host;
229             if(addQuote)
230             {
231                 s += "\"";
232             }
233         }
234 
235         s += " -p " + _port;
236 
237         if(_sourceAddr != null)
238         {
239             s += " --sourceAddress " + _sourceAddr.getAddress().getHostAddress();
240         }
241 
242         return s;
243     }
244 
245     @Override
compareTo(EndpointI obj)246     public int compareTo(EndpointI obj) // From java.lang.Comparable
247     {
248         if(!(obj instanceof IPEndpointI))
249         {
250             return type() < obj.type() ? -1 : 1;
251         }
252 
253         IPEndpointI p = (IPEndpointI)obj;
254         if(this == p)
255         {
256             return 0;
257         }
258 
259         int v = _host.compareTo(p._host);
260         if(v != 0)
261         {
262             return v;
263         }
264 
265         if(_port < p._port)
266         {
267             return -1;
268         }
269         else if(p._port < _port)
270         {
271             return 1;
272         }
273 
274         int rc = Network.compareAddress(_sourceAddr, p._sourceAddr);
275         if(rc != 0)
276         {
277             return rc;
278         }
279 
280         return _connectionId.compareTo(p._connectionId);
281     }
282 
283     @Override
streamWriteImpl(Ice.OutputStream s)284     public void streamWriteImpl(Ice.OutputStream s)
285     {
286         s.writeString(_host);
287         s.writeInt(_port);
288     }
289 
hashInit(int h)290     public int hashInit(int h)
291     {
292         h = HashUtil.hashAdd(h, _host);
293         h = HashUtil.hashAdd(h, _port);
294         if(_sourceAddr != null)
295         {
296             h = HashUtil.hashAdd(h, _sourceAddr.getAddress().getHostAddress());
297         }
298         h = HashUtil.hashAdd(h, _connectionId);
299         return h;
300     }
301 
fillEndpointInfo(Ice.IPEndpointInfo info)302     public void fillEndpointInfo(Ice.IPEndpointInfo info)
303     {
304         info.timeout = timeout();
305         info.compress = compress();
306         info.host = _host;
307         info.port = _port;
308         info.sourceAddress = _sourceAddr == null ? "" : _sourceAddr.getAddress().getHostAddress();
309     }
310 
initWithOptions(java.util.ArrayList<String> args, boolean oaEndpoint)311     public void initWithOptions(java.util.ArrayList<String> args, boolean oaEndpoint)
312     {
313         super.initWithOptions(args);
314 
315         if(_host == null || _host.length() == 0)
316         {
317             _host = _instance.defaultHost();
318         }
319         else if(_host.equals("*"))
320         {
321             if(oaEndpoint)
322             {
323                 _host = "";
324             }
325             else
326             {
327                 throw new Ice.EndpointParseException("`-h *' not valid for proxy endpoint `" + toString() + "'");
328             }
329         }
330 
331         if(_host == null)
332         {
333             _host = "";
334         }
335 
336         if(_sourceAddr == null)
337         {
338             if (!oaEndpoint)
339             {
340                 _sourceAddr = _instance.defaultSourceAddress();
341             }
342         }
343         else if(oaEndpoint)
344         {
345             throw new Ice.EndpointParseException("`--sourceAddress' not valid for object adapter endpoint `" +
346                                                  toString() + "'");
347         }
348     }
349 
350     @Override
checkOption(String option, String argument, String endpoint)351     protected boolean checkOption(String option, String argument, String endpoint)
352     {
353         if(option.equals("-h"))
354         {
355             if(argument == null)
356             {
357                 throw new Ice.EndpointParseException("no argument provided for -h option in endpoint " + endpoint);
358             }
359             _host = argument;
360         }
361         else if(option.equals("-p"))
362         {
363             if(argument == null)
364             {
365                 throw new Ice.EndpointParseException("no argument provided for -p option in endpoint " + endpoint);
366             }
367 
368             try
369             {
370                 _port = Integer.parseInt(argument);
371             }
372             catch(NumberFormatException ex)
373             {
374                 throw new Ice.EndpointParseException("invalid port value `" + argument +
375                                                      "' in endpoint " + endpoint);
376             }
377 
378             if(_port < 0 || _port > 65535)
379             {
380                 throw new Ice.EndpointParseException("port value `" + argument +
381                                                      "' out of range in endpoint " + endpoint);
382             }
383         }
384         else if(option.equals("--sourceAddress"))
385         {
386             if(argument == null)
387             {
388                 throw new Ice.EndpointParseException("no argument provided for --sourceAddress option in endpoint " +
389                                                      endpoint);
390             }
391             _sourceAddr = Network.getNumericAddress(argument);
392             if(_sourceAddr == null)
393             {
394                 throw new Ice.EndpointParseException(
395                     "invalid IP address provided for --sourceAddress option in endpoint " + endpoint);
396             }
397         }
398         else
399         {
400             return false;
401         }
402         return true;
403     }
404 
createConnector(java.net.InetSocketAddress addr, NetworkProxy proxy)405     protected abstract Connector createConnector(java.net.InetSocketAddress addr, NetworkProxy proxy);
createEndpoint(String host, int port, String connectionId)406     protected abstract IPEndpointI createEndpoint(String host, int port, String connectionId);
407 
408     protected ProtocolInstance _instance;
409     protected String _host;
410     protected int _port;
411     protected java.net.InetSocketAddress _sourceAddr;
412     protected String _connectionId;
413     private boolean _hashInitialized;
414     private int _hashValue;
415 }
416