Skip to content

Commit

Permalink
Merge pull request #20 from Zmax0/dev/2.4.2.2
Browse files Browse the repository at this point in the history
  • Loading branch information
Zmax0 committed Feb 20, 2024
2 parents 464d927 + 4cce869 commit 349f1d9
Show file tree
Hide file tree
Showing 39 changed files with 222 additions and 285 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.urbanspork.client;

import com.urbanspork.common.config.ServerConfig;
import com.urbanspork.common.transport.udp.TernaryDatagramPacket;
import com.urbanspork.common.transport.udp.DatagramPacketWrapper;
import com.urbanspork.common.util.LruCache;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
Expand All @@ -12,7 +12,7 @@

import java.time.Duration;

public abstract class AbstractClientUdpRelayHandler<K> extends SimpleChannelInboundHandler<TernaryDatagramPacket> {
public abstract class AbstractClientUdpRelayHandler<K> extends SimpleChannelInboundHandler<DatagramPacketWrapper> {

private static final Logger logger = LoggerFactory.getLogger(AbstractClientUdpRelayHandler.class);
protected final ServerConfig config;
Expand All @@ -26,25 +26,25 @@ protected AbstractClientUdpRelayHandler(ServerConfig config, Duration keepAlive)
});
}

protected abstract Object convertToWrite(TernaryDatagramPacket msg);
protected abstract Object convertToWrite(DatagramPacketWrapper msg);

protected abstract K getKey(TernaryDatagramPacket msg);
protected abstract K getKey(DatagramPacketWrapper msg);

protected abstract Channel newBindingChannel(Channel inboundChannel, K k);

@Override
public void channelRead0(ChannelHandlerContext ctx, TernaryDatagramPacket msg) {
public void channelRead0(ChannelHandlerContext ctx, DatagramPacketWrapper msg) {
DatagramPacket packet = msg.packet();
Channel inbound = ctx.channel();
Channel outbound = getBindingChannel(inbound, getKey(msg));
logger.info("[udp][{}]{}→{}~{}→{}", config.getProtocol(), packet.sender(), inbound.localAddress(), outbound.localAddress(), msg.third());
logger.info("[udp][{}]{}→{}~{}→{}", config.getProtocol(), packet.sender(), inbound.localAddress(), outbound.localAddress(), msg.proxy());
outbound.writeAndFlush(convertToWrite(msg));
}

@Override
public void handlerRemoved(ChannelHandlerContext ctx) {
logger.info("Stop timer and clear binding");
binding.clear();
binding.release();
}

private Channel getBindingChannel(Channel inboundChannel, K key) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package com.urbanspork.client;

import com.urbanspork.client.shadowsocks.ClientTCPChannelInitializer;
import com.urbanspork.client.vmess.ClientChannelInitializer;
import com.urbanspork.client.vmess.ClientAEADCodec;
import com.urbanspork.common.channel.AttributeKeys;
import com.urbanspork.common.channel.ChannelCloseUtils;
import com.urbanspork.common.channel.DefaultChannelInboundHandler;
import com.urbanspork.common.codec.shadowsocks.Mode;
import com.urbanspork.common.codec.shadowsocks.tcp.Context;
import com.urbanspork.common.codec.shadowsocks.tcp.TcpRelayCodec;
import com.urbanspork.common.config.ServerConfig;
import com.urbanspork.common.protocol.Protocol;
import com.urbanspork.common.protocol.socks.Socks5;
Expand All @@ -13,6 +15,7 @@
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.socksx.v5.DefaultSocks5CommandResponse;
Expand All @@ -33,17 +36,11 @@ protected void channelRead0(ChannelHandlerContext ctx, Socks5CommandRequest requ
Channel inboundChannel = ctx.channel();
ServerConfig config = inboundChannel.attr(AttributeKeys.SERVER_CONFIG).get();
InetSocketAddress serverAddress = new InetSocketAddress(config.getHost(), config.getPort());
ChannelHandler outboundHandler;
if (Protocol.vmess == config.getProtocol()) {
outboundHandler = new ClientChannelInitializer(request, config);
} else {
outboundHandler = new ClientTCPChannelInitializer(request, config);
}
new Bootstrap()
.group(inboundChannel.eventLoop())
.channel(inboundChannel.getClass())
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000)
.handler(outboundHandler)
.handler(getOutboundChannelHandler(request, config))
.connect(serverAddress).addListener((ChannelFutureListener) future -> {
if (future.isSuccess()) {
Channel outbound = future.channel();
Expand All @@ -60,4 +57,22 @@ protected void channelRead0(ChannelHandlerContext ctx, Socks5CommandRequest requ
}
});
}

private static ChannelHandler getOutboundChannelHandler(Socks5CommandRequest request, ServerConfig config) {
if (Protocol.vmess == config.getProtocol()) {
return new ChannelInitializer<>() {
@Override
protected void initChannel(Channel channel) {
channel.pipeline().addLast(new ClientAEADCodec(config.getCipher(), InetSocketAddress.createUnresolved(request.dstAddr(), request.dstPort()), config.getPassword()));
}
};
} else {
return new ChannelInitializer<>() {
@Override
protected void initChannel(Channel channel) {
channel.pipeline().addLast(new TcpRelayCodec(new Context(), config, request, Mode.Client));
}
};
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ private void channelRead0(ChannelHandlerContext ctx, Socks5CommandRequest reques
Channel channel = ctx.channel();
ServerConfig config = channel.attr(AttributeKeys.SERVER_CONFIG).get();
if (Protocol.vmess == config.getProtocol() && !config.udpEnabled()) {
channel.writeAndFlush(new DefaultSocks5CommandResponse(Socks5CommandStatus.FAILURE, request.dstAddrType()));
logger.error("UDP is not enabled");
channel.writeAndFlush(new DefaultSocks5CommandResponse(Socks5CommandStatus.FAILURE, request.dstAddrType()));
return;
}
if (request.dstPort() == 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import com.urbanspork.common.codec.shadowsocks.Mode;
import com.urbanspork.common.codec.shadowsocks.udp.UdpRelayCodec;
import com.urbanspork.common.config.ServerConfig;
import com.urbanspork.common.transport.udp.TernaryDatagramPacket;
import com.urbanspork.common.transport.udp.DatagramPacketWrapper;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
Expand Down Expand Up @@ -33,12 +33,12 @@ public ClientUdpRelayHandler(ServerConfig config, EventLoopGroup workerGroup) {
}

@Override
protected Object convertToWrite(TernaryDatagramPacket msg) {
return new TernaryDatagramPacket(new DatagramPacket(msg.packet().content(), msg.third()), relay);
protected Object convertToWrite(DatagramPacketWrapper msg) {
return new DatagramPacketWrapper(new DatagramPacket(msg.packet().content(), msg.proxy()), relay);
}

@Override
protected InetSocketAddress getKey(TernaryDatagramPacket msg) {
protected InetSocketAddress getKey(DatagramPacketWrapper msg) {
return msg.packet().sender();
}

Expand Down Expand Up @@ -72,7 +72,7 @@ private static class InboundHandler extends SimpleChannelInboundHandler<Datagram
@Override
public void channelRead0(ChannelHandlerContext ctx, DatagramPacket packet) {
logger.info("[udp][shadowsocks]{}←{}~{}←{}", sender, packet.recipient(), ctx.channel().localAddress(), packet.sender());
channel.writeAndFlush(new TernaryDatagramPacket(new DatagramPacket(packet.content(), packet.recipient()), sender));
channel.writeAndFlush(new DatagramPacketWrapper(new DatagramPacket(packet.content(), packet.recipient()), sender));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,17 @@
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageCodec;
import io.netty.handler.codec.DecoderException;
import io.netty.handler.codec.socksx.v5.Socks5CommandRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.InetSocketAddress;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

import static com.urbanspork.common.protocol.vmess.aead.Const.*;
import static com.urbanspork.common.protocol.vmess.aead.Const.KDF_SALT_AEAD_RESP_HEADER_LEN_IV;
import static com.urbanspork.common.protocol.vmess.aead.Const.KDF_SALT_AEAD_RESP_HEADER_LEN_KEY;
import static com.urbanspork.common.protocol.vmess.aead.Const.KDF_SALT_AEAD_RESP_HEADER_PAYLOAD_IV;
import static com.urbanspork.common.protocol.vmess.aead.Const.KDF_SALT_AEAD_RESP_HEADER_PAYLOAD_KEY;
import static com.urbanspork.common.protocol.vmess.aead.Encrypt.sealVMessAEADHeader;

public class ClientAEADCodec extends ByteToMessageCodec<ByteBuf> {
Expand All @@ -40,11 +43,11 @@ public class ClientAEADCodec extends ByteToMessageCodec<ByteBuf> {
private PayloadEncoder bodyEncoder;
private PayloadDecoder bodyDecoder;

public ClientAEADCodec(CipherKind cipher, Socks5CommandRequest address, String uuid) {
public ClientAEADCodec(CipherKind cipher, InetSocketAddress address, String uuid) {
this(cipher, RequestCommand.TCP, address, uuid);
}

ClientAEADCodec(CipherKind cipher, RequestCommand command, Socks5CommandRequest address, String uuid) {
ClientAEADCodec(CipherKind cipher, RequestCommand command, InetSocketAddress address, String uuid) {
this(RequestHeader.defaultHeader(SecurityType.valueOf(cipher), command, address, uuid), new ClientSession());
}

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@
import com.urbanspork.client.AbstractClientUdpRelayHandler;
import com.urbanspork.common.channel.DefaultChannelInboundHandler;
import com.urbanspork.common.config.ServerConfig;
import com.urbanspork.common.protocol.socks.Socks5;
import com.urbanspork.common.protocol.vmess.header.RequestCommand;
import com.urbanspork.common.transport.udp.TernaryDatagramPacket;
import com.urbanspork.common.transport.udp.DatagramPacketWrapper;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
Expand All @@ -17,8 +16,6 @@
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.DatagramPacket;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.socksx.v5.Socks5CommandRequest;
import io.netty.handler.codec.socksx.v5.Socks5CommandType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -36,13 +33,13 @@ public ClientUdpOverTCPHandler(ServerConfig config, EventLoopGroup workerGroup)
}

@Override
protected Object convertToWrite(TernaryDatagramPacket msg) {
protected Object convertToWrite(DatagramPacketWrapper msg) {
return msg.packet().content();
}

@Override
protected Key getKey(TernaryDatagramPacket msg) {
return new Key(msg.packet().sender(), msg.third() /* recipient */);
protected Key getKey(DatagramPacketWrapper msg) {
return new Key(msg.packet().sender(), msg.proxy() /* recipient */);
}

@Override
Expand All @@ -55,8 +52,7 @@ protected Channel newBindingChannel(Channel inboundChannel, Key key) {
.handler(new ChannelInitializer<>() {
@Override
protected void initChannel(Channel ch) {
Socks5CommandRequest request = Socks5.toCommandRequest(Socks5CommandType.CONNECT, key.recipient);
ch.pipeline().addLast(new ClientAEADCodec(config.getCipher(), RequestCommand.UDP, request, config.getPassword()));
ch.pipeline().addLast(new ClientAEADCodec(config.getCipher(), RequestCommand.UDP, key.recipient, config.getPassword()));
}
})
.connect(serverAddress).addListener((ChannelFutureListener) future -> {
Expand Down Expand Up @@ -94,7 +90,7 @@ private static class InboundHandler extends SimpleChannelInboundHandler<ByteBuf>
public void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) {
Channel inboundChannel = ctx.channel();
logger.info("[udp][vmess]{} ← {} ~ {} ← {}", sender, inboundChannel.localAddress(), inboundChannel.remoteAddress(), recipient);
channel.writeAndFlush(new TernaryDatagramPacket(new DatagramPacket(msg, recipient), sender));
channel.writeAndFlush(new DatagramPacketWrapper(new DatagramPacket(msg, recipient), sender));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@
import com.urbanspork.common.protocol.shadowsocks.aead.AEAD;
import com.urbanspork.common.protocol.shadowsocks.aead2022.AEAD2022;

import java.util.Base64;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public record Keys(byte[] encKey, byte[][] identityKeys) {
public static Keys from(CipherKind kind, String password) {
int keySize = kind.keySize();
Expand All @@ -24,11 +20,4 @@ public static Keys from(CipherKind kind, String password) {
}
return keys;
}

@Override
public String toString() {
return String.format("EK:%s, IK:%s",
Base64.getEncoder().encodeToString(encKey),
Stream.of(identityKeys).map(Base64.getEncoder()::encodeToString).collect(Collectors.joining("|")));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,9 @@ private void initAEAD2022PayloadDecoder(Session session, ByteBuf in, List<Object
throw new DecoderException(msg);
}
session.identity().setRequestSalt(salt);
ByteBuf sealedHeaderBuf = in.readBytes(eihLength + 1 + 8 + requestSaltLength + 2 + tagSize);
ByteBuf sealedHeaderBuf = Unpooled.buffer();
int sealedHeaderLength = eihLength + 1 + 8 + requestSaltLength + 2 + tagSize;
in.getBytes(in.readerIndex(), sealedHeaderBuf, sealedHeaderLength);
PayloadDecoder newPayloadDecoder;
if (requireEih) {
byte[] eih = new byte[16];
Expand All @@ -150,7 +152,6 @@ private void initAEAD2022PayloadDecoder(Session session, ByteBuf in, List<Object
Authenticator auth = newPayloadDecoder.auth();
byte[] sealedHeaderBytes = new byte[sealedHeaderBuf.readableBytes()];
sealedHeaderBuf.readBytes(sealedHeaderBytes);
sealedHeaderBuf.release();
ByteBuf headerBuf = Unpooled.wrappedBuffer(auth.open(sealedHeaderBytes));
byte streamTypeByte = headerBuf.readByte();
Mode expectedMode = switch (session.mode()) {
Expand All @@ -168,6 +169,7 @@ private void initAEAD2022PayloadDecoder(Session session, ByteBuf in, List<Object
headerBuf.readBytes(requestSalt);
session.identity().setRequestSalt(requestSalt);
}
in.skipBytes(sealedHeaderLength);
int length = headerBuf.readUnsignedShort();
if (in.readableBytes() < length + tagSize) {
in.resetReaderIndex();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ public boolean checkNonceReplay(byte[] nonce) {
}
}

public void release() {
saltCache.release();
}

record Key(byte[] nonce) {
@Override
public boolean equals(Object o) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import com.urbanspork.common.config.ServerConfig;
import com.urbanspork.common.manage.shadowsocks.ServerUserManager;
import com.urbanspork.common.protocol.shadowsocks.Control;
import com.urbanspork.common.transport.udp.TernaryDatagramPacket;
import com.urbanspork.common.transport.udp.DatagramPacketWrapper;
import com.urbanspork.common.util.LruCache;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
Expand All @@ -20,7 +20,7 @@
import java.util.ArrayList;
import java.util.List;

public class UdpRelayCodec extends MessageToMessageCodec<DatagramPacket, TernaryDatagramPacket> {
public class UdpRelayCodec extends MessageToMessageCodec<DatagramPacket, DatagramPacketWrapper> {
private static final Logger logger = LoggerFactory.getLogger(UdpRelayCodec.class);
private final ServerConfig config;
private final AeadCipherCodec cipher;
Expand All @@ -39,8 +39,8 @@ public UdpRelayCodec(ServerConfig config, Mode mode) {
}

@Override
protected void encode(ChannelHandlerContext ctx, TernaryDatagramPacket msg, List<Object> out) throws Exception {
InetSocketAddress proxy = msg.third();
protected void encode(ChannelHandlerContext ctx, DatagramPacketWrapper msg, List<Object> out) throws Exception {
InetSocketAddress proxy = msg.proxy();
if (proxy == null) {
throw new EncoderException("Relay address is null");
}
Expand Down Expand Up @@ -69,7 +69,7 @@ protected void decode(ChannelHandlerContext ctx, DatagramPacket msg, List<Object

@Override
public void handlerRemoved(ChannelHandlerContext ctx) {
controlMap.clear();
controlMap.release();
}

private Control getControl(InetSocketAddress key) {
Expand Down
Loading

0 comments on commit 349f1d9

Please sign in to comment.