代理逻辑优化

This commit is contained in:
aoshiguchen
2022-08-29 21:13:48 +08:00
parent c4cc6e89ed
commit e2f351d898
14 changed files with 108 additions and 28 deletions
@@ -23,6 +23,7 @@
package fun.asgc.neutrino.proxy.server.base.proxy;
import fun.asgc.neutrino.proxy.core.ProxyClientConfig;
import fun.asgc.neutrino.proxy.server.dal.entity.PortMappingDO;
import lombok.Data;
import java.io.Serializable;
@@ -52,12 +53,12 @@ public class ProxyServerConfig implements Serializable {
*/
private volatile Map<Integer, String> inetPortLanInfoMapping = new HashMap<Integer, String>();
public void addClientConfig(ProxyClientConfig clientConfig) {
String clientKey = clientConfig.getClientKey();
public void addClientConfig(String licenseKey, List<PortMappingDO> portMappingList) {
String clientKey = licenseKey;
List<Integer> ports = new ArrayList<>();
for (ProxyClientConfig.Proxy proxy : clientConfig.getProxy()) {
ports.add(proxy.getServerPort());
inetPortLanInfoMapping.put(proxy.getServerPort(), proxy.getClientInfo());
for (PortMappingDO portMapping : portMappingList) {
ports.add(portMapping.getServerPort());
inetPortLanInfoMapping.put(portMapping.getServerPort(), portMapping.getClientIp() + ":" + portMapping.getClientPort());
}
clientInetPortMapping.put(clientKey, ports);
}
@@ -89,4 +89,7 @@ public interface LicenseMapper extends SqlMapper {
@ResultType(LicenseDO.class)
@Select("select * from `license` where user_id = :userId and name =:name and id not in (:excludeIds) limit 0,1")
LicenseDO checkRepeat(@Param("userId") Integer userId, @Param("name") String name, @Param("excludeIds") Set<Integer> excludeIds);
@Select("select * from `license` where key = ?")
LicenseDO findByKey(String licenseKey);
}
@@ -33,6 +33,7 @@ import fun.asgc.neutrino.proxy.server.controller.req.PortMappingListReq;
import fun.asgc.neutrino.proxy.server.controller.res.PortMappingListRes;
import fun.asgc.neutrino.proxy.server.dal.entity.PortMappingDO;
import java.util.List;
import java.util.Set;
/**
@@ -65,4 +66,8 @@ public interface PortMappingMapper extends SqlMapper {
@Select("select * from port_mapping where server_port = :port and id not in (:excludeIds)")
PortMappingDO findByPort(@Param("port") Integer port, @Param("excludeIds") Set<Integer> excludeIds);
@ResultType(PortMappingDO.class)
@Select("select * from port_mapping where license_id = ? and enable = 1")
List<PortMappingDO> findEnableListByLicenseId(Integer licenseId);
}
@@ -22,16 +22,24 @@
package fun.asgc.neutrino.proxy.server.handler;
import com.alibaba.fastjson.JSONObject;
import fun.asgc.neutrino.core.annotation.Autowired;
import fun.asgc.neutrino.core.annotation.Component;
import fun.asgc.neutrino.core.annotation.Match;
import fun.asgc.neutrino.core.annotation.NonIntercept;
import fun.asgc.neutrino.core.util.CollectionUtil;
import fun.asgc.neutrino.core.util.StringUtil;
import fun.asgc.neutrino.proxy.core.*;
import fun.asgc.neutrino.proxy.server.base.proxy.ProxyConfig;
import fun.asgc.neutrino.proxy.server.base.proxy.ProxyServerConfig;
import fun.asgc.neutrino.proxy.server.base.rest.constant.EnableStatusEnum;
import fun.asgc.neutrino.proxy.server.core.BytesMetricsHandler;
import fun.asgc.neutrino.proxy.server.core.UserChannelHandler;
import fun.asgc.neutrino.proxy.server.dal.entity.LicenseDO;
import fun.asgc.neutrino.proxy.server.dal.entity.PortMappingDO;
import fun.asgc.neutrino.proxy.server.dal.entity.UserDO;
import fun.asgc.neutrino.proxy.server.service.LicenseService;
import fun.asgc.neutrino.proxy.server.service.PortMappingService;
import fun.asgc.neutrino.proxy.server.service.UserService;
import fun.asgc.neutrino.proxy.server.util.ProxyChannelManager;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
@@ -61,37 +69,59 @@ public class ProxyMessageAuthHandler implements ProxyMessageHandler {
private NioEventLoopGroup serverWorkerGroup;
@Autowired
private ProxyConfig proxyConfig;
@Autowired
private LicenseService licenseService;
@Autowired
private UserService userService;
@Autowired
private PortMappingService portMappingService;
@Override
public void handle(ChannelHandlerContext ctx, ProxyMessage proxyMessage) {
ProxyClientConfig clientConfig = JSONObject.parseObject(proxyMessage.getInfo(), ProxyClientConfig.class);
String clientKey = clientConfig.getClientKey();
if (!proxyConfig.getLicenseMap().containsKey(clientKey)) {
ctx.channel().writeAndFlush(ProxyMessage.buildErrMessage(ExceptionEnum.AUTH_FAILED, "无效的clientKey"));
String licenseKey = proxyMessage.getInfo();
if (StringUtil.isEmpty(licenseKey)) {
ctx.channel().writeAndFlush(ProxyMessage.buildErrMessage(ExceptionEnum.AUTH_FAILED, "license不能为空!"));
ctx.channel().close();
return;
}
LicenseDO licenseDO = licenseService.findByKey(licenseKey);
if (null == licenseDO) {
ctx.channel().writeAndFlush(ProxyMessage.buildErrMessage(ExceptionEnum.AUTH_FAILED, "license不存在!"));
ctx.channel().close();
return;
}
if (EnableStatusEnum.DISABLE.getStatus().equals(licenseDO.getEnable())) {
ctx.channel().writeAndFlush(ProxyMessage.buildErrMessage(ExceptionEnum.AUTH_FAILED, "当前license已被禁用!"));
ctx.channel().close();
return;
}
UserDO userDO = userService.findById(licenseDO.getId());
if (null == userDO || EnableStatusEnum.DISABLE.getStatus().equals(userDO.getEnable())) {
ctx.channel().writeAndFlush(ProxyMessage.buildErrMessage(ExceptionEnum.AUTH_FAILED, "当前license无效!"));
ctx.channel().close();
return;
}
List<PortMappingDO> portMappingList = portMappingService.findEnableListByLicenseId(licenseDO.getId());
if (CollectionUtil.isEmpty(portMappingList)) {
ctx.channel().writeAndFlush(ProxyMessage.buildErrMessage(ExceptionEnum.AUTH_FAILED, "当前license没有可用的端口映射!"));
ctx.channel().close();
return;
}
if (proxyConfig.getLicenseMap().get(clientKey) != -1 && clientConfig.getProxy().size() > proxyConfig.getLicenseMap().get(clientKey)) {
ctx.channel().writeAndFlush(ProxyMessage.buildErrMessage(ExceptionEnum.AUTH_FAILED, "代理端口数超过license限制"));
ctx.channel().close();
return;
}
ProxyServerConfig.getInstance().addClientConfig(clientConfig);
List<Integer> ports = ProxyServerConfig.getInstance().getClientInetPorts(clientKey);
ProxyServerConfig.getInstance().addClientConfig(licenseKey, portMappingList);
List<Integer> ports = ProxyServerConfig.getInstance().getClientInetPorts(licenseKey);
if (ports == null) {
ctx.channel().close();
return;
}
Channel channel = ProxyChannelManager.getCmdChannel(clientKey);
Channel channel = ProxyChannelManager.getCmdChannel(licenseKey);
if (channel != null) {
ctx.channel().close();
return;
}
ProxyChannelManager.addCmdChannel(ports, clientKey, ctx.channel());
ProxyChannelManager.addCmdChannel(ports, licenseKey, ctx.channel());
startUserPortServer(ports);
}
@@ -182,6 +182,10 @@ public class LicenseService {
licenseMapper.reset(id, key, now);
}
public LicenseDO findByKey(String license) {
return licenseMapper.findByKey(license);
}
/**
* 脱敏处理
* 非当前登录人的license,一律脱敏
@@ -203,4 +203,13 @@ public class PortMappingService {
portMappingMapper.delete(id);
}
/**
* 根据license查询可用的端口映射列表
* @param licenseId
* @return
*/
public List<PortMappingDO> findEnableListByLicenseId(Integer licenseId) {
return portMappingMapper.findEnableListByLicenseId(licenseId);
}
}
@@ -119,6 +119,10 @@ public class UserService {
return userMapper.findById(userTokenDO.getUserId());
}
public UserDO findById(Integer id) {
return userMapper.findById(id);
}
public void updateTokenExpirationTime(String token) {
Date now = new Date();
Date expirationTime = DateUtil.addDate(now, Calendar.HOUR, 1);
@@ -73,7 +73,7 @@ public class ProxyChannelManager {
channel.attr(CHANNEL_PORT).set(ports);
channel.attr(CHANNEL_CLIENT_KEY).set(clientKey);
channel.attr(USER_CHANNELS).set(new ConcurrentHashMap<String, Channel>());
channel.attr(USER_CHANNELS).set(new ConcurrentHashMap<>());
cmdChannels.put(clientKey, channel);
}