summaryrefslogtreecommitdiffhomepage
path: root/src/event/quic/ngx_event_quic_ssl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/event/quic/ngx_event_quic_ssl.c')
-rw-r--r--src/event/quic/ngx_event_quic_ssl.c111
1 files changed, 76 insertions, 35 deletions
diff --git a/src/event/quic/ngx_event_quic_ssl.c b/src/event/quic/ngx_event_quic_ssl.c
index a4e96d204..3ade0b5ac 100644
--- a/src/event/quic/ngx_event_quic_ssl.c
+++ b/src/event/quic/ngx_event_quic_ssl.c
@@ -33,6 +33,7 @@ static int ngx_quic_set_encryption_secrets(ngx_ssl_conn_t *ssl_conn,
static int ngx_quic_add_handshake_data(ngx_ssl_conn_t *ssl_conn,
enum ssl_encryption_level_t level, const uint8_t *data, size_t len);
static int ngx_quic_flush_flight(ngx_ssl_conn_t *ssl_conn);
+static ngx_int_t ngx_quic_crypto_input(ngx_connection_t *c, ngx_chain_t *data);
static SSL_QUIC_METHOD quic_method = {
@@ -149,14 +150,14 @@ static int
ngx_quic_add_handshake_data(ngx_ssl_conn_t *ssl_conn,
enum ssl_encryption_level_t level, const uint8_t *data, size_t len)
{
- u_char *p, *end;
- size_t client_params_len;
- const uint8_t *client_params;
- ngx_quic_tp_t ctp;
- ngx_quic_frame_t *frame;
- ngx_connection_t *c;
- ngx_quic_connection_t *qc;
- ngx_quic_frames_stream_t *fs;
+ u_char *p, *end;
+ size_t client_params_len;
+ const uint8_t *client_params;
+ ngx_quic_tp_t ctp;
+ ngx_quic_frame_t *frame;
+ ngx_connection_t *c;
+ ngx_quic_send_ctx_t *ctx;
+ ngx_quic_connection_t *qc;
c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn);
qc = ngx_quic_get_connection(c);
@@ -228,7 +229,7 @@ ngx_quic_add_handshake_data(ngx_ssl_conn_t *ssl_conn,
qc->client_tp_done = 1;
}
- fs = &qc->crypto[level];
+ ctx = ngx_quic_get_send_ctx(qc, level);
frame = ngx_quic_alloc_frame(c);
if (frame == NULL) {
@@ -242,10 +243,10 @@ ngx_quic_add_handshake_data(ngx_ssl_conn_t *ssl_conn,
frame->level = level;
frame->type = NGX_QUIC_FT_CRYPTO;
- frame->u.crypto.offset = fs->sent;
+ frame->u.crypto.offset = ctx->crypto_sent;
frame->u.crypto.length = len;
- fs->sent += len;
+ ctx->crypto_sent += len;
ngx_quic_queue_frame(qc, frame);
@@ -272,57 +273,97 @@ ngx_int_t
ngx_quic_handle_crypto_frame(ngx_connection_t *c, ngx_quic_header_t *pkt,
ngx_quic_frame_t *frame)
{
- uint64_t last;
- ngx_int_t rc;
- ngx_quic_send_ctx_t *ctx;
- ngx_quic_connection_t *qc;
- ngx_quic_crypto_frame_t *f;
- ngx_quic_frames_stream_t *fs;
+ size_t len;
+ uint64_t last;
+ ngx_buf_t *b;
+ ngx_chain_t *cl, **ll;
+ ngx_quic_send_ctx_t *ctx;
+ ngx_quic_connection_t *qc;
+ ngx_quic_crypto_frame_t *f;
qc = ngx_quic_get_connection(c);
- fs = &qc->crypto[pkt->level];
+ ctx = ngx_quic_get_send_ctx(qc, pkt->level);
f = &frame->u.crypto;
/* no overflow since both values are 62-bit */
last = f->offset + f->length;
- if (last > fs->received && last - fs->received > NGX_QUIC_MAX_BUFFERED) {
+ if (last > ctx->crypto_received + NGX_QUIC_MAX_BUFFERED) {
qc->error = NGX_QUIC_ERR_CRYPTO_BUFFER_EXCEEDED;
return NGX_ERROR;
}
- rc = ngx_quic_handle_ordered_frame(c, fs, frame, ngx_quic_crypto_input,
- NULL);
- if (rc != NGX_DECLINED) {
- return rc;
+ if (last <= ctx->crypto_received) {
+ if (pkt->level == ssl_encryption_initial) {
+ /* speeding up handshake completion */
+
+ if (!ngx_queue_empty(&ctx->sent)) {
+ ngx_quic_resend_frames(c, ctx);
+
+ ctx = ngx_quic_get_send_ctx(qc, ssl_encryption_handshake);
+ while (!ngx_queue_empty(&ctx->sent)) {
+ ngx_quic_resend_frames(c, ctx);
+ }
+ }
+ }
+
+ return NGX_OK;
}
- /* speeding up handshake completion */
+ if (f->offset > ctx->crypto_received) {
+ return ngx_quic_order_bufs(c, &ctx->crypto, frame->data,
+ f->offset - ctx->crypto_received);
+ }
- if (pkt->level == ssl_encryption_initial) {
- ctx = ngx_quic_get_send_ctx(qc, pkt->level);
+ ngx_quic_trim_bufs(frame->data, ctx->crypto_received - f->offset);
- if (!ngx_queue_empty(&ctx->sent)) {
- ngx_quic_resend_frames(c, ctx);
+ if (ngx_quic_crypto_input(c, frame->data) != NGX_OK) {
+ return NGX_ERROR;
+ }
- ctx = ngx_quic_get_send_ctx(qc, ssl_encryption_handshake);
- while (!ngx_queue_empty(&ctx->sent)) {
- ngx_quic_resend_frames(c, ctx);
- }
+ ngx_quic_trim_bufs(ctx->crypto, last - ctx->crypto_received);
+ ctx->crypto_received = last;
+
+ cl = ctx->crypto;
+ ll = &cl;
+ len = 0;
+
+ while (*ll) {
+ b = (*ll)->buf;
+
+ if (b->sync && b->pos != b->last) {
+ /* hole */
+ break;
+ }
+
+ len += b->last - b->pos;
+ ll = &(*ll)->next;
+ }
+
+ ctx->crypto_received += len;
+ ctx->crypto = *ll;
+ *ll = NULL;
+
+ if (cl) {
+ if (ngx_quic_crypto_input(c, cl) != NGX_OK) {
+ return NGX_ERROR;
}
+
+ ngx_quic_free_bufs(c, cl);
}
return NGX_OK;
}
-ngx_int_t
-ngx_quic_crypto_input(ngx_connection_t *c, ngx_quic_frame_t *frame, void *data)
+static ngx_int_t
+ngx_quic_crypto_input(ngx_connection_t *c, ngx_chain_t *data)
{
int n, sslerr;
ngx_buf_t *b;
ngx_chain_t *cl;
ngx_ssl_conn_t *ssl_conn;
+ ngx_quic_frame_t *frame;
ngx_quic_connection_t *qc;
qc = ngx_quic_get_connection(c);
@@ -334,7 +375,7 @@ ngx_quic_crypto_input(ngx_connection_t *c, ngx_quic_frame_t *frame, void *data)
(int) SSL_quic_read_level(ssl_conn),
(int) SSL_quic_write_level(ssl_conn));
- for (cl = frame->data; cl; cl = cl->next) {
+ for (cl = data; cl; cl = cl->next) {
b = cl->buf;
if (!SSL_provide_quic_data(ssl_conn, SSL_quic_read_level(ssl_conn),