All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.eventmesh.common.utils.IPUtils Maven / Gradle / Ivy

There is a newer version: 1.10.0-release
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.eventmesh.common.utils;

import org.apache.commons.lang3.StringUtils;

import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.NetworkInterface;
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Enumeration;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import io.netty.channel.Channel;

import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import inet.ipaddr.HostName;
import inet.ipaddr.IPAddress;
import inet.ipaddr.IPAddressString;

@Slf4j
public class IPUtils {

    @Getter
    public static String localAddress = init();

    private static String init() {
        // if the progress works under docker environment
        // return the host ip about this docker located from environment value
        String dockerHostIp = System.getenv("docker_host_ip");
        if (dockerHostIp != null && !"".equals(dockerHostIp)) {
            return dockerHostIp;
        }

        // priority of networkInterface when generating client ip
        String priority = System.getProperty("networkInterface.priority", "eth0 list = Arrays.asList(priority.split("<"));
        ArrayList preferList = new ArrayList<>(list);
        NetworkInterface preferNetworkInterface = null;
        boolean isInterfacePreferred = false;

        try {
            Enumeration enumeration1 = NetworkInterface.getNetworkInterfaces();
            while (enumeration1.hasMoreElements()) {
                final NetworkInterface networkInterface = enumeration1.nextElement();
                String interfaceName = networkInterface.getName();
                if (!isInterfacePreferred && preferList.contains(interfaceName)) {
                    isInterfacePreferred = true;
                }
                if (preferNetworkInterface == null) {
                    preferNetworkInterface = networkInterface;
                } else if (preferList.indexOf(interfaceName) // get the networkInterface that has higher priority
                    > preferList.indexOf(preferNetworkInterface.getName())) {
                    preferNetworkInterface = networkInterface;
                }
            }

            // Traversal Network interface to get the first non-loopback and non-private address
            ArrayList ipv4Result = new ArrayList();
            ArrayList ipv6Result = new ArrayList();

            if (preferNetworkInterface != null && isInterfacePreferred) {
                final Enumeration en = preferNetworkInterface.getInetAddresses();
                getIpResult(ipv4Result, ipv6Result, en);
            } else {
                Enumeration enumeration = NetworkInterface.getNetworkInterfaces();
                while (enumeration.hasMoreElements()) {
                    final NetworkInterface networkInterface = enumeration.nextElement();
                    final Enumeration en = networkInterface.getInetAddresses();
                    getIpResult(ipv4Result, ipv6Result, en);
                }
            }

            // prefer ipv4
            if (!ipv4Result.isEmpty()) {
                for (String ip : ipv4Result) {
                    if (isValidIPV4Address(ip) && !ip.startsWith("127.0") && !ip.startsWith("192.168")) {
                        return ip;
                    }
                }

                return ipv4Result.get(ipv4Result.size() - 1);
            } else if (!ipv6Result.isEmpty()) {
                return ipv6Result.get(0);
            }
            // If failed to find,fall back to localhost
            final InetAddress localHost = InetAddress.getLocalHost();
            return normalizeHostAddress(localHost);
        } catch (SocketException | UnknownHostException e) {
            log.error("socket or unknown host exception:", e);
        }
        return null;
    }

    public static boolean isValidIPV4Address(String ip) {

        // Regex for digit from 0 to 255.
        String zeroTo255 = "(\\d{1,2}|(0|1)\\"
            + "d{2}|2[0-4]\\d|25[0-5])";

        String regex = zeroTo255 + "\\."
            + zeroTo255 + "\\."
            + zeroTo255 + "\\."
            + zeroTo255;

        // Compile the ReGex
        Pattern p = Pattern.compile(regex);

        // If the IP address is empty, return false
        if (ip == null) {
            return false;
        }

        Matcher m = p.matcher(ip);

        // Return if the IP address matched the ReGex
        return m.matches();
    }

    private static void getIpResult(Collection ipv4Result, Collection ipv6Result, Enumeration en) {
        while (en.hasMoreElements()) {
            final InetAddress address = en.nextElement();
            if (!address.isLoopbackAddress()) {
                if (address instanceof Inet6Address) {
                    ipv6Result.add(normalizeHostAddress(address));
                } else {
                    ipv4Result.add(normalizeHostAddress(address));
                }
            }
        }
    }

    private static String normalizeHostAddress(final InetAddress localHost) {
        if (localHost instanceof Inet6Address) {
            return "[" + localHost.getHostAddress() + "]";
        } else {
            return localHost.getHostAddress();
        }
    }

    public static String parseChannelRemoteAddr(final Channel channel) {
        if (channel == null) {
            return "";
        }
        SocketAddress remote = channel.remoteAddress();
        final String addr = remote != null ? remote.toString() : "";

        if (addr.length() > 0) {
            int index = addr.lastIndexOf("/");
            if (index >= 0) {
                return addr.substring(index + 1);
            }

            return addr;
        }

        return "";
    }

    public static boolean isValidDomainOrIp(String url, List ipV4ReservedAddrs, List ipV6ReservedAddrs) {
        if (StringUtils.isBlank(url)) {
            return false;
        }
        // Engine only need to verify DNS transformed result
        if (isValidIp(url)) {
            return true;
        }
        IPAddress ipAddress = domain2Ip(url);
        if (ipAddress == null) {
            return false;
        }
        if (ipAddress.isIPv4()) {
            return !isReservedIp(ipAddress, ipV4ReservedAddrs);
        } else {
            return !isReservedIp(ipAddress, ipV6ReservedAddrs);
        }
    }

    public static boolean isValidIp(String url) {
        try {
            IPAddressString ipString = new IPAddressString(url);
            if (!ipString.isValid()) {
                return new IPAddressString(new URL(url).getHost()).isValid();
            }
        } catch (Exception e) {
            log.warn("Invalid URL format url={}", url, e);
            return false;
        }
        return true;
    }

    public static IPAddress domain2Ip(String url) {
        HostName hostName = new HostName(url);
        if (hostName.isValid()) {
            return hostName.getAddress();
        }
        try {
            String host = new URL(url).getHost();
            return new HostName(host).getAddress();
        } catch (MalformedURLException e) {
            log.error("Invalid URL format url={}", url, e);
            return null;
        }
    }

    private static boolean isReservedIp(IPAddress ipAddress, List reservedIps) {
        for (IPAddress address : reservedIps) {
            if (address.contains(ipAddress)) {
                return true;
            }
        }
        return false;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy