easy: reset errorbuf on eyeballing success
No binary (build failed)
—
(log yok)
| @@ -58,6 +58,10 @@ only send 800. | |
| The percentage of send() calls that should be answered with EAGAIN at random. | |
| QUIC only. | |
| + | ## `CURL_DBG_SOCK_FAIL_IPV6` |
| + | |
| + | Fail opening of sockets for the IPv6 address family. |
| + | |
| ## `CURL_DEBUG` | |
| Trace logging behavior as an alternative to calling curl_global_trace(3). | |
| @@ -222,6 +222,8 @@ static CURLcode baller_connected(struct Curl_cfilter *cf, | |
| /* install the winning filter below this one. */ | |
| cf->next = winner->cf; | |
| winner->cf = NULL; | |
| + | /* whatever errors where reported by ballers, clear our errorbuf */ |
| + | Curl_reset_fail(data); |
| #ifdef USE_NGHTTP2 | |
| { | |
| @@ -427,6 +427,10 @@ evaluate: | |
| addr = cf_ai_iter_next(&bs->addr_iter); | |
| ai_family = bs->addr_iter.ai_family; | |
| } | |
| + | /* We are (re-)starting attempts. We are not interested in |
| + | * keeping old failure information. The new attempt will either |
| + | * succeed or persist new failure. */ |
| + | Curl_reset_fail(data); |
| if(addr) { /* try another address */ | |
| result = cf_ip_attempt_new(&a, cf, data, addr, ai_family, | |
| @@ -793,6 +797,8 @@ static CURLcode cf_ip_happy_connect(struct Curl_cfilter *cf, | |
| ctx->ballers.winner->cf = NULL; | |
| cf_ip_happy_ctx_clear(cf, data); | |
| Curl_expire_done(data, EXPIRE_HAPPY_EYEBALLS); | |
| + | /* whatever errors where reported by ballers, clear our errorbuf */ |
| + | Curl_reset_fail(data); |
| if(cf->conn->scheme->protocol & PROTO_FAMILY_SSH) | |
| Curl_pgrsTime(data, TIMER_APPCONNECT); /* we are connected already */ | |
| @@ -332,6 +332,12 @@ static CURLcode socket_open(struct Curl_easy *data, | |
| } | |
| else { | |
| /* opensocket callback not set, so simply create the socket now */ | |
| + | #ifdef DEBUGBUILD |
| + | if((addr->family == AF_INET6) && getenv("CURL_DBG_SOCK_FAIL_IPV6")) { |
| + | failf(data, "CURL_DBG_SOCK_FAIL_IPV6: failed to open socket"); |
| + | return CURLE_COULDNT_CONNECT; |
| + | } |
| + | #endif |
| *sockfd = CURL_SOCKET(addr->family, addr->socktype, addr->protocol); | |
| if((*sockfd == CURL_SOCKET_BAD) && (SOCKERRNO == SOCKENOMEM)) | |
| return CURLE_OUT_OF_MEMORY; | |
| @@ -194,6 +194,13 @@ void Curl_failf(struct Curl_easy *data, const char *fmt, ...) | |
| } | |
| } | |
| + | void Curl_reset_fail(struct Curl_easy *data) |
| + | { |
| + | if(data->set.errorbuffer) |
| + | data->set.errorbuffer[0] = 0; |
| + | data->state.errorbuf = FALSE; |
| + | } |
| + | |
| #ifdef CURLVERBOSE | |
| struct curl_trc_feat Curl_trc_feat_multi = { | |
| "MULTI", | |
| @@ -61,6 +61,11 @@ void Curl_failf(struct Curl_easy *data, | |
| #define failf Curl_failf | |
| + | /* In case failf() reported into the errorbuf, clear it again. |
| + | * This is used to clear information from happy eyeballing attempts |
| + | * when ultimately a successful attempt was made. */ |
| + | void Curl_reset_fail(struct Curl_easy *data); |
| + | |
| #define CURL_LOG_LVL_NONE 0 | |
| #define CURL_LOG_LVL_INFO 1 | |
| @@ -25,6 +25,7 @@ | |
| ########################################################################### | |
| # | |
| import logging | |
| + | import os |
| import pytest | |
| from testenv import Env, CurlClient | |
| @@ -123,3 +124,19 @@ class TestErrors: | |
| else: | |
| r.check_exit_code(0) | |
| r.check_response(http_status=200, count=count) | |
| + | |
| + | # Make a connect with a fail for '::1' and wrong certificate for '127.0.0.1' |
| + | # The error message reported needs to be from the certificate. |
| + | # verifies issue #20608 |
| + | @pytest.mark.parametrize("proto", Env.http_h1_h2_protos()) |
| + | def test_05_05_failed_peer(self, env: Env, proto, httpd, nghttpx): |
| + | domain = f'invalid.{env.tld}' |
| + | url = f'https://{domain}:{env.port_for(proto)}/' |
| + | run_env = os.environ.copy() |
| + | run_env['CURL_DBG_SOCK_FAIL_IPV6'] = '1' |
| + | curl = CurlClient(env=env, run_env=run_env) |
| + | r = curl.http_download(urls=[url], alpn_proto=proto, extra_args=[ |
| + | '--resolve', f'{domain}:{env.port_for(proto)}:::1,127.0.0.1', |
| + | ]) |
| + | assert r.exit_code == 60, f'{r}' |
| + | assert r.stats[0]['errormsg'] != 'CURL_DBG_SOCK_FAIL_IPV6: failed to open socket' |