#ifdef ENABLE_QUIC
conf_t *pconf = conf();
size_t udp_pl = MIN(pconf->cache.srv_udp_max_payload_ipv4, pconf->cache.srv_udp_max_payload_ipv6);
- ctx->quic_table = knot_xquic_table_new(true, ctx->quic_max_conns, ctx->quic_max_inbufs,
+ ctx->quic_table = knot_xquic_table_new(ctx->quic_max_conns, ctx->quic_max_inbufs,
ctx->quic_max_obufs, udp_pl, server->quic_creds);
if (ctx->quic_table == NULL) {
xdp_handle_free(ctx);
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+/*!
+ * \file
+ *
+ * \brief General QUIC functionality.
+ *
+ * \addtogroup xdp
+ * @{
+ */
+
#pragma once
#include "libknot/xdp/quic_conn.h"
/*!
* \brief Loads data needed for session resumption.
*
- * \param conn QUIC connection.
- * \param conn QUIC session context.
+ * \param conn QUIC connection.
+ * \param session QUIC session context.
*
* \return KNOT_E*
*/
*/
void knot_xquic_free_creds(struct knot_quic_creds *creds);
+/*!
+ * \brief Returns timeout value for the connection.
+ */
uint64_t xquic_conn_get_timeout(knot_xquic_conn_t *conn);
/*!
* \brief Check if connection timed out due to inactivity.
*
* \param conn QUIC connection.
- * \param now In/out: current monotonic time. Use zero first and reuse for next calls for optimization.
+ * \param now In/out: current monotonic time. Use zero first and reuse for
+ * next calls for optimization.
*
* \return True if the connection timed out idle.
*/
int knot_xquic_send(knot_xquic_table_t *quic_table, knot_xquic_conn_t *relay,
knot_xdp_socket_t *sock, knot_xdp_msg_t *in_msg,
int handle_ret, unsigned max_msgs, bool ignore_lastbyte);
+
+/*! @} */
#define BUCKETS_PER_CONNS 8 // Each connecion has several dCIDs, and each CID takes one hash table bucket.
_public_
-knot_xquic_table_t *knot_xquic_table_new(bool server, size_t max_conns, size_t max_ibufs, size_t max_obufs,
- size_t udp_pl, struct knot_quic_creds *creds)
+knot_xquic_table_t *knot_xquic_table_new(size_t max_conns, size_t max_ibufs, size_t max_obufs,
+ size_t udp_payload, struct knot_quic_creds *creds)
{
size_t table_size = max_conns * BUCKETS_PER_CONNS;
res->max_conns = max_conns;
res->ibufs_max = max_ibufs;
res->obufs_max = max_obufs;
- res->udp_payload_limit = udp_pl;
+ res->udp_payload_limit = udp_payload;
init_list((list_t *)&res->timeout);
res->creds = creds;
return addto;
}
-knot_xquic_conn_t *xquic_table_add(ngtcp2_conn *conn, const ngtcp2_cid *cid, knot_xquic_table_t *table)
+knot_xquic_conn_t *xquic_table_add(ngtcp2_conn *conn, const ngtcp2_cid *cid,
+ knot_xquic_table_t *table)
{
knot_xquic_conn_t *xconn = calloc(1, sizeof(*xconn));
if (xconn == NULL) {
return *pcid == NULL ? NULL : (*pcid)->conn;
}
-void xquic_conn_mark_used(knot_xquic_conn_t *conn, knot_xquic_table_t *table, uint64_t now)
+void xquic_conn_mark_used(knot_xquic_conn_t *conn, knot_xquic_table_t *table,
+ uint64_t now)
{
node_t *n = (node_t *)&conn->timeout;
list_t *l = (list_t *)&table->timeout;
}
_public_
-knot_xquic_stream_t *knot_xquic_conn_get_stream(knot_xquic_conn_t *xconn, int64_t stream_id, bool create)
+knot_xquic_stream_t *knot_xquic_conn_get_stream(knot_xquic_conn_t *xconn,
+ int64_t stream_id, bool create)
{
if (stream_id % 4 != 0) {
return NULL;
}
}
- for (knot_xquic_stream_t *si = new_streams + xconn->streams_count; si < new_streams + new_streams_count; si++) {
+ for (knot_xquic_stream_t *si = new_streams + xconn->streams_count;
+ si < new_streams + new_streams_count; si++) {
memset(si, 0, sizeof(*si));
init_list((list_t *)&si->outbufs);
}
xconn->stream_inprocess = -1;
}
-int knot_xquic_stream_recv_data(knot_xquic_conn_t *xconn, int64_t stream_id, const uint8_t *data, size_t len, bool fin)
+int knot_xquic_stream_recv_data(knot_xquic_conn_t *xconn, int64_t stream_id,
+ const uint8_t *data, size_t len, bool fin)
{
if (len == 0) {
return KNOT_EINVAL;
struct iovec in = { (void *)data, len }, *outs;
size_t outs_count;
- int ret = knot_tcp_inbuf_update(&stream->inbuf, in, &outs, &outs_count, &xconn->ibufs_size);
+ int ret = knot_tcp_inbuf_update(&stream->inbuf, in, &outs, &outs_count,
+ &xconn->ibufs_size);
if (ret != KNOT_EOK || (outs_count == 0 && !fin)) {
return ret;
}
}
_public_
-knot_xquic_stream_t *knot_xquic_stream_get_process(knot_xquic_conn_t *xconn, int64_t *stream_id)
+knot_xquic_stream_t *knot_xquic_stream_get_process(knot_xquic_conn_t *xconn,
+ int64_t *stream_id)
{
if (xconn->stream_inprocess < 0) {
return NULL;
}
_public_
-uint8_t *knot_xquic_stream_add_data(knot_xquic_conn_t *xconn, int64_t stream_id, uint8_t *data, size_t len)
+uint8_t *knot_xquic_stream_add_data(knot_xquic_conn_t *xconn, int64_t stream_id,
+ uint8_t *data, size_t len)
{
knot_xquic_stream_t *s = knot_xquic_conn_get_stream(xconn, stream_id, true);
if (s == NULL) {
return obuf->buf + prefix;
}
-void knot_xquic_stream_ack_data(knot_xquic_conn_t *xconn, int64_t stream_id, size_t end_acked, bool keep_stream)
+void knot_xquic_stream_ack_data(knot_xquic_conn_t *xconn, int64_t stream_id,
+ size_t end_acked, bool keep_stream)
{
knot_xquic_stream_t *s = knot_xquic_conn_get_stream(xconn, stream_id, false);
if (s == NULL) {
}
}
-void knot_xquic_stream_mark_sent(knot_xquic_conn_t *xconn, int64_t stream_id, size_t amount_sent)
+void knot_xquic_stream_mark_sent(knot_xquic_conn_t *xconn, int64_t stream_id,
+ size_t amount_sent)
{
knot_xquic_stream_t *s = knot_xquic_conn_get_stream(xconn, stream_id, false);
if (s == NULL) {
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+/*!
+ * \file
+ *
+ * \brief QUIC connection management.
+ *
+ * \addtogroup xdp
+ * @{
+ */
+
#pragma once
#include <linux/if_ether.h>
/*!
* \brief Allocate QUIC connections hash table.
*
- * \param server Initialize server-side QUIC conn table.
* \param max_conns Maximum nuber of connections.
* \param max_ibufs Maximum size of buffers for fragmented incomming DNS msgs.
* \param max_obufs Maximum size of buffers for un-ACKed outgoing data.
*
* \return Allocated table, or NULL.
*/
-knot_xquic_table_t *knot_xquic_table_new(bool server, size_t max_conns, size_t max_ibufs, size_t max_obufs,
- size_t udp_pl, struct knot_quic_creds *creds);
+knot_xquic_table_t *knot_xquic_table_new(size_t max_conns, size_t max_ibufs, size_t max_obufs,
+ size_t udp_payload, struct knot_quic_creds *creds);
/*!
* \brief Free QUIC table including its contents.
* \brief Close timed out connections and some oldest ones if table full.
*
* \param table QUIC table to be cleaned up.
- * \param max_conns Limit for connections count in table.
- * \param max_obufs Limit of allocated outgiong payload buffers.
* \param timed_out Out: number of closed connections due to timeout.
* \param force_closed Out: number of closed connections due to overfull.
*
* \return KNOT_E*
*/
-int knot_xquic_table_sweep(knot_xquic_table_t *table,
- uint32_t *timed_out, uint32_t *force_closed);
+int knot_xquic_table_sweep(knot_xquic_table_t *table, uint32_t *timed_out,
+ uint32_t *force_closed);
/*!
* \brief Add new connection/CID link to table.
*
* \return Pointer on the CID reference in table, or NULL.
*/
-knot_xquic_cid_t **xquic_table_insert(knot_xquic_conn_t *xconn, const struct ngtcp2_cid *cid,
+knot_xquic_cid_t **xquic_table_insert(knot_xquic_conn_t *xconn,
+ const struct ngtcp2_cid *cid,
knot_xquic_table_t *table);
/*!
*
* \return Allocated (and linked) Knot conn struct, or NULL.
*/
-knot_xquic_conn_t *xquic_table_add(struct ngtcp2_conn *conn, const struct ngtcp2_cid *cid, knot_xquic_table_t *table);
+knot_xquic_conn_t *xquic_table_add(struct ngtcp2_conn *conn,
+ const struct ngtcp2_cid *cid,
+ knot_xquic_table_t *table);
/*!
* \brief Lookup connection/CID link in table.
*
* \return Pointer on the CID reference in table, or NULL.
*/
-knot_xquic_cid_t **xquic_table_lookup2(const struct ngtcp2_cid *cid, knot_xquic_table_t *table);
+knot_xquic_cid_t **xquic_table_lookup2(const struct ngtcp2_cid *cid,
+ knot_xquic_table_t *table);
/*!
* \brief Lookup QUIC connection in table.
*
* \return Connection that the CID belongs to, or NULL.
*/
-knot_xquic_conn_t *xquic_table_lookup(const struct ngtcp2_cid *cid, knot_xquic_table_t *table);
+knot_xquic_conn_t *xquic_table_lookup(const struct ngtcp2_cid *cid,
+ knot_xquic_table_t *table);
/*!
* \brief Put the connection on the end of timeout queue.
*/
-void xquic_conn_mark_used(knot_xquic_conn_t *conn, knot_xquic_table_t *table, uint64_t now);
+void xquic_conn_mark_used(knot_xquic_conn_t *conn, knot_xquic_table_t *table,
+ uint64_t now);
/*!
* \brief Remove connection/CID link from table.
*
* \return Stream or NULL.
*/
-knot_xquic_stream_t *knot_xquic_conn_get_stream(knot_xquic_conn_t *xconn, int64_t stream_id, bool create);
+knot_xquic_stream_t *knot_xquic_conn_get_stream(knot_xquic_conn_t *xconn,
+ int64_t stream_id, bool create);
/*!
* \brief Process incomming stream data to stream structure.
*
* \return KNOT_E*
*/
-int knot_xquic_stream_recv_data(knot_xquic_conn_t *xconn, int64_t stream_id, const uint8_t *data, size_t len, bool fin);
+int knot_xquic_stream_recv_data(knot_xquic_conn_t *xconn, int64_t stream_id,
+ const uint8_t *data, size_t len, bool fin);
/*!
* \brief Get next stream which has pending incomming data to be processed.
*
* \return Stream with incomming data.
*/
-knot_xquic_stream_t *knot_xquic_stream_get_process(knot_xquic_conn_t *xconn, int64_t *stream_id);
+knot_xquic_stream_t *knot_xquic_stream_get_process(knot_xquic_conn_t *xconn,
+ int64_t *stream_id);
/*!
* \brief Add outgiong data to the stream for sending.
*
* \return NULL if error, or pinter at the data in outgiong buffer.
*/
-uint8_t *knot_xquic_stream_add_data(knot_xquic_conn_t *xconn, int64_t stream_id, uint8_t *data, size_t len);
+uint8_t *knot_xquic_stream_add_data(knot_xquic_conn_t *xconn, int64_t stream_id,
+ uint8_t *data, size_t len);
/*!
* \brief Mark outgiong data as acknowledged after ACK received.
* \param end_acked Offset of ACKed data + ACKed length.
* \param keep_stream Don't free the stream even when ACKed all outgoing data.
*/
-void knot_xquic_stream_ack_data(knot_xquic_conn_t *xconn, int64_t stream_id, size_t end_acked, bool keep_stream);
+void knot_xquic_stream_ack_data(knot_xquic_conn_t *xconn, int64_t stream_id,
+ size_t end_acked, bool keep_stream);
/*!
* \brief Mark outgoing data as sent.
* \param stream_id Stream ID of sent data.
* \param amount_sent Length of sent data.
*/
-void knot_xquic_stream_mark_sent(knot_xquic_conn_t *xconn, int64_t stream_id, size_t amount_sent);
+void knot_xquic_stream_mark_sent(knot_xquic_conn_t *xconn, int64_t stream_id,
+ size_t amount_sent);
/*!
* \brief Toggle sending Retry packet as a reaction to Initial packet of new connection.
*
* \param table Connection table.
*
- * \return True if instead of continuing handshake, Retry packet shall be sent to verify counterpart's address.
+ * \return True if instead of continuing handshake, Retry packet shall be sent
+ * to verify counterpart's address.
*/
bool xquic_require_retry(knot_xquic_table_t *table);
+
+/*! @} */
ERR2("failed to initialize QUIC context\n");
return NULL;
}
- quic_table = knot_xquic_table_new(false, ctx->qps * 100, SIZE_MAX, SIZE_MAX, 1232, quic_creds);
+ quic_table = knot_xquic_table_new(ctx->qps * 100, SIZE_MAX, SIZE_MAX, 1232, quic_creds);
if (quic_table == NULL) {
ERR2("failed to allocate QUIC connection table\n");
return NULL;