diff --git a/neutrino-proxy-core/src/main/java/org/dromara/neutrinoproxy/core/ProxyMessage.java b/neutrino-proxy-core/src/main/java/org/dromara/neutrinoproxy/core/ProxyMessage.java index 5470565e..716557c4 100644 --- a/neutrino-proxy-core/src/main/java/org/dromara/neutrinoproxy/core/ProxyMessage.java +++ b/neutrino-proxy-core/src/main/java/org/dromara/neutrinoproxy/core/ProxyMessage.java @@ -66,6 +66,10 @@ public class ProxyMessage { * 通用异常信息 */ public static final byte TYPE_ERROR = 0x06; + /** + * UDP数据传输 + */ + private static final byte TYPE_UDP_TRANSFER = 0x07; /** * 消息类型 @@ -130,6 +134,17 @@ public class ProxyMessage { .setData(data); } + public static ProxyMessage buildUdpTransferMessage(String visitorIp, int visitorPort, String targetIp, int targetPort, byte[] data) { + return create().setType(TYPE_UDP_TRANSFER) + .setInfo(JSONObject.toJSONString(new UdpBaseInfo() + .setVisitorIp(visitorIp) + .setVisitorPort(visitorPort) + .setTargetIp(targetIp) + .setTargetPort(targetPort) + )) + .setData(data); + } + public static ProxyMessage buildErrMessage(ExceptionEnum exceptionEnum, String info) { JSONObject data = new JSONObject(); data.put("code", exceptionEnum.getCode()); @@ -142,4 +157,13 @@ public class ProxyMessage { public static ProxyMessage buildErrMessage(ExceptionEnum exceptionEnum) { return buildErrMessage(exceptionEnum, null); } + + @Accessors(chain = true) + @Data + public static class UdpBaseInfo { + private String visitorIp; + private int visitorPort; + private String targetIp; + private int targetPort; + } } diff --git a/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/proxy/core/UdpVisitorChannelHandler.java b/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/proxy/core/UdpVisitorChannelHandler.java index 6c07bf00..546b6993 100644 --- a/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/proxy/core/UdpVisitorChannelHandler.java +++ b/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/proxy/core/UdpVisitorChannelHandler.java @@ -1,9 +1,15 @@ package org.dromara.neutrinoproxy.server.proxy.core; +import cn.hutool.core.util.StrUtil; +import io.netty.channel.Channel; import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelOption; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.channel.socket.DatagramPacket; +import org.dromara.neutrinoproxy.core.ProxyMessage; +import org.dromara.neutrinoproxy.server.util.ProxyUtil; +import java.net.InetSocketAddress; import java.nio.charset.StandardCharsets; /** @@ -13,8 +19,40 @@ import java.nio.charset.StandardCharsets; public class UdpVisitorChannelHandler extends SimpleChannelInboundHandler { @Override - protected void channelRead0(ChannelHandlerContext channelHandlerContext, DatagramPacket datagramPacket) throws Exception { + protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket datagramPacket) throws Exception { System.out.println("服务端接收到消息 \nsender:" + datagramPacket.sender().toString() + "内容\n" + datagramPacket.content().toString(StandardCharsets.UTF_8)); - } + Channel visitorChannel = ctx.channel(); + InetSocketAddress sa = (InetSocketAddress) visitorChannel.localAddress(); + Channel cmdChannel = ProxyUtil.getCmdChannelByServerPort(sa.getPort()); + + if (null == cmdChannel) { + // 该端口还没有代理客户端 + ctx.channel().close(); + return; + } + + // 根据代理服务端端口,获取被代理客户端局域网连接信息 + String lanInfo = ProxyUtil.getClientLanInfoByServerPort(sa.getPort()); + if (StrUtil.isEmpty(lanInfo)) { + ctx.channel().close(); + return; + } + + String[] targetInfo = lanInfo.split(":"); + String targetIp = targetInfo[0]; + int targetPort = Integer.parseInt(targetInfo[1]); + + // 转发代理数据 + byte[] bytes = new byte[datagramPacket.content().readableBytes()]; + datagramPacket.content().readBytes(bytes); + + cmdChannel.writeAndFlush(ProxyMessage.buildUdpTransferMessage( + sa.getAddress().getHostAddress(), + sa.getPort(), + targetIp, + targetPort, + bytes + )); + } }