代理逻辑优化
This commit is contained in:
+1
-1
@@ -39,7 +39,7 @@ public class ProxyConfig {
|
||||
public static ProxyConfig instance;
|
||||
private Protocol protocol;
|
||||
private Client client;
|
||||
private ProxyClientConfig clientConfig;
|
||||
private String licenseKey;
|
||||
|
||||
@Data
|
||||
public static class Protocol {
|
||||
|
||||
+25
-4
@@ -28,6 +28,7 @@ import fun.asgc.neutrino.core.annotation.Bean;
|
||||
import fun.asgc.neutrino.core.annotation.Component;
|
||||
import fun.asgc.neutrino.core.annotation.NonIntercept;
|
||||
import fun.asgc.neutrino.core.context.ApplicationRunner;
|
||||
import fun.asgc.neutrino.core.util.ArrayUtil;
|
||||
import fun.asgc.neutrino.core.util.CollectionUtil;
|
||||
import fun.asgc.neutrino.core.util.FileUtil;
|
||||
import fun.asgc.neutrino.core.util.StringUtil;
|
||||
@@ -71,8 +72,7 @@ public class ProxyClientRunner implements ApplicationRunner {
|
||||
|
||||
@Override
|
||||
public void run(String[] args) {
|
||||
ProxyClientConfig clientConfig = getClientConfig(args.length >= 1 ? args[args.length - 1] : null);
|
||||
proxyConfig.setClientConfig(clientConfig);
|
||||
proxyConfig.setLicenseKey(getLicenseKey(args));
|
||||
connectProxyServer();
|
||||
}
|
||||
|
||||
@@ -115,13 +115,13 @@ public class ProxyClientRunner implements ApplicationRunner {
|
||||
@Override
|
||||
public void operationComplete(ChannelFuture future) throws Exception {
|
||||
if (future.isSuccess()) {
|
||||
|
||||
// 连接成功,向服务器发送客户端认证信息(clientKey)
|
||||
ClientChannelMannager.setCmdChannel(future.channel());
|
||||
future.channel().writeAndFlush(ProxyMessage.buildAuthMessage(JSONObject.toJSONString(proxyConfig.getClientConfig())));
|
||||
future.channel().writeAndFlush(ProxyMessage.buildAuthMessage(proxyConfig.getLicenseKey()));
|
||||
log.info("连接代理服务成功.");
|
||||
} else {
|
||||
log.info("连接代理服务失败!");
|
||||
System.exit(-1);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -183,4 +183,25 @@ public class ProxyClientRunner implements ApplicationRunner {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getLicenseKey(String[] args) {
|
||||
String license = "";
|
||||
if (null != args && ArrayUtil.notEmpty(args)) {
|
||||
for (String s : args) {
|
||||
if (s.startsWith("license=") && s.length() > 8) {
|
||||
license = s.substring(8).trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (StringUtil.isEmpty(license)) {
|
||||
license = FileUtil.readContentAsString("./.neutrino-proxy.license");
|
||||
}
|
||||
if (StringUtil.isEmpty(license)) {
|
||||
log.error("未配置license,执行结束.");
|
||||
System.exit(-1);
|
||||
}
|
||||
FileUtil.write("./.neutrino-proxy.license", license);
|
||||
|
||||
return license;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -75,7 +75,7 @@ public class ProxyMessageConnectHandler implements ProxyMessageHandler {
|
||||
realServerChannel.attr(Constants.NEXT_CHANNEL).set(channel);
|
||||
|
||||
// 远程绑定
|
||||
channel.writeAndFlush(ProxyMessage.buildConnectMessage(userId + "@" + ProxyConfig.instance.getClientConfig().getClientKey()));
|
||||
channel.writeAndFlush(ProxyMessage.buildConnectMessage(userId + "@" + ProxyConfig.instance.getLicenseKey()));
|
||||
|
||||
realServerChannel.config().setOption(ChannelOption.AUTO_READ, true);
|
||||
ClientChannelMannager.addRealServerChannel(userId, realServerChannel);
|
||||
|
||||
@@ -50,5 +50,6 @@ public interface Constants {
|
||||
String DISCONNECT = "DISCONNECT";
|
||||
String TRANSFER = "TRANSFER";
|
||||
String ERROR = "ERROR";
|
||||
String PORT_MAPPING_SYNC = "PORT_MAPPING_SYNC";
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -43,7 +43,8 @@ public enum ProxyDataTypeEnum {
|
||||
CONNECT(0x03, Constants.ProxyDataTypeName.CONNECT,"连接"),
|
||||
DISCONNECT(0x04, Constants.ProxyDataTypeName.DISCONNECT,"断开连接"),
|
||||
TRANSFER(0x05, Constants.ProxyDataTypeName.TRANSFER,"数据传输"),
|
||||
ERROR(0x06, Constants.ProxyDataTypeName.ERROR,"异常");
|
||||
ERROR(0x06, Constants.ProxyDataTypeName.ERROR,"异常"),
|
||||
PORT_MAPPING_SYNC(0x07, Constants.ProxyDataTypeName.PORT_MAPPING_SYNC, "端口映射同步");
|
||||
private static Map<Integer,ProxyDataTypeEnum> cache = Stream.of(values()).collect(Collectors.toMap(ProxyDataTypeEnum::getType, Function.identity()));
|
||||
|
||||
private int type;
|
||||
|
||||
@@ -27,6 +27,7 @@ import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
|
||||
+6
-5
@@ -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);
|
||||
}
|
||||
|
||||
+3
@@ -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);
|
||||
}
|
||||
|
||||
+5
@@ -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);
|
||||
}
|
||||
|
||||
+45
-15
@@ -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);
|
||||
}
|
||||
|
||||
+4
@@ -182,6 +182,10 @@ public class LicenseService {
|
||||
licenseMapper.reset(id, key, now);
|
||||
}
|
||||
|
||||
public LicenseDO findByKey(String license) {
|
||||
return licenseMapper.findByKey(license);
|
||||
}
|
||||
|
||||
/**
|
||||
* 脱敏处理
|
||||
* 非当前登录人的license,一律脱敏
|
||||
|
||||
+9
@@ -203,4 +203,13 @@ public class PortMappingService {
|
||||
portMappingMapper.delete(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据license查询可用的端口映射列表
|
||||
* @param licenseId
|
||||
* @return
|
||||
*/
|
||||
public List<PortMappingDO> findEnableListByLicenseId(Integer licenseId) {
|
||||
return portMappingMapper.findEnableListByLicenseId(licenseId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+4
@@ -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);
|
||||
|
||||
+1
-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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user