修复隧道添加问题

This commit is contained in:
qaq
2025-06-13 11:09:57 +08:00
parent 04902d67b4
commit fbe923301f
5 changed files with 167 additions and 1 deletions
@@ -36,7 +36,7 @@ public class NodeServiceImpl extends ServiceImpl<NodeMapper, Node> implements No
// ========== 常量定义 ==========
/** 节点默认状态:启用 */
private static final int NODE_STATUS_ACTIVE = 1;
private static final int NODE_STATUS_ACTIVE = 0;
/** 成功响应消息 */
private static final String SUCCESS_CREATE_MSG = "节点创建成功";
@@ -69,6 +69,8 @@ public class TunnelServiceImpl extends ServiceImpl<TunnelMapper, Tunnel> impleme
private static final String ERROR_IN_PORT_RANGE_INVALID = "入口端口开始不能大于结束端口";
private static final String ERROR_OUT_PORT_RANGE_INVALID = "出口端口开始不能大于结束端口";
private static final String ERROR_NO_AVAILABLE_TUNNELS = "暂无可用隧道";
private static final String ERROR_IN_NODE_IP_INVALID = "入口节点IP地址无效,请先安装节点端的gost(支持IPv4和IPv6)";
private static final String ERROR_OUT_NODE_IP_INVALID = "出口节点IP地址无效,请先安装节点端的gost(支持IPv4和IPv6)";
/** 使用检查相关消息 */
private static final String ERROR_FORWARDS_IN_USE = "该隧道还有 %d 个转发在使用,请先删除相关转发";
@@ -221,6 +223,11 @@ public class TunnelServiceImpl extends ServiceImpl<TunnelMapper, Tunnel> impleme
return NodeValidationResult.error(ERROR_IN_NODE_NOT_FOUND);
}
// 验证入口节点IP地址
if (!isValidNodeIp(inNode.getIp())) {
return NodeValidationResult.error(ERROR_IN_NODE_IP_INVALID);
}
// 验证入口端口范围
if (tunnelDto.getInPortSta() > tunnelDto.getInPortEnd()) {
return NodeValidationResult.error(ERROR_IN_PORT_RANGE_INVALID);
@@ -306,6 +313,11 @@ public class TunnelServiceImpl extends ServiceImpl<TunnelMapper, Tunnel> impleme
return R.err(ERROR_OUT_NODE_NOT_FOUND);
}
// 验证出口节点IP地址
if (!isValidNodeIp(outNode.getIp())) {
return R.err(ERROR_OUT_NODE_IP_INVALID);
}
// 验证出口端口参数
if (tunnelDto.getOutIpSta() == null || tunnelDto.getOutIpEnd() == null) {
return R.err(ERROR_OUT_PORT_REQUIRED);
@@ -333,6 +345,115 @@ public class TunnelServiceImpl extends ServiceImpl<TunnelMapper, Tunnel> impleme
tunnel.setUpdatedTime(currentTime);
}
/**
* 验证节点IP地址是否有效
* 支持IPv4和IPv6格式
*
* @param ip IP地址字符串
* @return IP地址是否有效
*/
private boolean isValidNodeIp(String ip) {
if (StrUtil.isBlank(ip)) {
return false;
}
// 验证IPv4格式
if (isValidIpv4(ip)) {
return true;
}
// 验证IPv6格式
return isValidIpv6(ip);
}
/**
* 验证IPv4地址格式
*
* @param ip IP地址字符串
* @return 是否为有效的IPv4地址
*/
private boolean isValidIpv4(String ip) {
if (StrUtil.isBlank(ip)) {
return false;
}
String[] parts = ip.split("\\.");
if (parts.length != 4) {
return false;
}
try {
for (String part : parts) {
int num = Integer.parseInt(part);
if (num < 0 || num > 255) {
return false;
}
}
return true;
} catch (NumberFormatException e) {
return false;
}
}
/**
* 验证IPv6地址格式
*
* @param ip IP地址字符串
* @return 是否为有效的IPv6地址
*/
private boolean isValidIpv6(String ip) {
if (StrUtil.isBlank(ip)) {
return false;
}
// 简化的IPv6验证,支持标准格式和压缩格式
try {
// 移除可能的端口号
if (ip.startsWith("[") && ip.contains("]:")) {
ip = ip.substring(1, ip.indexOf("]:"));
}
// 检查是否包含非法字符
if (!ip.matches("^[0-9a-fA-F:]+$")) {
return false;
}
// 处理双冒号压缩格式
if (ip.contains("::")) {
if (ip.indexOf("::") != ip.lastIndexOf("::")) {
// 不能有多个双冒号
return false;
}
// 展开双冒号
String[] parts = ip.split("::");
int leftParts = parts[0].isEmpty() ? 0 : parts[0].split(":").length;
int rightParts = parts.length > 1 && !parts[1].isEmpty() ? parts[1].split(":").length : 0;
int totalParts = leftParts + rightParts;
if (totalParts >= 8) {
return false;
}
} else {
// 标准格式,必须有8个部分
String[] parts = ip.split(":");
if (parts.length != 8) {
return false;
}
// 验证每个部分都是有效的十六进制数
for (String part : parts) {
if (part.length() > 4 || part.isEmpty()) {
return false;
}
Integer.parseInt(part, 16); // 如果不是有效的十六进制会抛出异常
}
}
return true;
} catch (Exception e) {
return false;
}
}
/**
* 检查隧道是否存在
*