Line data Source code
1 : // Copyright (C) 2009 The Android Open Source Project 2 : // 3 : // Licensed under the Apache License, Version 2.0 (the "License"); 4 : // you may not use this file except in compliance with the License. 5 : // You may obtain a copy of the License at 6 : // 7 : // http://www.apache.org/licenses/LICENSE-2.0 8 : // 9 : // Unless required by applicable law or agreed to in writing, software 10 : // distributed under the License is distributed on an "AS IS" BASIS, 11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 : // See the License for the specific language governing permissions and 13 : // limitations under the License. 14 : 15 : package com.google.gerrit.server.util; 16 : 17 : import java.net.Inet6Address; 18 : import java.net.InetAddress; 19 : import java.net.InetSocketAddress; 20 : import java.net.SocketAddress; 21 : import java.net.UnknownHostException; 22 : 23 : public final class SocketUtil { 24 : /** True if this InetAddress is a raw IPv6 in dotted quad notation. */ 25 : public static boolean isIPv6(InetAddress ip) { 26 1 : return ip instanceof Inet6Address && ip.getHostName().equals(ip.getHostAddress()); 27 : } 28 : 29 : /** Get the name or IP address, or {@code *} if this address is a wildcard IP. */ 30 : public static String hostname(InetSocketAddress addr) { 31 28 : if (addr.getAddress() != null) { 32 28 : if (addr.getAddress().isAnyLocalAddress()) { 33 8 : return "*"; 34 : } 35 21 : return addr.getAddress().getHostName(); 36 : } 37 9 : return addr.getHostName(); 38 : } 39 : 40 : /** Format an address string into {@code host:port} or {@code *:port} syntax. */ 41 : public static String format(SocketAddress s, int defaultPort) { 42 28 : if (s instanceof InetSocketAddress) { 43 28 : final InetSocketAddress addr = (InetSocketAddress) s; 44 28 : if (addr.getPort() == defaultPort) { 45 1 : return safeHostname(hostname(addr)); 46 : } 47 28 : return format(hostname(addr), addr.getPort()); 48 : } 49 0 : return s.toString(); 50 : } 51 : 52 : /** Format an address string into {@code host:port} or {@code *:port} syntax. */ 53 : public static String format(String hostname, int port) { 54 28 : return safeHostname(hostname) + ":" + port; 55 : } 56 : 57 : private static String safeHostname(String hostname) { 58 28 : if (0 <= hostname.indexOf(':')) { 59 1 : hostname = "[" + hostname + "]"; 60 : } 61 28 : return hostname; 62 : } 63 : 64 : /** Parse an address string such as {@code host:port} or {@code *:port}. */ 65 : public static InetSocketAddress parse(String desc, int defaultPort) { 66 : String hostStr; 67 : String portStr; 68 : 69 21 : if (desc.startsWith("[")) { 70 : // IPv6, as a raw IP address. 71 : // 72 1 : final int hostEnd = desc.indexOf(']'); 73 1 : if (hostEnd < 0) { 74 1 : throw new IllegalArgumentException("invalid IPv6: " + desc); 75 : } 76 : 77 1 : hostStr = desc.substring(1, hostEnd); 78 1 : portStr = desc.substring(hostEnd + 1); 79 1 : } else { 80 : // IPv4, or a host name. 81 : // 82 21 : final int hostEnd = desc.indexOf(':'); 83 21 : hostStr = 0 <= hostEnd ? desc.substring(0, hostEnd) : desc; 84 21 : portStr = 0 <= hostEnd ? desc.substring(hostEnd) : ""; 85 : } 86 : 87 21 : if ("".equals(hostStr)) { 88 1 : hostStr = "*"; 89 : } 90 21 : if (portStr.startsWith(":")) { 91 21 : portStr = portStr.substring(1); 92 : } 93 : 94 : final int port; 95 21 : if (portStr.length() > 0) { 96 : try { 97 21 : port = Integer.parseInt(portStr); 98 1 : } catch (NumberFormatException e) { 99 1 : throw new IllegalArgumentException("invalid port: " + desc, e); 100 21 : } 101 : } else { 102 1 : port = defaultPort; 103 : } 104 : 105 21 : if ("*".equals(hostStr)) { 106 1 : return new InetSocketAddress(port); 107 : } 108 21 : return InetSocketAddress.createUnresolved(hostStr, port); 109 : } 110 : 111 : /** Parse and resolve an address string, looking up the IP address. */ 112 : public static InetSocketAddress resolve(String desc, int defaultPort) { 113 21 : final InetSocketAddress addr = parse(desc, defaultPort); 114 21 : if (addr.getAddress() != null && addr.getAddress().isAnyLocalAddress()) { 115 1 : return addr; 116 : } 117 : try { 118 21 : final InetAddress host = InetAddress.getByName(addr.getHostName()); 119 21 : return new InetSocketAddress(host, addr.getPort()); 120 0 : } catch (UnknownHostException e) { 121 0 : throw new IllegalArgumentException("unknown host: " + desc, e); 122 : } 123 : } 124 : 125 : private SocketUtil() {} 126 : }