QUIC: allowed old DCID for initial packets until first ACK.

If a packet sent in response to an initial client packet was lost, then
successive client initial packets were dropped by nginx with the unexpected
dcid message logged.  This was because the new DCID generated by the server was
not available to the client.
This commit is contained in:
Roman Arutyunyan 2020-09-09 16:35:29 +03:00
parent f3bed9cd67
commit 2e24e3811b

View File

@ -1991,22 +1991,35 @@ ngx_quic_early_input(ngx_connection_t *c, ngx_quic_header_t *pkt)
static ngx_int_t static ngx_int_t
ngx_quic_check_peer(ngx_quic_connection_t *qc, ngx_quic_header_t *pkt) ngx_quic_check_peer(ngx_quic_connection_t *qc, ngx_quic_header_t *pkt)
{ {
ngx_str_t *dcid;
ngx_queue_t *q; ngx_queue_t *q;
ngx_quic_send_ctx_t *ctx;
ngx_quic_client_id_t *cid; ngx_quic_client_id_t *cid;
dcid = ngx_quic_pkt_zrtt(pkt->flags) ? &qc->odcid : &qc->dcid; ctx = ngx_quic_get_send_ctx(qc, ssl_encryption_initial);
if (pkt->dcid.len != dcid->len) { if (ngx_quic_pkt_zrtt(pkt->flags)
ngx_log_error(NGX_LOG_INFO, pkt->log, 0, "quic unexpected quic dcidl"); || (ngx_quic_pkt_in(pkt->flags) && ctx->largest_ack == (uint64_t) -1))
return NGX_ERROR; {
if (pkt->dcid.len == qc->odcid.len
&& ngx_memcmp(pkt->dcid.data, qc->odcid.data, qc->odcid.len) == 0)
{
goto found;
}
} }
if (ngx_memcmp(pkt->dcid.data, dcid->data, dcid->len) != 0) { if (!ngx_quic_pkt_zrtt(pkt->flags)) {
ngx_log_error(NGX_LOG_INFO, pkt->log, 0, "quic unexpected quic dcid"); if (pkt->dcid.len == qc->dcid.len
return NGX_ERROR; && ngx_memcmp(pkt->dcid.data, qc->dcid.data, qc->dcid.len) == 0)
{
goto found;
}
} }
ngx_log_error(NGX_LOG_INFO, pkt->log, 0, "quic unexpected quic dcid");
return NGX_ERROR;
found:
for (q = ngx_queue_head(&qc->client_ids); for (q = ngx_queue_head(&qc->client_ids);
q != ngx_queue_sentinel(&qc->client_ids); q != ngx_queue_sentinel(&qc->client_ids);
q = ngx_queue_next(q)) q = ngx_queue_next(q))