feature: support ipv6
Dubbo
访问 PR 界面:https://github.com/apache/incubator-seata/pull/5902
本地查看:
1 2 3 4 5
| $ git remote -vv origin git@github.com:solisamicus/incubator-seata.git (fetch) origin git@github.com:solisamicus/incubator-seata.git (push) upstream https://github.com/apache/incubator-seata.git (fetch) upstream https://github.com/apache/incubator-seata.git (push)
|
找到合并提交:
1 2 3 4 5 6
| $ git log upstream/2.x --grep="feature: support ipv6" commit df32ebe431c49b22889dae1816c621c3994914ce Author: Ifdevil <384867771@qq.com> Date: Mon Oct 9 13:47:42 2023 +0800
feature: support ipv6 (#5902)
|
查看具体改动:
1
| $ git show df32ebe431c49b22889dae1816c621c3994914ce
|
工具类
Java
$ \text {NetAddressValidatorUtil}$:链接
常量成员:
1 2 3 4 5 6 7
| private static final String PERCENT = "%" private static final String DOUBLE_COLON = "::" private static final String DOUBLE_COLON_FFFF = "::ffff:" private static final String FE80 = "fe80:" private static final int ZERO = 0 private static final int SEVEN = 7 private static final int FIVE = 5
|
正则表达式成员:
1 2 3 4 5
| private static final Pattern IPV4_PATTERN private static final Pattern IPV6_STD_PATTERN private static final Pattern IPV6_HEX_COMPRESSED_PATTERN private static final Pattern IPV6_MIXED_COMPRESSED_REGEX private static final Pattern IPV6_MIXED_UNCOMPRESSED_REGEX
|
公共方法:
1 2 3 4 5 6 7
| public static boolean isIPv4Address(String input) public static boolean isIPv6Address(String input) public static boolean isIPv6StdAddress(String input) public static boolean isIPv6HexCompressedAddress(String input) public static boolean isIPv6MixedAddress(String input) public static boolean isIPv6IPv4MappedAddress(String input) public static boolean isLinkLocalIPv6WithZoneIndex(String input)
|
$\text {NetUtil}$:链接
常量成员:
1 2 3 4 5 6 7 8
| private static final Logger LOGGER public static final boolean PREFER_IPV6_ADDRESSES private static final String LOCALHOST = "127.0.0.1" private static final String ANY_HOST = "0.0.0.0" public static final String LOCALHOST_IPV6 = "0:0:0:0:0:0:0:1" public static final String LOCALHOST_SHORT_IPV6 = "::1" public static final String ANY_HOST_IPV6 = "0:0:0:0:0:0:0:0" public static final String ANY_HOST_SHORT_IPV6 = "::"
|
缓存成员:
1 2
| private static volatile InetAddress LOCAL_ADDRESS = null private static final Set<String> FORBIDDEN_HOSTS
|
地址转换方法:
1 2 3 4 5 6
| public static String toStringAddress(SocketAddress address) public static String toIpAddress(SocketAddress address) public static String toStringAddress(InetSocketAddress address) public static InetSocketAddress toInetSocketAddress(String address) public static String[] splitIPPortStr(String address) public static long toLong(String address)
|
本地地址方法:
1 2 3 4 5
| public static String getLocalIp(String... preferredNetworks) public static String localIP() public static String getLocalHost() public static InetAddress getLocalAddress(String... preferredNetworks) private static InetAddress getLocalAddress0(String... preferredNetworks)
|
地址验证方法:
1 2 3 4 5 6 7 8
| public static void validAddress(InetSocketAddress address) private static boolean isValidAddress(InetAddress address) public static boolean isValidIp(String ip, boolean validLocalAndAny) private static String convertIpIfNecessary(String ip) public static boolean isValidIPv4(String ip) public static boolean isValidIPv6(String ip) private static boolean isUniqueLocalAddress(InetAddress address) private static String removeBrackets(String str)
|
Go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
| package util
import ( "regexp" "strings" )
type IPValidator struct { percent string doubleColon string doubleColonFFFF string fe80 string
ipv4Pattern *regexp.Regexp ipv6StdPattern *regexp.Regexp ipv6HexCompressedPattern *regexp.Regexp ipv6MixedCompressedPattern *regexp.Regexp ipv6MixedUncompressedPattern *regexp.Regexp }
var defaultIPValidator = newIPValidator()
func newIPValidator() *IPValidator { validator := &IPValidator{ percent: "%", doubleColon: "::", doubleColonFFFF: "::ffff:", fe80: "fe80:", }
validator.ipv4Pattern = regexp.MustCompile(`^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$`) validator.ipv6StdPattern = regexp.MustCompile(`^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$`) validator.ipv6HexCompressedPattern = regexp.MustCompile(`^((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)::((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)$`) validator.ipv6MixedCompressedPattern = regexp.MustCompile(`^((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)::((?:[0-9A-Fa-f]{1,4}:(?:[0-9A-Fa-f]{1,4}:)*)?)$`) validator.ipv6MixedUncompressedPattern = regexp.MustCompile(`^(?:[0-9a-fA-F]{1,4}:){6}$`)
return validator }
func IsIPv4(input string) bool { return defaultIPValidator.isIPv4(input) }
func (v *IPValidator) isIPv4(input string) bool { return v.ipv4Pattern.MatchString(input) }
func IsIPv6(input string) bool { return defaultIPValidator.isIPv6(input) }
func (v *IPValidator) isIPv6(input string) bool { return v.isIPv6Std(input) || v.isIPv6HexCompressed(input) || v.isLinkLocalIPv6WithZoneIndex(input) || v.isIPv6IPv4Mapped(input) || v.isIPv6Mixed(input) }
func IsIPv6Std(input string) bool { return defaultIPValidator.isIPv6Std(input) }
func (v *IPValidator) isIPv6Std(input string) bool { return v.ipv6StdPattern.MatchString(input) }
func IsIPv6HexCompressed(input string) bool { return defaultIPValidator.isIPv6HexCompressed(input) }
func (v *IPValidator) isIPv6HexCompressed(input string) bool { return v.ipv6HexCompressedPattern.MatchString(input) }
func IsIPv6Mixed(input string) bool { return defaultIPValidator.isIPv6Mixed(input) }
func (v *IPValidator) isIPv6Mixed(input string) bool { splitIndex := strings.LastIndex(input, ":") if splitIndex == -1 { return false }
ipv4Part := input[splitIndex+1:] ipv4Valid := v.isIPv4(ipv4Part)
ipv6Part := input[:splitIndex+1] if ipv6Part == v.doubleColon { return ipv4Valid }
ipv6Uncompressed := v.ipv6MixedUncompressedPattern.MatchString(ipv6Part) ipv6Compressed := v.ipv6MixedCompressedPattern.MatchString(ipv6Part)
return ipv4Valid && (ipv6Uncompressed || ipv6Compressed) }
func IsIPv6IPv4Mapped(input string) bool { return defaultIPValidator.isIPv6IPv4Mapped(input) }
func (v *IPValidator) isIPv6IPv4Mapped(input string) bool { if len(input) > 7 && strings.EqualFold(input[:7], v.doubleColonFFFF) { return v.isIPv4(input[7:]) } return false }
func IsLinkLocalIPv6WithZoneIndex(input string) bool { return defaultIPValidator.isLinkLocalIPv6WithZoneIndex(input) }
func (v *IPValidator) isLinkLocalIPv6WithZoneIndex(input string) bool { if len(input) > 5 && strings.EqualFold(input[:5], v.fe80) { lastIndex := strings.LastIndex(input, v.percent) if lastIndex > 0 && lastIndex < len(input)-1 { ipPart := input[:lastIndex] return v.isIPv6Std(ipPart) || v.isIPv6HexCompressed(ipPart) } } return false }
|
未完待续…