2 * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved.
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
10 # define OSSL_QUIC_CC_H
12 #include "openssl/params.h"
13 #include "internal/time.h"
15 # ifndef OPENSSL_NO_QUIC
17 typedef struct ossl_cc_data_st OSSL_CC_DATA
;
19 typedef struct ossl_cc_ack_info_st
{
20 /* The time the packet being acknowledged was originally sent. */
23 /* The size in bytes of the packet being acknowledged. */
27 typedef struct ossl_cc_loss_info_st
{
28 /* The time the packet being lost was originally sent. */
31 /* The size in bytes of the packet which has been determined lost. */
35 typedef struct ossl_cc_ecn_info_st
{
37 * The time at which the largest acked PN (in the incoming ACK frame) was
40 OSSL_TIME largest_acked_time
;
43 /* Parameter (read-write): Maximum datagram payload length in bytes. */
44 #define OSSL_CC_OPTION_MAX_DGRAM_PAYLOAD_LEN 1
46 /* Diagnostic (read-only): current congestion window size in bytes. */
47 #define OSSL_CC_OPTION_CUR_CWND_SIZE 2
49 /* Diagnostic (read-only): minimum congestion window size in bytes. */
50 #define OSSL_CC_OPTION_MIN_CWND_SIZE 3
52 /* Diagnostic (read-only): current net bytes in flight. */
53 #define OSSL_CC_OPTION_CUR_BYTES_IN_FLIGHT 4
56 * Congestion control abstract interface.
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.
66 * Particular changes include:
68 * - In our implementation, it is the responsibility of the ACKM to determine
69 * if a loss event constitutes persistent congestion.
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.
75 * All of these changes are intended to avoid having a congestion controller
76 * have to access ACKM internal state.
79 #define OSSL_CC_LOST_FLAG_PERSISTENT_CONGESTION (1U << 0)
81 typedef struct ossl_cc_method_st
{
85 OSSL_CC_DATA
*(*new)(OSSL_TIME (*now_cb
)(void *arg
),
88 void (*free
)(OSSL_CC_DATA
*ccdata
);
93 void (*reset
)(OSSL_CC_DATA
*ccdata
);
96 * Escape hatch for option configuration.
98 * option_id: One of OSSL_CC_OPTION_*.
100 * value: The option value to set.
102 * Returns 1 on success and 0 on failure.
104 int (*set_option_uint
)(OSSL_CC_DATA
*ccdata
,
109 * On success, returns 1 and writes the current value of the given option to
110 * *value. Otherwise, returns 0.
112 int (*get_option_uint
)(OSSL_CC_DATA
*ccdata
,
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.
122 uint64_t (*get_tx_allowance
)(OSSL_CC_DATA
*ccdata
);
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
130 OSSL_TIME (*get_wakeup_deadline
)(OSSL_CC_DATA
*ccdata
);
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
137 int (*on_data_sent
)(OSSL_CC_DATA
*ccdata
,
141 * The On Data Acked event. See OSSL_CC_ACK_INFO structure for details
142 * of the information to be passed.
144 int (*on_data_acked
)(OSSL_CC_DATA
*ccdata
,
145 const OSSL_CC_ACK_INFO
*info
);
148 * The On Data Lost event. See OSSL_CC_LOSS_INFO structure for details
149 * of the information to be passed.
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().
160 int (*on_data_lost
)(OSSL_CC_DATA
*ccdata
,
161 const OSSL_CC_LOSS_INFO
*info
);
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.
167 * Flags may be 0 or OSSL_CC_LOST_FLAG_PERSISTENT_CONGESTION.
169 int (*on_data_lost_finished
)(OSSL_CC_DATA
*ccdata
, uint32_t flags
);
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.
176 int (*on_data_invalidated
)(OSSL_CC_DATA
*ccdata
,
180 * Called from the ACKM when detecting an increased ECN-CE value in an ACK
181 * frame. This indicates congestion.
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.
190 int (*on_ecn
)(OSSL_CC_DATA
*ccdata
,
191 const OSSL_CC_ECN_INFO
*info
);
194 extern const OSSL_CC_METHOD ossl_cc_dummy_method
;