mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-01-02 02:02:03 +00:00
MINOR: quic: extract datagram parsing code
Extract individual datagram parsing code outside of datagrams list loop in quic_lstnr_dghdlr(). This is moved in a new function named quic_dgram_parse(). To complete this change, quic_lstnr_dghdlr() has been moved into quic_sock source file : it belongs to QUIC socket lower layer and is directly called by quic_sock_fd_iocb(). This commit will ease implementation of quic-conn owned socket. New function quic_dgram_parse() will be easily usable after a receive operation done on quic-conn IO-cb. This should be backported up to 2.7.
This commit is contained in:
parent
3f474e64c8
commit
8687b63c69
@ -743,7 +743,6 @@ void chunk_frm_appendf(struct buffer *buf, const struct quic_frame *frm);
|
||||
void quic_set_connection_close(struct quic_conn *qc, const struct quic_err err);
|
||||
void quic_set_tls_alert(struct quic_conn *qc, int alert);
|
||||
int quic_set_app_ops(struct quic_conn *qc, const unsigned char *alpn, size_t alpn_len);
|
||||
struct task *quic_lstnr_dghdlr(struct task *t, void *ctx, unsigned int state);
|
||||
int quic_get_dgram_dcid(unsigned char *buf, const unsigned char *end,
|
||||
unsigned char **dcid, size_t *dcid_len);
|
||||
int qc_send_mux(struct quic_conn *qc, struct list *frms);
|
||||
@ -756,5 +755,8 @@ void qc_check_close_on_released_mux(struct quic_conn *qc);
|
||||
|
||||
void quic_conn_release(struct quic_conn *qc);
|
||||
|
||||
int quic_dgram_parse(struct quic_dgram *dgram, struct quic_conn *qc,
|
||||
struct listener *li);
|
||||
|
||||
#endif /* USE_QUIC */
|
||||
#endif /* _HAPROXY_QUIC_CONN_H */
|
||||
|
@ -39,6 +39,8 @@ int quic_sock_get_src(struct connection *conn, struct sockaddr *addr, socklen_t
|
||||
int quic_sock_get_dst(struct connection *conn, struct sockaddr *addr, socklen_t len);
|
||||
int quic_sock_accepting_conn(const struct receiver *rx);
|
||||
struct connection *quic_sock_accept_conn(struct listener *l, int *status);
|
||||
|
||||
struct task *quic_lstnr_dghdlr(struct task *t, void *ctx, unsigned int state);
|
||||
void quic_sock_fd_iocb(int fd);
|
||||
int qc_snd_buf(struct quic_conn *qc, const struct buffer *buf, size_t count,
|
||||
int flags);
|
||||
|
149
src/quic_conn.c
149
src/quic_conn.c
@ -7242,99 +7242,110 @@ static void __quic_conn_deinit(void)
|
||||
}
|
||||
REGISTER_POST_DEINIT(__quic_conn_deinit);
|
||||
|
||||
/* Read all the QUIC packets found in <buf> from QUIC connection with <owner>
|
||||
* as owner calling <func> function.
|
||||
* Return the number of bytes read if succeeded, -1 if not.
|
||||
/* Handle a new <dgram> received. Parse each QUIC packets and copied their
|
||||
* content to a quic-conn instance. The datagram content can be released after
|
||||
* this function.
|
||||
*
|
||||
* If datagram has been received on a quic-conn owned FD, <from_qc> must be set
|
||||
* to the connection instance. <li> is the attached listener. The caller is
|
||||
* responsible to ensure that the first packet is destined to this connection
|
||||
* by comparing CIDs.
|
||||
*
|
||||
* If datagram has been received on a receiver FD, <from_qc> will be NULL. This
|
||||
* function will thus retrieve the connection from the CID tree or allocate a
|
||||
* new one if possible. <li> is the listener attached to the receiver.
|
||||
*
|
||||
* Returns 0 on success else non-zero. If an error happens, some packets from
|
||||
* the datagram may not have been parsed.
|
||||
*/
|
||||
struct task *quic_lstnr_dghdlr(struct task *t, void *ctx, unsigned int state)
|
||||
int quic_dgram_parse(struct quic_dgram *dgram, struct quic_conn *from_qc,
|
||||
struct listener *li)
|
||||
{
|
||||
unsigned char *pos;
|
||||
const unsigned char *end;
|
||||
struct quic_dghdlr *dghdlr = ctx;
|
||||
struct quic_dgram *dgram;
|
||||
struct quic_rx_packet *pkt;
|
||||
struct quic_conn *qc = NULL;
|
||||
unsigned char *pos, *end;
|
||||
struct list *tasklist_head = NULL;
|
||||
int max_dgrams = global.tune.maxpollevents;
|
||||
|
||||
TRACE_ENTER(QUIC_EV_CONN_LPKT);
|
||||
|
||||
while ((dgram = MT_LIST_POP(&dghdlr->dgrams, typeof(dgram), handler_list))) {
|
||||
pos = dgram->buf;
|
||||
end = pos + dgram->len;
|
||||
do {
|
||||
struct quic_rx_packet *pkt;
|
||||
struct quic_conn *qc;
|
||||
pos = dgram->buf;
|
||||
end = pos + dgram->len;
|
||||
do {
|
||||
/* TODO replace zalloc -> alloc. */
|
||||
pkt = pool_zalloc(pool_head_quic_rx_packet);
|
||||
if (!pkt) {
|
||||
TRACE_ERROR("RX packet allocation failed", QUIC_EV_CONN_LPKT);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* TODO replace zalloc -> alloc. */
|
||||
pkt = pool_zalloc(pool_head_quic_rx_packet);
|
||||
if (!pkt) {
|
||||
TRACE_ERROR("RX packet allocation failed", QUIC_EV_CONN_LPKT);
|
||||
/* TODO count lost datagram. */
|
||||
goto leave;
|
||||
}
|
||||
pkt->version = NULL;
|
||||
pkt->pn_offset = 0;
|
||||
|
||||
pkt->version = NULL;
|
||||
pkt->pn_offset = 0;
|
||||
/* Set flag if pkt is the first one in dgram. */
|
||||
if (pos == dgram->buf)
|
||||
pkt->flags |= QUIC_FL_RX_PACKET_DGRAM_FIRST;
|
||||
|
||||
/* Set flag if pkt is the first one in dgram. */
|
||||
if (pos == dgram->buf)
|
||||
pkt->flags |= QUIC_FL_RX_PACKET_DGRAM_FIRST;
|
||||
LIST_INIT(&pkt->qc_rx_pkt_list);
|
||||
pkt->time_received = now_ms;
|
||||
quic_rx_packet_refinc(pkt);
|
||||
if (quic_rx_pkt_parse(pkt, pos, end, dgram, li))
|
||||
goto next;
|
||||
|
||||
LIST_INIT(&pkt->qc_rx_pkt_list);
|
||||
pkt->time_received = now_ms;
|
||||
quic_rx_packet_refinc(pkt);
|
||||
if (quic_rx_pkt_parse(pkt, pos, end, dgram, dgram->owner))
|
||||
goto next;
|
||||
|
||||
qc = quic_rx_pkt_retrieve_conn(pkt, dgram, dgram->owner);
|
||||
if (!qc)
|
||||
goto next;
|
||||
|
||||
BUG_ON(dgram->qc && dgram->qc != qc);
|
||||
dgram->qc = qc;
|
||||
|
||||
if (qc_rx_check_closing(qc, pkt)) {
|
||||
/* Search quic-conn instance for first packet of the datagram.
|
||||
* quic_rx_packet_parse() is responsible to discard packets
|
||||
* with different DCID as the first one in the same datagram.
|
||||
*/
|
||||
if (!qc) {
|
||||
qc = from_qc ? from_qc : quic_rx_pkt_retrieve_conn(pkt, dgram, li);
|
||||
/* qc is NULL if receiving a non Initial packet for an
|
||||
* unknown connection.
|
||||
*/
|
||||
if (!qc) {
|
||||
/* Skip the entire datagram. */
|
||||
pkt->len = end - pos;
|
||||
goto next;
|
||||
}
|
||||
|
||||
qc_rx_pkt_handle(qc, pkt, dgram, pos, &tasklist_head);
|
||||
dgram->qc = qc;
|
||||
}
|
||||
|
||||
if (qc_rx_check_closing(qc, pkt)) {
|
||||
/* Skip the entire datagram. */
|
||||
pkt->len = end - pos;
|
||||
goto next;
|
||||
}
|
||||
|
||||
qc_rx_pkt_handle(qc, pkt, dgram, pos, &tasklist_head);
|
||||
|
||||
next:
|
||||
pos += pkt->len;
|
||||
quic_rx_packet_refdec(pkt);
|
||||
pos += pkt->len;
|
||||
quic_rx_packet_refdec(pkt);
|
||||
|
||||
/* Free rejected packets */
|
||||
if (!pkt->refcnt) {
|
||||
BUG_ON(LIST_INLIST(&pkt->qc_rx_pkt_list));
|
||||
pool_free(pool_head_quic_rx_packet, pkt);
|
||||
}
|
||||
} while (pos < end);
|
||||
/* Free rejected packets */
|
||||
if (!pkt->refcnt) {
|
||||
BUG_ON(LIST_INLIST(&pkt->qc_rx_pkt_list));
|
||||
pool_free(pool_head_quic_rx_packet, pkt);
|
||||
}
|
||||
} while (pos < end);
|
||||
|
||||
/* Increasing the received bytes counter by the UDP datagram length
|
||||
* if this datagram could be associated to a connection.
|
||||
*/
|
||||
if (dgram->qc)
|
||||
dgram->qc->rx.bytes += dgram->len;
|
||||
/* Increasing the received bytes counter by the UDP datagram length
|
||||
* if this datagram could be associated to a connection.
|
||||
*/
|
||||
if (dgram->qc)
|
||||
dgram->qc->rx.bytes += dgram->len;
|
||||
|
||||
/* Mark this datagram as consumed */
|
||||
HA_ATOMIC_STORE(&dgram->buf, NULL);
|
||||
|
||||
if (--max_dgrams <= 0)
|
||||
goto stop_here;
|
||||
}
|
||||
/* This must never happen. */
|
||||
BUG_ON(pos > end);
|
||||
BUG_ON(pos < end || pos > dgram->buf + dgram->len);
|
||||
/* Mark this datagram as consumed */
|
||||
HA_ATOMIC_STORE(&dgram->buf, NULL);
|
||||
|
||||
TRACE_LEAVE(QUIC_EV_CONN_LPKT);
|
||||
return 0;
|
||||
|
||||
return t;
|
||||
|
||||
stop_here:
|
||||
/* too much work done at once, come back here later */
|
||||
if (!MT_LIST_ISEMPTY(&dghdlr->dgrams))
|
||||
tasklet_wakeup((struct tasklet *)t);
|
||||
leave:
|
||||
err:
|
||||
TRACE_LEAVE(QUIC_EV_CONN_LPKT);
|
||||
return t;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Retrieve the DCID from a QUIC datagram or packet with <buf> as first octet.
|
||||
|
@ -36,8 +36,11 @@
|
||||
#include <haproxy/session.h>
|
||||
#include <haproxy/stats-t.h>
|
||||
#include <haproxy/task.h>
|
||||
#include <haproxy/trace.h>
|
||||
#include <haproxy/tools.h>
|
||||
|
||||
#define TRACE_SOURCE &trace_quic
|
||||
|
||||
/* Retrieve a connection's source address. Returns -1 on failure. */
|
||||
int quic_sock_get_src(struct connection *conn, struct sockaddr *addr, socklen_t len)
|
||||
{
|
||||
@ -160,6 +163,37 @@ struct connection *quic_sock_accept_conn(struct listener *l, int *status)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* QUIC datagrams handler task. */
|
||||
struct task *quic_lstnr_dghdlr(struct task *t, void *ctx, unsigned int state)
|
||||
{
|
||||
struct quic_dghdlr *dghdlr = ctx;
|
||||
struct quic_dgram *dgram;
|
||||
int max_dgrams = global.tune.maxpollevents;
|
||||
|
||||
TRACE_ENTER(QUIC_EV_CONN_LPKT);
|
||||
|
||||
while ((dgram = MT_LIST_POP(&dghdlr->dgrams, typeof(dgram), handler_list))) {
|
||||
if (quic_dgram_parse(dgram, NULL, dgram->owner)) {
|
||||
/* TODO should we requeue the datagram ? */
|
||||
break;
|
||||
}
|
||||
|
||||
if (--max_dgrams <= 0)
|
||||
goto stop_here;
|
||||
}
|
||||
|
||||
TRACE_LEAVE(QUIC_EV_CONN_LPKT);
|
||||
return t;
|
||||
|
||||
stop_here:
|
||||
/* too much work done at once, come back here later */
|
||||
if (!MT_LIST_ISEMPTY(&dghdlr->dgrams))
|
||||
tasklet_wakeup((struct tasklet *)t);
|
||||
|
||||
TRACE_LEAVE(QUIC_EV_CONN_LPKT);
|
||||
return t;
|
||||
}
|
||||
|
||||
/* Retrieve the DCID from the datagram found in <buf> and deliver it to the
|
||||
* correct datagram handler.
|
||||
* Return 1 if a correct datagram could be found, 0 if not.
|
||||
|
Loading…
Reference in New Issue
Block a user