QUIC CC: Major revisions to CC abstract interface
[openssl.git] / include / internal / quic_cc.h
1 /*
2  * Copyright 2022 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 #ifndef OSSL_QUIC_CC_H
10 # define OSSL_QUIC_CC_H
11
12 #include "openssl/params.h"
13 #include "internal/time.h"
14
15 # ifndef OPENSSL_NO_QUIC
16
17 typedef struct ossl_cc_data_st OSSL_CC_DATA;
18
19 typedef struct ossl_cc_ack_info_st {
20     /* The time the packet being acknowledged was originally sent. */
21     OSSL_TIME   tx_time;
22
23     /* The size in bytes of the packet being acknowledged. */
24     size_t      tx_size;
25 } OSSL_CC_ACK_INFO;
26
27 typedef struct ossl_cc_loss_info_st {
28     /* The time the packet being lost was originally sent. */
29     OSSL_TIME   tx_time;
30
31     /* The size in bytes of the packet which has been determined lost. */
32     size_t      tx_size;
33 } OSSL_CC_LOSS_INFO;
34
35 typedef struct ossl_cc_ecn_info_st {
36     /*
37      * The time at which the largest acked PN (in the incoming ACK frame) was
38      * sent.
39      */
40     OSSL_TIME   largest_acked_time;
41 } OSSL_CC_ECN_INFO;
42
43 /* Parameter (read-write): Maximum datagram payload length in bytes. */
44 #define OSSL_CC_OPTION_MAX_DGRAM_PAYLOAD_LEN        1
45
46 /* Diagnostic (read-only): current congestion window size in bytes. */
47 #define OSSL_CC_OPTION_CUR_CWND_SIZE                2
48
49 /* Diagnostic (read-only): minimum congestion window size in bytes. */
50 #define OSSL_CC_OPTION_MIN_CWND_SIZE                3
51
52 /* Diagnostic (read-only): current net bytes in flight. */
53 #define OSSL_CC_OPTION_CUR_BYTES_IN_FLIGHT          4
54
55 /*
56  * Congestion control abstract interface.
57  *
58  * This interface is broadly based on the design described in RFC 9002. However,
59  * the demarcation between the ACKM and the congestion controller does not
60  * exactly match that delineated in the RFC 9002 psuedocode. Where aspects of
61  * the demarcation involve the congestion controller accessing internal state of
62  * the ACKM, the interface has been revised where possible to provide the
63  * information needed by the congestion controller and avoid needing to give the
64  * congestion controller access to the ACKM's internal data structures.
65  *
66  * Particular changes include:
67  *
68  *   - In our implementation, it is the responsibility of the ACKM to determine
69  *     if a loss event constitutes persistent congestion.
70  *
71  *   - In our implementation, it is the responsibility of the ACKM to determine
72  *     if the ECN-CE counter has increased. The congestion controller is simply
73  *     informed when an ECN-CE event occurs.
74  *
75  * All of these changes are intended to avoid having a congestion controller
76  * have to access ACKM internal state.
77  *
78  */
79 #define OSSL_CC_LOST_FLAG_PERSISTENT_CONGESTION     (1U << 0)
80
81 typedef struct ossl_cc_method_st {
82     /*
83      * Instantiation.
84      */
85     OSSL_CC_DATA *(*new)(OSSL_TIME (*now_cb)(void *arg),
86                          void *now_cb_arg);
87
88     void (*free)(OSSL_CC_DATA *ccdata);
89
90     /*
91      * Reset of state.
92      */
93     void (*reset)(OSSL_CC_DATA *ccdata);
94
95     /*
96      * Escape hatch for option configuration.
97      *
98      * option_id: One of OSSL_CC_OPTION_*.
99      *
100      * value: The option value to set.
101      *
102      * Returns 1 on success and 0 on failure.
103      */
104     int (*set_option_uint)(OSSL_CC_DATA *ccdata,
105                            uint32_t option_id,
106                            uint64_t value);
107
108     /*
109      * On success, returns 1 and writes the current value of the given option to
110      * *value. Otherwise, returns 0.
111      */
112     int (*get_option_uint)(OSSL_CC_DATA *ccdata,
113                            uint32_t option_id,
114                            uint64_t *value);
115
116     /*
117      * Returns the amount of additional data (above and beyond the data
118      * currently in flight) which can be sent in bytes. Returns 0 if no more
119      * data can be sent at this time. The return value of this method
120      * can vary as time passes.
121      */
122     uint64_t (*get_tx_allowance)(OSSL_CC_DATA *ccdata);
123
124     /*
125      * Returns the time at which the return value of get_tx_allowance might be
126      * higher than its current value. This is not a guarantee and spurious
127      * wakeups are allowed. Returns ossl_time_infinite() if there is no current
128      * wakeup deadline.
129      */
130     OSSL_TIME (*get_wakeup_deadline)(OSSL_CC_DATA *ccdata);
131
132     /*
133      * The On Data Sent event. num_bytes should be the size of the packet in
134      * bytes (or the aggregate size of multiple packets which have just been
135      * sent).
136      */
137     int (*on_data_sent)(OSSL_CC_DATA *ccdata,
138                         uint64_t num_bytes);
139
140     /*
141      * The On Data Acked event. See OSSL_CC_ACK_INFO structure for details
142      * of the information to be passed.
143      */
144     int (*on_data_acked)(OSSL_CC_DATA *ccdata,
145                          const OSSL_CC_ACK_INFO *info);
146
147     /*
148      * The On Data Lost event. See OSSL_CC_LOSS_INFO structure for details
149      * of the information to be passed.
150      *
151      * Note: When the ACKM determines that a set of multiple packets has been
152      * lost, it is useful for a congestion control algorithm to be able to
153      * process this as a single loss event rather than multiple loss events.
154      * Thus, calling this function may cause the congestion controller to defer
155      * state updates under the assumption that subsequent calls to
156      * on_data_lost() representing further lost packets in the same loss event
157      * may be forthcoming. Always call on_data_lost_finished() after one or more
158      * calls to on_data_lost().
159      */
160     int (*on_data_lost)(OSSL_CC_DATA *ccdata,
161                         const OSSL_CC_LOSS_INFO *info);
162
163     /*
164      * To be called after a sequence of one or more on_data_lost() calls
165      * representing multiple packets in a single loss detection incident.
166      *
167      * Flags may be 0 or OSSL_CC_LOST_FLAG_PERSISTENT_CONGESTION.
168      */
169     int (*on_data_lost_finished)(OSSL_CC_DATA *ccdata, uint32_t flags);
170
171     /*
172      * For use when a PN space is invalidated or a packet must otherwise be
173      * 'undone' for congestion control purposes without acting as a loss signal.
174      * Only the size of the packet is needed.
175      */
176     int (*on_data_invalidated)(OSSL_CC_DATA *ccdata,
177                                uint64_t num_bytes);
178
179     /*
180      * Called from the ACKM when detecting an increased ECN-CE value in an ACK
181      * frame. This indicates congestion.
182      *
183      * Note that this differs from the RFC's conceptual segregation of the loss
184      * detection and congestion controller functions, as in our implementation
185      * the ACKM is responsible for detecting increases to ECN-CE and simply
186      * tells the congestion controller when ECN-triggered congestion has
187      * occurred. This allows a slightly more efficient implementation and
188      * narrower interface between the ACKM and CC.
189      */
190     int (*on_ecn)(OSSL_CC_DATA *ccdata,
191                   const OSSL_CC_ECN_INFO *info);
192 } OSSL_CC_METHOD;
193
194 extern const OSSL_CC_METHOD ossl_cc_dummy_method;
195
196 # endif
197
198 #endif