blob: d95e9dc0d22def7ceef7959be93ee9f62549d7c7 [file] [log] [blame]
#ifndef _HAPROXY_MUX_QUIC_T_H
#define _HAPROXY_MUX_QUIC_T_H
#ifdef USE_QUIC
#ifndef USE_OPENSSL
#error "Must define USE_OPENSSL"
#endif
#include <import/ebtree-t.h>
#include <haproxy/buf-t.h>
#include <haproxy/connection-t.h>
#include <haproxy/list-t.h>
#include <haproxy/quic_stream-t.h>
#include <haproxy/xprt_quic-t.h>
#include <haproxy/conn_stream-t.h>
/* Stream types */
enum qcs_type {
QCS_CLT_BIDI,
QCS_SRV_BIDI,
QCS_CLT_UNI,
QCS_SRV_UNI,
/* Must be the last one */
QCS_MAX_TYPES
};
#define QC_CF_BLK_MFCTL 0x00000001 /* sending blocked due to connection flow-control */
#define QC_CF_CONN_FULL 0x00000002 /* no stream buffers available on connection */
struct qcc {
struct connection *conn;
uint64_t nb_cs; /* number of attached conn-streams */
uint32_t flags; /* QC_CF_* */
struct {
uint64_t max_streams; /* maximum number of concurrent streams */
uint64_t largest_id; /* Largest ID of the open streams */
uint64_t nb_streams; /* Number of open streams */
struct {
uint64_t max_data; /* Maximum number of bytes which may be received */
uint64_t bytes; /* Number of bytes received */
} rx;
struct {
uint64_t max_data; /* Maximum number of bytes which may be sent */
uint64_t bytes; /* Number of bytes sent */
} tx;
} strms[QCS_MAX_TYPES];
/* flow-control fields set by us enforced on our side. */
struct {
uint64_t ms_bidi_init; /* max initial sub-ID of bidi stream allowed for the peer */
uint64_t ms_bidi; /* max sub-ID of bidi stream allowed for the peer */
uint64_t cl_bidi_r; /* total count of closed remote bidi stream since last MAX_STREAMS emission */
} lfctl;
/* flow-control fields set by the peer which we must respect. */
struct {
uint64_t md; /* connection flow control limit updated on MAX_DATA frames reception */
uint64_t msd_bidi_l; /* initial max-stream-data for peer local streams */
uint64_t msd_bidi_r; /* initial max-stream-data for peer remote streams */
} rfctl;
struct {
uint64_t max_data; /* Maximum number of bytes which may be received */
} rx;
struct {
uint64_t sent_offsets; /* sum of all offset sent */
} tx;
struct eb_root streams_by_id; /* all active streams by their ID */
struct list send_retry_list; /* list of qcs eligible to send retry */
struct wait_event wait_event; /* To be used if we're waiting for I/Os */
struct wait_event *subs;
/* haproxy timeout management */
struct task *task;
int timeout;
const struct qcc_app_ops *app_ops;
void *ctx; /* Application layer context */
};
#define QC_SF_NONE 0x00000000
#define QC_SF_FIN_RECV 0x00000001 /* last frame received for this stream */
#define QC_SF_FIN_STREAM 0x00000002 /* FIN bit must be set for last frame of the stream */
#define QC_SF_BLK_MROOM 0x00000004 /* app layer is blocked waiting for room in the qcs.tx.buf */
#define QC_SF_DETACH 0x00000008 /* cs is detached but there is remaining data to send */
#define QC_SF_BLK_SFCTL 0x00000010 /* stream blocked due to stream flow control limit */
struct qcs {
struct qcc *qcc;
struct conn_stream *cs;
struct cs_endpoint *endp;
uint32_t flags; /* QC_SF_* */
struct {
struct eb_root frms; /* received frames ordered by their offsets */
uint64_t offset; /* the current offset of received data */
struct buffer buf; /* receive buffer, always valid (buf_empty or real buffer) */
struct buffer app_buf; /* receive buffer used by conn_stream layer */
} rx;
struct {
uint64_t offset; /* last offset of data ready to be sent */
uint64_t sent_offset; /* last offset sent by transport layer */
struct buffer buf; /* transmit buffer before sending via xprt */
uint64_t msd; /* fctl bytes limit to respect on emission */
} tx;
struct eb64_node by_id;
uint64_t id;
struct qc_stream_desc *stream;
struct list el; /* element of qcc.send_retry_list */
struct wait_event wait_event;
struct wait_event *subs;
};
/* QUIC application layer operations */
struct qcc_app_ops {
int (*init)(struct qcc *qcc);
int (*attach_ruqs)(struct qcs *qcs, void *ctx);
int (*decode_qcs)(struct qcs *qcs, int fin, void *ctx);
size_t (*snd_buf)(struct conn_stream *cs, struct buffer *buf, size_t count, int flags);
int (*finalize)(void *ctx);
int (*is_active)(const struct qcc *qcc, void *ctx);
void (*release)(void *ctx);
};
#endif /* USE_QUIC */
#endif /* _HAPROXY_MUX_QUIC_T_H */