1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.handler.codec.quic;
17
18 import io.netty.buffer.ByteBuf;
19 import io.netty.buffer.Unpooled;
20 import io.netty.util.CharsetUtil;
21 import io.netty.util.NetUtil;
22
23 import java.net.InetSocketAddress;
24
25
26
27
28
29
30
31 public final class InsecureQuicTokenHandler implements QuicTokenHandler {
32
33 private static final String SERVER_NAME = "netty";
34 private static final byte[] SERVER_NAME_BYTES = SERVER_NAME.getBytes(CharsetUtil.US_ASCII);
35 private static final ByteBuf SERVER_NAME_BUFFER = Unpooled.unreleasableBuffer(
36 Unpooled.wrappedBuffer(SERVER_NAME_BYTES)).asReadOnly();
37
38
39 static final int MAX_TOKEN_LEN = Quic.MAX_CONN_ID_LEN +
40 NetUtil.LOCALHOST6.getAddress().length + SERVER_NAME_BYTES.length;
41
42 private InsecureQuicTokenHandler() {
43 Quic.ensureAvailability();
44 }
45
46 public static final InsecureQuicTokenHandler INSTANCE = new InsecureQuicTokenHandler();
47
48 @Override
49 public boolean writeToken(ByteBuf out, ByteBuf dcid, InetSocketAddress address) {
50 byte[] addr = address.getAddress().getAddress();
51 out.writeBytes(SERVER_NAME_BYTES)
52 .writeBytes(addr)
53 .writeBytes(dcid, dcid.readerIndex(), dcid.readableBytes());
54 return true;
55 }
56
57 @Override
58 public int validateToken(ByteBuf token, InetSocketAddress address) {
59 final byte[] addr = address.getAddress().getAddress();
60
61 int minLength = SERVER_NAME_BYTES.length + address.getAddress().getAddress().length;
62 if (token.readableBytes() <= SERVER_NAME_BYTES.length + addr.length) {
63 return -1;
64 }
65
66 if (!SERVER_NAME_BUFFER.equals(token.slice(0, SERVER_NAME_BYTES.length))) {
67 return -1;
68 }
69 ByteBuf addressBuffer = Unpooled.wrappedBuffer(addr);
70 try {
71 if (!addressBuffer.equals(token.slice(SERVER_NAME_BYTES.length, addr.length))) {
72 return -1;
73 }
74 } finally {
75 addressBuffer.release();
76 }
77 return minLength;
78 }
79
80 @Override
81 public int maxTokenLength() {
82 return MAX_TOKEN_LEN;
83 }
84 }