mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-20 22:21:24 +02:00
The conn-stream endpoint is now shared between the conn-stream and the applet or the multiplexer. If the mux or the applet is created first, it is responsible to also create the endpoint and share it with the conn-stream. If the conn-stream is created first, it is the opposite. When the endpoint is only owned by an applet or a mux, it is called an orphan endpoint (there is no conn-stream). When it is only owned by a conn-stream, it is called a detached endpoint (there is no mux/applet). The last entity that owns an endpoint is responsible to release it. When a mux or an applet is detached from a conn-stream, the conn-stream relinquishes the endpoint to recreate a new one. This way, the endpoint state is never lost for the mux or the applet.
124 lines
3.5 KiB
C
124 lines
3.5 KiB
C
#ifndef _HAPROXY_MUX_QUIC_H
|
|
#define _HAPROXY_MUX_QUIC_H
|
|
|
|
#ifdef USE_QUIC
|
|
#ifndef USE_OPENSSL
|
|
#error "Must define USE_OPENSSL"
|
|
#endif
|
|
|
|
#include <import/eb64tree.h>
|
|
|
|
#include <haproxy/api.h>
|
|
#include <haproxy/connection.h>
|
|
#include <haproxy/mux_quic-t.h>
|
|
#include <haproxy/stream.h>
|
|
#include <haproxy/xprt_quic-t.h>
|
|
|
|
struct qcs *qcs_new(struct qcc *qcc, uint64_t id, enum qcs_type type);
|
|
void qcs_free(struct qcs *qcs);
|
|
|
|
struct buffer *qc_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);
|
|
|
|
int qcc_recv(struct qcc *qcc, uint64_t id, uint64_t len, uint64_t offset,
|
|
char fin, char *data, struct qcs **out_qcs);
|
|
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_decode_qcs(struct qcc *qcc, struct qcs *qcs);
|
|
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);
|
|
}
|
|
|
|
struct qcs *qcc_get_qcs(struct qcc *qcc, uint64_t id);
|
|
|
|
/* Install the <app_ops> applicative layer of a QUIC connection on mux <qcc>.
|
|
* Returns 0 on success else non-zero.
|
|
*/
|
|
static inline int qcc_install_app_ops(struct qcc *qcc,
|
|
const struct qcc_app_ops *app_ops)
|
|
{
|
|
qcc->app_ops = app_ops;
|
|
if (qcc->app_ops->init && !qcc->app_ops->init(qcc))
|
|
return 1;
|
|
|
|
if (qcc->app_ops->finalize)
|
|
qcc->app_ops->finalize(qcc->ctx);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* Retrieve a qc_stream_desc from the MUX <qcc> with <id>. This function is
|
|
* useful for the transport layer.
|
|
*
|
|
* Returns the stream instance or NULL if not found.
|
|
*/
|
|
static inline struct qc_stream_desc *qcc_get_stream(struct qcc *qcc, uint64_t id)
|
|
{
|
|
struct eb64_node *node;
|
|
|
|
node = eb64_lookup(&qcc->streams_by_id, id);
|
|
if (!node)
|
|
return NULL;
|
|
|
|
return eb64_entry(node, struct qc_stream_desc, by_id);
|
|
}
|
|
|
|
static inline struct conn_stream *qc_attach_cs(struct qcs *qcs, struct buffer *buf)
|
|
{
|
|
struct conn_stream *cs;
|
|
|
|
cs = cs_new_from_mux(qcs->endp, qcs->qcc->conn->owner, buf);
|
|
if (!cs)
|
|
return NULL;
|
|
qcs->cs = cs;
|
|
++qcs->qcc->nb_cs;
|
|
|
|
return cs;
|
|
}
|
|
|
|
#endif /* USE_QUIC */
|
|
|
|
#endif /* _HAPROXY_MUX_QUIC_H */
|