1 | /*
|
---|
2 | * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
|
---|
3 | *
|
---|
4 | * Licensed under the Apache License 2.0 (the "License"). You may not use
|
---|
5 | * this file except in compliance with the License. You can obtain a copy
|
---|
6 | * in the file LICENSE in the source distribution or at
|
---|
7 | * https://www.openssl.org/source/license.html
|
---|
8 | */
|
---|
9 |
|
---|
10 | #ifndef OSSL_INTERNAL_QUIC_SRTM_H
|
---|
11 | # define OSSL_INTERNAL_QUIC_SRTM_H
|
---|
12 | # pragma once
|
---|
13 |
|
---|
14 | # include "internal/e_os.h"
|
---|
15 | # include "internal/time.h"
|
---|
16 | # include "internal/quic_types.h"
|
---|
17 | # include "internal/quic_wire.h"
|
---|
18 | # include "internal/quic_predef.h"
|
---|
19 |
|
---|
20 | # ifndef OPENSSL_NO_QUIC
|
---|
21 |
|
---|
22 | /*
|
---|
23 | * QUIC Stateless Reset Token Manager
|
---|
24 | * ==================================
|
---|
25 | *
|
---|
26 | * The stateless reset token manager is responsible for mapping stateless reset
|
---|
27 | * tokens to connections. It is used to identify stateless reset tokens in
|
---|
28 | * incoming packets. In this regard it can be considered an alternate "routing"
|
---|
29 | * mechanism for incoming packets, and is somewhat analogous with the LCIDM,
|
---|
30 | * except that it uses SRTs to route rather than DCIDs.
|
---|
31 | *
|
---|
32 | * The SRTM specifically stores a bidirectional mapping of the form
|
---|
33 | *
|
---|
34 | * (opaque pointer, sequence number) [1] <-> [0..n] SRT
|
---|
35 | *
|
---|
36 | * The (opaque pointer, sequence number) tuple is used to refer to an entry (for
|
---|
37 | * example for the purposes of removing it later when it is no longer needed).
|
---|
38 | * Likewise, an entry can be looked up using SRT to get the opaque pointer and
|
---|
39 | * sequence number.
|
---|
40 | *
|
---|
41 | * It is important to note that the same SRT may exist multiple times and map to
|
---|
42 | * multiple (opaque pointer, sequence number) tuples, for example, if we
|
---|
43 | * initiate multiple connections to the same peer using the same local QUIC_PORT
|
---|
44 | * and the peer decides to behave bizarrely and issue the same SRT for both
|
---|
45 | * connections. It should not do this, but we have to be resilient against
|
---|
46 | * byzantine peer behaviour. Thus we are capable of storing multiple identical
|
---|
47 | * SRTs for different (opaque pointer, sequence number) keys.
|
---|
48 | *
|
---|
49 | * The SRTM supports arbitrary insertion, arbitrary deletion of specific keys
|
---|
50 | * identified by a (opaque pointer, sequence number) key, and mass deletion of
|
---|
51 | * all entries under a specific opaque pointer. It supports lookup by SRT to
|
---|
52 | * identify zero or more corresponding (opaque pointer, sequence number) tuples.
|
---|
53 | *
|
---|
54 | * The opaque pointer may be used for any purpose but is intended to represent a
|
---|
55 | * connection identity and must therefore be consistent (usefully comparable).
|
---|
56 | */
|
---|
57 |
|
---|
58 | /* Creates a new empty SRTM instance. */
|
---|
59 | QUIC_SRTM *ossl_quic_srtm_new(OSSL_LIB_CTX *libctx, const char *propq);
|
---|
60 |
|
---|
61 | /* Frees a SRTM instance. No-op if srtm is NULL. */
|
---|
62 | void ossl_quic_srtm_free(QUIC_SRTM *srtm);
|
---|
63 |
|
---|
64 | /*
|
---|
65 | * Add a (opaque, seq_num) -> SRT entry to the SRTM. This operation fails if a
|
---|
66 | * SRT entry already exists with the same (opaque, seq_num) tuple. The token is
|
---|
67 | * copied. Returns 1 on success or 0 on failure.
|
---|
68 | */
|
---|
69 | int ossl_quic_srtm_add(QUIC_SRTM *srtm, void *opaque, uint64_t seq_num,
|
---|
70 | const QUIC_STATELESS_RESET_TOKEN *token);
|
---|
71 |
|
---|
72 | /*
|
---|
73 | * Removes an entry by identifying it via its (opaque, seq_num) tuple.
|
---|
74 | * Returns 1 if the entry was found and removed, and 0 if it was not found.
|
---|
75 | */
|
---|
76 | int ossl_quic_srtm_remove(QUIC_SRTM *srtm, void *opaque, uint64_t seq_num);
|
---|
77 |
|
---|
78 | /*
|
---|
79 | * Removes all entries (opaque, *) with the given opaque pointer.
|
---|
80 | *
|
---|
81 | * Returns 1 on success and 0 on failure. If no entries with the given opaque
|
---|
82 | * pointer were found, this is considered a success condition.
|
---|
83 | */
|
---|
84 | int ossl_quic_srtm_cull(QUIC_SRTM *strm, void *opaque);
|
---|
85 |
|
---|
86 | /*
|
---|
87 | * Looks up a SRT to find the corresponding opaque pointer and sequence number.
|
---|
88 | * An output field pointer can be set to NULL if it is not required.
|
---|
89 | *
|
---|
90 | * This function is designed to avoid exposing timing channels on token values
|
---|
91 | * or the contents of the SRT mapping.
|
---|
92 | *
|
---|
93 | * If there are several identical SRTs, idx can be used to get the nth entry.
|
---|
94 | * Call this function with idx set to 0 first, and keep calling it after
|
---|
95 | * incrementing idx until it returns 0.
|
---|
96 | *
|
---|
97 | * Returns 1 if an entry was found and 0 otherwise.
|
---|
98 | */
|
---|
99 | int ossl_quic_srtm_lookup(QUIC_SRTM *srtm,
|
---|
100 | const QUIC_STATELESS_RESET_TOKEN *token,
|
---|
101 | size_t idx,
|
---|
102 | void **opaque, uint64_t *seq_num);
|
---|
103 |
|
---|
104 | /* Verify internal invariants and assert if they are not met. */
|
---|
105 | void ossl_quic_srtm_check(const QUIC_SRTM *srtm);
|
---|
106 |
|
---|
107 | # endif
|
---|
108 |
|
---|
109 | #endif
|
---|