diff options
Diffstat (limited to 'src/event/quic/ngx_event_quic_connid.c')
| -rw-r--r-- | src/event/quic/ngx_event_quic_connid.c | 80 |
1 files changed, 53 insertions, 27 deletions
diff --git a/src/event/quic/ngx_event_quic_connid.c b/src/event/quic/ngx_event_quic_connid.c index 8b9805b1e..503a71b4e 100644 --- a/src/event/quic/ngx_event_quic_connid.c +++ b/src/event/quic/ngx_event_quic_connid.c @@ -403,6 +403,10 @@ ngx_quic_handle_retire_connection_id_frame(ngx_connection_t *c, return NGX_OK; } + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, + "quic socket #%uL is retired", qsock->sid.seqnum); + + /* check if client is willing to retire sid we have in use */ if (qsock->sid.seqnum == qc->socket->sid.seqnum) { tmp = &qc->socket; @@ -410,46 +414,68 @@ ngx_quic_handle_retire_connection_id_frame(ngx_connection_t *c, tmp = &qc->backup; } else { - tmp = NULL; - } - - if (ngx_quic_create_sockets(c) != NGX_OK) { - return NGX_ERROR; - } - if (tmp) { - /* replace socket in use (active or backup) */ + ngx_quic_close_socket(c, qsock); - ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0, - "quic %s socket #%uL:%uL:%uL retired", - (*tmp) == qc->socket ? "active" : "backup", - (*tmp)->sid.seqnum, (*tmp)->cid->seqnum, - (*tmp)->path->seqnum); - - qsock = ngx_quic_get_unconnected_socket(c); - if (qsock == NULL) { + /* restore socket count up to a limit after deletion */ + if (ngx_quic_create_sockets(c) != NGX_OK) { return NGX_ERROR; } - path = (*tmp)->path; - cid = (*tmp)->cid; + return NGX_OK; + } - ngx_quic_connect(c, qsock, path, cid); + /* preserve path/cid from retired socket */ + path = qsock->path; + cid = qsock->cid; + /* ensure that closing_socket will not drop path and cid */ + path->refcnt++; + cid->refcnt++; - ngx_log_debug5(NGX_LOG_DEBUG_EVENT, c->log, 0, - "quic %s socket is now #%uL:%uL:%uL (%s)", - (*tmp) == qc->socket ? "active" : "backup", - qsock->sid.seqnum, qsock->cid->seqnum, - qsock->path->seqnum, - ngx_quic_path_state_str(qsock->path)); + ngx_quic_close_socket(c, qsock); - ngx_quic_close_socket(c, *tmp); /* no longer used */ + /* restore original values */ + path->refcnt--; + cid->refcnt--; - *tmp = qsock; + /* restore socket count up to a limit after deletion */ + if (ngx_quic_create_sockets(c) != NGX_OK) { + goto failed; } + qsock = ngx_quic_get_unconnected_socket(c); + if (qsock == NULL) { + qc->error = NGX_QUIC_ERR_CONNECTION_ID_LIMIT_ERROR; + qc->error_reason = "not enough server IDs"; + goto failed; + } + + ngx_quic_connect(c, qsock, path, cid); + + ngx_log_debug5(NGX_LOG_DEBUG_EVENT, c->log, 0, + "quic %s socket is now #%uL:%uL:%uL (%s)", + (*tmp) == qc->socket ? "active" : "backup", + qsock->sid.seqnum, qsock->cid->seqnum, + qsock->path->seqnum, + ngx_quic_path_state_str(qsock->path)); + + /* restore active/backup pointer in quic connection */ + *tmp = qsock; + return NGX_OK; + +failed: + + /* + * socket was closed, path and cid were preserved artifically + * to be reused, but it didn't happen, thus unref here + */ + + ngx_quic_unref_path(c, path); + ngx_quic_unref_client_id(c, cid); + + return NGX_ERROR; } |
