| 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 | } |