use of org.rx.io.Bytes in project rxlib by RockyLOMO.
the class Udp2rawHandler method channelRead0.
@SneakyThrows
@Override
protected void channelRead0(ChannelHandlerContext inbound, DatagramPacket in) throws Exception {
ByteBuf inBuf = in.content();
if (inBuf.readableBytes() < 4) {
return;
}
SocksProxyServer server = SocksContext.server(inbound.channel());
final InetSocketAddress srcEp0 = in.sender();
List<InetSocketAddress> udp2rawServers = server.config.getUdp2rawServers();
// client
if (udp2rawServers != null) {
if (!udp2rawServers.contains(srcEp0) && !clientRoutes.containsKey(srcEp0)) {
final UnresolvedEndpoint dstEp = UdpManager.socks5Decode(inBuf);
RouteEventArgs e = new RouteEventArgs(srcEp0, dstEp);
server.raiseEvent(server.onUdpRoute, e);
Upstream upstream = e.getValue();
AuthenticEndpoint svrEp = upstream.getSocksServer();
if (svrEp != null) {
ByteBuf outBuf = Bytes.directBuffer(64 + inBuf.readableBytes());
outBuf.writeShort(STREAM_MAGIC);
outBuf.writeByte(STREAM_VERSION);
UdpManager.encode(outBuf, new UnresolvedEndpoint(srcEp0));
UdpManager.encode(outBuf, dstEp);
zip(outBuf, inBuf);
inbound.writeAndFlush(new DatagramPacket(outBuf, svrEp.getEndpoint()));
// log.info("UDP2RAW CLIENT {} => {}[{}]", srcEp0, svrEp.getEndpoint(), dstEp);
return;
}
UnresolvedEndpoint upDstEp = upstream.getDestination();
log.debug("UDP2RAW[{}] CLIENT DIRECT {} => {}[{}]", server.config.getListenPort(), srcEp0, upDstEp, dstEp);
inbound.writeAndFlush(new DatagramPacket(inBuf.retain(), upDstEp.socketAddress()));
clientRoutes.put(upDstEp.socketAddress(), Tuple.of(srcEp0, dstEp));
return;
}
Tuple<InetSocketAddress, UnresolvedEndpoint> upSrcs = clientRoutes.get(srcEp0);
if (upSrcs != null) {
ByteBuf outBuf = UdpManager.socks5Encode(inBuf, upSrcs.right);
log.debug("UDP2RAW[{}] CLIENT DIRECT {}[{}] => {}", server.config.getListenPort(), srcEp0, upSrcs.right, upSrcs.left);
inbound.writeAndFlush(new DatagramPacket(outBuf, upSrcs.left));
return;
}
if (inBuf.readShort() != STREAM_MAGIC & inBuf.readByte() != STREAM_VERSION) {
log.warn("discard {} bytes", inBuf.readableBytes());
return;
}
UnresolvedEndpoint srcEp = UdpManager.decode(inBuf);
UnresolvedEndpoint dstEp = UdpManager.decode(inBuf);
ByteBuf outBuf = UdpManager.socks5Encode(inBuf, dstEp);
inbound.writeAndFlush(new DatagramPacket(outBuf, srcEp.socketAddress()));
// log.info("UDP2RAW CLIENT {}[{}] => {}", srcEp0, dstEp, srcEp);
return;
}
// server
if (inBuf.readShort() != STREAM_MAGIC & inBuf.readByte() != STREAM_VERSION) {
log.warn("discard {} bytes", inBuf.readableBytes());
return;
}
final UnresolvedEndpoint srcEp = UdpManager.decode(inBuf);
final UnresolvedEndpoint dstEp = UdpManager.decode(inBuf);
Channel outbound = UdpManager.openChannel(srcEp.socketAddress(), k -> {
RouteEventArgs e = new RouteEventArgs(srcEp.socketAddress(), dstEp);
server.raiseEvent(server.onUdpRoute, e);
Upstream upstream = e.getValue();
return SocksContext.initOutbound(Sockets.udpBootstrap(server.config.getMemoryMode(), ob -> {
SocksContext.server(ob, server);
upstream.initChannel(ob);
ob.pipeline().addLast(new IdleStateHandler(0, 0, server.config.getUdpTimeoutSeconds()) {
@Override
protected IdleStateEvent newIdleStateEvent(IdleState state, boolean first) {
UdpManager.closeChannel(SocksContext.realSource(ob));
return super.newIdleStateEvent(state, first);
}
}, new SimpleChannelInboundHandler<DatagramPacket>() {
@Override
protected void channelRead0(ChannelHandlerContext outbound, DatagramPacket out) {
ByteBuf outBuf = Bytes.directBuffer(64 + out.content().readableBytes());
outBuf.writeShort(STREAM_MAGIC);
outBuf.writeByte(STREAM_VERSION);
UdpManager.encode(outBuf, srcEp);
UdpManager.encode(outBuf, dstEp);
outBuf.writeBytes(out.content());
inbound.writeAndFlush(new DatagramPacket(outBuf, srcEp0));
// log.info("UDP2RAW SERVER {}[{}] => {}[{}]", out.sender(), dstEp, srcEp0, srcEp);
}
});
}).bind(0).addListener(Sockets.logBind(0)).addListener(UdpManager.FLUSH_PENDING_QUEUE).channel(), srcEp.socketAddress(), dstEp, upstream);
});
ByteBuf outBuf = unzip(inBuf);
UdpManager.pendOrWritePacket(outbound, new DatagramPacket(outBuf, dstEp.socketAddress()));
// log.info("UDP2RAW SERVER {}[{}] => {}", srcEp0, srcEp, dstEp);
}
Aggregations