1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.handler.codec.socksx.v5;
17
18 import io.netty.buffer.ByteBuf;
19 import io.netty.channel.ChannelHandlerContext;
20 import io.netty.handler.codec.ByteToMessageDecoder;
21 import io.netty.handler.codec.DecoderException;
22 import io.netty.handler.codec.DecoderResult;
23 import io.netty.util.internal.UnstableApi;
24
25 import java.util.List;
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 public final class Socks5PrivateAuthResponseDecoder extends ByteToMessageDecoder {
50
51
52
53
54 private enum State {
55
56
57
58 INIT,
59
60
61
62 SUCCESS,
63
64
65
66 FAILURE
67 }
68
69 private State state = State.INIT;
70
71 @Override
72 protected void decode(ChannelHandlerContext ctx, ByteBuf in,
73 List<Object> out) throws Exception {
74 try {
75 switch (state) {
76 case INIT:
77 if (in.readableBytes() < 2) {
78 return;
79 }
80
81 final byte version = in.readByte();
82 if (version != 1) {
83 throw new DecoderException(
84 "unsupported subnegotiation version: " + version + " (expected: 1)");
85 }
86
87 out.add(new DefaultSocks5PrivateAuthResponse(
88 Socks5PrivateAuthStatus.valueOf(in.readByte())));
89 state = State.SUCCESS;
90 break;
91 case SUCCESS:
92 int readableBytes = in.readableBytes();
93 if (readableBytes > 0) {
94 out.add(in.readRetainedSlice(readableBytes));
95 }
96 break;
97 case FAILURE:
98 in.skipBytes(in.readableBytes());
99 break;
100 default:
101 throw new Error();
102 }
103 } catch (Exception e) {
104 fail(out, e);
105 }
106 }
107
108
109
110
111
112
113
114 private void fail(List<Object> out, Exception cause) {
115 if (!(cause instanceof DecoderException)) {
116 cause = new DecoderException(cause);
117 }
118
119 state = State.FAILURE;
120
121 Socks5Message m = new DefaultSocks5PrivateAuthResponse(Socks5PrivateAuthStatus.FAILURE);
122 m.setDecoderResult(DecoderResult.failure(cause));
123 out.add(m);
124 }
125 }