mirror of
https://github.com/curl/curl.git
synced 2026-08-25 02:43:33 +03:00
ngtcp2: check error code on connect failure
Access the error codes of ngtcp2 when a connect attempt failes. Trace the information for analysis. Treat errors as permanent failure by default, trigger retrying only when the server refused without indicating an error. Closes #18521
This commit is contained in:
parent
b178d58266
commit
115fe808f2
2 changed files with 29 additions and 8 deletions
|
|
@ -2578,11 +2578,31 @@ static CURLcode cf_ngtcp2_connect(struct Curl_cfilter *cf,
|
|||
out:
|
||||
if(result == CURLE_RECV_ERROR && ctx->qconn &&
|
||||
ngtcp2_conn_in_draining_period(ctx->qconn)) {
|
||||
/* When a QUIC server instance is shutting down, it may send us a
|
||||
* CONNECTION_CLOSE right away. Our connection then enters the DRAINING
|
||||
* state. The CONNECT may work in the near future again. Indicate
|
||||
* that as a "weird" reply. */
|
||||
result = CURLE_WEIRD_SERVER_REPLY;
|
||||
const ngtcp2_ccerr *cerr = ngtcp2_conn_get_ccerr(ctx->qconn);
|
||||
|
||||
result = CURLE_COULDNT_CONNECT;
|
||||
if(cerr) {
|
||||
CURL_TRC_CF(data, cf, "connect error, type=%d, code=%"
|
||||
FMT_PRIu64,
|
||||
cerr->type, (curl_uint64_t)cerr->error_code);
|
||||
switch(cerr->type) {
|
||||
case NGTCP2_CCERR_TYPE_VERSION_NEGOTIATION:
|
||||
CURL_TRC_CF(data, cf, "error in version negotiation");
|
||||
break;
|
||||
default:
|
||||
if(cerr->error_code >= NGTCP2_CRYPTO_ERROR) {
|
||||
CURL_TRC_CF(data, cf, "crypto error, tls alert=%u",
|
||||
(unsigned int)(cerr->error_code & 0xffu));
|
||||
}
|
||||
else if(cerr->error_code == NGTCP2_CONNECTION_REFUSED) {
|
||||
CURL_TRC_CF(data, cf, "connection refused by server");
|
||||
/* When a QUIC server instance is shutting down, it may send us a
|
||||
* CONNECTION_CLOSE with this code right away. We want
|
||||
* to keep on trying in this case. */
|
||||
result = CURLE_WEIRD_SERVER_REPLY;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
||||
|
|
|
|||
|
|
@ -124,15 +124,16 @@ class Nghttpx:
|
|||
running = self._process
|
||||
self._process = None
|
||||
os.kill(running.pid, signal.SIGQUIT)
|
||||
end_wait = datetime.now() + timeout
|
||||
end_wait = datetime.now() + timedelta(seconds=5)
|
||||
if not self.start(wait_live=False):
|
||||
self._process = running
|
||||
return False
|
||||
while datetime.now() < end_wait:
|
||||
try:
|
||||
log.debug(f'waiting for nghttpx({running.pid}) to exit.')
|
||||
running.wait(2)
|
||||
running.wait(1)
|
||||
log.debug(f'nghttpx({running.pid}) terminated -> {running.returncode}')
|
||||
running = None
|
||||
break
|
||||
except subprocess.TimeoutExpired:
|
||||
log.warning(f'nghttpx({running.pid}), not shut down yet.')
|
||||
|
|
@ -142,7 +143,7 @@ class Nghttpx:
|
|||
os.kill(running.pid, signal.SIGKILL)
|
||||
running.terminate()
|
||||
running.wait(1)
|
||||
return self.wait_live(timeout=timedelta(seconds=Env.SERVER_TIMEOUT))
|
||||
return self.wait_live(timeout=timeout)
|
||||
return False
|
||||
|
||||
def wait_dead(self, timeout: timedelta):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue