1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package io.netty.handler.codec.socksx.v5;
18
19 import io.netty.buffer.ByteBuf;
20 import io.netty.channel.ChannelHandlerContext;
21 import io.netty.handler.codec.DecoderException;
22 import io.netty.handler.codec.DecoderResult;
23 import io.netty.handler.codec.ReplayingDecoder;
24 import io.netty.handler.codec.socksx.v5.Socks5PasswordAuthResponseDecoder.State;
25 import io.netty.util.internal.UnstableApi;
26
27 import java.util.List;
28
29
30
31
32
33
34
35 public class Socks5PasswordAuthResponseDecoder extends ReplayingDecoder<State> {
36
37 @UnstableApi
38 public enum State {
39 INIT,
40 SUCCESS,
41 FAILURE
42 }
43
44 public Socks5PasswordAuthResponseDecoder() {
45 super(State.INIT);
46 }
47
48 @Override
49 protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
50 try {
51 switch (state()) {
52 case INIT: {
53 final byte version = in.readByte();
54 if (version != 1) {
55 throw new DecoderException("unsupported subnegotiation version: " + version + " (expected: 1)");
56 }
57
58 out.add(new DefaultSocks5PasswordAuthResponse(Socks5PasswordAuthStatus.valueOf(in.readByte())));
59 checkpoint(State.SUCCESS);
60 }
61 case SUCCESS: {
62 int readableBytes = actualReadableBytes();
63 if (readableBytes > 0) {
64 out.add(in.readRetainedSlice(readableBytes));
65 }
66 break;
67 }
68 case FAILURE: {
69 in.skipBytes(actualReadableBytes());
70 break;
71 }
72 }
73 } catch (Exception e) {
74 fail(out, e);
75 }
76 }
77
78 private void fail(List<Object> out, Exception cause) {
79 if (!(cause instanceof DecoderException)) {
80 cause = new DecoderException(cause);
81 }
82
83 checkpoint(State.FAILURE);
84
85 Socks5Message m = new DefaultSocks5PasswordAuthResponse(Socks5PasswordAuthStatus.FAILURE);
86 m.setDecoderResult(DecoderResult.failure(cause));
87 out.add(m);
88 }
89 }