001/** 002 * 003 * Licensed to the Apache Software Foundation (ASF) under one 004 * or more contributor license agreements. See the NOTICE file 005 * distributed with this work for additional information 006 * regarding copyright ownership. The ASF licenses this file 007 * to you under the Apache License, Version 2.0 (the 008 * "License"); you may not use this file except in compliance 009 * with the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 */ 019package org.apache.hadoop.hbase.util; 020 021import java.net.Inet4Address; 022import java.net.Inet6Address; 023import java.net.InetAddress; 024import java.net.InetSocketAddress; 025import java.net.NetworkInterface; 026import java.net.SocketException; 027import java.util.Enumeration; 028 029import org.apache.yetus.audience.InterfaceAudience; 030 031/** 032 * Utility for network addresses, resolving and naming. 033 */ 034@InterfaceAudience.Private 035public class Addressing { 036 public static final String VALID_PORT_REGEX = "[\\d]+"; 037 public static final String HOSTNAME_PORT_SEPARATOR = ":"; 038 039 /** 040 * @param hostAndPort Formatted as <code><hostname> ':' <port></code> 041 * @return An InetSocketInstance 042 */ 043 public static InetSocketAddress createInetSocketAddressFromHostAndPortStr( 044 final String hostAndPort) { 045 return new InetSocketAddress(parseHostname(hostAndPort), parsePort(hostAndPort)); 046 } 047 048 /** 049 * @param hostname Server hostname 050 * @param port Server port 051 * @return Returns a concatenation of <code>hostname</code> and 052 * <code>port</code> in following 053 * form: <code><hostname> ':' <port></code>. For example, if hostname 054 * is <code>example.org</code> and port is 1234, this method will return 055 * <code>example.org:1234</code> 056 */ 057 public static String createHostAndPortStr(final String hostname, final int port) { 058 return hostname + HOSTNAME_PORT_SEPARATOR + port; 059 } 060 061 /** 062 * @param hostAndPort Formatted as <code><hostname> ':' <port></code> 063 * @return The hostname portion of <code>hostAndPort</code> 064 */ 065 public static String parseHostname(final String hostAndPort) { 066 int colonIndex = hostAndPort.lastIndexOf(HOSTNAME_PORT_SEPARATOR); 067 if (colonIndex < 0) { 068 throw new IllegalArgumentException("Not a host:port pair: " + hostAndPort); 069 } 070 return hostAndPort.substring(0, colonIndex); 071 } 072 073 /** 074 * @param hostAndPort Formatted as <code><hostname> ':' <port></code> 075 * @return The port portion of <code>hostAndPort</code> 076 */ 077 public static int parsePort(final String hostAndPort) { 078 int colonIndex = hostAndPort.lastIndexOf(HOSTNAME_PORT_SEPARATOR); 079 if (colonIndex < 0) { 080 throw new IllegalArgumentException("Not a host:port pair: " + hostAndPort); 081 } 082 return Integer.parseInt(hostAndPort.substring(colonIndex + 1)); 083 } 084 085 public static InetAddress getIpAddress() throws SocketException { 086 return getIpAddress(new AddressSelectionCondition() { 087 @Override 088 public boolean isAcceptableAddress(InetAddress addr) { 089 return addr instanceof Inet4Address || addr instanceof Inet6Address; 090 } 091 }); 092 } 093 094 public static InetAddress getIp4Address() throws SocketException { 095 return getIpAddress(new AddressSelectionCondition() { 096 @Override 097 public boolean isAcceptableAddress(InetAddress addr) { 098 return addr instanceof Inet4Address; 099 } 100 }); 101 } 102 103 public static InetAddress getIp6Address() throws SocketException { 104 return getIpAddress(new AddressSelectionCondition() { 105 @Override 106 public boolean isAcceptableAddress(InetAddress addr) { 107 return addr instanceof Inet6Address; 108 } 109 }); 110 } 111 112 private static InetAddress getIpAddress(AddressSelectionCondition condition) throws 113 SocketException { 114 // Before we connect somewhere, we cannot be sure about what we'd be bound to; however, 115 // we only connect when the message where client ID is, is long constructed. Thus, 116 // just use whichever IP address we can find. 117 Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces(); 118 while (interfaces.hasMoreElements()) { 119 NetworkInterface current = interfaces.nextElement(); 120 if (!current.isUp() || current.isLoopback() || current.isVirtual()) continue; 121 Enumeration<InetAddress> addresses = current.getInetAddresses(); 122 while (addresses.hasMoreElements()) { 123 InetAddress addr = addresses.nextElement(); 124 if (addr.isLoopbackAddress()) continue; 125 if (condition.isAcceptableAddress(addr)) { 126 return addr; 127 } 128 } 129 } 130 131 throw new SocketException("Can't get our ip address, interfaces are: " + interfaces); 132 } 133 134 /** 135 * Given an InetAddress, checks to see if the address is a local address, by comparing the address 136 * with all the interfaces on the node. 137 * @param addr address to check if it is local node's address 138 * @return true if the address corresponds to the local node 139 */ 140 public static boolean isLocalAddress(InetAddress addr) { 141 // Check if the address is any local or loop back 142 boolean local = addr.isAnyLocalAddress() || addr.isLoopbackAddress(); 143 144 // Check if the address is defined on any interface 145 if (!local) { 146 try { 147 local = NetworkInterface.getByInetAddress(addr) != null; 148 } catch (SocketException e) { 149 local = false; 150 } 151 } 152 return local; 153 } 154 155 /** 156 * Interface for AddressSelectionCondition to check if address is acceptable 157 */ 158 public interface AddressSelectionCondition{ 159 /** 160 * Condition on which to accept inet address 161 * @param address to check 162 * @return true to accept this address 163 */ 164 public boolean isAcceptableAddress(InetAddress address); 165 } 166}