From 20d002542c36bf2460532c742bde5285c2a1ff41 Mon Sep 17 00:00:00 2001 From: jsonwan Date: Mon, 28 Nov 2022 16:05:29 +0800 Subject: [PATCH 1/3] =?UTF-8?q?bugfix:=20=E7=BA=AFIPv6=E7=8E=AF=E5=A2=83?= =?UTF-8?q?=E5=88=86=E5=8F=91=E6=9C=AC=E5=9C=B0=E6=96=87=E4=BB=B6/?= =?UTF-8?q?=E7=AC=AC=E4=B8=89=E6=96=B9=E6=96=87=E4=BB=B6=E4=B8=80=E7=9B=B4?= =?UTF-8?q?=E5=8D=A1=E4=BD=8F=20#1530?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 获取本机/file-worker所在机器IPv6时使用完整无压缩格式 --- .../bk/job/common/util/ip/IpUtils.java | 68 ++++++++++++++++++- .../bk/job/common/util/IpUtilsTest.java | 42 ++++++++++++ .../service/impl/AgentServiceImpl.java | 5 ++ .../cos/service/EnvironmentService.java | 4 ++ 4 files changed, 118 insertions(+), 1 deletion(-) diff --git a/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/util/ip/IpUtils.java b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/util/ip/IpUtils.java index 13b718959a..e8908aeee7 100644 --- a/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/util/ip/IpUtils.java +++ b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/util/ip/IpUtils.java @@ -205,6 +205,12 @@ public static boolean compileIP(String ip) { return matcher.matches(); } + /** + * 从网卡获取首个机器IP,优先获取IPv4地址 + * 若获取到的值为v6协议的IP,默认提供完整无压缩的IPv6地址 + * + * @return 首个机器IP地址 + */ public static String getFirstMachineIP() { return getFirstMachineIpPreferV4(); } @@ -216,7 +222,8 @@ private static String getFirstMachineIpPreferV4() { } Map ipv6Map = getMachineIPv6Map(); if (!ipv6Map.isEmpty()) { - return ipv6Map.values().iterator().next(); + String ipv6 = ipv6Map.values().iterator().next(); + return getFullIpv6ByCompressedOne(ipv6); } log.error("no available ip, plz check net interface"); return null; @@ -361,4 +368,63 @@ public static String inferProtocolByIp(String ip) { } return PROTOCOL_IP_V4; } + + /** + * 有压缩的IPv6地址转换成完整无压缩的IPv6 + * + * @param compressedIpv6 有压缩的IPv6地址 + * @return 完整无压缩的IPv6地址 + */ + public static String getFullIpv6ByCompressedOne(String compressedIpv6) { + if (StringUtils.isEmpty(compressedIpv6)) { + return compressedIpv6; + } + String[] finalSeqArr = new String[]{"0000", "0000", "0000", "0000", "0000", "0000", "0000", "0000"}; + // 连续0标识符 + String continueZeroToken = "::"; + // 段之间分隔符 + String seqSeparator = ":"; + // 一个IPv6地址最多有8段 + int maxSeqNum = 8; + if (compressedIpv6.startsWith(continueZeroToken)) { + compressedIpv6 = "0" + compressedIpv6; + } + if (compressedIpv6.endsWith(continueZeroToken)) { + compressedIpv6 = compressedIpv6 + "0"; + } + if (compressedIpv6.contains(continueZeroToken)) { + String[] seqArr = compressedIpv6.split(continueZeroToken); + String[] leftSeqArr = seqArr[0].split(seqSeparator); + for (int i = 0; i < leftSeqArr.length && i < maxSeqNum; i++) { + finalSeqArr[i] = getStandardIpv6Seq(leftSeqArr[i]); + } + String[] rightSeqArr = seqArr[1].split(seqSeparator); + for (int i = 0; i < rightSeqArr.length && i < maxSeqNum; i++) { + finalSeqArr[i + maxSeqNum - rightSeqArr.length] = getStandardIpv6Seq(rightSeqArr[i]); + } + } else { + String[] seqArr = compressedIpv6.split(seqSeparator); + for (int i = 0; i < seqArr.length && i < maxSeqNum; i++) { + finalSeqArr[i] = getStandardIpv6Seq(seqArr[i]); + } + } + return StringUtils.join(finalSeqArr, ":"); + } + + /** + * 获取含有4个字符的Ipv6标准段,不足4字符则添加前缀0,超出4字符则截取最后4字符 + * + * @param ipv6Seq ipv6地址的一段 + * @return 4个字符的标准段 + */ + public static String getStandardIpv6Seq(String ipv6Seq) { + String template = "0000"; + if (StringUtils.isBlank(ipv6Seq)) { + return template; + } + if (ipv6Seq.length() > template.length()) { + return ipv6Seq.substring(ipv6Seq.length() - template.length()); + } + return template.substring(0, template.length() - ipv6Seq.length()) + ipv6Seq; + } } diff --git a/src/backend/commons/common/src/test/java/com/tencent/bk/job/common/util/IpUtilsTest.java b/src/backend/commons/common/src/test/java/com/tencent/bk/job/common/util/IpUtilsTest.java index 13a81dc02e..c9565e480b 100644 --- a/src/backend/commons/common/src/test/java/com/tencent/bk/job/common/util/IpUtilsTest.java +++ b/src/backend/commons/common/src/test/java/com/tencent/bk/job/common/util/IpUtilsTest.java @@ -63,8 +63,10 @@ void testCheckIpv6() { assertThat(IpUtils.checkIpv6("01:23:45:67:89:ab:cd:ef")).isTrue(); assertThat(IpUtils.checkIpv6("001:023:45:67:89:ab:cd:ef")).isTrue(); assertThat(IpUtils.checkIpv6("1101:23:45:67:89:ab:cd:ef")).isTrue(); + assertThat(IpUtils.checkIpv6("::192.168.0.1")).isTrue(); assertThat(IpUtils.checkIpv6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")).isTrue(); assertThat(IpUtils.checkIpv6("0ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")).isFalse(); + assertThat(IpUtils.checkIpv6("::192.168.0.1/96")).isFalse(); assertThat(IpUtils.checkIpv6("ff:ff:ff:ff:ff:ff:ff:fg")).isFalse(); assertThat(IpUtils.checkIpv6("1::1::1")).isFalse(); assertThat(IpUtils.checkIpv6("1::1::123")).isFalse(); @@ -116,4 +118,44 @@ void testInferProtocolByIp() { assertThat(IpUtils.inferProtocolByIp("::1")).isNotEqualTo(IpUtils.PROTOCOL_IP_V4); assertThat(IpUtils.inferProtocolByIp("01:23:45:67:89:ab:cd:ef")).isNotEqualTo(IpUtils.PROTOCOL_IP_V4); } + + @Test + void testGetStandardIpv6Seq() { + assertThat(IpUtils.getStandardIpv6Seq("")).isEqualTo("0000"); + assertThat(IpUtils.getStandardIpv6Seq("0")).isEqualTo("0000"); + assertThat(IpUtils.getStandardIpv6Seq("1")).isEqualTo("0001"); + assertThat(IpUtils.getStandardIpv6Seq("1001")).isEqualTo("1001"); + assertThat(IpUtils.getStandardIpv6Seq("ff")).isEqualTo("00ff"); + assertThat(IpUtils.getStandardIpv6Seq("aabbcc")).isEqualTo("bbcc"); + } + + @Test + void testGetFullIpv6ByCompressedOne() { + assertThat(IpUtils.getFullIpv6ByCompressedOne(null)).isEqualTo(null); + assertThat(IpUtils.getFullIpv6ByCompressedOne("")).isEqualTo(""); + assertThat(IpUtils.getFullIpv6ByCompressedOne("::")) + .isEqualTo("0000:0000:0000:0000:0000:0000:0000:0000"); + assertThat(IpUtils.getFullIpv6ByCompressedOne("::1")) + .isEqualTo("0000:0000:0000:0000:0000:0000:0000:0001"); + assertThat(IpUtils.getFullIpv6ByCompressedOne("0::1")) + .isEqualTo("0000:0000:0000:0000:0000:0000:0000:0001"); + assertThat(IpUtils.getFullIpv6ByCompressedOne("00::1")) + .isEqualTo("0000:0000:0000:0000:0000:0000:0000:0001"); + assertThat(IpUtils.getFullIpv6ByCompressedOne("0000::1")) + .isEqualTo("0000:0000:0000:0000:0000:0000:0000:0001"); + assertThat(IpUtils.getFullIpv6ByCompressedOne("00000::1")) + .isEqualTo("0000:0000:0000:0000:0000:0000:0000:0001"); + assertThat(IpUtils.getFullIpv6ByCompressedOne("1:0000::1")) + .isEqualTo("0001:0000:0000:0000:0000:0000:0000:0001"); + assertThat(IpUtils.getFullIpv6ByCompressedOne("1:1:1:1:1:1:1:1")) + .isEqualTo("0001:0001:0001:0001:0001:0001:0001:0001"); + assertThat(IpUtils.getFullIpv6ByCompressedOne("1:1:1:0:0:1:1:1")) + .isEqualTo("0001:0001:0001:0000:0000:0001:0001:0001"); + assertThat(IpUtils.getFullIpv6ByCompressedOne("ffff:1:1:0:0:1:1:ffff")) + .isEqualTo("ffff:0001:0001:0000:0000:0001:0001:ffff"); + assertThat(IpUtils.getFullIpv6ByCompressedOne("aaffff:1:1:0:0:1:1:bbffff")) + .isEqualTo("ffff:0001:0001:0000:0000:0001:0001:ffff"); + assertThat(IpUtils.getFullIpv6ByCompressedOne("ffff:0001:0001:0000:0000:0001:0001:ffff")) + .isEqualTo("ffff:0001:0001:0000:0000:0001:0001:ffff"); + } } diff --git a/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/service/impl/AgentServiceImpl.java b/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/service/impl/AgentServiceImpl.java index 8b1864ad36..ebc9ff71c6 100644 --- a/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/service/impl/AgentServiceImpl.java +++ b/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/service/impl/AgentServiceImpl.java @@ -29,6 +29,7 @@ import com.google.common.cache.LoadingCache; import com.tencent.bk.job.common.gse.service.AgentStateClient; import com.tencent.bk.job.common.model.dto.HostDTO; +import com.tencent.bk.job.common.util.ip.IpUtils; import com.tencent.bk.job.execute.engine.consts.Consts; import com.tencent.bk.job.execute.model.ServersDTO; import com.tencent.bk.job.execute.service.AgentService; @@ -118,8 +119,12 @@ private HostDTO getAgentBindHost() { } ServiceHostDTO host; if (physicalMachineMultiIp.contains(":")) { + // IPv6地址 + // 首先转为完整无压缩格式 + physicalMachineMultiIp = IpUtils.getFullIpv6ByCompressedOne(physicalMachineMultiIp); host = getServiceHostByMultiIpv6(physicalMachineMultiIp); } else { + // IPv4地址 host = getServiceHostByMultiIpv4(physicalMachineMultiIp); } if (host == null) { diff --git a/src/backend/job-file-worker-sdk/service-job-file-worker-sdk/src/main/java/com/tencent/bk/job/file/worker/cos/service/EnvironmentService.java b/src/backend/job-file-worker-sdk/service-job-file-worker-sdk/src/main/java/com/tencent/bk/job/file/worker/cos/service/EnvironmentService.java index d50f8bf2bb..1afd57bbc1 100644 --- a/src/backend/job-file-worker-sdk/service-job-file-worker-sdk/src/main/java/com/tencent/bk/job/file/worker/cos/service/EnvironmentService.java +++ b/src/backend/job-file-worker-sdk/service-job-file-worker-sdk/src/main/java/com/tencent/bk/job/file/worker/cos/service/EnvironmentService.java @@ -98,6 +98,10 @@ public Pair getInnerProtocolAndIp() { } else { innerIpProtocol = protocolInferredByIp; } + // 将IPv6地址转为完整无压缩格式 + if (IpUtils.PROTOCOL_IP_V6.equalsIgnoreCase(innerIpProtocol)) { + innerIp = IpUtils.getFullIpv6ByCompressedOne(innerIp); + } return Pair.of(innerIpProtocol, innerIp); } } From 40c12044b0cd44b5ec29a7bf7e7266d281a2536e Mon Sep 17 00:00:00 2001 From: jsonwan Date: Mon, 28 Nov 2022 17:37:13 +0800 Subject: [PATCH 2/3] =?UTF-8?q?bugfix:=20=E7=BA=AFIPv6=E7=8E=AF=E5=A2=83?= =?UTF-8?q?=E5=88=86=E5=8F=91=E6=9C=AC=E5=9C=B0=E6=96=87=E4=BB=B6/?= =?UTF-8?q?=E7=AC=AC=E4=B8=89=E6=96=B9=E6=96=87=E4=BB=B6=E4=B8=80=E7=9B=B4?= =?UTF-8?q?=E5=8D=A1=E4=BD=8F=20#1530?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit IpUtils解析异常IPv6地址时抛出异常 --- .../i18n/exception/message.properties | 1 + .../i18n/exception/message_en.properties | 1 + .../i18n/exception/message_en_US.properties | 1 + .../i18n/exception/message_zh.properties | 1 + .../i18n/exception/message_zh_CN.properties | 1 + .../bk/job/common/constant/ErrorCode.java | 2 + .../exception/InvalidIpv6SeqException.java | 70 +++++++++++++++++++ .../bk/job/common/util/ip/IpUtils.java | 9 ++- .../bk/job/common/util/IpUtilsTest.java | 10 ++- 9 files changed, 89 insertions(+), 7 deletions(-) create mode 100644 src/backend/commons/common/src/main/java/com/tencent/bk/job/common/exception/InvalidIpv6SeqException.java diff --git a/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message.properties b/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message.properties index fcb1511b22..d1ded691cc 100644 --- a/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message.properties +++ b/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message.properties @@ -101,6 +101,7 @@ 1241011=尚未支持的功能 1241012=请求参数不合法,原因:{0} 1241013=该功能在业务集下暂不支持 +1241014=IPv6地址段不合法,用于校验的正则表达式:[0-9a-fA-F]{1,4} ##业务错误-作业管理(job-manage) 1243001=脚本不存在 diff --git a/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_en.properties b/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_en.properties index 0313c73a18..899f418cf7 100644 --- a/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_en.properties +++ b/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_en.properties @@ -100,6 +100,7 @@ 1241011=Not support yet 1241012=Invalid request parameter, reason: {0} 1241013=Not support for biz set yet +1241014=IPv6 seq is invalid, valid regex: [0-9a-fA-F]{1,4} ## Business error - job-manage 1243001=Script not exist diff --git a/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_en_US.properties b/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_en_US.properties index 0313c73a18..899f418cf7 100644 --- a/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_en_US.properties +++ b/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_en_US.properties @@ -100,6 +100,7 @@ 1241011=Not support yet 1241012=Invalid request parameter, reason: {0} 1241013=Not support for biz set yet +1241014=IPv6 seq is invalid, valid regex: [0-9a-fA-F]{1,4} ## Business error - job-manage 1243001=Script not exist diff --git a/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_zh.properties b/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_zh.properties index fcb1511b22..d1ded691cc 100644 --- a/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_zh.properties +++ b/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_zh.properties @@ -101,6 +101,7 @@ 1241011=尚未支持的功能 1241012=请求参数不合法,原因:{0} 1241013=该功能在业务集下暂不支持 +1241014=IPv6地址段不合法,用于校验的正则表达式:[0-9a-fA-F]{1,4} ##业务错误-作业管理(job-manage) 1243001=脚本不存在 diff --git a/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_zh_CN.properties b/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_zh_CN.properties index fcb1511b22..d1ded691cc 100644 --- a/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_zh_CN.properties +++ b/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_zh_CN.properties @@ -101,6 +101,7 @@ 1241011=尚未支持的功能 1241012=请求参数不合法,原因:{0} 1241013=该功能在业务集下暂不支持 +1241014=IPv6地址段不合法,用于校验的正则表达式:[0-9a-fA-F]{1,4} ##业务错误-作业管理(job-manage) 1243001=脚本不存在 diff --git a/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/constant/ErrorCode.java b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/constant/ErrorCode.java index c8bf25b12d..2e647a481a 100644 --- a/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/constant/ErrorCode.java +++ b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/constant/ErrorCode.java @@ -79,6 +79,8 @@ public class ErrorCode { public static final int ILLEGAL_PARAM_WITH_REASON = 1241012; // 该功能暂不支持业务集 public static final int NOT_SUPPORT_FEATURE_FOR_BIZ_SET = 1241013; + // IPv6地址段不合法,用于校验的正则表达式:[0-9a-fA-F]{1,4} + public static final int INVALID_IPV6_SEQ = 1241014; // 业务通用 end // 配置服务 start diff --git a/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/exception/InvalidIpv6SeqException.java b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/exception/InvalidIpv6SeqException.java new file mode 100644 index 0000000000..39a65a6960 --- /dev/null +++ b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/exception/InvalidIpv6SeqException.java @@ -0,0 +1,70 @@ +/* + * Tencent is pleased to support the open source community by making BK-JOB蓝鲸智云作业平台 available. + * + * Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-JOB蓝鲸智云作业平台 is licensed under the MIT License. + * + * License for BK-JOB蓝鲸智云作业平台: + * -------------------------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and + * to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO + * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +package com.tencent.bk.job.common.exception; + +import com.tencent.bk.job.common.model.error.ErrorType; +import lombok.Getter; +import lombok.ToString; + +/** + * IPv6地址段不合法 + */ +@Getter +@ToString +public class InvalidIpv6SeqException extends ServiceException { + + public InvalidIpv6SeqException(Integer errorCode) { + super(ErrorType.INTERNAL, errorCode); + } + + public InvalidIpv6SeqException(Integer errorCode, Object[] errorParams) { + super(ErrorType.INTERNAL, errorCode, errorParams); + } + + public InvalidIpv6SeqException(String message, Integer errorCode) { + super(message, ErrorType.INTERNAL, errorCode); + } + + public InvalidIpv6SeqException(String message, Integer errorCode, Object[] errorParams) { + super(message, ErrorType.INTERNAL, errorCode, errorParams); + } + + public InvalidIpv6SeqException(Throwable cause, Integer errorCode) { + super(cause, ErrorType.INTERNAL, errorCode); + } + + public InvalidIpv6SeqException(Throwable cause, Integer errorCode, Object[] errorParams) { + super(cause, ErrorType.INTERNAL, errorCode, errorParams); + } + + public InvalidIpv6SeqException(String message, Throwable cause, Integer errorCode) { + super(message, cause, ErrorType.INTERNAL, errorCode); + } + + public InvalidIpv6SeqException(String message, Throwable cause, Integer errorCode, + Object[] errorParams) { + super(message, cause, ErrorType.INTERNAL, errorCode, errorParams); + } +} diff --git a/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/util/ip/IpUtils.java b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/util/ip/IpUtils.java index e8908aeee7..bde171a741 100644 --- a/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/util/ip/IpUtils.java +++ b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/util/ip/IpUtils.java @@ -24,6 +24,8 @@ package com.tencent.bk.job.common.util.ip; +import com.tencent.bk.job.common.constant.ErrorCode; +import com.tencent.bk.job.common.exception.InvalidIpv6SeqException; import com.tencent.bk.job.common.model.dto.HostDTO; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; @@ -386,12 +388,15 @@ public static String getFullIpv6ByCompressedOne(String compressedIpv6) { String seqSeparator = ":"; // 一个IPv6地址最多有8段 int maxSeqNum = 8; + // ::开头的IP首位补0便于后续统一分割处理 if (compressedIpv6.startsWith(continueZeroToken)) { compressedIpv6 = "0" + compressedIpv6; } + // ::结尾的IP末位补0便于后续统一分割处理 if (compressedIpv6.endsWith(continueZeroToken)) { compressedIpv6 = compressedIpv6 + "0"; } + // 统一分割、解析 if (compressedIpv6.contains(continueZeroToken)) { String[] seqArr = compressedIpv6.split(continueZeroToken); String[] leftSeqArr = seqArr[0].split(seqSeparator); @@ -422,8 +427,10 @@ public static String getStandardIpv6Seq(String ipv6Seq) { if (StringUtils.isBlank(ipv6Seq)) { return template; } + if (ipv6Seq.length() > template.length()) { - return ipv6Seq.substring(ipv6Seq.length() - template.length()); + log.warn("ipv6Seq {} exceed max length({})", ipv6Seq, template.length()); + throw new InvalidIpv6SeqException(ErrorCode.INVALID_IPV6_SEQ); } return template.substring(0, template.length() - ipv6Seq.length()) + ipv6Seq; } diff --git a/src/backend/commons/common/src/test/java/com/tencent/bk/job/common/util/IpUtilsTest.java b/src/backend/commons/common/src/test/java/com/tencent/bk/job/common/util/IpUtilsTest.java index c9565e480b..47a64ef327 100644 --- a/src/backend/commons/common/src/test/java/com/tencent/bk/job/common/util/IpUtilsTest.java +++ b/src/backend/commons/common/src/test/java/com/tencent/bk/job/common/util/IpUtilsTest.java @@ -28,6 +28,7 @@ import org.junit.jupiter.api.Test; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; public class IpUtilsTest { @Test @@ -121,12 +122,11 @@ void testInferProtocolByIp() { @Test void testGetStandardIpv6Seq() { - assertThat(IpUtils.getStandardIpv6Seq("")).isEqualTo("0000"); assertThat(IpUtils.getStandardIpv6Seq("0")).isEqualTo("0000"); assertThat(IpUtils.getStandardIpv6Seq("1")).isEqualTo("0001"); assertThat(IpUtils.getStandardIpv6Seq("1001")).isEqualTo("1001"); assertThat(IpUtils.getStandardIpv6Seq("ff")).isEqualTo("00ff"); - assertThat(IpUtils.getStandardIpv6Seq("aabbcc")).isEqualTo("bbcc"); + assertThatThrownBy(() -> IpUtils.getStandardIpv6Seq("aabbcc")); } @Test @@ -143,8 +143,7 @@ void testGetFullIpv6ByCompressedOne() { .isEqualTo("0000:0000:0000:0000:0000:0000:0000:0001"); assertThat(IpUtils.getFullIpv6ByCompressedOne("0000::1")) .isEqualTo("0000:0000:0000:0000:0000:0000:0000:0001"); - assertThat(IpUtils.getFullIpv6ByCompressedOne("00000::1")) - .isEqualTo("0000:0000:0000:0000:0000:0000:0000:0001"); + assertThatThrownBy(() -> IpUtils.getFullIpv6ByCompressedOne("00000::1")); assertThat(IpUtils.getFullIpv6ByCompressedOne("1:0000::1")) .isEqualTo("0001:0000:0000:0000:0000:0000:0000:0001"); assertThat(IpUtils.getFullIpv6ByCompressedOne("1:1:1:1:1:1:1:1")) @@ -153,8 +152,7 @@ void testGetFullIpv6ByCompressedOne() { .isEqualTo("0001:0001:0001:0000:0000:0001:0001:0001"); assertThat(IpUtils.getFullIpv6ByCompressedOne("ffff:1:1:0:0:1:1:ffff")) .isEqualTo("ffff:0001:0001:0000:0000:0001:0001:ffff"); - assertThat(IpUtils.getFullIpv6ByCompressedOne("aaffff:1:1:0:0:1:1:bbffff")) - .isEqualTo("ffff:0001:0001:0000:0000:0001:0001:ffff"); + assertThatThrownBy(() -> IpUtils.getFullIpv6ByCompressedOne("aaffff:1:1:0:0:1:1:bbffff")); assertThat(IpUtils.getFullIpv6ByCompressedOne("ffff:0001:0001:0000:0000:0001:0001:ffff")) .isEqualTo("ffff:0001:0001:0000:0000:0001:0001:ffff"); } From 44ed20eab6e02ec1ffd62901322c677e67837a26 Mon Sep 17 00:00:00 2001 From: jsonwan Date: Mon, 28 Nov 2022 17:57:28 +0800 Subject: [PATCH 3/3] =?UTF-8?q?bugfix:=20=E7=BA=AFIPv6=E7=8E=AF=E5=A2=83?= =?UTF-8?q?=E5=88=86=E5=8F=91=E6=9C=AC=E5=9C=B0=E6=96=87=E4=BB=B6/?= =?UTF-8?q?=E7=AC=AC=E4=B8=89=E6=96=B9=E6=96=87=E4=BB=B6=E4=B8=80=E7=9B=B4?= =?UTF-8?q?=E5=8D=A1=E4=BD=8F=20#1530?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit IpUtils解析异常IPv6地址时抛出异常 --- .../resources/i18n/exception/message.properties | 2 +- .../resources/i18n/exception/message_en.properties | 2 +- .../i18n/exception/message_en_US.properties | 2 +- .../resources/i18n/exception/message_zh.properties | 2 +- .../i18n/exception/message_zh_CN.properties | 2 +- .../com/tencent/bk/job/common/util/ip/IpUtils.java | 13 ++++++------- .../com/tencent/bk/job/common/util/IpUtilsTest.java | 4 ++++ 7 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message.properties b/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message.properties index d1ded691cc..1d2ef027fc 100644 --- a/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message.properties +++ b/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message.properties @@ -101,7 +101,7 @@ 1241011=尚未支持的功能 1241012=请求参数不合法,原因:{0} 1241013=该功能在业务集下暂不支持 -1241014=IPv6地址段不合法,用于校验的正则表达式:[0-9a-fA-F]{1,4} +1241014=IPv6地址段不合法,用于校验的正则表达式:^[0-9a-fA-F]{1,4}$ ##业务错误-作业管理(job-manage) 1243001=脚本不存在 diff --git a/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_en.properties b/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_en.properties index 899f418cf7..f0c7d8cb50 100644 --- a/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_en.properties +++ b/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_en.properties @@ -100,7 +100,7 @@ 1241011=Not support yet 1241012=Invalid request parameter, reason: {0} 1241013=Not support for biz set yet -1241014=IPv6 seq is invalid, valid regex: [0-9a-fA-F]{1,4} +1241014=IPv6 seq is invalid, valid regex: ^[0-9a-fA-F]{1,4}$ ## Business error - job-manage 1243001=Script not exist diff --git a/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_en_US.properties b/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_en_US.properties index 899f418cf7..f0c7d8cb50 100644 --- a/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_en_US.properties +++ b/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_en_US.properties @@ -100,7 +100,7 @@ 1241011=Not support yet 1241012=Invalid request parameter, reason: {0} 1241013=Not support for biz set yet -1241014=IPv6 seq is invalid, valid regex: [0-9a-fA-F]{1,4} +1241014=IPv6 seq is invalid, valid regex: ^[0-9a-fA-F]{1,4}$ ## Business error - job-manage 1243001=Script not exist diff --git a/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_zh.properties b/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_zh.properties index d1ded691cc..1d2ef027fc 100644 --- a/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_zh.properties +++ b/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_zh.properties @@ -101,7 +101,7 @@ 1241011=尚未支持的功能 1241012=请求参数不合法,原因:{0} 1241013=该功能在业务集下暂不支持 -1241014=IPv6地址段不合法,用于校验的正则表达式:[0-9a-fA-F]{1,4} +1241014=IPv6地址段不合法,用于校验的正则表达式:^[0-9a-fA-F]{1,4}$ ##业务错误-作业管理(job-manage) 1243001=脚本不存在 diff --git a/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_zh_CN.properties b/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_zh_CN.properties index d1ded691cc..1d2ef027fc 100644 --- a/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_zh_CN.properties +++ b/src/backend/commons/common-i18n/src/main/resources/i18n/exception/message_zh_CN.properties @@ -101,7 +101,7 @@ 1241011=尚未支持的功能 1241012=请求参数不合法,原因:{0} 1241013=该功能在业务集下暂不支持 -1241014=IPv6地址段不合法,用于校验的正则表达式:[0-9a-fA-F]{1,4} +1241014=IPv6地址段不合法,用于校验的正则表达式:^[0-9a-fA-F]{1,4}$ ##业务错误-作业管理(job-manage) 1243001=脚本不存在 diff --git a/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/util/ip/IpUtils.java b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/util/ip/IpUtils.java index bde171a741..28f483030a 100644 --- a/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/util/ip/IpUtils.java +++ b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/util/ip/IpUtils.java @@ -416,20 +416,19 @@ public static String getFullIpv6ByCompressedOne(String compressedIpv6) { return StringUtils.join(finalSeqArr, ":"); } + private static final Pattern ipv6SeqPattern = Pattern.compile("^[A-Fa-f0-9]{1,4}$"); + /** - * 获取含有4个字符的Ipv6标准段,不足4字符则添加前缀0,超出4字符则截取最后4字符 + * 获取含有4个字符的Ipv6标准段,不足4字符则添加前缀0 * * @param ipv6Seq ipv6地址的一段 * @return 4个字符的标准段 */ public static String getStandardIpv6Seq(String ipv6Seq) { String template = "0000"; - if (StringUtils.isBlank(ipv6Seq)) { - return template; - } - - if (ipv6Seq.length() > template.length()) { - log.warn("ipv6Seq {} exceed max length({})", ipv6Seq, template.length()); + Matcher m = ipv6SeqPattern.matcher(ipv6Seq); + if (!m.matches()) { + log.warn("invalid ipv6Seq:{}, valid pattern:{}", ipv6Seq, ipv6SeqPattern.pattern()); throw new InvalidIpv6SeqException(ErrorCode.INVALID_IPV6_SEQ); } return template.substring(0, template.length() - ipv6Seq.length()) + ipv6Seq; diff --git a/src/backend/commons/common/src/test/java/com/tencent/bk/job/common/util/IpUtilsTest.java b/src/backend/commons/common/src/test/java/com/tencent/bk/job/common/util/IpUtilsTest.java index 47a64ef327..d054e75624 100644 --- a/src/backend/commons/common/src/test/java/com/tencent/bk/job/common/util/IpUtilsTest.java +++ b/src/backend/commons/common/src/test/java/com/tencent/bk/job/common/util/IpUtilsTest.java @@ -126,6 +126,8 @@ void testGetStandardIpv6Seq() { assertThat(IpUtils.getStandardIpv6Seq("1")).isEqualTo("0001"); assertThat(IpUtils.getStandardIpv6Seq("1001")).isEqualTo("1001"); assertThat(IpUtils.getStandardIpv6Seq("ff")).isEqualTo("00ff"); + assertThatThrownBy(() -> IpUtils.getStandardIpv6Seq(".*gg")); + assertThatThrownBy(() -> IpUtils.getStandardIpv6Seq("aagg")); assertThatThrownBy(() -> IpUtils.getStandardIpv6Seq("aabbcc")); } @@ -152,6 +154,8 @@ void testGetFullIpv6ByCompressedOne() { .isEqualTo("0001:0001:0001:0000:0000:0001:0001:0001"); assertThat(IpUtils.getFullIpv6ByCompressedOne("ffff:1:1:0:0:1:1:ffff")) .isEqualTo("ffff:0001:0001:0000:0000:0001:0001:ffff"); + assertThat(IpUtils.getFullIpv6ByCompressedOne("FFFF:1:1:0:0:1:1:FFFF")) + .isEqualTo("FFFF:0001:0001:0000:0000:0001:0001:FFFF"); assertThatThrownBy(() -> IpUtils.getFullIpv6ByCompressedOne("aaffff:1:1:0:0:1:1:bbffff")); assertThat(IpUtils.getFullIpv6ByCompressedOne("ffff:0001:0001:0000:0000:0001:0001:ffff")) .isEqualTo("ffff:0001:0001:0000:0000:0001:0001:ffff");