Added basic offset support in client CRYPTO frames.

The offset in client CRYPTO frames is tracked in c->quic->crypto_offset_in.
This means that CRYPTO frames with non-zero offset are now accepted making
possible to finish handshake with client certificates that exceed max packet
size (if no reordering happens).

The c->quic->crypto_offset field is renamed to crypto_offset_out to avoid
confusion with tracking of incoming CRYPTO stream.
This commit is contained in:
Vladimir Homutov 2020-04-07 15:50:38 +03:00
parent f540602ad2
commit c64a3939e4

View File

@ -69,7 +69,8 @@ struct ngx_quic_connection_s {
ngx_quic_namespace_t ns[NGX_QUIC_NAMESPACE_LAST];
ngx_quic_secrets_t keys[NGX_QUIC_ENCRYPTION_LAST];
ngx_quic_secrets_t next_key;
uint64_t crypto_offset[NGX_QUIC_ENCRYPTION_LAST];
uint64_t crypto_offset_out[NGX_QUIC_ENCRYPTION_LAST];
uint64_t crypto_offset_in[NGX_QUIC_ENCRYPTION_LAST];
ngx_ssl_t *ssl;
@ -334,11 +335,11 @@ ngx_quic_add_handshake_data(ngx_ssl_conn_t *ssl_conn,
frame->level = level;
frame->type = NGX_QUIC_FT_CRYPTO;
frame->u.crypto.offset += qc->crypto_offset[level];
frame->u.crypto.offset += qc->crypto_offset_out[level];
frame->u.crypto.len = len;
frame->u.crypto.data = frame->data;
qc->crypto_offset[level] += len;
qc->crypto_offset_out[level] += len;
ngx_sprintf(frame->info, "crypto, generated by SSL len=%ui level=%d", len, level);
@ -1368,14 +1369,21 @@ static ngx_int_t
ngx_quic_handle_crypto_frame(ngx_connection_t *c, ngx_quic_header_t *pkt,
ngx_quic_crypto_frame_t *f)
{
int sslerr;
ssize_t n;
ngx_ssl_conn_t *ssl_conn;
int sslerr;
ssize_t n;
uint64_t *curr_offset;
ngx_ssl_conn_t *ssl_conn;
ngx_quic_connection_t *qc;
if (f->offset != 0x0) {
qc = c->quic;
curr_offset = &qc->crypto_offset_in[pkt->level];
if (f->offset != *curr_offset) {
ngx_log_error(NGX_LOG_INFO, c->log, 0,
"crypto frame with non-zero offset");
// TODO: add support for crypto frames spanning packets
"crypto frame with unexpected offset");
/* TODO: support reordering/buffering of data */
return NGX_ERROR;
}
@ -1394,6 +1402,8 @@ ngx_quic_handle_crypto_frame(ngx_connection_t *c, ngx_quic_header_t *pkt,
return NGX_ERROR;
}
*curr_offset += f->len;
n = SSL_do_handshake(ssl_conn);
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_do_handshake: %d", n);