KLALB V3.6.0 写了一半

This commit is contained in:
Administrator
2026-02-27 08:32:03 +08:00
parent 816e672843
commit 620afef715
164 changed files with 8381 additions and 13495 deletions
@@ -0,0 +1,400 @@
package org.kne.cloud.network.ipv6;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicLong;
import org.kne.cloud.network.klalb.KLALBUtils;
/**
* 高性能IPv6地址实现,使用两个long代替byte[16]
* 大幅减少GC压力和提高路由表查找性能
*/
public final class IPv6Address implements Comparable<IPv6Address> {
private final long high;
private final long low;
// 常用常量地址
public static final IPv6Address LOOPBACK = new IPv6Address(0, 1);
public static final IPv6Address UNSPECIFIED = new IPv6Address(0, 0);
public static final IPv6Address LOCALHOST = LOOPBACK;
// IPv4映射的IPv6地址前缀
private static final long IPV4_MAPPED_HIGH = 0x0000_0000_0000_0000L;
private static final long IPV4_MAPPED_LOW_PREFIX = 0x0000_0000_FFFF_0000L;
// 构造方法
public IPv6Address(long high, long low) {
this.high = high;
this.low = low;
}
public IPv6Address(Inet6Address address) {
this(address.getAddress());
}
public IPv6Address(byte[] bytes) {
if (bytes.length != 16) {
throw new IllegalArgumentException("IPv6 address must be 16 bytes");
}
this. high = ((long)(bytes[0] & 0xFF) << 56) |
((long)(bytes[1] & 0xFF) << 48) |
((long)(bytes[2] & 0xFF) << 40) |
((long)(bytes[3] & 0xFF) << 32) |
((long)(bytes[4] & 0xFF) << 24) |
((long)(bytes[5] & 0xFF) << 16) |
((long)(bytes[6] & 0xFF) << 8) |
((long)(bytes[7] & 0xFF));
this.low = ((long)(bytes[8] & 0xFF) << 56) |
((long)(bytes[9] & 0xFF) << 48) |
((long)(bytes[10] & 0xFF) << 40) |
((long)(bytes[11] & 0xFF) << 32) |
((long)(bytes[12] & 0xFF) << 24) |
((long)(bytes[13] & 0xFF) << 16) |
((long)(bytes[14] & 0xFF) << 8) |
((long)(bytes[15] & 0xFF));
}
/**
* 从两个long创建IPv6地址
*/
public static IPv6Address valueOf(long high, long low) {
return new IPv6Address(high, low);
}
/**
* 从byte[16]创建IPv6地址(高性能版本)
*/
public static IPv6Address valueOf(byte[] bytes) {
return new IPv6Address(bytes);
}
/**
* 从ByteBuffer创建IPv6地址(零拷贝友好)
*/
public static IPv6Address valueOf(ByteBuffer buffer) {
if (buffer.remaining() < 16) {
throw new IllegalArgumentException("Buffer must have at least 16 bytes remaining");
}
long high = buffer.getLong();
long low = buffer.getLong();
return valueOf(high, low);
}
public static IPv6Address valueOf(int offset, ByteBuffer buffer) {
long high = buffer.getLong(offset);
long low = buffer.getLong(offset+8);
return valueOf(high, low);
}
/**
* 从字符串解析IPv6地址(高性能版本)
* @throws UnknownHostException
*/
public static IPv6Address valueOf(String ipString) throws UnknownHostException {
if (ipString == null || ipString.isEmpty()) {
throw new IllegalArgumentException("Invalid IPv6 address string");
}
return new IPv6Address((Inet6Address)Inet6Address.getByName(ipString));
}
/**
* 从Java InetAddress转换
*/
public static IPv6Address valueOf(InetAddress inetAddress) {
if (inetAddress == null) {
throw new IllegalArgumentException("InetAddress cannot be null");
}
byte[] bytes = inetAddress.getAddress();
if (bytes.length == 4) {
// IPv4地址,转换为IPv4映射的IPv6地址
return valueOf(IPV4_MAPPED_HIGH,
IPV4_MAPPED_LOW_PREFIX |
(((long)(bytes[0] & 0xFF) << 24) |
((bytes[1] & 0xFF) << 16) |
((bytes[2] & 0xFF) << 8) |
(bytes[3] & 0xFF)));
}
return valueOf(bytes);
}
// 核心getter方法
public long getHigh() {
return high;
}
public long getLow() {
return low;
}
/**
* 转换为byte[16](需要时使用)
*/
public byte[] toByteArray() {
byte[] bytes = new byte[16];
toByteArray(bytes, 0);
return bytes;
}
/**
* 写入到现有byte数组(避免创建新对象)
*/
public void toByteArray(byte[] dest, int offset) {
if (dest.length - offset < 16) {
throw new IllegalArgumentException("Destination array too small");
}
dest[offset] = (byte) (high >> 56);
dest[offset + 1] = (byte) (high >> 48);
dest[offset + 2] = (byte) (high >> 40);
dest[offset + 3] = (byte) (high >> 32);
dest[offset + 4] = (byte) (high >> 24);
dest[offset + 5] = (byte) (high >> 16);
dest[offset + 6] = (byte) (high >> 8);
dest[offset + 7] = (byte) high;
dest[offset + 8] = (byte) (low >> 56);
dest[offset + 9] = (byte) (low >> 48);
dest[offset + 10] = (byte) (low >> 40);
dest[offset + 11] = (byte) (low >> 32);
dest[offset + 12] = (byte) (low >> 24);
dest[offset + 13] = (byte) (low >> 16);
dest[offset + 14] = (byte) (low >> 8);
dest[offset + 15] = (byte) low;
}
/**
* 写入到ByteBuffer(高性能网络操作)
*/
public void writeTo(ByteBuffer buffer) {
buffer.putLong(high);
buffer.putLong(low);
}
public void writeTo(int offset, ByteBuffer buffer) {
buffer.putLong(offset,high);
buffer.putLong(offset+8,low);
}
/**
* 转换为标准IPv6字符串表示
*/
@Override
public String toString() {
try {
return Inet6Address.getByAddress(toByteArray()).getHostAddress();
} catch (UnknownHostException e) {
return "Internal Error";
}
}
/**
* 转换为压缩形式的字符串(::格式)
*/
public String toCompressedString() {
return KLALBUtils.parseAbbrIPv6(toString());
}
/**
* 检查是否为IPv4映射地址
*/
public boolean isIPv4MappedAddress() {
return high == IPV4_MAPPED_HIGH &&
(low & 0x0000_0000_FFFF_0000L) == IPV4_MAPPED_LOW_PREFIX;
}
/**
* 如果这是IPv4映射地址,提取IPv4部分
*/
public byte[] getIPv4Bytes() {
if (!isIPv4MappedAddress()) {
throw new IllegalStateException("Not an IPv4 mapped address");
}
byte[] ipv4 = new byte[4];
ipv4[0] = (byte) (low >> 24);
ipv4[1] = (byte) (low >> 16);
ipv4[2] = (byte) (low >> 8);
ipv4[3] = (byte) low;
return ipv4;
}
/**
* 检查是否为多播地址
*/
public boolean isMulticastAddress() {
return (high & 0xFF00_0000_0000_0000L) == 0xFF00_0000_0000_0000L;
}
/**
* 检查是否为链路本地地址
*/
public boolean isLinkLocalAddress() {
return (high & 0xFFC0_0000_0000_0000L) == 0xFE80_0000_0000_0000L;
}
/**
* 检查是否为站点本地地址(已弃用,但为了兼容性保留)
*/
public boolean isSiteLocalAddress() {
return (high & 0xFFC0_0000_0000_0000L) == 0xFEC0_0000_0000_0000L;
}
/**
* 检查是否为唯一本地地址 (ULA)
*/
public boolean isUniqueLocalAddress() {
return (high & 0xFE00_0000_0000_0000L) == 0xFC00_0000_0000_0000L;
}
/**
* 检查是否为环回地址
*/
public boolean isLoopbackAddress() {
return this.equals(LOOPBACK);
}
/**
* 检查是否为未指定地址
*/
public boolean isUnspecifiedAddress() {
return this.equals(UNSPECIFIED);
}
/**
* 获取多播地址的scope
*/
public int getMulticastScope() {
if (!isMulticastAddress()) {
return -1;
}
return (int) ((low >> 48) & 0x0F);
}
// 路由表相关的实用方法
/**
* 创建掩码(用于CIDR表示法)
*/
public static IPv6Address createMask(int prefixLength) {
if (prefixLength < 0 || prefixLength > 128) {
throw new IllegalArgumentException("Prefix length must be between 0 and 128");
}
long maskHigh, maskLow;
if (prefixLength == 128) {
maskHigh = -1L; // 0xFFFFFFFF_FFFFFFFF
maskLow = -1L;
} else if (prefixLength > 64) {
maskHigh = -1L;
maskLow = (-1L) << (64 - (prefixLength - 64));
} else if (prefixLength == 64) {
maskHigh = -1L;
maskLow = 0;
} else {
maskHigh = (-1L) << (64 - prefixLength);
maskLow = 0;
}
return valueOf(maskHigh, maskLow);
}
/**
* 应用掩码(用于网络地址计算)
*/
public IPv6Address maskWith(IPv6Address mask) {
return valueOf(high & mask.high, low & mask.low);
}
/**
* 检查地址是否在指定网络内
*/
public boolean isInNetwork(IPv6Address network, IPv6Address mask) {
IPv6Address maskedThis = this.maskWith(mask);
IPv6Address maskedNetwork = network.maskWith(mask);
return maskedThis.equals(maskedNetwork);
}
/**
* 检查地址是否在指定CIDR网络内
*/
public boolean isInNetwork(IPv6Address network, int prefixLength) {
IPv6Address mask = createMask(prefixLength);
return isInNetwork(network, mask);
}
// 比较和哈希
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
IPv6Address other = (IPv6Address) obj;
return high == other.high && low == other.low;
}
@Override
public int hashCode() {
// 优化的哈希计算,考虑long的分布
return (int) (high ^ (high >>> 32) ^ low ^ (low >>> 32));
}
@Override
public int compareTo(IPv6Address other) {
int highCompare = Long.compareUnsigned(high, other.high);
if (highCompare != 0) return highCompare;
return Long.compareUnsigned(low, other.low);
}
public static void main(String[] args) throws UnknownHostException {
// 创建IPv6地址
IPv6Address addr1 = IPv6Address.valueOf("2001:db8::1");
IPv6Address addr2 = IPv6Address.valueOf(0x20010DB800000000L, 0x0000000000000001L);
// 高性能路由表查找
IPv6Address target = IPv6Address.valueOf("2001:db8:1234::5678");
IPv6Address network = IPv6Address.valueOf("2001:db8:1234::");
int prefixLength = 64;
if (target.isInNetwork(network, prefixLength)) {
System.out.println("地址在目标网络内");
}
// 转换为字节数组(需要时)
byte[] bytes = addr1.toByteArray();
// 直接写入ByteBuffer(零拷贝)
ByteBuffer buffer = ByteBuffer.allocateDirect(16);
addr1.writeTo(buffer);
}
public Inet6Address toInet6Address() {
try {
return (Inet6Address) Inet6Address.getByAddress(toByteArray());
} catch (UnknownHostException e) {
return null;
}
}
public boolean isAnyLocalAddress() {
return high==0&&low==0;
}
}