1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.example.socksproxy;
17
18 import io.netty.channel.ChannelHandler;
19 import io.netty.channel.ChannelHandlerContext;
20 import io.netty.channel.SimpleChannelInboundHandler;
21 import io.netty.handler.codec.socksx.SocksMessage;
22 import io.netty.handler.codec.socksx.v4.Socks4CommandRequest;
23 import io.netty.handler.codec.socksx.v4.Socks4CommandType;
24 import io.netty.handler.codec.socksx.v5.DefaultSocks5InitialResponse;
25 import io.netty.handler.codec.socksx.v5.DefaultSocks5PasswordAuthResponse;
26 import io.netty.handler.codec.socksx.v5.Socks5AuthMethod;
27 import io.netty.handler.codec.socksx.v5.Socks5InitialRequest;
28 import io.netty.handler.codec.socksx.v5.Socks5CommandRequest;
29 import io.netty.handler.codec.socksx.v5.Socks5CommandRequestDecoder;
30 import io.netty.handler.codec.socksx.v5.Socks5CommandType;
31 import io.netty.handler.codec.socksx.v5.Socks5PasswordAuthRequest;
32 import io.netty.handler.codec.socksx.v5.Socks5PasswordAuthStatus;
33
34 @ChannelHandler.Sharable
35 public final class SocksServerHandler extends SimpleChannelInboundHandler<SocksMessage> {
36
37 public static final SocksServerHandler INSTANCE = new SocksServerHandler();
38
39 private SocksServerHandler() { }
40
41 @Override
42 public void channelRead0(ChannelHandlerContext ctx, SocksMessage socksRequest) throws Exception {
43 switch (socksRequest.version()) {
44 case SOCKS4a:
45 Socks4CommandRequest socksV4CmdRequest = (Socks4CommandRequest) socksRequest;
46 if (socksV4CmdRequest.type() == Socks4CommandType.CONNECT) {
47 ctx.pipeline().addLast(new SocksServerConnectHandler());
48 ctx.pipeline().remove(this);
49 ctx.fireChannelRead(socksRequest);
50 } else {
51 ctx.close();
52 }
53 break;
54 case SOCKS5:
55 if (socksRequest instanceof Socks5InitialRequest) {
56
57
58
59 ctx.pipeline().addFirst(new Socks5CommandRequestDecoder());
60 ctx.write(new DefaultSocks5InitialResponse(Socks5AuthMethod.NO_AUTH));
61 } else if (socksRequest instanceof Socks5PasswordAuthRequest) {
62 ctx.pipeline().addFirst(new Socks5CommandRequestDecoder());
63 ctx.write(new DefaultSocks5PasswordAuthResponse(Socks5PasswordAuthStatus.SUCCESS));
64 } else if (socksRequest instanceof Socks5CommandRequest) {
65 Socks5CommandRequest socks5CmdRequest = (Socks5CommandRequest) socksRequest;
66 if (socks5CmdRequest.type() == Socks5CommandType.CONNECT) {
67 ctx.pipeline().addLast(new SocksServerConnectHandler());
68 ctx.pipeline().remove(this);
69 ctx.fireChannelRead(socksRequest);
70 } else {
71 ctx.close();
72 }
73 } else {
74 ctx.close();
75 }
76 break;
77 case UNKNOWN:
78 ctx.close();
79 break;
80 }
81 }
82
83 @Override
84 public void channelReadComplete(ChannelHandlerContext ctx) {
85 ctx.flush();
86 }
87
88 @Override
89 public void exceptionCaught(ChannelHandlerContext ctx, Throwable throwable) {
90 throwable.printStackTrace();
91 SocksServerUtils.closeOnFlush(ctx.channel());
92 }
93 }