diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml
index 288235b..d153b52 100644
--- a/.github/workflows/docker-build.yml
+++ b/.github/workflows/docker-build.yml
@@ -2,7 +2,7 @@ name: Build and Push Images Based on Version
# 在这里定义统一版本号
env:
- VERSION: "2.0.2-beta"
+ VERSION: "2.0.3-beta"
on:
push:
@@ -223,29 +223,11 @@ jobs:
# 创建 release
gh release create "${VERSION}" \
--title "Release ${VERSION}" \
- --notes "Version ${VERSION}
-
- ## 📝 Commit Information
+ --notes "## 📝 Commit Information
- **Message**: ${COMMIT_MSG}
- **Author**: ${COMMIT_AUTHOR}
- **Date**: ${COMMIT_DATE}
- - **Commit**: [\`${GITHUB_SHA:0:7}\`](https://github.com/${{ github.repository }}/commit/${{ github.sha }})
-
- ## 📦 Components
- - **GOST Binary AMD64** - \`gost-amd64\` (Linux x86_64, compressed with UPX)
- - **GOST Binary ARM64** - \`gost-arm64\` (Linux ARM64/aarch64, compressed with UPX)
- - **Vite Frontend** Docker Image: \`bqlpfy/vite-frontend:${VERSION}\` / \`bqlpfy/vite-frontend:latest\` (支持 AMD64/ARM64)
- - **Spring Boot Backend** Docker Image: \`bqlpfy/springboot-backend:${VERSION}\` / \`bqlpfy/springboot-backend:latest\` (支持 AMD64/ARM64)
-
- ## 📥 Installation Files
- - \`install.sh\` - GOST 客户端安装脚本
- - \`panel_install.sh\` - 面板安装脚本
- - \`docker-compose-v4.yml\` - Docker Compose 配置 (IPv4)
- - \`docker-compose-v6.yml\` - Docker Compose 配置 (IPv6)
-
- ## ℹ️ Build Details
- - Build date: $(date -u +%Y-%m-%dT%H:%M:%SZ)
- - Branch: ${{ github.ref_name }}" \
+ - **Commit**: [\`${GITHUB_SHA:0:7}\`](https://github.com/${{ github.repository }}/commit/${{ github.sha }})" \
--repo ${{ github.repository }}
# 上传所有文件到 release
diff --git a/README.md b/README.md
index d5fb6a7..3c50191 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,51 @@
# flux-panel转发面板 哆啦A梦转发面板
+# 1.x无法无损升级到2.x请备份好数据
+# 1.x无法无损升级到2.x请备份好数据
+# 1.x无法无损升级到2.x请备份好数据
+# 1.x无法无损升级到2.x请备份好数据
+# 1.x无法无损升级到2.x请备份好数据
+
+# 赞助商
+
+
+
+ 
+ vps.town
+
+
+
+ 
+ DreamCloud
+
+
+
+
+
+
+1.x迁移2.x流程如下
+1.进入1.x的后台在转发页面导出所有转发保存
+2.使用1.x节点脚本卸载所有节点
+```
+curl -L https://github.com/bqlpfy/flux-panel/releases/download/1.4.2/install.sh -o install.sh && chmod +x install.sh && ./install.sh
+```
+3.使用1.x面版脚本卸载面板
+
+```
+curl -L https://github.com/bqlpfy/flux-panel/releases/download/1.4.2/panel_install.sh -o panel_install.sh && chmod +x panel_install.sh && ./panel_install.sh
+```
+4.使用2.x脚本安装面板
+
+```
+curl -L https://raw.githubusercontent.com/bqlpfy/flux-panel/refs/heads/main/panel_install.sh -o panel_install.sh && chmod +x panel_install.sh && ./panel_install.sh
+```
+
+
+使用1.x版本的请使用上面给出的脚本,不要使用最新的,最新的默认2.x
+嫌弃麻烦或者想稳定的我不推荐你升级到2.x版本 目前还在beta阶段,很多问题。
+
+
本项目基于 [go-gost/gost](https://github.com/go-gost/gost) 和 [go-gost/x](https://github.com/go-gost/x) 两个开源库,实现了转发面板。
---
## 特性
@@ -18,11 +63,21 @@
---
### Docker Compose部署
#### 快速部署
-面板端:
+面板端(1.x):
+```bash
+curl -L https://github.com/bqlpfy/flux-panel/releases/download/1.4.2/panel_install.sh -o panel_install.sh && chmod +x panel_install.sh && ./panel_install.sh
+```
+节点端(1.x):
+```bash
+curl -L https://github.com/bqlpfy/flux-panel/releases/download/1.4.2/install.sh -o install.sh && chmod +x install.sh && ./install.sh
+
+```
+
+面板端(2.x):
```bash
curl -L https://raw.githubusercontent.com/bqlpfy/flux-panel/refs/heads/main/panel_install.sh -o panel_install.sh && chmod +x panel_install.sh && ./panel_install.sh
```
-节点端:
+节点端(2.x):
```bash
curl -L https://raw.githubusercontent.com/bqlpfy/flux-panel/refs/heads/main/install.sh -o install.sh && chmod +x install.sh && ./install.sh
diff --git a/docker-compose-v4.yml b/docker-compose-v4.yml
index 89f0eb0..08e137f 100644
--- a/docker-compose-v4.yml
+++ b/docker-compose-v4.yml
@@ -1,6 +1,6 @@
services:
backend:
- image: bqlpfy/springboot-backend:2.0.2-beta
+ image: bqlpfy/springboot-backend:2.0.3-beta
container_name: springboot-backend
restart: unless-stopped
environment:
@@ -23,7 +23,7 @@ services:
start_period: 60s
frontend:
- image: bqlpfy/vite-frontend:2.0.2-beta
+ image: bqlpfy/vite-frontend:2.0.3-beta
container_name: vite-frontend
restart: unless-stopped
ports:
diff --git a/docker-compose-v6.yml b/docker-compose-v6.yml
index 23d35c3..65b53f7 100644
--- a/docker-compose-v6.yml
+++ b/docker-compose-v6.yml
@@ -1,6 +1,6 @@
services:
backend:
- image: bqlpfy/springboot-backend:2.0.2-beta
+ image: bqlpfy/springboot-backend:2.0.3-beta
container_name: springboot-backend
restart: unless-stopped
environment:
@@ -23,7 +23,7 @@ services:
start_period: 60s
frontend:
- image: bqlpfy/vite-frontend:2.0.2-beta
+ image: bqlpfy/vite-frontend:2.0.3-beta
container_name: vite-frontend
restart: unless-stopped
ports:
diff --git a/install.sh b/install.sh
index a13d27e..d1d5b6f 100644
--- a/install.sh
+++ b/install.sh
@@ -19,7 +19,7 @@ get_architecture() {
# 构建下载地址
build_download_url() {
local ARCH=$(get_architecture)
- echo "https://github.com/bqlpfy/flux-panel/releases/download/2.0.2-beta/gost-${ARCH}"
+ echo "https://github.com/bqlpfy/flux-panel/releases/download/2.0.3-beta/gost-${ARCH}"
}
# 下载地址
diff --git a/panel_install.sh b/panel_install.sh
index d7de1a6..423feb7 100755
--- a/panel_install.sh
+++ b/panel_install.sh
@@ -8,8 +8,8 @@ export LC_ALL=C
# 全局下载地址配置
-DOCKER_COMPOSEV4_URL="https://github.com/bqlpfy/flux-panel/releases/download/2.0.2-beta/docker-compose-v4.yml"
-DOCKER_COMPOSEV6_URL="https://github.com/bqlpfy/flux-panel/releases/download/2.0.2-beta/docker-compose-v6.yml"
+DOCKER_COMPOSEV4_URL="https://github.com/bqlpfy/flux-panel/releases/download/2.0.3-beta/docker-compose-v4.yml"
+DOCKER_COMPOSEV6_URL="https://github.com/bqlpfy/flux-panel/releases/download/2.0.3-beta/docker-compose-v6.yml"
COUNTRY=$(curl -s https://ipinfo.io/country)
if [ "$COUNTRY" = "CN" ]; then
diff --git a/springboot-backend/src/main/java/com/admin/common/task/ResetFlowAsync.java b/springboot-backend/src/main/java/com/admin/common/task/ResetFlowAsync.java
index 6f5d305..208e79c 100644
--- a/springboot-backend/src/main/java/com/admin/common/task/ResetFlowAsync.java
+++ b/springboot-backend/src/main/java/com/admin/common/task/ResetFlowAsync.java
@@ -1,5 +1,6 @@
package com.admin.common.task;
+import com.admin.common.dto.GostDto;
import com.admin.common.utils.GostUtil;
import com.admin.entity.*;
import com.admin.service.*;
diff --git a/springboot-backend/src/main/java/com/admin/common/utils/GostUtil.java b/springboot-backend/src/main/java/com/admin/common/utils/GostUtil.java
index b3a7093..eba8cbc 100644
--- a/springboot-backend/src/main/java/com/admin/common/utils/GostUtil.java
+++ b/springboot-backend/src/main/java/com/admin/common/utils/GostUtil.java
@@ -1,5 +1,7 @@
package com.admin.common.utils;
+import cn.hutool.core.util.StrUtil;
+import com.admin.common.dto.GostDto;
import com.admin.entity.*;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
@@ -12,26 +14,34 @@ import java.util.Objects;
public class GostUtil {
- public static void AddLimiters(Long node_id, Long name, String speed) {
+ public static GostDto AddLimiters(Long node_id, Long name, String speed) {
JSONObject data = createLimiterData(name, speed);
- WebSocketServer.send_msg(node_id, data, "AddLimiters");
+ GostDto gostDto = WebSocketServer.send_msg(node_id, data, "AddLimiters");
+ if (gostDto.getMsg().contains("exists")){
+ gostDto.setMsg("OK");
+ }
+ return gostDto;
}
- public static void UpdateLimiters(Long node_id, Long name, String speed) {
+ public static GostDto UpdateLimiters(Long node_id, Long name, String speed) {
JSONObject data = createLimiterData(name, speed);
JSONObject req = new JSONObject();
req.put("limiter", name + "");
req.put("data", data);
- WebSocketServer.send_msg(node_id, req, "UpdateLimiters");
+ return WebSocketServer.send_msg(node_id, req, "UpdateLimiters");
}
- public static void DeleteLimiters(Long node_id, Long name) {
+ public static GostDto DeleteLimiters(Long node_id, Long name) {
JSONObject req = new JSONObject();
req.put("limiter", name + "");
- WebSocketServer.send_msg(node_id, req, "DeleteLimiters");
+ GostDto gostDto = WebSocketServer.send_msg(node_id, req, "DeleteLimiters");
+ if (gostDto.getMsg().contains("not found")){
+ gostDto.setMsg("OK");
+ }
+ return gostDto;
}
- public static void AddChains(Long node_id, List chainTunnels, Map node_s) {
+ public static GostDto AddChains(Long node_id, List chainTunnels, Map node_s) {
JSONArray nodes = new JSONArray();
for (ChainTunnel chainTunnel : chainTunnels) {
JSONObject dialer = new JSONObject();
@@ -43,19 +53,23 @@ public class GostUtil {
Node node_info = node_s.get(chainTunnel.getNodeId());
JSONObject node = new JSONObject();
node.put("name", "node_" + chainTunnel.getInx());
- node.put("addr", node_info.getServerIp() + ":" + chainTunnel.getPort());
+ node.put("addr", processServerAddress(node_info.getServerIp()) + ":" + chainTunnel.getPort());
node.put("connector", connector);
node.put("dialer", dialer);
- if (StringUtils.isNotBlank(node_info.getInterfaceName())) {
- node.put("interface", node_info.getInterfaceName());
- }
+
nodes.add(node);
}
JSONObject hop = new JSONObject();
hop.put("name", "hop_" + chainTunnels.getFirst().getTunnelId());
+ // interface设置在转发链
+ if (StringUtils.isNotBlank(node_s.get(node_id).getInterfaceName())) {
+ hop.put("interface", node_s.get(node_id).getInterfaceName());
+ }
+
+
JSONObject selector = new JSONObject();
selector.put("strategy", chainTunnels.getFirst().getStrategy());
selector.put("maxFails", 1);
@@ -72,24 +86,34 @@ public class GostUtil {
data.put("name", "chains_" + chainTunnels.getFirst().getTunnelId());
data.put("hops", hops);
- WebSocketServer.send_msg(node_id, data, "AddChains");
+ GostDto gostDto = WebSocketServer.send_msg(node_id, data, "AddChains");
+ if (gostDto.getMsg().contains("exists")){
+ gostDto.setMsg("OK");
+ }
+ return gostDto;
}
- public static void DeleteChains(Long node_id, String name) {
+ public static GostDto DeleteChains(Long node_id, String name) {
JSONObject data = new JSONObject();
data.put("chain", name);
- WebSocketServer.send_msg(node_id, data, "DeleteChains");
+ GostDto gostDto = WebSocketServer.send_msg(node_id, data, "DeleteChains");
+ if (gostDto.getMsg().contains("not found")){
+ gostDto.setMsg("OK");
+ }
+ return gostDto;
}
- public static void AddChainService(Long node_id, ChainTunnel chainTunnel, Map node_s) {
+ public static GostDto AddChainService(Long node_id, ChainTunnel chainTunnel, Map node_s) {
JSONArray services = new JSONArray();
Node node_info = node_s.get(chainTunnel.getNodeId());
JSONObject service_item = new JSONObject();
service_item.put("name", chainTunnel.getTunnelId() + "_tls");
service_item.put("addr", node_info.getTcpListenAddr() + ":" + chainTunnel.getPort());
- if (StringUtils.isNotBlank(node_info.getInterfaceName())) {
+
+ // 只为出口节点(chainType=3)设置 interface
+ if (chainTunnel.getChainType() == 3 && StringUtils.isNotBlank(node_s.get(node_id).getInterfaceName())) {
JSONObject metadata = new JSONObject();
- metadata.put("interface", node_info.getInterfaceName());
+ metadata.put("interface", node_s.get(node_id).getInterfaceName());
service_item.put("metadata", metadata);
}
@@ -106,16 +130,14 @@ public class GostUtil {
services.add(service_item);
- WebSocketServer.send_msg(node_id, services, "AddService");
+ GostDto gostDto = WebSocketServer.send_msg(node_id, services, "AddService");
+ if (gostDto.getMsg().contains("exists")){
+ gostDto.setMsg("OK");
+ }
+ return gostDto;
}
- public static void DeleteChainService(Long node_id, JSONArray services) {
- JSONObject data = new JSONObject();
- data.put("services", services);
- WebSocketServer.send_msg(node_id, data, "DeleteService");
- }
-
- public static void AddAndUpdateService(String name, Integer limiter, Node node, Forward forward, ForwardPort forwardPort, Tunnel tunnel, String meth) {
+ public static GostDto AddAndUpdateService(String name, Integer limiter, Node node, Forward forward, ForwardPort forwardPort, Tunnel tunnel, String meth) {
JSONArray services = new JSONArray();
String[] protocols = {"tcp", "udp"};
for (String protocol : protocols) {
@@ -127,7 +149,8 @@ public class GostUtil {
service.put("addr", node.getUdpListenAddr() + ":" + forwardPort.getPort());
}
- if (StringUtils.isNotBlank(node.getInterfaceName())) {
+ // 只在端口转发时设置 interface(隧道转发时 interface 在转发链的节点上设置)
+ if (tunnel.getType() == 1 && StringUtils.isNotBlank(node.getInterfaceName())) {
JSONObject metadata = new JSONObject();
metadata.put("interface", node.getInterfaceName());
service.put("metadata", metadata);
@@ -155,22 +178,30 @@ public class GostUtil {
services.add(service);
}
- WebSocketServer.send_msg(node.getId(), services, meth);
+ GostDto gostDto = WebSocketServer.send_msg(node.getId(), services, meth);
+ if (gostDto.getMsg().contains("exists")){
+ gostDto.setMsg("OK");
+ }
+ return gostDto;
}
- public static void DeleteService(Long node_id, JSONArray services) {
+ public static GostDto DeleteService(Long node_id, JSONArray services) {
JSONObject data = new JSONObject();
data.put("services", services);
- WebSocketServer.send_msg(node_id, data, "DeleteService");
+ GostDto gostDto = WebSocketServer.send_msg(node_id, data, "DeleteService");
+ if (gostDto.getMsg().contains("not found")){
+ gostDto.setMsg("OK");
+ }
+ return gostDto;
}
- public static void PauseAndResumeService(Long node_id, String name, String meth) {
+ public static GostDto PauseAndResumeService(Long node_id, String name, String meth) {
JSONObject data = new JSONObject();
JSONArray services = new JSONArray();
services.add(name + "_tcp");
services.add(name + "_udp");
data.put("services", services);
- WebSocketServer.send_msg(node_id, data, meth);
+ return WebSocketServer.send_msg(node_id, data, meth);
}
@@ -208,7 +239,7 @@ public class GostUtil {
num++;
}
- if (strategy == null || strategy.equals("")) {
+ if (strategy == null || strategy.isEmpty()) {
strategy = "fifo";
}
@@ -222,5 +253,42 @@ public class GostUtil {
return forwarder;
}
+ public static String processServerAddress(String serverAddr) {
+ if (StrUtil.isBlank(serverAddr)) {
+ return serverAddr;
+ }
+ // 如果已经被方括号包裹,直接返回
+ if (serverAddr.startsWith("[")) {
+ return serverAddr;
+ }
+
+ // 查找最后一个冒号,分离主机和端口
+ int lastColonIndex = serverAddr.lastIndexOf(':');
+ if (lastColonIndex == -1) {
+ // 没有端口号,直接检查是否需要包裹
+ return isIPv6Address(serverAddr) ? "[" + serverAddr + "]" : serverAddr;
+ }
+
+ String host = serverAddr.substring(0, lastColonIndex);
+ String port = serverAddr.substring(lastColonIndex);
+
+ // 检查主机部分是否为IPv6地址
+ if (isIPv6Address(host)) {
+ return "[" + host + "]" + port;
+ }
+
+ return serverAddr;
+ }
+
+ private static boolean isIPv6Address(String address) {
+ // IPv6地址包含多个冒号,至少2个
+ if (!address.contains(":")) {
+ return false;
+ }
+
+ // 计算冒号数量,IPv6地址至少有2个冒号
+ long colonCount = address.chars().filter(ch -> ch == ':').count();
+ return colonCount >= 2;
+ }
}
diff --git a/springboot-backend/src/main/java/com/admin/service/TunnelService.java b/springboot-backend/src/main/java/com/admin/service/TunnelService.java
index 7b1e995..f949f57 100644
--- a/springboot-backend/src/main/java/com/admin/service/TunnelService.java
+++ b/springboot-backend/src/main/java/com/admin/service/TunnelService.java
@@ -56,6 +56,4 @@ public interface TunnelService extends IService {
* @return 诊断结果
*/
R diagnoseTunnel(Long tunnelId);
-
- Integer getNodePort(Long nodeId, Integer type, Integer port);
}
diff --git a/springboot-backend/src/main/java/com/admin/service/impl/ForwardServiceImpl.java b/springboot-backend/src/main/java/com/admin/service/impl/ForwardServiceImpl.java
index 4fcf716..ce4d0f3 100644
--- a/springboot-backend/src/main/java/com/admin/service/impl/ForwardServiceImpl.java
+++ b/springboot-backend/src/main/java/com/admin/service/impl/ForwardServiceImpl.java
@@ -18,6 +18,7 @@ import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.*;
@@ -82,53 +83,60 @@ public class ForwardServiceImpl extends ServiceImpl impl
// 判断是否使用隧道的inIp
boolean useTunnelInIp = tunnel.getInIp() != null && !tunnel.getInIp().trim().isEmpty();
- // 收集所有的IP列表
- List ipList = new ArrayList<>();
- // 收集所有的端口列表
- List portList = new ArrayList<>();
+ Set ipPortSet = new LinkedHashSet<>();
if (useTunnelInIp) {
- // 使用隧道的inIp
+ // 使用隧道的inIp(求笛卡尔积)
+ List ipList = new ArrayList<>();
+ List portList = new ArrayList<>();
+
String[] tunnelInIps = tunnel.getInIp().split(",");
for (String ip : tunnelInIps) {
if (ip != null && !ip.trim().isEmpty()) {
ipList.add(ip.trim());
}
}
- } else {
- // 使用节点的serverIp
+
+ // 收集所有端口
for (ForwardPort forwardPort : forwardPorts) {
- Node node = nodeService.getById(forwardPort.getNodeId());
- if (node != null && node.getServerIp() != null) {
- ipList.add(node.getServerIp());
+ if (forwardPort.getPort() != null) {
+ portList.add(forwardPort.getPort());
}
}
- }
-
- // 收集所有端口
- for (ForwardPort forwardPort : forwardPorts) {
- if (forwardPort.getPort() != null) {
- portList.add(forwardPort.getPort());
+
+ // 去重
+ List uniqueIps = ipList.stream().distinct().toList();
+ List uniquePorts = portList.stream().distinct().toList();
+
+ // 组合 IP:Port(笛卡尔积)
+ for (String ip : uniqueIps) {
+ for (Integer port : uniquePorts) {
+ ipPortSet.add(ip + ":" + port);
+ }
+ }
+
+ // inPort设置为第一个端口(用于向后兼容)
+ if (!uniquePorts.isEmpty()) {
+ forward.setInPort(uniquePorts.getFirst());
+ }
+ } else {
+ // 使用节点的serverIp(一对一,不求笛卡尔积)
+ for (ForwardPort forwardPort : forwardPorts) {
+ Node node = nodeService.getById(forwardPort.getNodeId());
+ if (node != null && node.getServerIp() != null && forwardPort.getPort() != null) {
+ ipPortSet.add(node.getServerIp() + ":" + forwardPort.getPort());
+ }
+ }
+
+ // inPort设置为第一个端口(用于向后兼容)
+ if (!forwardPorts.isEmpty() && forwardPorts.getFirst().getPort() != null) {
+ forward.setInPort(forwardPorts.getFirst().getPort());
}
}
- // 去重
- List uniqueIps = ipList.stream().distinct().toList();
- List uniquePorts = portList.stream().distinct().toList();
-
- // 组合 IP:Port(笛卡尔积)
- Set ipPortSet = new LinkedHashSet<>();
- for (String ip : uniqueIps) {
- for (Integer port : uniquePorts) {
- ipPortSet.add(ip + ":" + port);
- }
- }
-
- // 设置入口IP和端口
+ // 设置入口IP
if (!ipPortSet.isEmpty()) {
forward.setInIp(String.join(",", ipPortSet));
- // inPort设置为第一个端口(用于向后兼容)
- forward.setInPort(uniquePorts.getFirst());
}
}
@@ -159,25 +167,43 @@ public class ForwardServiceImpl extends ServiceImpl impl
forward.setUserName(currentUser.getUserName());
forward.setCreatedTime(System.currentTimeMillis());
forward.setUpdatedTime(System.currentTimeMillis());
+ List success = new ArrayList<>();
+ List chainTunnels = chainTunnelService.list(new QueryWrapper().eq("tunnel_id", tunnel.getId()).eq("chain_type", 1));
+ chainTunnels = get_port(chainTunnels, forwardDto.getInPort());
this.save(forward);
- List chainTunnels = chainTunnelService.list(new QueryWrapper().eq("tunnel_id", tunnel.getId()).eq("chain_type", 1));
for (ChainTunnel chainTunnel : chainTunnels) {
- Integer nodePort = tunnelService.getNodePort(chainTunnel.getNodeId(), 2, forwardDto.getInPort());
ForwardPort forwardPort = new ForwardPort();
forwardPort.setForwardId(forward.getId());
forwardPort.setNodeId(chainTunnel.getNodeId());
- forwardPort.setPort(nodePort);
+ forwardPort.setPort(chainTunnel.getPort());
forwardPortService.save(forwardPort);
String serviceName = buildServiceName(forward.getId(), forward.getUserId(), permissionResult.getUserTunnel());
Integer limiter = permissionResult.getLimiter();
Node node = nodeService.getById(chainTunnel.getNodeId());
- if (node == null){
+ if (node == null) {
return R.err("部分节点不存在");
}
- GostUtil.AddAndUpdateService(serviceName, limiter, node, forward, forwardPort, tunnel, "AddService");
+ GostDto gostDto = GostUtil.AddAndUpdateService(serviceName, limiter, node, forward, forwardPort, tunnel, "AddService");
+ if (Objects.equals(gostDto.getMsg(), "OK")) {
+ JSONObject data = new JSONObject();
+ data.put("node_id", node.getId());
+ data.put("name", serviceName);
+ success.add(data);
+ } else {
+ this.removeById(forward.getId());
+ forwardPortService.remove(new QueryWrapper().eq("forward_id", forward.getId()));
+ for (JSONObject jsonObject : success) {
+ JSONArray se = new JSONArray();
+ se.add(jsonObject.getString("name") + "_tcp");
+ se.add(jsonObject.getString("name") + "_udp");
+ GostUtil.DeleteService(jsonObject.getLong("node_id"), se);
+ return R.err(gostDto.getMsg());
+ }
+ }
+
}
return R.ok();
}
@@ -225,25 +251,22 @@ public class ForwardServiceImpl extends ServiceImpl impl
List chainTunnels = chainTunnelService.list(new QueryWrapper().eq("tunnel_id", tunnel.getId()).eq("chain_type", 1));
+ chainTunnels = get_port(chainTunnels, forwardUpdateDto.getInPort());
for (ChainTunnel chainTunnel : chainTunnels) {
String serviceName = buildServiceName(existForward.getId(), existForward.getUserId(), userTunnel);
Integer limiter = permissionResult.getLimiter();
Node node = nodeService.getById(chainTunnel.getNodeId());
- if (node == null){
+ if (node == null) {
return R.err("部分节点不存在");
}
ForwardPort forwardPort = forwardPortService.getOne(new QueryWrapper().eq("forward_id", existForward.getId()).eq("node_id", node.getId()));
- if (forwardPort == null){
+ if (forwardPort == null) {
return R.err("部分节点不存在1");
}
- if (forwardUpdateDto.getInPort() != null && !forwardUpdateDto.getInPort().equals(forwardPort.getPort())) {
- Integer nodePort = tunnelService.getNodePort(forwardPort.getNodeId(), 2, forwardUpdateDto.getInPort());
- if (Objects.equals(nodePort, forwardUpdateDto.getInPort())) {
- forwardPort.setPort(nodePort);
- forwardPortService.updateById(forwardPort);
- }
- }
- GostUtil.AddAndUpdateService(serviceName, limiter, node, existForward, forwardPort, tunnel, "UpdateService");
+ forwardPort.setPort(chainTunnel.getPort());
+ forwardPortService.updateById(forwardPort);
+ GostDto gostDto = GostUtil.AddAndUpdateService(serviceName, limiter, node, existForward, forwardPort, tunnel, "UpdateService");
+ if (!Objects.equals(gostDto.getMsg(), "OK")) return R.err(gostDto.getMsg());
}
return R.ok();
@@ -289,7 +312,7 @@ public class ForwardServiceImpl extends ServiceImpl impl
String serviceName = buildServiceName(forward.getId(), forward.getUserId(), userTunnel);
Node node = nodeService.getById(chainTunnel.getNodeId());
- if (node == null){
+ if (node == null) {
return R.err("部分节点不存在");
}
@@ -305,7 +328,7 @@ public class ForwardServiceImpl extends ServiceImpl impl
@Override
public R pauseForward(Long id) {
- return changeForwardStatus(id, 0, "PauseService");
+ return changeForwardStatus(id, 0, "PauseService");
}
@Override
@@ -400,7 +423,7 @@ public class ForwardServiceImpl extends ServiceImpl impl
// 1. 入口->第一跳(或出口)
for (ChainTunnel inNode : inNodes) {
Node fromNode = nodeService.getById(inNode.getNodeId());
-
+
if (fromNode != null) {
if (!chainNodesList.isEmpty()) {
for (ChainTunnel firstChainNode : chainNodesList.getFirst()) {
@@ -436,10 +459,10 @@ public class ForwardServiceImpl extends ServiceImpl impl
// 2. 链路测试
for (int i = 0; i < chainNodesList.size(); i++) {
List currentHop = chainNodesList.get(i);
-
+
for (ChainTunnel currentNode : currentHop) {
Node fromNode = nodeService.getById(currentNode.getNodeId());
-
+
if (fromNode != null) {
if (i + 1 < chainNodesList.size()) {
for (ChainTunnel nextNode : chainNodesList.get(i + 1)) {
@@ -507,65 +530,57 @@ public class ForwardServiceImpl extends ServiceImpl impl
}
@Override
+ @Transactional
public R updateForwardOrder(Map params) {
- try {
- // 1. 获取当前用户信息
- UserInfo currentUser = getCurrentUserInfo();
+ // 1. 获取当前用户信息
+ UserInfo currentUser = getCurrentUserInfo();
- // 2. 验证参数
- if (!params.containsKey("forwards")) {
- return R.err("缺少forwards参数");
- }
-
- @SuppressWarnings("unchecked")
- List