Socks5CmdRequesthandler.java
3.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package org.shadowsocks.handler.local;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.socksx.v5.*;
import org.shadowsocks.config.Config;
import org.shadowsocks.crypto.CryptoFactory;
import org.shadowsocks.crypto.SSCrypto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* handle socks5 request
*/
public class Socks5CmdRequesthandler extends SimpleChannelInboundHandler<DefaultSocks5CommandRequest> {
private static final Logger logger = LoggerFactory.getLogger(Socks5CmdRequesthandler.class);
private Config config;
private EventLoopGroup bossGroup = new NioEventLoopGroup();
private SSCrypto ssCrypto ;
private boolean isProxy = true;
public Socks5CmdRequesthandler(Config config){
this.config = config;
try{
ssCrypto = CryptoFactory.create(config.getMethod(),config.getPassword());
}
catch (Exception e){
e.printStackTrace();
}
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, DefaultSocks5CommandRequest msg) {
if(msg.type().equals(Socks5CommandType.CONNECT)) {
logger.trace("connecting remote server");
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(bossGroup)
.channel(NioSocketChannel.class)
.option(ChannelOption.TCP_NODELAY, true)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new Remote2LocalHandler(ctx,ssCrypto,isProxy));
}
});
ChannelFuture future;
if(isProxy){
future = bootstrap.connect(config.getServerAddress(), config.getServerPort());
}
else {
future = bootstrap.connect(msg.dstAddr(),msg.dstPort());
}
future.addListener(new ChannelFutureListener() {
public void operationComplete(final ChannelFuture future) throws Exception {
if(future.isSuccess()) {
logger.info("successfully connected remote server");
ctx.pipeline().addLast(new Local2RemoteHandler(future,ssCrypto,msg,isProxy));
Socks5CommandResponse commandResponse = new DefaultSocks5CommandResponse(Socks5CommandStatus.SUCCESS, Socks5AddressType.IPv4);
ctx.writeAndFlush(commandResponse);
} else {
Socks5CommandResponse commandResponse = new DefaultSocks5CommandResponse(Socks5CommandStatus.FAILURE, Socks5AddressType.IPv4);
ctx.writeAndFlush(commandResponse);
}
}
});
} else {
ctx.fireChannelRead(msg);
}
}
}