1 | package org.dcache.util; |
2 | |
3 | import java.net.DatagramSocket; |
4 | import java.util.List; |
5 | import java.util.ArrayList; |
6 | import java.util.Enumeration; |
7 | import java.net.InetAddress; |
8 | import java.net.Inet4Address; |
9 | import java.net.NetworkInterface; |
10 | import java.net.SocketException; |
11 | import java.net.UnknownHostException; |
12 | import java.net.URL; |
13 | import java.net.URI; |
14 | import java.net.URISyntaxException; |
15 | import java.net.MalformedURLException; |
16 | |
17 | import org.slf4j.Logger; |
18 | import org.slf4j.LoggerFactory; |
19 | |
20 | /** |
21 | * Various network related utility functions. |
22 | */ |
23 | public abstract class NetworkUtils { |
24 | |
25 | private static final int RANDOM_PORT = 23241; |
26 | private static final int FIRST_CLIENT_HOST = 0; |
27 | private static final Logger _log = LoggerFactory.getLogger(NetworkUtils.class); |
28 | |
29 | /** |
30 | * Returns the list of IP V4 addresses of this host. |
31 | */ |
32 | public static List<InetAddress> getLocalAddressesV4() |
33 | throws SocketException { |
34 | List<InetAddress> result = new ArrayList<InetAddress>(); |
35 | |
36 | Enumeration<NetworkInterface> interfaces = |
37 | NetworkInterface.getNetworkInterfaces(); |
38 | while (interfaces.hasMoreElements()) { |
39 | NetworkInterface i = interfaces.nextElement(); |
40 | if (i.isUp() && !i.isLoopback()) { |
41 | Enumeration<InetAddress> addresses = i.getInetAddresses(); |
42 | while (addresses.hasMoreElements()) { |
43 | InetAddress address = addresses.nextElement(); |
44 | if (address instanceof Inet4Address) { |
45 | result.add(address); |
46 | } |
47 | } |
48 | } |
49 | } |
50 | return result; |
51 | } |
52 | |
53 | public static InetAddress getLocalAddressForClient(String[] clientHosts) throws SocketException, UnknownHostException { |
54 | // try to pick the ip address with corresponds to the |
55 | // hostname (which is hopefully visible to the world) |
56 | // by service method |
57 | _log.debug("hostname: {}", clientHosts[FIRST_CLIENT_HOST]); |
58 | InetAddress clientAddress = InetAddress.getByName(clientHosts[FIRST_CLIENT_HOST]); |
59 | |
60 | _log.debug("client: {}", clientAddress.toString()); |
61 | InetAddress localAddress = NetworkUtils.getLocalAddress(clientAddress); |
62 | _log.debug("local: {}", localAddress.toString()); |
63 | _log.debug("canonical: {}", localAddress.getCanonicalHostName()); |
64 | return localAddress; |
65 | } |
66 | |
67 | /** |
68 | * Return the local address via which the given destination |
69 | * address is reachable. |
70 | * |
71 | * Java does not provide this functionality and therefore we need |
72 | * this workaround. |
73 | */ |
74 | public static InetAddress getLocalAddress(InetAddress intendedDestination) |
75 | throws SocketException { |
76 | DatagramSocket socket = new DatagramSocket(); |
77 | try { |
78 | socket.connect(intendedDestination, RANDOM_PORT); |
79 | return socket.getLocalAddress(); |
80 | } finally { |
81 | socket.close(); |
82 | } |
83 | } |
84 | |
85 | /** |
86 | * Like URI.toURL, but translates exceptions to URISyntaxException |
87 | * with a descriptive error message. |
88 | */ |
89 | public static URL toURL(URI uri) |
90 | throws URISyntaxException |
91 | { |
92 | try { |
93 | return uri.toURL(); |
94 | } catch (IllegalArgumentException e) { |
95 | URISyntaxException exception = |
96 | new URISyntaxException(uri.toString(), e.getMessage()); |
97 | exception.initCause(e); |
98 | throw exception; |
99 | } catch (MalformedURLException e) { |
100 | URISyntaxException exception = |
101 | new URISyntaxException(uri.toString(), e.getMessage()); |
102 | exception.initCause(e); |
103 | throw exception; |
104 | } |
105 | } |
106 | } |