hostip: make more functions return CURLcode
No binary (build failed)
—
(log yok)
| @@ -718,25 +718,18 @@ static void async_ares_rr_done(void *user_data, ares_status_t status, | |
| /* | |
| * Curl_async_getaddrinfo() - when using ares | |
| * | |
| - | * Returns name information about the given hostname and port number. If |
| - | * successful, the 'hostent' is returned and the fourth argument will point to |
| - | * memory we need to free after use. That memory *MUST* be freed with |
| - | * Curl_freeaddrinfo(), nothing else. |
| + | * Starts a name resolve for the given hostname and port number. |
| */ | |
| - | struct Curl_addrinfo *Curl_async_getaddrinfo(struct Curl_easy *data, |
| - | const char *hostname, |
| - | int port, |
| - | int ip_version, |
| - | int *waitp) |
| + | CURLcode Curl_async_getaddrinfo(struct Curl_easy *data, const char *hostname, |
| + | int port, int ip_version) |
| { | |
| struct async_ares_ctx *ares = &data->state.async.ares; | |
| #ifdef USE_HTTPSRR | |
| char *rrname = NULL; | |
| #endif | |
| - | *waitp = 0; /* default to synchronous response */ |
| if(async_ares_init_lazy(data)) | |
| - | return NULL; |
| + | return CURLE_FAILED_INIT; |
| data->state.async.done = FALSE; /* not done */ | |
| data->state.async.dns = NULL; /* clear */ | |
| @@ -744,12 +737,12 @@ struct Curl_addrinfo *Curl_async_getaddrinfo(struct Curl_easy *data, | |
| data->state.async.ip_version = ip_version; | |
| data->state.async.hostname = strdup(hostname); | |
| if(!data->state.async.hostname) | |
| - | return NULL; |
| + | return CURLE_OUT_OF_MEMORY; |
| #ifdef USE_HTTPSRR | |
| if(port != 443) { | |
| rrname = curl_maprintf("_%d_.https.%s", port, hostname); | |
| if(!rrname) | |
| - | return NULL; |
| + | return CURLE_OUT_OF_MEMORY; |
| } | |
| #endif | |
| @@ -836,9 +829,8 @@ struct Curl_addrinfo *Curl_async_getaddrinfo(struct Curl_easy *data, | |
| async_ares_rr_done, data, NULL); | |
| } | |
| #endif | |
| - | *waitp = 1; /* expect asynchronous response */ |
| - | return NULL; /* no struct yet */ |
| + | return CURLE_OK; |
| } | |
| /* Set what DNS server are is to use. This is called in 2 situations: | |
| @@ -755,15 +755,11 @@ struct Curl_addrinfo *Curl_async_getaddrinfo(struct Curl_easy *data, | |
| /* | |
| * Curl_async_getaddrinfo() - for getaddrinfo | |
| */ | |
| - | struct Curl_addrinfo *Curl_async_getaddrinfo(struct Curl_easy *data, |
| - | const char *hostname, |
| - | int port, |
| - | int ip_version, |
| - | int *waitp) |
| + | CURLcode Curl_async_getaddrinfo(struct Curl_easy *data, const char *hostname, |
| + | int port, int ip_version) |
| { | |
| struct addrinfo hints; | |
| int pf = PF_INET; | |
| - | *waitp = 0; /* default to synchronous response */ |
| CURL_TRC_DNS(data, "init threaded resolve of %s:%d", hostname, port); | |
| #ifdef CURLRES_IPV6 | |
| @@ -785,14 +781,11 @@ struct Curl_addrinfo *Curl_async_getaddrinfo(struct Curl_easy *data, | |
| SOCK_STREAM : SOCK_DGRAM; | |
| /* fire up a new resolver thread! */ | |
| - | if(async_thrdd_init(data, hostname, port, ip_version, &hints)) { |
| - | *waitp = 1; /* expect asynchronous response */ |
| - | return NULL; |
| - | } |
| + | if(async_thrdd_init(data, hostname, port, ip_version, &hints)) |
| + | return CURLE_OK; |
| failf(data, "getaddrinfo() thread failed to start"); | |
| - | return NULL; |
| - | |
| + | return CURLE_FAILED_INIT; |
| } | |
| #endif /* !HAVE_GETADDRINFO */ | |
| @@ -118,11 +118,8 @@ CURLcode Curl_async_await(struct Curl_easy *data, | |
| * Each resolver backend must of course make sure to return data in the | |
| * correct format to comply with this. | |
| */ | |
| - | struct Curl_addrinfo *Curl_async_getaddrinfo(struct Curl_easy *data, |
| - | const char *hostname, |
| - | int port, |
| - | int ip_version, |
| - | int *waitp); |
| + | CURLcode Curl_async_getaddrinfo(struct Curl_easy *data, const char *hostname, |
| + | int port, int ip_version); |
| #ifdef USE_ARES | |
| /* common functions for c-ares and threaded resolver with HTTPSRR */ | |
| @@ -347,7 +347,7 @@ Curl_he2ai(const struct hostent *he, int port) | |
| #endif | |
| /* | |
| - | * Curl_ip2addr() |
| + | * ip2addr() |
| * | |
| * This function takes an Internet address, in binary form, as input parameter | |
| * along with its address family and the string version of the address, and it | |
| @@ -355,8 +355,9 @@ Curl_he2ai(const struct hostent *he, int port) | |
| * given address/host | |
| */ | |
| - | struct Curl_addrinfo * |
| - | Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port) |
| + | static CURLcode |
| + | ip2addr(struct Curl_addrinfo **addrp, |
| + | int af, const void *inaddr, const char *hostname, int port) |
| { | |
| struct Curl_addrinfo *ai; | |
| size_t addrsize; | |
| @@ -369,6 +370,7 @@ Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port) | |
| DEBUGASSERT(inaddr && hostname); | |
| namelen = strlen(hostname) + 1; | |
| + | *addrp = NULL; |
| if(af == AF_INET) | |
| addrsize = sizeof(struct sockaddr_in); | |
| @@ -377,12 +379,12 @@ Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port) | |
| addrsize = sizeof(struct sockaddr_in6); | |
| #endif | |
| else | |
| - | return NULL; |
| + | return CURLE_BAD_FUNCTION_ARGUMENT; |
| /* allocate memory to hold the struct, the address and the name */ | |
| ai = calloc(1, sizeof(struct Curl_addrinfo) + addrsize + namelen); | |
| if(!ai) | |
| - | return NULL; |
| + | return CURLE_OUT_OF_MEMORY; |
| /* put the address after the struct */ | |
| ai->ai_addr = (void *)((char *)ai + sizeof(struct Curl_addrinfo)); | |
| /* then put the name after the address */ | |
| @@ -412,29 +414,46 @@ Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port) | |
| break; | |
| #endif | |
| } | |
| - | |
| - | return ai; |
| + | *addrp = ai; |
| + | return CURLE_OK; |
| } | |
| /* | |
| * Given an IPv4 or IPv6 dotted string address, this converts it to a proper | |
| * allocated Curl_addrinfo struct and returns it. | |
| */ | |
| - | struct Curl_addrinfo *Curl_str2addr(char *address, int port) |
| + | CURLcode Curl_str2addr(const char *address, int port, |
| + | struct Curl_addrinfo **addrp) |
| { | |
| struct in_addr in; | |
| if(curlx_inet_pton(AF_INET, address, &in) > 0) | |
| /* This is a dotted IP address 123.123.123.123-style */ | |
| - | return Curl_ip2addr(AF_INET, &in, address, port); |
| + | return ip2addr(addrp, AF_INET, &in, address, port); |
| + | #ifdef USE_IPV6 |
| + | { |
| + | struct in6_addr in6; |
| + | if(curlx_inet_pton(AF_INET6, address, &in6) > 0) |
| + | /* This is a dotted IPv6 address ::1-style */ |
| + | return ip2addr(addrp, AF_INET6, &in6, address, port); |
| + | } |
| + | #endif |
| + | return CURLE_BAD_FUNCTION_ARGUMENT; /* bad input format */ |
| + | } |
| + | |
| + | bool Curl_is_ipaddr(const char *address) |
| + | { |
| + | struct in_addr in; |
| + | if(curlx_inet_pton(AF_INET, address, &in) > 0) |
| + | return TRUE; |
| #ifdef USE_IPV6 | |
| { | |
| struct in6_addr in6; | |
| if(curlx_inet_pton(AF_INET6, address, &in6) > 0) | |
| /* This is a dotted IPv6 address ::1-style */ | |
| - | return Curl_ip2addr(AF_INET6, &in6, address, port); |
| + | return TRUE; |
| } | |
| #endif | |
| - | return NULL; /* bad input format */ |
| + | return FALSE; |
| } | |
| #ifdef USE_UNIX_SOCKETS | |
| @@ -76,10 +76,8 @@ struct Curl_addrinfo * | |
| Curl_he2ai(const struct hostent *he, int port); | |
| #endif | |
| - | struct Curl_addrinfo * |
| - | Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port); |
| - | |
| - | struct Curl_addrinfo *Curl_str2addr(char *dotted, int port); |
| + | bool Curl_is_ipaddr(const char *address); |
| + | CURLcode Curl_str2addr(const char *dotted, int port, struct Curl_addrinfo **); |
| #ifdef USE_UNIX_SOCKETS | |
| struct Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath, | |
| @@ -441,15 +441,12 @@ error: | |
| } | |
| /* | |
| - | * Curl_doh() resolves a name using DoH. It resolves a name and returns a |
| - | * 'Curl_addrinfo *' with the address information. |
| + | * Curl_doh() starts a name resolve using DoH. It resolves a name and returns |
| + | * a 'Curl_addrinfo *' with the address information. |
| */ | |
| - | struct Curl_addrinfo *Curl_doh(struct Curl_easy *data, |
| - | const char *hostname, |
| - | int port, |
| - | int ip_version, |
| - | int *waitp) |
| + | CURLcode Curl_doh(struct Curl_easy *data, const char *hostname, |
| + | int port, int ip_version) |
| { | |
| CURLcode result = CURLE_OK; | |
| struct doh_probes *dohp = NULL; | |
| @@ -467,12 +464,12 @@ struct Curl_addrinfo *Curl_doh(struct Curl_easy *data, | |
| data->state.async.ip_version = ip_version; | |
| data->state.async.hostname = strdup(hostname); | |
| if(!data->state.async.hostname) | |
| - | return NULL; |
| + | return CURLE_OUT_OF_MEMORY; |
| /* start clean, consider allocating this struct on demand */ | |
| data->state.async.doh = dohp = calloc(1, sizeof(struct doh_probes)); | |
| if(!dohp) | |
| - | return NULL; |
| + | return CURLE_OUT_OF_MEMORY; |
| for(i = 0; i < DOH_SLOT_COUNT; ++i) { | |
| dohp->probe_resp[i].probe_mid = UINT_MAX; | |
| @@ -527,12 +524,11 @@ struct Curl_addrinfo *Curl_doh(struct Curl_easy *data, | |
| dohp->pending++; | |
| } | |
| #endif | |
| - | *waitp = TRUE; /* this never returns synchronously */ |
| - | return NULL; |
| + | return CURLE_OK; |
| error: | |
| Curl_doh_cleanup(data); | |
| - | return NULL; |
| + | return result; |
| } | |
| static DOHcode doh_skipqname(const unsigned char *doh, size_t dohlen, | |
| @@ -1300,6 +1296,8 @@ CURLcode Curl_doh_is_resolved(struct Curl_easy *data, | |
| result = Curl_dnscache_add(data, dns); | |
| *dnsp = data->state.async.dns; | |
| } | |
| + | else |
| + | Curl_freeaddrinfo(ai); |
| } /* address processing done */ | |
| /* All done */ | |
| @@ -112,15 +112,12 @@ struct doh_probes { | |
| }; | |
| /* | |
| - | * Curl_doh() resolve a name using DoH (DNS-over-HTTPS). It resolves a name |
| - | * and returns a 'Curl_addrinfo *' with the address information. |
| + | * Curl_doh() starts a name resolve using DoH (DNS-over-HTTPS). It resolves a |
| + | * name and returns a 'Curl_addrinfo *' with the address information. |
| */ | |
| - | struct Curl_addrinfo *Curl_doh(struct Curl_easy *data, |
| - | const char *hostname, |
| - | int port, |
| - | int ip_version, |
| - | int *waitp); |
| + | CURLcode Curl_doh(struct Curl_easy *data, const char *hostname, |
| + | int port, int ip_version); |
| CURLcode Curl_doh_is_resolved(struct Curl_easy *data, | |
| struct Curl_dns_entry **dns); | |
| @@ -509,10 +509,8 @@ Curl_dnscache_mk_entry(struct Curl_easy *data, | |
| /* shuffle addresses if requested */ | |
| if(data->set.dns_shuffle_addresses) { | |
| CURLcode result = Curl_shuffle_addr(data, &addr); | |
| - | if(result) { |
| - | Curl_freeaddrinfo(addr); |
| + | if(result) |
| return NULL; | |
| - | } |
| } | |
| #else | |
| (void)data; | |
| @@ -522,10 +520,8 @@ Curl_dnscache_mk_entry(struct Curl_easy *data, | |
| /* Create a new cache entry */ | |
| dns = calloc(1, sizeof(struct Curl_dns_entry) + hostlen); | |
| - | if(!dns) { |
| - | Curl_freeaddrinfo(addr); |
| + | if(!dns) |
| return NULL; | |
| - | } |
| dns->refcount = 1; /* the cache has the first reference */ | |
| dns->addr = addr; /* this is the address(es) */ | |
| @@ -569,6 +565,7 @@ dnscache_add_addr(struct Curl_easy *data, | |
| dns2 = Curl_hash_add(&dnscache->entries, entry_id, entry_len + 1, | |
| (void *)dns); | |
| if(!dns2) { | |
| + | dns->addr = NULL; |
| dnscache_entry_free(dns); | |
| return NULL; | |
| } | |
| @@ -744,40 +741,6 @@ static bool tailmatch(const char *full, size_t flen, | |
| return curl_strnequal(part, &full[flen - plen], plen); | |
| } | |
| - | static struct Curl_addrinfo * |
| - | convert_ipaddr_direct(const char *hostname, int port, bool *is_ipaddr) |
| - | { |
| - | struct in_addr in; |
| - | *is_ipaddr = FALSE; |
| - | /* First check if this is an IPv4 address string */ |
| - | if(curlx_inet_pton(AF_INET, hostname, &in) > 0) { |
| - | /* This is a dotted IP address 123.123.123.123-style */ |
| - | *is_ipaddr = TRUE; |
| - | #ifdef USE_RESOLVE_ON_IPS |
| - | (void)port; |
| - | return NULL; |
| - | #else |
| - | return Curl_ip2addr(AF_INET, &in, hostname, port); |
| - | #endif |
| - | } |
| - | #ifdef USE_IPV6 |
| - | else { |
| - | struct in6_addr in6; |
| - | /* check if this is an IPv6 address string */ |
| - | if(curlx_inet_pton(AF_INET6, hostname, &in6) > 0) { |
| - | /* This is an IPv6 address literal */ |
| - | *is_ipaddr = TRUE; |
| - | #ifdef USE_RESOLVE_ON_IPS |
| - | return NULL; |
| - | #else |
| - | return Curl_ip2addr(AF_INET6, &in6, hostname, port); |
| - | #endif |
| - | } |
| - | } |
| - | #endif /* USE_IPV6 */ |
| - | return NULL; |
| - | } |
| - | |
| static bool can_resolve_ip_version(struct Curl_easy *data, int ip_version) | |
| { | |
| #ifdef CURLRES_IPV6 | |
| @@ -841,10 +804,10 @@ CURLcode Curl_resolv(struct Curl_easy *data, | |
| struct Curl_dnscache *dnscache = dnscache_get(data); | |
| struct Curl_dns_entry *dns = NULL; | |
| struct Curl_addrinfo *addr = NULL; | |
| - | int respwait = 0; |
| - | bool is_ipaddr; |
| + | bool respwait = FALSE; |
| size_t hostname_len; | |
| bool keep_negative = TRUE; /* cache a negative result */ | |
| + | CURLcode result = CURLE_COULDNT_RESOLVE_HOST; |
| *entry = NULL; | |
| @@ -853,8 +816,11 @@ CURLcode Curl_resolv(struct Curl_easy *data, | |
| #else | |
| (void)allowDOH; | |
| #endif | |
| - | if(!dnscache) |
| + | DEBUGASSERT(dnscache); |
| + | if(!dnscache) { |
| + | result = CURLE_BAD_FUNCTION_ARGUMENT; |
| goto error; | |
| + | } |
| /* We should intentionally error and not resolve .onion TLDs */ | |
| hostname_len = strlen(hostname); | |
| @@ -874,6 +840,7 @@ CURLcode Curl_resolv(struct Curl_easy *data, | |
| dnscache_unlock(data, dnscache); | |
| if(dns) { | |
| infof(data, "Hostname %s was found in DNS cache", hostname); | |
| + | result = CURLE_OK; |
| goto out; | |
| } | |
| @@ -882,7 +849,8 @@ CURLcode Curl_resolv(struct Curl_easy *data, | |
| void *resolver = NULL; | |
| int st; | |
| #ifdef CURLRES_ASYNCH | |
| - | if(Curl_async_get_impl(data, &resolver)) |
| + | result = Curl_async_get_impl(data, &resolver); |
| + | if(result) |
| goto error; | |
| #endif | |
| Curl_set_in_callback(data, TRUE); | |
| @@ -891,57 +859,58 @@ CURLcode Curl_resolv(struct Curl_easy *data, | |
| Curl_set_in_callback(data, FALSE); | |
| if(st) { | |
| keep_negative = FALSE; | |
| + | result = CURLE_ABORTED_BY_CALLBACK; |
| goto error; | |
| } | |
| } | |
| - | /* shortcut literal IP addresses, if we are not told to resolve them. */ |
| - | addr = convert_ipaddr_direct(hostname, port, &is_ipaddr); |
| - | if(addr) |
| - | goto out; |
| - | |
| + | if(Curl_is_ipaddr(hostname)) { |
| #ifndef USE_RESOLVE_ON_IPS | |
| - | /* allowed to convert, hostname is IP address, then NULL means error */ |
| - | if(is_ipaddr) { |
| - | keep_negative = FALSE; |
| - | goto error; |
| - | } |
| + | /* shortcut literal IP addresses, if we are not told to resolve them. */ |
| + | result = Curl_str2addr(hostname, port, &addr); |
| + | if(result) |
| + | goto error; |
| + | goto out; |
| #endif | |
| + | } |
| - | /* Really need a resolver for hostname. */ |
| - | if(ip_version == CURL_IPRESOLVE_V6 && !Curl_ipv6works(data)) |
| - | goto error; |
| - | |
| - | if(!is_ipaddr && |
| - | (curl_strequal(hostname, "localhost") || |
| - | curl_strequal(hostname, "localhost.") || |
| - | tailmatch(hostname, hostname_len, STRCONST(".localhost")) || |
| - | tailmatch(hostname, hostname_len, STRCONST(".localhost.")))) { |
| + | if(curl_strequal(hostname, "localhost") || |
| + | curl_strequal(hostname, "localhost.") || |
| + | tailmatch(hostname, hostname_len, STRCONST(".localhost")) || |
| + | tailmatch(hostname, hostname_len, STRCONST(".localhost."))) { |
| addr = get_localhost(port, hostname); | |
| + | result = addr ? CURLE_OK : CURLE_OUT_OF_MEMORY; |
| } | |
| #ifndef CURL_DISABLE_DOH | |
| - | else if(!is_ipaddr && allowDOH && data->set.doh) { |
| - | addr = Curl_doh(data, hostname, port, ip_version, &respwait); |
| + | else if(!Curl_is_ipaddr(hostname) && allowDOH && data->set.doh) { |
| + | result = Curl_doh(data, hostname, port, ip_version); |
| + | respwait = TRUE; |
| } | |
| #endif | |
| else { | |
| /* Can we provide the requested IP specifics in resolving? */ | |
| - | if(!can_resolve_ip_version(data, ip_version)) |
| + | if(!can_resolve_ip_version(data, ip_version)) { |
| + | result = CURLE_COULDNT_RESOLVE_HOST; |
| goto error; | |
| + | } |
| #ifdef CURLRES_ASYNCH | |
| - | addr = Curl_async_getaddrinfo(data, hostname, port, ip_version, &respwait); |
| + | result = Curl_async_getaddrinfo(data, hostname, port, ip_version); |
| + | respwait = TRUE; |
| #else | |
| - | respwait = 0; /* no async waiting here */ |
| + | respwait = FALSE; /* no async waiting here */ |
| addr = Curl_sync_getaddrinfo(data, hostname, port, ip_version); | |
| + | if(addr) |
| + | result = CURLE_OK; |
| #endif | |
| } | |
| out: | |
| - | /* We either have found a `dns` or looked up the `addr` |
| - | * or `respwait` is set for an async operation. |
| - | * Everything else is a failure to resolve. */ |
| - | if(dns) { |
| + | /* We either have found a `dns` or looked up the `addr` or `respwait` is set |
| + | * for an async operation. Everything else is a failure to resolve. */ |
| + | if(result) |
| + | ; |
| + | else if(dns) { |
| if(!dns->addr) { | |
| infof(data, "Negative DNS entry"); | |
| dns->refcount--; | |
| @@ -955,7 +924,12 @@ out: | |
| dns = Curl_dnscache_mk_entry(data, addr, hostname, 0, port, FALSE); | |
| if(!dns || Curl_dnscache_add(data, dns)) { | |
| /* this is OOM or similar, do not store such negative resolves */ | |
| + | Curl_freeaddrinfo(addr); |
| + | if(dns) |
| + | /* avoid a dangling pointer to addr in the dying dns entry */ |
| + | dns->addr = NULL; |
| keep_negative = FALSE; | |
| + | result = CURLE_OUT_OF_MEMORY; |
| goto error; | |
| } | |
| show_resolve_info(data, dns); | |
| @@ -967,6 +941,7 @@ out: | |
| *entry = dns; | |
| return dns ? CURLE_OK : CURLE_AGAIN; | |
| } | |
| + | result = CURLE_COULDNT_RESOLVE_HOST; |
| } | |
| error: | |
| if(dns) | |
| @@ -974,7 +949,8 @@ error: | |
| Curl_async_shutdown(data); | |
| if(keep_negative) | |
| store_negative_resolve(data, hostname, port); | |
| - | return CURLE_COULDNT_RESOLVE_HOST; |
| + | DEBUGASSERT(result); |
| + | return result; |
| } | |
| CURLcode Curl_resolv_blocking(struct Curl_easy *data, | |
| @@ -1338,6 +1314,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) | |
| while(*host) { | |
| struct Curl_str target; | |
| struct Curl_addrinfo *ai; | |
| + | CURLcode result; |
| if(!curlx_str_single(&host, '[')) { | |
| if(curlx_str_until(&host, &target, MAX_IPADR_LEN, ']') || | |
| @@ -1368,8 +1345,8 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) | |
| memcpy(address, curlx_str(&target), curlx_strlen(&target)); | |
| address[curlx_strlen(&target)] = '\0'; | |
| - | ai = Curl_str2addr(address, (int)port); |
| - | if(!ai) { |
| + | result = Curl_str2addr(address, (int)port, &ai); |
| + | if(result) { |
| infof(data, "Resolve address '%s' found illegal", address); | |
| goto err; | |
| } | |
| @@ -1428,11 +1405,12 @@ err: | |
| /* put this new host in the cache */ | |
| dns = dnscache_add_addr(data, dnscache, head, curlx_str(&source), | |
| curlx_strlen(&source), (int)port, permanent); | |
| - | if(dns) { |
| + | if(dns) |
| /* release the returned reference; the cache itself will keep the | |
| * entry alive: */ | |
| dns->refcount--; | |
| - | } |
| + | else |
| + | Curl_freeaddrinfo(head); |
| dnscache_unlock(data, dnscache); | |
| @@ -82,9 +82,9 @@ static CURLcode test_lib655(const char *URL) | |
| /* this should fail */ | |
| res = curl_easy_perform(curl); | |
| - | if(res != CURLE_COULDNT_RESOLVE_HOST) { |
| + | if(res != CURLE_ABORTED_BY_CALLBACK) { |
| curl_mfprintf(stderr, "curl_easy_perform should have returned " | |
| - | "CURLE_COULDNT_RESOLVE_HOST but instead returned error %d\n", |
| + | "CURLE_ABORTED_BY_CALLBACK but instead returned error %d\n", |
| res); | |
| if(res == CURLE_OK) | |
| res = TEST_ERR_FAILURE; | |