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

host.anzo.commons.utils.IpUtils Maven / Gradle / Ivy

There is a newer version: 1.29
Show newest version
package host.anzo.commons.utils;

import host.anzo.core.service.CloudflareService;
import host.anzo.core.service.HttpService;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.jetty.websocket.api.Session;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import spark.Request;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;

/**
 * @author ANZO
 */
@Slf4j
public class IpUtils {
    private static final Pattern VALID_IPV4_PATTERN = Pattern.compile("(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d\\d?|2[0-4]\\d|25[0-5])", Pattern.CASE_INSENSITIVE);
    private static String EXTERNAL_IP = null;

    /**
     * @return external IP address, {@code null} if can't detect external IP
     */
    public static @Nullable String getExternalIP() {
        if (checkIPv4(EXTERNAL_IP)) {
            return EXTERNAL_IP;
        }
        String ip = HttpService.getInstance().httpGet("https://api.ipify.org/");
        if (!checkIPv4(ip)) {
            ip = HttpService.getInstance().httpGet("http://ipinfo.io/ip");
        }
        if (!checkIPv4(ip)) {
            ip = HttpService.getInstance().httpGet("https://www.trackip.net/ip");
        }
        if (!checkIPv4(ip)) {
            ip = HttpService.getInstance().httpGet("http://checkip.amazonaws.com/");
        }
        if (checkIPv4(ip)) {
            EXTERNAL_IP = ip;
            return ip;
        }
        return null;
    }

    /**
     * @param address address for check
     * @return {@code true} if specified address is local, {@code false} otherwise
     */
    public static boolean isLocalAddress(@NotNull InetAddress address) {
        // Check if the address is a valid special local or loop back
        if (address.isAnyLocalAddress() || address.isLoopbackAddress()) {
            return true;
        }

        // Check if the address is defined on any interface
        try {
            return NetworkInterface.getByInetAddress(address) != null;
        } catch (SocketException e) {
            return false;
        }
    }

    /**
     * @param address address to ping
     * @return "dirty" (request-response) ping to specified InetAddress
     */
    public static long getPing(@NotNull InetAddress address) {
        try {
            final long startTime = System.nanoTime();
            final boolean status = address.isReachable(1000);
            if (status) {
                return TimeUnit.MILLISECONDS.convert(System.nanoTime() - startTime, TimeUnit.NANOSECONDS);
            }
            else {
                return -1;
            }
        }
        catch (Exception e) {
            return -1;
        }
    }

    /**
     * @param ip IP for check
     * @return {@code true} if specified IP string is valid IPv4 address
     */
    private static boolean checkIPv4(final String ip) {
        if (ip == null || ip.isEmpty()) {
            return false;
        }
        return VALID_IPV4_PATTERN.matcher(ip).matches();
    }

    /**
     * @param request request object
     * @return real client IP (in case if using reverse-proxify like a CloudFlare)
     */
    public static String getRealIp(@NotNull Request request) {
        if (CloudflareService.getInstance().isCloudflareIP(request.ip())) {
            final String realIp = request.headers("CF-Connecting-IP");
            if (realIp != null) {
                return realIp;
            }
        }
        return request.ip();
    }

    /**
     * @param session websocket session
     * @return extracted from websocket session IP address
     */
    public static String getRealIp(@NotNull Session session) {
        final String cloudflareTunnelIp = session.getUpgradeRequest().getHeader("Cf-Connecting-Ip");
        if (cloudflareTunnelIp != null) {
            return cloudflareTunnelIp;
        }
        return ((InetSocketAddress)session.getRemoteAddress()).getHostString();
    }

    /**
     * @param ip IP address
     * @return IP address packed to long
     */
    public static long toLong(final @NotNull String ip) {
        try {
            final String[] octets = ip.split("\\.");
            final int[] octetsNum = new int[] {
                    Integer.parseInt(octets[0]),
                    Integer.parseInt(octets[1]),
                    Integer.parseInt(octets[2]),
                    Integer.parseInt(octets[3])
            };
            return (((long)octetsNum[0] * (int)Math.pow(256, 3)) + ((long)octetsNum[1] * (int)Math.pow(256, 2)) + (octetsNum[2] * 256L) + (octetsNum[3]));
        }
        catch (Exception e) {
            log.error("Can't parse ip=[{}] to long", ip);
            return 0;
        }
    }

    /**
     * @param ipLong IP address as packed long value
     * @return unpacked from long IP address
     */
    public static @NotNull String fromLong(final long ipLong) {
        return ((ipLong >> 24) & 0xFF) + "." + ((ipLong >> 16 ) & 0xFF) + "." + ((ipLong >> 8) & 0xFF) + "." + (ipLong & 0xFF);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy