Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions common/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ repositories {
}

dependencies {
implementation("org.yaml:snakeyaml:$snakeYamlVersion")
implementation("io.netty:netty-codec:$nettyVersion")
implementation("io.netty:netty-codec-haproxy:$nettyVersion")
implementation("commons-validator:commons-validator:1.7")
implementation("org.bstats:bstats-base:$bstatsBaseVersion")
implementation("org.slf4j:slf4j-api:$slf4jVersion")
implementation(kotlin("stdlib-jdk8"))
compileOnly("org.yaml:snakeyaml:$snakeYamlVersion")
compileOnly("io.netty:netty-codec:$nettyVersion")
compileOnly("io.netty:netty-codec-haproxy:$nettyVersion")
compileOnly("commons-validator:commons-validator:1.7")
compileOnly("org.bstats:bstats-base:$bstatsBaseVersion")
compileOnly("org.slf4j:slf4j-api:$slf4jVersion")
compileOnly(kotlin("stdlib-jdk8"))
}

kotlin {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package top.zient.haproxyreduce.common

import org.apache.commons.validator.routines.InetAddressValidator
import java.math.BigInteger
import java.net.InetAddress
import java.net.UnknownHostException
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
/*
* Taken from apache commons 2.1.
*/

package top.zient.haproxyreduce.common;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
* <p><b>InetAddress</b> validation and conversion routines (<code>java.net.InetAddress</code>).</p>
*
* <p>This class provides methods to validate a candidate IP address.
*
* <p>
* This class is a Singleton; you can retrieve the instance via the {@link #getInstance()} method.
* </p>
*
* @version $Revision$
* @since Validator 1.4
*/
public class InetAddressValidator implements Serializable {

private static final int IPV4_MAX_OCTET_VALUE = 255;

private static final int MAX_UNSIGNED_SHORT = 0xffff;

private static final int BASE_16 = 16;

private static final long serialVersionUID = -919201640201914789L;

private static final String IPV4_REGEX =
"^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$";

// Max number of hex groups (separated by :) in an IPV6 address
private static final int IPV6_MAX_HEX_GROUPS = 8;

// Max hex digits in each IPv6 group
private static final int IPV6_MAX_HEX_DIGITS_PER_GROUP = 4;

/**
* Singleton instance of this class.
*/
private static final InetAddressValidator VALIDATOR = new InetAddressValidator();

/** IPv4 RegexValidator */
private final RegexValidator ipv4Validator = new RegexValidator(IPV4_REGEX);

/**
* Returns the singleton instance of this validator.
* @return the singleton instance of this validator
*/
public static InetAddressValidator getInstance() {
return VALIDATOR;
}

/**
* Checks if the specified string is a valid IP address.
* @param inetAddress the string to validate
* @return true if the string validates as an IP address
*/
public boolean isValid(String inetAddress) {
return isValidInet4Address(inetAddress) || isValidInet6Address(inetAddress);
}

/**
* Validates an IPv4 address. Returns true if valid.
* @param inet4Address the IPv4 address to validate
* @return true if the argument contains a valid IPv4 address
*/
public boolean isValidInet4Address(String inet4Address) {
// verify that address conforms to generic IPv4 format
String[] groups = ipv4Validator.match(inet4Address);

if (groups == null) {
return false;
}

// verify that address subgroups are legal
for (String ipSegment : groups) {
if (ipSegment == null || ipSegment.length() == 0) {
return false;
}

int iIpSegment = 0;

try {
iIpSegment = Integer.parseInt(ipSegment);
} catch(NumberFormatException e) {
return false;
}

if (iIpSegment > IPV4_MAX_OCTET_VALUE) {
return false;
}

if (ipSegment.length() > 1 && ipSegment.startsWith("0")) {
return false;
}

}

return true;
}

/**
* Validates an IPv6 address. Returns true if valid.
* @param inet6Address the IPv6 address to validate
* @return true if the argument contains a valid IPv6 address
*
* @since 1.4.1
*/
public boolean isValidInet6Address(String inet6Address) {
String[] parts;
// remove prefix size. This will appear after the zone id (if any)
parts = inet6Address.split("/", -1);
if (parts.length > 2) {
return false; // can only have one prefix specifier
}
if (parts.length == 2) {
if (parts[1].matches("\\d{1,3}")) { // Need to eliminate signs
int bits = Integer.parseInt(parts[1]); // cannot fail because of RE check
if (bits < 0 || bits > 128) {
return false; // out of range
}
} else {
return false; // not a valid number
}
}
// remove zone-id
parts = parts[0].split("%", -1);
if (parts.length > 2) {
return false;
} else if (parts.length == 2){
// The id syntax is implemenatation independent, but it presumably cannot allow:
// whitespace, '/' or '%'
if (!parts[1].matches("[^\\s/%]+")) {
return false; // invalid id
}
}
inet6Address = parts[0];
boolean containsCompressedZeroes = inet6Address.contains("::");
if (containsCompressedZeroes && (inet6Address.indexOf("::") != inet6Address.lastIndexOf("::"))) {
return false;
}
if ((inet6Address.startsWith(":") && !inet6Address.startsWith("::"))
|| (inet6Address.endsWith(":") && !inet6Address.endsWith("::"))) {
return false;
}
String[] octets = inet6Address.split(":");
if (containsCompressedZeroes) {
List<String> octetList = new ArrayList<String>(Arrays.asList(octets));
if (inet6Address.endsWith("::")) {
// String.split() drops ending empty segments
octetList.add("");
} else if (inet6Address.startsWith("::") && !octetList.isEmpty()) {
octetList.remove(0);
}
octets = octetList.toArray(new String[octetList.size()]);
}
if (octets.length > IPV6_MAX_HEX_GROUPS) {
return false;
}
int validOctets = 0;
int emptyOctets = 0; // consecutive empty chunks
for (int index = 0; index < octets.length; index++) {
String octet = octets[index];
if (octet.length() == 0) {
emptyOctets++;
if (emptyOctets > 1) {
return false;
}
} else {
emptyOctets = 0;
// Is last chunk an IPv4 address?
if (index == octets.length - 1 && octet.contains(".")) {
if (!isValidInet4Address(octet)) {
return false;
}
validOctets += 2;
continue;
}
if (octet.length() > IPV6_MAX_HEX_DIGITS_PER_GROUP) {
return false;
}
int octetInt = 0;
try {
octetInt = Integer.parseInt(octet, BASE_16);
} catch (NumberFormatException e) {
return false;
}
if (octetInt < 0 || octetInt > MAX_UNSIGNED_SHORT) {
return false;
}
}
validOctets++;
}
if (validOctets > IPV6_MAX_HEX_GROUPS || (validOctets < IPV6_MAX_HEX_GROUPS && !containsCompressedZeroes)) {
return false;
}
return true;
}
}

Loading