forked from cory/tildefriends
220 lines
8.2 KiB
C
220 lines
8.2 KiB
C
|
/*
|
||
|
* Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved.
|
||
|
*
|
||
|
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||
|
* this file except in compliance with the License. You can obtain a copy
|
||
|
* in the file LICENSE in the source distribution or at
|
||
|
* https://www.openssl.org/source/license.html
|
||
|
*/
|
||
|
#ifndef OSSL_QUIC_CC_H
|
||
|
# define OSSL_QUIC_CC_H
|
||
|
|
||
|
#include "openssl/params.h"
|
||
|
#include "internal/time.h"
|
||
|
|
||
|
# ifndef OPENSSL_NO_QUIC
|
||
|
|
||
|
typedef struct ossl_cc_data_st OSSL_CC_DATA;
|
||
|
|
||
|
typedef struct ossl_cc_ack_info_st {
|
||
|
/* The time the packet being acknowledged was originally sent. */
|
||
|
OSSL_TIME tx_time;
|
||
|
|
||
|
/* The size in bytes of the packet being acknowledged. */
|
||
|
size_t tx_size;
|
||
|
} OSSL_CC_ACK_INFO;
|
||
|
|
||
|
typedef struct ossl_cc_loss_info_st {
|
||
|
/* The time the packet being lost was originally sent. */
|
||
|
OSSL_TIME tx_time;
|
||
|
|
||
|
/* The size in bytes of the packet which has been determined lost. */
|
||
|
size_t tx_size;
|
||
|
} OSSL_CC_LOSS_INFO;
|
||
|
|
||
|
typedef struct ossl_cc_ecn_info_st {
|
||
|
/*
|
||
|
* The time at which the largest acked PN (in the incoming ACK frame) was
|
||
|
* sent.
|
||
|
*/
|
||
|
OSSL_TIME largest_acked_time;
|
||
|
} OSSL_CC_ECN_INFO;
|
||
|
|
||
|
/* Parameter (read-write): Maximum datagram payload length in bytes. */
|
||
|
#define OSSL_CC_OPTION_MAX_DGRAM_PAYLOAD_LEN "max_dgram_payload_len"
|
||
|
|
||
|
/* Diagnostic (read-only): current congestion window size in bytes. */
|
||
|
#define OSSL_CC_OPTION_CUR_CWND_SIZE "cur_cwnd_size"
|
||
|
|
||
|
/* Diagnostic (read-only): minimum congestion window size in bytes. */
|
||
|
#define OSSL_CC_OPTION_MIN_CWND_SIZE "min_cwnd_size"
|
||
|
|
||
|
/* Diagnostic (read-only): current net bytes in flight. */
|
||
|
#define OSSL_CC_OPTION_CUR_BYTES_IN_FLIGHT "bytes_in_flight"
|
||
|
|
||
|
/* Diagnostic (read-only): method-specific state value. */
|
||
|
#define OSSL_CC_OPTION_CUR_STATE "cur_state"
|
||
|
|
||
|
/*
|
||
|
* Congestion control abstract interface.
|
||
|
*
|
||
|
* This interface is broadly based on the design described in RFC 9002. However,
|
||
|
* the demarcation between the ACKM and the congestion controller does not
|
||
|
* exactly match that delineated in the RFC 9002 pseudocode. Where aspects of
|
||
|
* the demarcation involve the congestion controller accessing internal state of
|
||
|
* the ACKM, the interface has been revised where possible to provide the
|
||
|
* information needed by the congestion controller and avoid needing to give the
|
||
|
* congestion controller access to the ACKM's internal data structures.
|
||
|
*
|
||
|
* Particular changes include:
|
||
|
*
|
||
|
* - In our implementation, it is the responsibility of the ACKM to determine
|
||
|
* if a loss event constitutes persistent congestion.
|
||
|
*
|
||
|
* - In our implementation, it is the responsibility of the ACKM to determine
|
||
|
* if the ECN-CE counter has increased. The congestion controller is simply
|
||
|
* informed when an ECN-CE event occurs.
|
||
|
*
|
||
|
* All of these changes are intended to avoid having a congestion controller
|
||
|
* have to access ACKM internal state.
|
||
|
*/
|
||
|
#define OSSL_CC_LOST_FLAG_PERSISTENT_CONGESTION (1U << 0)
|
||
|
|
||
|
typedef struct ossl_cc_method_st {
|
||
|
/*
|
||
|
* Instantiation.
|
||
|
*/
|
||
|
OSSL_CC_DATA *(*new)(OSSL_TIME (*now_cb)(void *arg),
|
||
|
void *now_cb_arg);
|
||
|
|
||
|
void (*free)(OSSL_CC_DATA *ccdata);
|
||
|
|
||
|
/*
|
||
|
* Reset of state.
|
||
|
*/
|
||
|
void (*reset)(OSSL_CC_DATA *ccdata);
|
||
|
|
||
|
/*
|
||
|
* Escape hatch for option configuration.
|
||
|
*
|
||
|
* params is an array of OSSL_PARAM structures.
|
||
|
*
|
||
|
* Returns 1 on success and 0 on failure.
|
||
|
*/
|
||
|
int (*set_input_params)(OSSL_CC_DATA *ccdata,
|
||
|
const OSSL_PARAM *params);
|
||
|
|
||
|
/*
|
||
|
* (Re)bind output (diagnostic) information.
|
||
|
*
|
||
|
* params is an array of OSSL_PARAM structures used to output values. The
|
||
|
* storage locations associated with each parameter are stored internally
|
||
|
* and updated whenever the state of the congestion controller is updated;
|
||
|
* thus, the storage locations associated with the OSSL_PARAMs passed in the
|
||
|
* call to this function must remain valid until the congestion controller
|
||
|
* is freed or those parameters are unbound. A given parameter name may be
|
||
|
* bound to only one location at a time. The params structures themselves
|
||
|
* do not need to remain allocated after this call returns.
|
||
|
*
|
||
|
* Returns 1 on success and 0 on failure.
|
||
|
*/
|
||
|
int (*bind_diagnostics)(OSSL_CC_DATA *ccdata,
|
||
|
OSSL_PARAM *params);
|
||
|
|
||
|
/*
|
||
|
* Unbind diagnostic information. The parameters with the given names are
|
||
|
* unbound, cancelling the effects of a previous call to bind_diagnostic().
|
||
|
* params is an array of OSSL_PARAMs. The values of the parameters are
|
||
|
* ignored. If a parameter is already unbound, there is no effect for that
|
||
|
* parameter but other parameters are still unbound.
|
||
|
*
|
||
|
* Returns 1 on success or 0 on failure.
|
||
|
*/
|
||
|
int (*unbind_diagnostics)(OSSL_CC_DATA *ccdata,
|
||
|
OSSL_PARAM *params);
|
||
|
|
||
|
/*
|
||
|
* Returns the amount of additional data (above and beyond the data
|
||
|
* currently in flight) which can be sent in bytes. Returns 0 if no more
|
||
|
* data can be sent at this time. The return value of this method
|
||
|
* can vary as time passes.
|
||
|
*/
|
||
|
uint64_t (*get_tx_allowance)(OSSL_CC_DATA *ccdata);
|
||
|
|
||
|
/*
|
||
|
* Returns the time at which the return value of get_tx_allowance might be
|
||
|
* higher than its current value. This is not a guarantee and spurious
|
||
|
* wakeups are allowed. Returns ossl_time_infinite() if there is no current
|
||
|
* wakeup deadline.
|
||
|
*/
|
||
|
OSSL_TIME (*get_wakeup_deadline)(OSSL_CC_DATA *ccdata);
|
||
|
|
||
|
/*
|
||
|
* The On Data Sent event. num_bytes should be the size of the packet in
|
||
|
* bytes (or the aggregate size of multiple packets which have just been
|
||
|
* sent).
|
||
|
*/
|
||
|
int (*on_data_sent)(OSSL_CC_DATA *ccdata,
|
||
|
uint64_t num_bytes);
|
||
|
|
||
|
/*
|
||
|
* The On Data Acked event. See OSSL_CC_ACK_INFO structure for details
|
||
|
* of the information to be passed.
|
||
|
*/
|
||
|
int (*on_data_acked)(OSSL_CC_DATA *ccdata,
|
||
|
const OSSL_CC_ACK_INFO *info);
|
||
|
|
||
|
/*
|
||
|
* The On Data Lost event. See OSSL_CC_LOSS_INFO structure for details
|
||
|
* of the information to be passed.
|
||
|
*
|
||
|
* Note: When the ACKM determines that a set of multiple packets has been
|
||
|
* lost, it is useful for a congestion control algorithm to be able to
|
||
|
* process this as a single loss event rather than multiple loss events.
|
||
|
* Thus, calling this function may cause the congestion controller to defer
|
||
|
* state updates under the assumption that subsequent calls to
|
||
|
* on_data_lost() representing further lost packets in the same loss event
|
||
|
* may be forthcoming. Always call on_data_lost_finished() after one or more
|
||
|
* calls to on_data_lost().
|
||
|
*/
|
||
|
int (*on_data_lost)(OSSL_CC_DATA *ccdata,
|
||
|
const OSSL_CC_LOSS_INFO *info);
|
||
|
|
||
|
/*
|
||
|
* To be called after a sequence of one or more on_data_lost() calls
|
||
|
* representing multiple packets in a single loss detection incident.
|
||
|
*
|
||
|
* Flags may be 0 or OSSL_CC_LOST_FLAG_PERSISTENT_CONGESTION.
|
||
|
*/
|
||
|
int (*on_data_lost_finished)(OSSL_CC_DATA *ccdata, uint32_t flags);
|
||
|
|
||
|
/*
|
||
|
* For use when a PN space is invalidated or a packet must otherwise be
|
||
|
* 'undone' for congestion control purposes without acting as a loss signal.
|
||
|
* Only the size of the packet is needed.
|
||
|
*/
|
||
|
int (*on_data_invalidated)(OSSL_CC_DATA *ccdata,
|
||
|
uint64_t num_bytes);
|
||
|
|
||
|
/*
|
||
|
* Called from the ACKM when detecting an increased ECN-CE value in an ACK
|
||
|
* frame. This indicates congestion.
|
||
|
*
|
||
|
* Note that this differs from the RFC's conceptual segregation of the loss
|
||
|
* detection and congestion controller functions, as in our implementation
|
||
|
* the ACKM is responsible for detecting increases to ECN-CE and simply
|
||
|
* tells the congestion controller when ECN-triggered congestion has
|
||
|
* occurred. This allows a slightly more efficient implementation and
|
||
|
* narrower interface between the ACKM and CC.
|
||
|
*/
|
||
|
int (*on_ecn)(OSSL_CC_DATA *ccdata,
|
||
|
const OSSL_CC_ECN_INFO *info);
|
||
|
} OSSL_CC_METHOD;
|
||
|
|
||
|
extern const OSSL_CC_METHOD ossl_cc_dummy_method;
|
||
|
extern const OSSL_CC_METHOD ossl_cc_newreno_method;
|
||
|
|
||
|
# endif
|
||
|
|
||
|
#endif
|