服务端收到UDP数据包转发至客户端调通

This commit is contained in:
aoshiguchen
2023-09-20 11:57:00 +08:00
parent 6880898321
commit fd306ce8c3
17 changed files with 365 additions and 46 deletions
@@ -47,7 +47,7 @@ public class TcpProxyChannelHandler extends SimpleChannelInboundHandler<ProxyMes
realServerChannel.close();
}
ProxyUtil.removeProxyChanel(ctx.channel());
ProxyUtil.removeTcpProxyChanel(ctx.channel());
super.channelInactive(ctx);
}
@@ -47,7 +47,7 @@ public class UdpProxyChannelHandler extends SimpleChannelInboundHandler<ProxyMes
realServerChannel.close();
}
ProxyUtil.removeProxyChanel(ctx.channel());
ProxyUtil.removeTcpProxyChanel(ctx.channel());
super.channelInactive(ctx);
}
@@ -26,7 +26,7 @@ public class ProxyMessageDisconnectHandler implements ProxyMessageHandler {
Channel realServerChannel = ctx.channel().attr(Constants.NEXT_CHANNEL).get();
if (null != realServerChannel) {
ctx.channel().attr(Constants.NEXT_CHANNEL).remove();
ProxyUtil.returnProxyChanel(ctx.channel());
ProxyUtil.returnTcpProxyChanel(ctx.channel());
realServerChannel.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
}
ctx.close();
@@ -0,0 +1,64 @@
package org.dromara.neutrinoproxy.client.handler;
import com.alibaba.fastjson.JSONObject;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.dromara.neutrinoproxy.client.config.ProxyConfig;
import org.dromara.neutrinoproxy.client.core.ProxyChannelBorrowListener;
import org.dromara.neutrinoproxy.client.util.ProxyUtil;
import org.dromara.neutrinoproxy.core.Constants;
import org.dromara.neutrinoproxy.core.ProxyDataTypeEnum;
import org.dromara.neutrinoproxy.core.ProxyMessage;
import org.dromara.neutrinoproxy.core.ProxyMessageHandler;
import org.dromara.neutrinoproxy.core.dispatcher.Match;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
/**
* @author: aoshiguchen
* @date: 2023/9/19
*/
@Slf4j
@Match(type = Constants.ProxyDataTypeName.UDP_CONNECT)
@Component
public class UdpProxyMessageConnectHandler implements ProxyMessageHandler {
@Inject
private ProxyConfig proxyConfig;
@Inject("udpProxyTunnelBootstrap")
private Bootstrap udpProxyTunnelBootstrap;
@Override
public void handle(ChannelHandlerContext ctx, ProxyMessage proxyMessage) {
final Channel cmdChannel = ctx.channel();
final ProxyMessage.UdpBaseInfo udpBaseInfo = JSONObject.parseObject(proxyMessage.getInfo(), ProxyMessage.UdpBaseInfo.class);
log.info("[UDP connect]info:{}", proxyMessage.getInfo());
// 获取连接
ProxyUtil.borrowTcpProxyChanel(udpProxyTunnelBootstrap, new ProxyChannelBorrowListener() {
@Override
public void success(Channel channel) {
ctx.channel().writeAndFlush(ProxyMessage.buildUdpConnectMessage(new ProxyMessage.UdpBaseInfo()
.setVisitorId(udpBaseInfo.getVisitorId())
.setServerPort(udpBaseInfo.getServerPort())
.setTargetIp(udpBaseInfo.getTargetIp())
.setTargetPort(udpBaseInfo.getTargetPort())
).setData(proxyConfig.getTunnel().getLicenseKey().getBytes()));
}
@Override
public void error(Throwable cause) {
cmdChannel.writeAndFlush(ProxyMessage.buildDisconnectMessage(udpBaseInfo.toJsonString()));
}
});
}
@Override
public String name() {
return ProxyDataTypeEnum.UDP_CONNECT.getDesc();
}
}
@@ -0,0 +1,33 @@
package org.dromara.neutrinoproxy.client.handler;
import com.alibaba.fastjson.JSONObject;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.dromara.neutrinoproxy.core.Constants;
import org.dromara.neutrinoproxy.core.ProxyDataTypeEnum;
import org.dromara.neutrinoproxy.core.ProxyMessage;
import org.dromara.neutrinoproxy.core.ProxyMessageHandler;
import org.dromara.neutrinoproxy.core.dispatcher.Match;
import org.noear.solon.annotation.Component;
/**
* @author: aoshiguchen
* @date: 2023/9/20
*/
@Slf4j
@Match(type = Constants.ProxyDataTypeName.UDP_TRANSFER)
@Component
public class UdpProxyMessageTransferHandler implements ProxyMessageHandler {
@Override
public void handle(ChannelHandlerContext ctx, ProxyMessage proxyMessage) {
final ProxyMessage.UdpBaseInfo udpBaseInfo = JSONObject.parseObject(proxyMessage.getInfo(), ProxyMessage.UdpBaseInfo.class);
log.info("[UDP transfer]info:{} data:{}", proxyMessage.getInfo(), new String(proxyMessage.getData()));
}
@Override
public String name() {
return ProxyDataTypeEnum.UDP_TRANSFER.getDesc();
}
}
@@ -64,7 +64,8 @@ public class ProxyUtil {
private static Map<String, Channel> realServerChannels = new ConcurrentHashMap<String, Channel>();
private static ConcurrentLinkedQueue<Channel> proxyChannelPool = new ConcurrentLinkedQueue<Channel>();
private static ConcurrentLinkedQueue<Channel> tcpProxyChannelPool = new ConcurrentLinkedQueue<Channel>();
private static ConcurrentLinkedQueue<Channel> udpProxyChannelPool = new ConcurrentLinkedQueue<>();
private static volatile Channel cmdChannel;
@@ -72,7 +73,7 @@ public class ProxyUtil {
private static final String CLIENT_ID_FILE = ".NEUTRINO_PROXY_CLIENT_ID";
public static void borrowTcpProxyChanel(Bootstrap tcpProxyTunnelBootstrap, final ProxyChannelBorrowListener borrowListener) {
Channel channel = proxyChannelPool.poll();
Channel channel = tcpProxyChannelPool.poll();
if (null != channel) {
borrowListener.success(channel);
return;
@@ -87,18 +88,52 @@ public class ProxyUtil {
});
}
public static void returnProxyChanel(Channel proxyChanel) {
if (proxyChannelPool.size() > MAX_POOL_SIZE) {
public static void returnTcpProxyChanel(Channel proxyChanel) {
if (tcpProxyChannelPool.size() > MAX_POOL_SIZE) {
proxyChanel.close();
} else {
proxyChanel.config().setOption(ChannelOption.AUTO_READ, true);
proxyChanel.attr(Constants.NEXT_CHANNEL).remove();
proxyChannelPool.offer(proxyChanel);
tcpProxyChannelPool.offer(proxyChanel);
}
}
public static void removeProxyChanel(Channel proxyChanel) {
proxyChannelPool.remove(proxyChanel);
public static void removeTcpProxyChanel(Channel proxyChanel) {
tcpProxyChannelPool.remove(proxyChanel);
}
public static void borrowUdpProxyChanel(Bootstrap tcpProxyTunnelBootstrap, final ProxyChannelBorrowListener borrowListener) {
Channel channel = udpProxyChannelPool.poll();
if (null != channel) {
borrowListener.success(channel);
return;
}
tcpProxyTunnelBootstrap.connect().addListener((ChannelFutureListener) future -> {
if (future.isSuccess()) {
borrowListener.success(future.channel());
} else {
borrowListener.error(future.cause());
}
});
}
public static void returnUdpProxyChanel(Channel proxyChanel) {
if (udpProxyChannelPool.size() > MAX_POOL_SIZE) {
proxyChanel.close();
} else {
proxyChanel.config().setOption(ChannelOption.AUTO_READ, true);
proxyChanel.attr(Constants.NEXT_CHANNEL).remove();
udpProxyChannelPool.offer(proxyChanel);
}
}
public static void removeUdpProxyChanel(Channel proxyChanel) {
udpProxyChannelPool.remove(proxyChanel);
}
public static void setCmdChannel(Channel cmdChannel) {