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