dst->len = src->len;
}
-/* Concatenate the port and address of <saddr> to <cid> QUIC connection ID.
+/* Concatenate the port and address of <saddr> to <cid> QUIC connection ID. The
+ * <addrlen> field of <cid> will be updated with the size of the concatenated
+ * address.
+ *
* Returns the number of bytes concatenated to <cid>.
*/
-static inline size_t quic_cid_saddr_cat(struct quic_cid *cid, struct sockaddr_storage *saddr)
+static inline size_t quic_cid_saddr_cat(struct quic_cid *cid,
+ struct sockaddr_storage *saddr)
{
void *port, *addr;
size_t port_len, addr_len;
+ cid->addrlen = 0;
+
if (saddr->ss_family == AF_INET6) {
port = &((struct sockaddr_in6 *)saddr)->sin6_port;
addr = &((struct sockaddr_in6 *)saddr)->sin6_addr;
port_len = sizeof ((struct sockaddr_in *)saddr)->sin_port;
addr_len = sizeof ((struct sockaddr_in *)saddr)->sin_addr;
}
+
memcpy(cid->data + cid->len, port, port_len);
- cid->len += port_len;
- memcpy(cid->data + cid->len, addr, addr_len);
- cid->len += addr_len;
+ cid->addrlen += port_len;
+ memcpy(cid->data + cid->len + port_len, addr, addr_len);
+ cid->addrlen += addr_len;
return port_len + addr_len;
}
* Returns 1 if succeeded, 0 if not.
*/
static struct quic_conn *qc_new_conn(unsigned int version, int ipv4,
- unsigned char *dcid, size_t dcid_len,
+ unsigned char *dcid, size_t dcid_len, size_t dcid_addr_len,
unsigned char *scid, size_t scid_len, int server, void *owner)
{
int i;
l = owner;
HA_ATOMIC_STORE(&qc->state, QUIC_HS_ST_SERVER_INITIAL);
- /* Copy the initial DCID. */
+ /* Copy the initial DCID with the address. */
qc->odcid.len = dcid_len;
- if (qc->odcid.len)
- memcpy(qc->odcid.data, dcid, dcid_len);
+ qc->odcid.addrlen = dcid_addr_len;
+ memcpy(qc->odcid.data, dcid, dcid_len + dcid_addr_len);
/* copy the packet SCID to reuse it as DCID for sending */
if (scid_len)
unsigned char *beg;
struct quic_conn *qc;
struct eb_root *cids;
+ unsigned char dcid_lookup_len;
struct ebmb_node *node;
struct listener *l;
struct ssl_sock_ctx *conn_ctx;
/* Header form */
qc_parse_hd_form(pkt, *(*buf)++, &long_header);
if (long_header) {
- unsigned char dcid_len;
-
if (!quic_packet_read_long_header(buf, end, pkt)) {
TRACE_PROTO("Packet dropped", QUIC_EV_CONN_LPKT);
goto err;
goto out;
}
- dcid_len = pkt->dcid.len;
/* For Initial packets, and for servers (QUIC clients connections),
* there is no Initial connection IDs storage.
*/
*/
quic_cid_saddr_cat(&pkt->dcid, saddr);
cids = &l->rx.odcids;
+ dcid_lookup_len = pkt->dcid.len + pkt->dcid.addrlen;
if (pkt->type == QUIC_PACKET_TYPE_INITIAL) {
if (!quic_dec_int(&token_len, (const unsigned char **)buf, end) ||
}
cids = &l->rx.cids;
+ dcid_lookup_len = pkt->dcid.len;
}
/* Only packets packets with long headers and not RETRY or VERSION as type
HA_RWLOCK_RDLOCK(OTHER_LOCK, &l->rx.cids_lock);
- node = ebmb_lookup(cids, pkt->dcid.data, pkt->dcid.len);
+ node = ebmb_lookup(cids, pkt->dcid.data, dcid_lookup_len);
if (!node && pkt->type == QUIC_PACKET_TYPE_INITIAL &&
- dcid_len == QUIC_HAP_CID_LEN && cids == &l->rx.odcids) {
+ pkt->dcid.len == QUIC_HAP_CID_LEN && cids == &l->rx.odcids) {
/* Switch to the definitive tree ->cids containing the final CIDs. */
- node = ebmb_lookup(&l->rx.cids, pkt->dcid.data, dcid_len);
+ node = ebmb_lookup(&l->rx.cids, pkt->dcid.data, pkt->dcid.len);
if (node) {
/* If found, signal this with NULL as special value for <cids>. */
- pkt->dcid.len = dcid_len;
cids = NULL;
}
}
}
pkt->saddr = *saddr;
- /* Note that here, odcid_len equals to pkt->dcid.len minus the length
- * of <saddr>.
- */
- pkt->odcid_len = dcid_len;
ipv4 = saddr->ss_family == AF_INET;
- qc = qc_new_conn(pkt->version, ipv4, pkt->dcid.data, pkt->dcid.len,
+ qc = qc_new_conn(pkt->version, ipv4,
+ pkt->dcid.data, pkt->dcid.len, pkt->dcid.addrlen,
pkt->scid.data, pkt->scid.len, 1, l);
if (qc == NULL)
goto err;
/* Copy the transport parameters. */
qc->rx.params = l->bind_conf->quic_params;
/* Copy original_destination_connection_id transport parameter. */
- memcpy(odcid->data, &pkt->dcid, pkt->odcid_len);
- odcid->len = pkt->odcid_len;
+ memcpy(odcid->data, &pkt->dcid.data, pkt->dcid.len);
+ odcid->len = pkt->dcid.len;
/* Copy the initial source connection ID. */
quic_cid_cpy(&qc->rx.params.initial_source_connection_id, &qc->scid);
qc->enc_params_len =
salt_len = sizeof initial_salt_draft_29;
}
if (!qc_new_isecs(qc, salt, salt_len,
- pkt->dcid.data, pkt->odcid_len, 1)) {
+ pkt->dcid.data, pkt->dcid.len, 1)) {
TRACE_PROTO("Packet dropped", QUIC_EV_CONN_LPKT, qc->conn);
goto err;
}
HA_RWLOCK_WRLOCK(QUIC_LOCK, &l->rx.cids_lock);
/* Insert the DCID the QUIC client has chosen (only for listeners) */
- n = ebmb_insert(&l->rx.odcids, &qc->odcid_node, qc->odcid.len);
+ n = ebmb_insert(&l->rx.odcids, &qc->odcid_node,
+ qc->odcid.len + qc->odcid.addrlen);
HA_ATOMIC_OR(&qc->flags, QUIC_FL_CONN_ODCID_NODE_TO_DELETE);
HA_RWLOCK_WRUNLOCK(QUIC_LOCK, &l->rx.cids_lock);
ipv4 = conn->dst->ss_family == AF_INET;
qc = qc_new_conn(QUIC_PROTOCOL_VERSION_DRAFT_28, ipv4,
- dcid, sizeof dcid, NULL, 0, 0, srv);
+ dcid, sizeof dcid, 0, NULL, 0, 0, srv);
if (qc == NULL)
goto err;