View Javadoc
1   /*
2    * Copyright 2023 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package io.netty.handler.codec.quic;
17  
18  import java.net.InetSocketAddress;
19  import java.util.Objects;
20  
21  import static java.util.Objects.requireNonNull;
22  
23  /**
24   * A network path specific {@link QuicEvent}.
25   */
26  public abstract class QuicPathEvent implements QuicEvent {
27  
28      private final InetSocketAddress local;
29      private final InetSocketAddress remote;
30  
31      QuicPathEvent(InetSocketAddress local, InetSocketAddress remote) {
32          this.local = requireNonNull(local, "local");
33          this.remote = requireNonNull(remote, "remote");
34      }
35  
36      /**
37       * The local address of the network path.
38       *
39       * @return  local
40       */
41      public InetSocketAddress local() {
42          return local;
43      }
44  
45      /**
46       * The remote address of the network path.
47       *
48       * @return  local
49       */
50      public InetSocketAddress remote() {
51          return remote;
52      }
53  
54      @Override
55      public String toString() {
56          return "QuicPathEvent{" +
57                  "local=" + local +
58                  ", remote=" + remote +
59                  '}';
60      }
61  
62      @Override
63      public boolean equals(Object o) {
64          if (this == o) {
65              return true;
66          }
67          if (o == null || getClass() != o.getClass()) {
68              return false;
69          }
70  
71          QuicPathEvent that = (QuicPathEvent) o;
72          if (!Objects.equals(local, that.local)) {
73              return false;
74          }
75          return Objects.equals(remote, that.remote);
76      }
77  
78      @Override
79      public int hashCode() {
80          int result = local != null ? local.hashCode() : 0;
81          result = 31 * result + (remote != null ? remote.hashCode() : 0);
82          return result;
83      }
84  
85      public static final class New extends QuicPathEvent {
86          /**
87           * A new network path (local address, remote address) has been seen on a received packet.
88           * Note that this event is only triggered for servers, as the client is responsible from initiating new paths.
89           * The application may then probe this new path, if desired.
90           *
91           * @param local     local address.
92           * @param remote    remote address.
93           */
94          public New(InetSocketAddress local, InetSocketAddress remote) {
95              super(local, remote);
96          }
97  
98          @Override
99          public String toString() {
100             return "QuicPathEvent.New{" +
101                     "local=" + local() +
102                     ", remote=" + remote() +
103                     '}';
104         }
105     }
106 
107     public static final class Validated extends QuicPathEvent {
108         /**
109          * The related network path between local and remote has been validated.
110          *
111          * @param local     local address.
112          * @param remote    remote address.
113          */
114         public Validated(InetSocketAddress local, InetSocketAddress remote) {
115             super(local, remote);
116         }
117 
118         @Override
119         public String toString() {
120             return "QuicPathEvent.Validated{" +
121                     "local=" + local() +
122                     ", remote=" + remote() +
123                     '}';
124         }
125     }
126 
127     public static final class FailedValidation extends QuicPathEvent {
128         /**
129          * The related network path between local and remote failed to be validated.
130          * This network path will not be used anymore, unless the application requests probing this path again.
131          *
132          * @param local     local address.
133          * @param remote    remote address.
134          */
135         public FailedValidation(InetSocketAddress local, InetSocketAddress remote) {
136             super(local, remote);
137         }
138 
139         @Override
140         public String toString() {
141             return "QuicPathEvent.FailedValidation{" +
142                     "local=" + local() +
143                     ", remote=" + remote() +
144                     '}';
145         }
146     }
147 
148     public static final class Closed extends QuicPathEvent {
149 
150         /**
151          * The related network path between local and remote has been closed and is now unusable on this connection.
152          *
153          * @param local     local address.
154          * @param remote    remote address.
155          */
156         public Closed(InetSocketAddress local, InetSocketAddress remote) {
157             super(local, remote);
158         }
159 
160         @Override
161         public boolean equals(Object o) {
162             if (this == o) {
163                 return true;
164             }
165             if (o == null || getClass() != o.getClass()) {
166                 return false;
167             }
168             return super.equals(o);
169         }
170 
171         @Override
172         public int hashCode() {
173             return 31 * super.hashCode();
174         }
175 
176         @Override
177         public String toString() {
178             return "QuicPathEvent.Closed{" +
179                     "local=" + local() +
180                     ", remote=" + remote() +
181                     '}';
182         }
183     }
184 
185     public static final class ReusedSourceConnectionId extends QuicPathEvent {
186         private final long seq;
187         private final InetSocketAddress oldLocal;
188         private final InetSocketAddress oldRemote;
189 
190         /**
191          * The stack observes that the Source Connection ID with the given sequence number,
192          * initially used by the peer over the first pair of addresses, is now reused over
193          * the second pair of addresses.
194          *
195          * @param seq           sequence number
196          * @param oldLocal      old local address.
197          * @param oldRemote     old remote address.
198          * @param local         local address.
199          * @param remote        remote address.
200          */
201         public ReusedSourceConnectionId(long seq, InetSocketAddress oldLocal, InetSocketAddress oldRemote,
202                                        InetSocketAddress local, InetSocketAddress remote) {
203             super(local, remote);
204             this.seq = seq;
205             this.oldLocal = requireNonNull(oldLocal, "oldLocal");
206             this.oldRemote = requireNonNull(oldRemote, "oldRemote");
207         }
208 
209         /**
210          * Source connection id sequence number.
211          *
212          * @return  sequence number
213          */
214         public long seq() {
215             return seq;
216         }
217 
218         /**
219          * The old local address of the network path.
220          *
221          * @return  local
222          */
223         public InetSocketAddress oldLocal() {
224             return oldLocal;
225         }
226 
227         /**
228          * The old remote address of the network path.
229          *
230          * @return  local
231          */
232         public InetSocketAddress oldRemote() {
233             return oldRemote;
234         }
235 
236         @Override
237         public boolean equals(Object o) {
238             if (this == o) {
239                 return true;
240             }
241             if (o == null || getClass() != o.getClass()) {
242                 return false;
243             }
244             if (!super.equals(o)) {
245                 return false;
246             }
247 
248             ReusedSourceConnectionId that = (ReusedSourceConnectionId) o;
249 
250             if (seq != that.seq) {
251                 return false;
252             }
253             if (!Objects.equals(oldLocal, that.oldLocal)) {
254                 return false;
255             }
256             return Objects.equals(oldRemote, that.oldRemote);
257         }
258 
259         @Override
260         public int hashCode() {
261             int result = super.hashCode();
262             result = 31 * result + (int) (seq ^ (seq >>> 32));
263             result = 31 * result + (oldLocal != null ? oldLocal.hashCode() : 0);
264             result = 31 * result + (oldRemote != null ? oldRemote.hashCode() : 0);
265             return result;
266         }
267 
268         @Override
269         public String toString() {
270             return "QuicPathEvent.ReusedSourceConnectionId{" +
271                     "seq=" + seq +
272                     ", oldLocal=" + oldLocal +
273                     ", oldRemote=" + oldRemote +
274                     ", local=" + local() +
275                     ", remote=" + remote() +
276                     '}';
277         }
278     }
279 
280     public static final class PeerMigrated extends QuicPathEvent {
281 
282         /**
283          * The connection observed that the remote migrated over the network path denoted by the pair of addresses,
284          * i.e., non-probing packets have been received on this network path. This is a server side only event.
285          * Note that this event is only raised if the path has been validated.
286          *
287          * @param local     local address.
288          * @param remote    remote address.
289          */
290         public PeerMigrated(InetSocketAddress local, InetSocketAddress remote) {
291             super(local, remote);
292         }
293 
294         @Override
295         public String toString() {
296             return "QuicPathEvent.PeerMigrated{" +
297                     "local=" + local() +
298                     ", remote=" + remote() +
299                     '}';
300         }
301     }
302 }