2 * Copyright 2015-present Open Networking Foundation
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package io.atomix.utils.net;
18 import java.net.Inet6Address;
19 import java.net.InetAddress;
20 import java.net.UnknownHostException;
21 import java.util.Objects;
24 * Representation of a network address.
26 public final class Address {
27 private static final int DEFAULT_PORT = 5679;
38 * Returns an address that binds to all interfaces.
42 public static Address local() {
43 return from(DEFAULT_PORT);
47 * Returns the address from the given host:port string.
49 * @param address the address string
52 public static Address from(String address) {
53 int lastColon = address.lastIndexOf(':');
54 int openBracket = address.indexOf('[');
55 int closeBracket = address.indexOf(']');
58 if (openBracket != -1 && closeBracket != -1) {
59 host = address.substring(openBracket + 1, closeBracket);
60 } else if (lastColon != -1) {
61 host = address.substring(0, lastColon);
67 if (lastColon != -1) {
69 port = Integer.parseInt(address.substring(lastColon + 1));
70 } catch (NumberFormatException e) {
71 throw new MalformedAddressException(address, e);
76 return new Address(host, port);
80 * Returns an address for the given host/port.
82 * @param host the host name
83 * @param port the port
84 * @return a new address
86 public static Address from(String host, int port) {
87 return new Address(host, port);
91 * Returns an address for the local host and the given port.
93 * @param port the port
94 * @return a new address
96 public static Address from(int port) {
98 InetAddress address = getLocalAddress();
99 return new Address(address.getHostName(), port);
100 } catch (UnknownHostException e) {
101 throw new IllegalArgumentException("Failed to locate host", e);
106 * Returns the local host.
108 private static InetAddress getLocalAddress() throws UnknownHostException {
110 return InetAddress.getLocalHost(); // first NIC
111 } catch (Exception ignore) {
112 return InetAddress.getByName(null);
116 private final String host;
117 private final int port;
118 private transient volatile Type type;
119 private transient volatile InetAddress address;
121 public Address(String host, int port) {
122 this(host, port, null);
125 public Address(String host, int port, InetAddress address) {
128 this.address = address;
129 if (address != null) {
130 this.type = address instanceof Inet6Address ? Type.IPV6 : Type.IPV4;
135 * Returns the host name.
137 * @return the host name
139 public String host() {
153 * Returns the IP address.
155 * @return the IP address
157 public InetAddress address() {
158 return address(false);
162 * Returns the IP address.
164 * @param resolve whether to force resolve the hostname
165 * @return the IP address
167 public InetAddress address(boolean resolve) {
169 address = resolveAddress();
173 if (address == null) {
174 synchronized (this) {
175 if (address == null) {
176 address = resolveAddress();
184 * Resolves the IP address from the hostname.
186 * @return the resolved IP address or {@code null} if the IP could not be resolved
188 private InetAddress resolveAddress() {
190 return InetAddress.getByName(host);
191 } catch (UnknownHostException e) {
197 * Returns the address type.
199 * @return the address type
203 synchronized (this) {
205 type = address() instanceof Inet6Address ? Type.IPV6 : Type.IPV4;
213 public String toString() {
214 String host = host();
216 if (host.matches("([0-9a-f]{1,4}:){7}([0-9a-f]){1,4}")) {
217 return String.format("[%s]:%d", host, port);
219 return String.format("%s:%d", host, port);
224 public int hashCode() {
225 return Objects.hash(host, port);
229 public boolean equals(Object obj) {
233 if (!(obj instanceof Address)) {
236 Address that = (Address) obj;
237 return this.host.equals(that.host)
238 && this.port == that.port;