1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements.  See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership.  The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License.  You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 package org.apache.zookeeper.common;
20 
21 import java.net.Inet6Address;
22 import java.net.InetAddress;
23 import java.net.InetSocketAddress;
24 
25 /**
26  * This class contains common utilities for netstuff. Like printing IPv6 literals correctly
27  */
28 public class NetUtils {
29 
formatInetAddr(InetSocketAddress addr)30     public static String formatInetAddr(InetSocketAddress addr) {
31         InetAddress ia = addr.getAddress();
32 
33         if (ia == null) {
34             return String.format("%s:%s", addr.getHostString(), addr.getPort());
35         }
36 
37         if (ia instanceof Inet6Address) {
38             return String.format("[%s]:%s", ia.getHostAddress(), addr.getPort());
39         } else {
40             return String.format("%s:%s", ia.getHostAddress(), addr.getPort());
41         }
42     }
43 
44     /**
45      * Separates host and port from given host port string if host port string is enclosed
46      * within square bracket.
47      *
48      * @param hostPort host port string
49      * @return String[]{host, port} if host port string is host:port
50      * or String[] {host, port:port} if host port string is host:port:port
51      * or String[] {host} if host port string is host
52      * or String[]{} if not a ipv6 host port string.
53      */
getIPV6HostAndPort(String hostPort)54     public static String[] getIPV6HostAndPort(String hostPort) {
55         if (hostPort.startsWith("[")) {
56             int i = hostPort.lastIndexOf(']');
57             if (i < 0) {
58                 throw new IllegalArgumentException(
59                     hostPort + " starts with '[' but has no matching ']'");
60             }
61             String host = hostPort.substring(1, i);
62             if (host.isEmpty()) {
63                 throw new IllegalArgumentException(host + " is empty.");
64             }
65             if (hostPort.length() > i + 1) {
66                 return getHostPort(hostPort, i, host);
67             }
68             return new String[] { host };
69         } else {
70             //Not an IPV6 host port string
71             return new String[] {};
72         }
73     }
74 
getHostPort(String hostPort, int indexOfClosingBracket, String host)75     private static String[] getHostPort(String hostPort, int indexOfClosingBracket, String host) {
76         // [127::1]:2181 , check separator : exits
77         if (hostPort.charAt(indexOfClosingBracket + 1) != ':') {
78             throw new IllegalArgumentException(hostPort + " does not have : after ]");
79         }
80         // [127::1]: scenario
81         if (indexOfClosingBracket + 2 == hostPort.length()) {
82             throw new IllegalArgumentException(hostPort + " doesn't have a port after colon.");
83         }
84         //do not include
85         String port = hostPort.substring(indexOfClosingBracket + 2);
86         return new String[] { host, port };
87     }
88 }
89