mirror of
https://github.com/Sagit-chu/flvx.git
synced 2026-09-28 23:56:36 +08:00
修复隧道编辑新增入口节点后转发规则不生效的问题 (#9)
当编辑隧道添加新入口节点时,现有转发规则的ForwardPort和GOST服务未同步更新, 导致新入口节点的端口实际不可用。 修复方案:在updateTunnel成功更新节点后,同步更新所有使用该隧道的转发规则: - 对移除的入口节点:删除ForwardPort记录和GOST服务 - 对新增的入口节点:分配端口、创建ForwardPort记录和GOST服务
This commit is contained in:
@@ -430,6 +430,15 @@ public class TunnelServiceImpl extends ServiceImpl<TunnelMapper, Tunnel> impleme
|
||||
if (hasNodeChanges && tunnelUpdateDto.getInNodeId() != null) {
|
||||
List<ChainTunnel> backupChains = deepCopyChainTunnels(oldChainTunnels);
|
||||
|
||||
Set<Long> oldEntryNodeIds = oldChainTunnels.stream()
|
||||
.filter(ct -> ct.getChainType() != null && ct.getChainType() == 1)
|
||||
.map(ChainTunnel::getNodeId)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
Set<Long> newEntryNodeIds = tunnelUpdateDto.getInNodeId().stream()
|
||||
.map(ChainTunnel::getNodeId)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
List<Long> nodeIds = new ArrayList<>();
|
||||
Map<Long, Node> nodes = new HashMap<>();
|
||||
|
||||
@@ -511,6 +520,8 @@ public class TunnelServiceImpl extends ServiceImpl<TunnelMapper, Tunnel> impleme
|
||||
|
||||
chainTunnelService.saveBatch(newChainTunnels);
|
||||
|
||||
syncForwardsForEntryNodeChanges(existingTunnel.getId(), oldEntryNodeIds, newEntryNodeIds);
|
||||
|
||||
} catch (Exception e) {
|
||||
chainTunnelService.saveBatch(backupChains);
|
||||
rebuildGostConfig(backupChains, existingTunnel);
|
||||
@@ -1153,5 +1164,148 @@ public class TunnelServiceImpl extends ServiceImpl<TunnelMapper, Tunnel> impleme
|
||||
}
|
||||
}
|
||||
|
||||
private void syncForwardsForEntryNodeChanges(Long tunnelId, Set<Long> oldEntryNodeIds, Set<Long> newEntryNodeIds) {
|
||||
Set<Long> addedNodeIds = new HashSet<>(newEntryNodeIds);
|
||||
addedNodeIds.removeAll(oldEntryNodeIds);
|
||||
|
||||
Set<Long> removedNodeIds = new HashSet<>(oldEntryNodeIds);
|
||||
removedNodeIds.removeAll(newEntryNodeIds);
|
||||
|
||||
if (addedNodeIds.isEmpty() && removedNodeIds.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<Forward> forwards = forwardService.list(
|
||||
new QueryWrapper<Forward>().eq("tunnel_id", tunnelId.intValue())
|
||||
);
|
||||
|
||||
if (forwards.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Tunnel tunnel = this.getById(tunnelId);
|
||||
if (tunnel == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (Forward forward : forwards) {
|
||||
if (forward.getStatus() != 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
UserTunnel userTunnel = userTunnelService.getOne(
|
||||
new QueryWrapper<UserTunnel>()
|
||||
.eq("user_id", forward.getUserId())
|
||||
.eq("tunnel_id", tunnelId.intValue())
|
||||
);
|
||||
|
||||
for (Long removedNodeId : removedNodeIds) {
|
||||
ForwardPort forwardPort = forwardPortService.getOne(
|
||||
new QueryWrapper<ForwardPort>()
|
||||
.eq("forward_id", forward.getId())
|
||||
.eq("node_id", removedNodeId)
|
||||
);
|
||||
|
||||
if (forwardPort != null) {
|
||||
String serviceName = buildForwardServiceName(forward.getId(), forward.getUserId(), userTunnel);
|
||||
JSONArray services = new JSONArray();
|
||||
services.add(serviceName + "_tcp");
|
||||
services.add(serviceName + "_udp");
|
||||
GostUtil.DeleteService(removedNodeId, services);
|
||||
|
||||
forwardPortService.removeById(forwardPort.getId());
|
||||
}
|
||||
}
|
||||
|
||||
for (Long addedNodeId : addedNodeIds) {
|
||||
ForwardPort existingPort = forwardPortService.getOne(
|
||||
new QueryWrapper<ForwardPort>()
|
||||
.eq("forward_id", forward.getId())
|
||||
.eq("node_id", addedNodeId)
|
||||
);
|
||||
|
||||
if (existingPort != null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
List<ForwardPort> existingPorts = forwardPortService.list(
|
||||
new QueryWrapper<ForwardPort>().eq("forward_id", forward.getId())
|
||||
);
|
||||
|
||||
Integer targetPort = null;
|
||||
if (!existingPorts.isEmpty()) {
|
||||
targetPort = existingPorts.get(0).getPort();
|
||||
}
|
||||
|
||||
Integer allocatedPort = allocatePortForNode(addedNodeId, targetPort, forward.getId());
|
||||
if (allocatedPort == null) {
|
||||
System.err.println("Failed to allocate port on node " + addedNodeId + " for forward " + forward.getId());
|
||||
continue;
|
||||
}
|
||||
|
||||
ForwardPort newForwardPort = new ForwardPort();
|
||||
newForwardPort.setForwardId(forward.getId());
|
||||
newForwardPort.setNodeId(addedNodeId);
|
||||
newForwardPort.setPort(allocatedPort);
|
||||
forwardPortService.save(newForwardPort);
|
||||
|
||||
Node node = nodeService.getById(addedNodeId);
|
||||
if (node != null) {
|
||||
String serviceName = buildForwardServiceName(forward.getId(), forward.getUserId(), userTunnel);
|
||||
Integer limiter = (userTunnel != null && userTunnel.getSpeedId() != null) ? userTunnel.getSpeedId() : null;
|
||||
GostUtil.AddAndUpdateService(serviceName, limiter, node, forward, newForwardPort, tunnel, "AddService");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Integer allocatePortForNode(Long nodeId, Integer preferredPort, Long forwardId) {
|
||||
Node node = nodeService.getById(nodeId);
|
||||
if (node == null || node.getPort() == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Set<Integer> usedPorts = new HashSet<>();
|
||||
|
||||
List<ChainTunnel> chainTunnels = chainTunnelService.list(
|
||||
new QueryWrapper<ChainTunnel>().eq("node_id", nodeId)
|
||||
);
|
||||
for (ChainTunnel ct : chainTunnels) {
|
||||
if (ct.getPort() != null) {
|
||||
usedPorts.add(ct.getPort());
|
||||
}
|
||||
}
|
||||
|
||||
List<ForwardPort> forwardPorts = forwardPortService.list(
|
||||
new QueryWrapper<ForwardPort>()
|
||||
.eq("node_id", nodeId)
|
||||
.ne("forward_id", forwardId)
|
||||
);
|
||||
for (ForwardPort fp : forwardPorts) {
|
||||
if (fp.getPort() != null) {
|
||||
usedPorts.add(fp.getPort());
|
||||
}
|
||||
}
|
||||
|
||||
List<Integer> availablePorts = parsePorts(node.getPort());
|
||||
|
||||
if (preferredPort != null && availablePorts.contains(preferredPort) && !usedPorts.contains(preferredPort)) {
|
||||
return preferredPort;
|
||||
}
|
||||
|
||||
for (Integer port : availablePorts) {
|
||||
if (!usedPorts.contains(port)) {
|
||||
return port;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private String buildForwardServiceName(Long forwardId, Integer userId, UserTunnel userTunnel) {
|
||||
int userTunnelId = (userTunnel != null) ? userTunnel.getId() : 0;
|
||||
return forwardId + "_" + userId + "_" + userTunnelId;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user