#ifndef _HAPROXY_MUX_QUIC_H #define _HAPROXY_MUX_QUIC_H #ifdef USE_QUIC #ifndef USE_OPENSSL #error "Must define USE_OPENSSL" #endif #include #include #include #include #include void qcc_set_error(struct qcc *qcc, int err, int app); struct qcs *qcc_init_stream_local(struct qcc *qcc, int bidi); struct stconn *qcs_attach_sc(struct qcs *qcs, struct buffer *buf, char fin); int qcs_is_close_local(struct qcs *qcs); int qcs_is_close_remote(struct qcs *qcs); struct buffer *qcs_get_buf(struct qcs *qcs, struct buffer *bptr); int qcs_subscribe(struct qcs *qcs, int event_type, struct wait_event *es); void qcs_notify_recv(struct qcs *qcs); void qcs_notify_send(struct qcs *qcs); void qcc_emit_cc_app(struct qcc *qcc, int err, int immediate); void qcc_reset_stream(struct qcs *qcs, int err); void qcc_send_stream(struct qcs *qcs, int urg); void qcc_abort_stream_read(struct qcs *qcs); int qcc_recv(struct qcc *qcc, uint64_t id, uint64_t len, uint64_t offset, char fin, char *data); int qcc_recv_max_data(struct qcc *qcc, uint64_t max); int qcc_recv_max_stream_data(struct qcc *qcc, uint64_t id, uint64_t max); int qcc_recv_reset_stream(struct qcc *qcc, uint64_t id, uint64_t err, uint64_t final_size); int qcc_recv_stop_sending(struct qcc *qcc, uint64_t id, uint64_t err); void qcc_streams_sent_done(struct qcs *qcs, uint64_t data, uint64_t offset); /* Bit shift to get the stream sub ID for internal use which is obtained * shifting the stream IDs by this value, knowing that the * QCS_ID_TYPE_SHIFT less significant bits identify the stream ID * types (client initiated bidirectional, server initiated bidirectional, * client initiated unidirectional, server initiated bidirectional). * Note that there is no reference to such stream sub IDs in the RFC. */ #define QCS_ID_TYPE_MASK 0x3 #define QCS_ID_TYPE_SHIFT 2 /* The less significant bit of a stream ID is set for a server initiated stream */ #define QCS_ID_SRV_INTIATOR_BIT 0x1 /* This bit is set for unidirectional streams */ #define QCS_ID_DIR_BIT 0x2 static inline enum qcs_type qcs_id_type(uint64_t id) { return id & QCS_ID_TYPE_MASK; } /* Return true if stream has been opened locally. */ static inline int quic_stream_is_local(struct qcc *qcc, uint64_t id) { return conn_is_back(qcc->conn) == !(id & QCS_ID_SRV_INTIATOR_BIT); } /* Return true if stream is opened by peer. */ static inline int quic_stream_is_remote(struct qcc *qcc, uint64_t id) { return !quic_stream_is_local(qcc, id); } static inline int quic_stream_is_uni(uint64_t id) { return id & QCS_ID_DIR_BIT; } static inline int quic_stream_is_bidi(uint64_t id) { return !quic_stream_is_uni(id); } static inline char *qcs_st_to_str(enum qcs_state st) { switch (st) { case QC_SS_IDLE: return "IDL"; case QC_SS_OPEN: return "OPN"; case QC_SS_HLOC: return "HCL"; case QC_SS_HREM: return "HCR"; case QC_SS_CLO: return "CLO"; default: return "???"; } } int qcc_install_app_ops(struct qcc *qcc, const struct qcc_app_ops *app_ops); /* Register stream for http-request timeout. If the stream is not yet * attached in the configured delay, qcc timeout task will be triggered. This * means the full header section was not received in time. * * This function should be called by the application protocol layer on request * streams initialization. */ static inline void qcs_wait_http_req(struct qcs *qcs) { struct qcc *qcc = qcs->qcc; /* A stream cannot be registered several times. */ BUG_ON_HOT(tick_isset(qcs->start)); qcs->start = now_ms; /* qcc.opening_list size is limited by flow-control so no custom * restriction is needed here. */ LIST_APPEND(&qcc->opening_list, &qcs->el_opening); } #endif /* USE_QUIC */ #endif /* _HAPROXY_MUX_QUIC_H */