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.ByteBufUtil;
20 import io.netty.buffer.Unpooled;
21 import io.netty.util.internal.EmptyArrays;
22
23 import java.net.SocketAddress;
24 import java.nio.ByteBuffer;
25 import java.util.Objects;
26
27
28
29
30 public final class QuicConnectionAddress extends SocketAddress {
31
32 static final QuicConnectionAddress NULL_LEN = new QuicConnectionAddress(EmptyArrays.EMPTY_BYTES);
33
34
35
36
37
38 public static final QuicConnectionAddress EPHEMERAL = new QuicConnectionAddress(null, false);
39
40 private final String toStr;
41
42 private final ByteBuffer connId;
43
44
45
46
47
48
49 public QuicConnectionAddress(byte[] connId) {
50 this(ByteBuffer.wrap(connId.clone()), true);
51 }
52
53
54
55
56
57
58 public QuicConnectionAddress(ByteBuffer connId) {
59 this(connId.duplicate(), true);
60 }
61
62 private QuicConnectionAddress(ByteBuffer connId, boolean validate) {
63 Quic.ensureAvailability();
64 if (validate && connId.remaining() > Quiche.QUICHE_MAX_CONN_ID_LEN) {
65 throw new IllegalArgumentException("Connection ID can only be of max length "
66 + Quiche.QUICHE_MAX_CONN_ID_LEN);
67 }
68 if (connId == null) {
69 this.connId = null;
70 toStr = "QuicConnectionAddress{EPHEMERAL}";
71 } else {
72 this.connId = connId.asReadOnlyBuffer().duplicate();
73 ByteBuf buffer = Unpooled.wrappedBuffer(connId);
74 try {
75 toStr = "QuicConnectionAddress{" +
76 "connId=" + ByteBufUtil.hexDump(buffer) + '}';
77 } finally {
78 buffer.release();
79 }
80 }
81 }
82
83 @Override
84 public String toString() {
85 return toStr;
86 }
87
88 @Override
89 public int hashCode() {
90 if (this == EPHEMERAL) {
91 return System.identityHashCode(EPHEMERAL);
92 }
93 return Objects.hash(connId);
94 }
95
96 @Override
97 public boolean equals(Object obj) {
98 if (!(obj instanceof QuicConnectionAddress)) {
99 return false;
100 }
101 QuicConnectionAddress address = (QuicConnectionAddress) obj;
102 if (obj == this) {
103 return true;
104 }
105 return connId.equals(address.connId);
106 }
107
108 ByteBuffer id() {
109 if (connId == null) {
110 return ByteBuffer.allocate(0);
111 }
112 return connId.duplicate();
113 }
114
115
116
117
118
119
120
121
122 public static QuicConnectionAddress random(int length) {
123 return new QuicConnectionAddress(QuicConnectionIdGenerator.randomGenerator().newId(length));
124 }
125
126
127
128
129
130
131
132 public static QuicConnectionAddress random() {
133 return random(Quiche.QUICHE_MAX_CONN_ID_LEN);
134 }
135 }