* with a connection \
*/ \
struct eb_root *cids; \
- enum obj_type *target; \
+ struct listener *li; \
/* Idle timer task */ \
struct task *idle_timer_task; \
unsigned int idle_expire; \
static inline void *qc_counters(enum obj_type *o, const struct stats_module *m)
{
struct proxy *p;
- struct listener *l = objt_listener(o);
- struct server *s = objt_server(o);
+ struct listener *l;
+ struct server *s;
+ if (!o)
+ return NULL;
+
+ l = objt_listener(o);
+ s = objt_server(o);
p = l ? l->bind_conf->frontend :
s ? s->proxy : NULL;
*/
static inline int qc_fd(struct quic_conn *qc)
{
- /* TODO: check this: For backends, qc->fd is always initialized */
- return qc_test_fd(qc) ? qc->fd : __objt_listener(qc->target)->rx.fd;
+ /* For backends, qc->fd is always initialized */
+ return qc_test_fd(qc) ? qc->fd : qc->li->rx.fd;
}
/* Try to increment <l> handshake current counter. If listener limit is
#if defined(USE_QUIC)
else if (fdt.iocb == quic_conn_sock_fd_iocb) {
qc = fdtab[fd].owner;
- li = qc ? objt_listener(qc->target) : NULL;
- sv = qc ? objt_server(qc->target) : NULL;
+ li = qc ? qc->li : NULL;
+ sv = qc ? (qc->conn ? objt_server(qc->conn->target) : NULL) : NULL;
xprt_ctx = qc ? qc->xprt_ctx : NULL;
conn = qc ? qc->conn : NULL;
xprt = conn ? conn->xprt : NULL; // in fact it's &ssl_quic
char bufaddr[INET6_ADDRSTRLEN], bufport[6];
int ret;
unsigned char cid_len;
- struct listener *l = objt_listener(qc->target);
+ struct listener *l = qc->li;
ret = chunk_appendf(&trash, "%p[%02u]/%-.12s ", qc, ctx->thr,
- l ? l->bind_conf->frontend->id : __objt_server(qc->target)->id);
+ l ? l->bind_conf->frontend->id :
+ qc->conn ? __objt_server(qc->conn->target)->id : "UNKNOWN");
chunk_appendf(&trash, "%*s", 36 - ret, " "); /* align output */
cc_qc->dcid = qc->dcid;
cc_qc->scid = qc->scid;
- cc_qc->target = qc->target;
+ cc_qc->li = qc->li;
cc_qc->cids = qc->cids;
cc_qc->idle_timer_task = qc->idle_timer_task;
goto err;
}
- qc->target = target;
+ qc->li = l;
/* Now that quic_conn instance is allocated, quic_conn_release() will
* ensure global accounting is decremented.
*/
* used during the handshake, unless the endpoint has acted on a
* preferred_address transport parameter from the peer.
*/
- if (__objt_listener(qc->target)->bind_conf->quic_params.disable_active_migration) {
+ if (qc->li->bind_conf->quic_params.disable_active_migration) {
TRACE_ERROR("Active migration was disabled, datagram dropped", QUIC_EV_CONN_LPKT, qc);
goto err;
}
*/
if (MT_LIST_INLIST(&qc->accept_list)) {
MT_LIST_DELETE(&qc->accept_list);
- BUG_ON(__objt_listener(qc->target)->rx.quic_curr_accept == 0);
- HA_ATOMIC_DEC(&__objt_listener(qc->target)->rx.quic_curr_accept);
+ BUG_ON(qc->li->rx.quic_curr_accept == 0);
+ HA_ATOMIC_DEC(&qc->li->rx.quic_curr_accept);
}
/* Subtract last congestion window from global memory counter. */
/* Connection released before handshake completion. */
if (unlikely(qc->state < QUIC_HS_ST_COMPLETE)) {
if (!qc_is_back(qc)) {
- BUG_ON(__objt_listener(qc->target)->rx.quic_curr_handshake == 0);
- HA_ATOMIC_DEC(&__objt_listener(qc->target)->rx.quic_curr_handshake);
+ BUG_ON(qc->li->rx.quic_curr_handshake == 0);
+ HA_ATOMIC_DEC(&qc->li->rx.quic_curr_handshake);
}
}
/* At this point no connection was accounted for yet on this
* listener so it's OK to just swap the pointer.
*/
- if (new_li && new_li != __objt_listener(qc->target)) {
- qc->target = &new_li->obj_type;
+ if (new_li && new_li != qc->li) {
+ qc->li = new_li;
/* Update GSO conn support based on new listener status. */
if (HA_ATOMIC_LOAD(&new_li->flags) & LI_F_UDP_GSO_NOTSUPP)
goto leave;
}
-/* Find the associated connection to the packet <pkt> or create a new one if
+/* Listener only function.
+ *
+ * Find the associated connection to the packet <pkt> or create a new one if
* this is an Initial packet. <dgram> is the datagram containing the packet and
* <l> is the listener instance on which it was received.
*
return 0;
drop:
- HA_ATOMIC_INC(&prx_counters->dropped_pkt);
+ if (prx_counters)
+ HA_ATOMIC_INC(&prx_counters->dropped_pkt);
drop_silent:
if (!pkt->len)
pkt->len = end - beg;
* 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.
*
+ * Note that for a QUIC backend, <from_qc> is never NULL. <o> is never NULL
+ * for a QUIC frontend.
+ *
* Returns 0 on success else non-zero. If an error happens, some packets from
* the datagram may not have been parsed.
*/
memcpy(addr, &qc->peer_addr, len);
} else {
struct sockaddr_storage *from;
- struct listener *l = objt_listener(qc->target);
+ struct listener *l = qc->li;
/* Return listener address if IP_PKTINFO or friends are not
* supported by the socket.
* possible. This is not useful if the listening socket is bound to
* a specific address. It is even prohibited on FreeBSD.
*/
- return (!is_addr(&__objt_listener(qc->target)->rx.addr) &&
+ return (!is_addr(&qc->li->rx.addr) &&
is_addr(&qc->local_addr));
}
struct buffer buf = BUF_NULL;
unsigned char *dgram_buf;
ssize_t ret = 0;
- struct listener *l = objt_listener(qc->target);
+ struct listener *l = qc->li;
/* Do not call this if quic-conn FD is uninitialized. */
BUG_ON(qc->fd < 0);
continue;
}
- quic_dgram_parse(new_dgram, qc, qc->target);
+ quic_dgram_parse(new_dgram, qc, l ? &l->obj_type :
+ (qc->conn ? &__objt_server(qc->conn->target)->obj_type : NULL));
/* A datagram must always be consumed after quic_parse_dgram(). */
BUG_ON(new_dgram->buf);
} while (ret > 0);
void qc_alloc_fd(struct quic_conn *qc, const struct sockaddr_storage *src,
const struct sockaddr_storage *dst)
{
- struct listener *l = __objt_listener(qc->target);
+ struct listener *l = qc->li;
struct bind_conf *bc = l->bind_conf;
struct proxy *p = bc->frontend;
int fd = -1;
void quic_accept_push_qc(struct quic_conn *qc)
{
struct quic_accept_queue *queue = &quic_accept_queues[tid];
- struct listener *l = __objt_listener(qc->target);
+ struct listener *l = qc->li;
struct li_per_thread *lthr = &l->per_thr[ti->ltid];
/* A connection must only be accepted once per instance. */
* handshake level CRYPTO data which are validated by the TLS stack.
*/
if (!qc_is_back(qc)) {
- if (__objt_listener(qc->target)->bind_conf->ssl_conf.early_data &&
+ if (qc->li->bind_conf->ssl_conf.early_data &&
(!qc->ael || !qc->ael->tls_ctx.rx.secret)) {
TRACE_PROTO("SSL handshake in progress",
QUIC_EV_CONN_IO_CB, qc, &state, &ssl_err);
qc->flags |= QUIC_FL_CONN_NEED_POST_HANDSHAKE_FRMS;
if (!qc_is_back(qc)) {
- struct listener *l = __objt_listener(qc->target);
+ struct listener *l = qc->li;
/* I/O callback switch */
qc->wait_event.tasklet->process = quic_conn_app_io_cb;
qc->state = QUIC_HS_ST_CONFIRMED;
ctx->qc = qc;
if (!qc_is_back(qc)) {
- struct bind_conf *bc = __objt_listener(qc->target)->bind_conf;
+ struct bind_conf *bc = qc->li->bind_conf;
if (qc_ssl_sess_init(qc, bc->initial_ctx, &ctx->ssl, NULL, 1) == -1)
goto err;
/* Permanently disable UDP GSO for future conns which use current listener/server instance. */
if (!qc_is_back(qc)) {
- struct listener *l = __objt_listener(qc->target);
+ struct listener *l = qc->li;
TRACE_ERROR("mark listener UDP GSO as unsupported", QUIC_EV_CONN_SPPKTS, qc, first_pkt);
HA_ATOMIC_OR(&l->flags, LI_F_UDP_GSO_NOTSUPP);
}
s = __objt_listener(conn->target)->bind_conf;
#ifdef USE_QUIC
else if (qc)
- s = __objt_listener(qc->target)->bind_conf;
+ s = qc->li->bind_conf;
#endif /* USE_QUIC */
if (!s) {
struct quic_conn *qc = SSL_get_ex_data(ssl, ssl_qc_app_data_index);
/* null if not a listener */
- li = objt_listener(qc->target);
+ li = qc->li;
}
#endif
ref = __objt_listener(conn->target)->bind_conf->keys_ref;
#ifdef USE_QUIC
else if (qc)
- ref = __objt_listener(qc->target)->bind_conf->keys_ref;
+ ref = qc->li->bind_conf->keys_ref;
#endif
if (!ref) {
else {
qc = SSL_get_ex_data(ssl, ssl_qc_app_data_index);
BUG_ON(!qc); /* Must never happen */
- bind_conf = __objt_listener(qc->target)->bind_conf;
+ bind_conf = qc->li->bind_conf;
ctx = qc->xprt_ctx;
}
#endif