diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/event/quic/ngx_event_quic_connid.c | 29 | ||||
-rw-r--r-- | src/event/quic/ngx_event_quic_connid.h | 2 | ||||
-rw-r--r-- | src/event/quic/ngx_event_quic_migration.c | 19 |
3 files changed, 44 insertions, 6 deletions
diff --git a/src/event/quic/ngx_event_quic_connid.c b/src/event/quic/ngx_event_quic_connid.c index a30e7ef35..4dbb2bbd6 100644 --- a/src/event/quic/ngx_event_quic_connid.c +++ b/src/event/quic/ngx_event_quic_connid.c @@ -325,6 +325,35 @@ ngx_quic_next_client_id(ngx_connection_t *c) } +ngx_quic_client_id_t * +ngx_quic_used_client_id(ngx_connection_t *c, ngx_quic_path_t *path) +{ + ngx_queue_t *q; + ngx_quic_socket_t *qsock; + ngx_quic_connection_t *qc; + + qc = ngx_quic_get_connection(c); + + /* best guess: cid used by active path is good for us */ + if (qc->socket->path == path) { + return qc->socket->cid; + } + + for (q = ngx_queue_head(&qc->sockets); + q != ngx_queue_sentinel(&qc->sockets); + q = ngx_queue_next(q)) + { + qsock = ngx_queue_data(q, ngx_quic_socket_t, queue); + + if (qsock->path && qsock->path == path) { + return qsock->cid; + } + } + + return NULL; +} + + ngx_int_t ngx_quic_handle_retire_connection_id_frame(ngx_connection_t *c, ngx_quic_header_t *pkt, ngx_quic_retire_cid_frame_t *f) diff --git a/src/event/quic/ngx_event_quic_connid.h b/src/event/quic/ngx_event_quic_connid.h index fc7850a9c..a0552e9dd 100644 --- a/src/event/quic/ngx_event_quic_connid.h +++ b/src/event/quic/ngx_event_quic_connid.h @@ -23,6 +23,8 @@ ngx_int_t ngx_quic_create_server_id(ngx_connection_t *c, u_char *id); ngx_quic_client_id_t *ngx_quic_create_client_id(ngx_connection_t *c, ngx_str_t *id, uint64_t seqnum, u_char *token); ngx_quic_client_id_t *ngx_quic_next_client_id(ngx_connection_t *c); +ngx_quic_client_id_t *ngx_quic_used_client_id(ngx_connection_t *c, + ngx_quic_path_t *path); void ngx_quic_unref_client_id(ngx_connection_t *c, ngx_quic_client_id_t *cid); #endif /* _NGX_EVENT_QUIC_CONNID_H_INCLUDED_ */ diff --git a/src/event/quic/ngx_event_quic_migration.c b/src/event/quic/ngx_event_quic_migration.c index f1c923f83..74dc0113b 100644 --- a/src/event/quic/ngx_event_quic_migration.c +++ b/src/event/quic/ngx_event_quic_migration.c @@ -348,16 +348,23 @@ ngx_quic_update_paths(ngx_connection_t *c, ngx_quic_header_t *pkt) } } + /* prefer unused client IDs if available */ cid = ngx_quic_next_client_id(c); if (cid == NULL) { - qc = ngx_quic_get_connection(c); - qc->error = NGX_QUIC_ERR_CONNECTION_ID_LIMIT_ERROR; - qc->error_reason = "no available client ids for new path"; - ngx_log_error(NGX_LOG_ERR, c->log, 0, - "no available client ids for new path"); + /* try to reuse connection ID used on the same path */ + cid = ngx_quic_used_client_id(c, path); + if (cid == NULL) { - return NGX_ERROR; + qc = ngx_quic_get_connection(c); + qc->error = NGX_QUIC_ERR_CONNECTION_ID_LIMIT_ERROR; + qc->error_reason = "no available client ids for new path"; + + ngx_log_error(NGX_LOG_ERR, c->log, 0, + "no available client ids for new path"); + + return NGX_ERROR; + } } ngx_quic_connect(c, qsock, path, cid); |