mirror of
https://github.com/curl/curl.git
synced 2024-11-21 01:16:58 +08:00
url: Add option CURLOPT_HAPPY_EYEBALLS_TIMEOUT
- Add new option CURLOPT_HAPPY_EYEBALLS_TIMEOUT to set libcurl's happy eyeball timeout value. - Add new optval macro CURL_HET_DEFAULT to represent the default happy eyeballs timeout value (currently 200 ms). - Add new tool option --happy-eyeballs-timeout-ms to expose CURLOPT_HAPPY_EYEBALLS_TIMEOUT. The -ms suffix is used because the other -timeout options in the tool expect seconds not milliseconds. Closes https://github.com/curl/curl/pull/2260
This commit is contained in:
parent
73050fb6ae
commit
2427d94c6d
@ -12,7 +12,9 @@ DPAGES = abstract-unix-socket.d anyauth.d append.d basic.d cacert.d capath.d cer
|
||||
form.d form-string.d ftp-account.d ftp-alternative-to-user.d \
|
||||
ftp-create-dirs.d ftp-method.d ftp-pasv.d ftp-port.d ftp-pret.d \
|
||||
ftp-skip-pasv-ip.d ftp-ssl-ccc.d ftp-ssl-ccc-mode.d ftp-ssl-control.d \
|
||||
get.d globoff.d head.d header.d help.d hostpubmd5.d http1.0.d \
|
||||
get.d globoff.d \
|
||||
happy-eyeballs-timeout-ms.d \
|
||||
head.d header.d help.d hostpubmd5.d http1.0.d \
|
||||
http1.1.d http2.d http2-prior-knowledge.d ignore-content-length.d \
|
||||
include.d insecure.d interface.d ipv4.d ipv6.d junk-session-cookies.d \
|
||||
keepalive-time.d key.d key-type.d krb.d libcurl.d limit-rate.d \
|
||||
|
17
docs/cmdline-opts/happy-eyeballs-timeout-ms.d
Normal file
17
docs/cmdline-opts/happy-eyeballs-timeout-ms.d
Normal file
@ -0,0 +1,17 @@
|
||||
Long: happy-eyeballs-timeout-ms
|
||||
Arg: <milliseconds>
|
||||
Help: How long to wait in milliseconds for IPv6 before trying IPv4
|
||||
Added: 7.59.0
|
||||
---
|
||||
Happy eyeballs is an algorithm that attempts to connect to both IPv4 and IPv6
|
||||
addresses for dual-stack hosts, preferring IPv6 first for the number of
|
||||
milliseconds. If the IPv6 address cannot be connected to within that time then
|
||||
a connection attempt is made to the IPv4 address in parallel. The first
|
||||
connection to be established is the one that is used.
|
||||
|
||||
The range of suggested useful values is limited. Happy Eyeballs RFC 6555 says
|
||||
"It is RECOMMENDED that connection attempts be paced 150-250 ms apart to
|
||||
balance human factors against network load." libcurl currently defaults to
|
||||
200 ms. Firefox and Chrome currently default to 300 ms.
|
||||
|
||||
If this option is used several times, the last one will be used.
|
@ -577,6 +577,8 @@ Mode for creating new remote directories. See \fICURLOPT_NEW_DIRECTORY_PERMS(3)\
|
||||
.SH TELNET OPTIONS
|
||||
.IP CURLOPT_TELNETOPTIONS
|
||||
TELNET options. See \fICURLOPT_TELNETOPTIONS(3)\fP
|
||||
.IP CURLOPT_HAPPY_EYEBALLS_TIMEOUT
|
||||
Timeout for happy eyeballs. See \fICURLOPT_HAPPY_EYEBALLS_TIMEOUT(3)\fP
|
||||
.SH RETURN VALUE
|
||||
\fICURLE_OK\fP (zero) means that the option was set properly, non-zero means an
|
||||
error occurred as \fI<curl/curl.h>\fP defines. See the \fIlibcurl-errors(3)\fP
|
||||
|
59
docs/libcurl/opts/CURLOPT_HAPPY_EYEBALLS_TIMEOUT.3
Normal file
59
docs/libcurl/opts/CURLOPT_HAPPY_EYEBALLS_TIMEOUT.3
Normal file
@ -0,0 +1,59 @@
|
||||
.\" **************************************************************************
|
||||
.\" * _ _ ____ _
|
||||
.\" * Project ___| | | | _ \| |
|
||||
.\" * / __| | | | |_) | |
|
||||
.\" * | (__| |_| | _ <| |___
|
||||
.\" * \___|\___/|_| \_\_____|
|
||||
.\" *
|
||||
.\" * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
.\" *
|
||||
.\" * This software is licensed as described in the file COPYING, which
|
||||
.\" * you should have received as part of this distribution. The terms
|
||||
.\" * are also available at https://curl.haxx.se/docs/copyright.html.
|
||||
.\" *
|
||||
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
.\" * copies of the Software, and permit persons to whom the Software is
|
||||
.\" * furnished to do so, under the terms of the COPYING file.
|
||||
.\" *
|
||||
.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
.\" * KIND, either express or implied.
|
||||
.\" *
|
||||
.\" **************************************************************************
|
||||
.\"
|
||||
.TH CURLOPT_HAPPY_EYEBALLS_TIMEOUT 3 "1 Feb 2018" "libcurl 7.59.0" "curl_easy_setopt options"
|
||||
.SH NAME
|
||||
CURLOPT_HAPPY_EYEBALLS_TIMEOUT \- head start for ipv6 for happy eyeballs
|
||||
.SH SYNOPSIS
|
||||
#include <curl/curl.h>
|
||||
|
||||
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_HAPPY_EYEBALLS_TIMEOUT, long timeout);
|
||||
.SH DESCRIPTION
|
||||
Happy eyeballs is an algorithm that attempts to connect to both IPv4 and IPv6
|
||||
addresses for dual-stack hosts, preferring IPv6 first for \fItimeout\fP
|
||||
milliseconds. If the IPv6 address cannot be connected to within that time then
|
||||
a connection attempt is made to the IPv4 address in parallel. The first
|
||||
connection to be established is the one that is used.
|
||||
|
||||
The range of suggested useful values for \fItimeout\fP is limited. Happy
|
||||
Eyeballs RFC 6555 says "It is RECOMMENDED that connection attempts be paced
|
||||
150-250 ms apart to balance human factors against network load." libcurl
|
||||
currently defaults to 200 ms. Firefox and Chrome currently default to 300 ms.
|
||||
.SH DEFAULT
|
||||
CURL_HET_DEFAULT (currently defined as 200L)
|
||||
.SH EXAMPLE
|
||||
.nf
|
||||
CURL *curl = curl_easy_init();
|
||||
if(curl) {
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
|
||||
curl_easy_setopt(curl, CURLOPT_HAPPY_EYEBALLS_TIMEOUT, 300L);
|
||||
|
||||
curl_easy_perform(curl);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
.fi
|
||||
.SH AVAILABILITY
|
||||
Added in 7.59.0
|
||||
.SH RETURN VALUE
|
||||
Returns CURLE_OK
|
@ -136,6 +136,7 @@ man_MANS = \
|
||||
CURLOPT_FTP_USE_EPSV.3 \
|
||||
CURLOPT_FTP_USE_PRET.3 \
|
||||
CURLOPT_GSSAPI_DELEGATION.3 \
|
||||
CURLOPT_HAPPY_EYEBALLS_TIMEOUT.3 \
|
||||
CURLOPT_HEADER.3 \
|
||||
CURLOPT_HEADERDATA.3 \
|
||||
CURLOPT_HEADERFUNCTION.3 \
|
||||
|
@ -403,6 +403,7 @@ CURLOPT_FTP_USE_EPRT 7.10.5
|
||||
CURLOPT_FTP_USE_EPSV 7.9.2
|
||||
CURLOPT_FTP_USE_PRET 7.20.0
|
||||
CURLOPT_GSSAPI_DELEGATION 7.22.0
|
||||
CURLOPT_HAPPY_EYEBALLS_TIMEOUT 7.59.0
|
||||
CURLOPT_HEADER 7.1
|
||||
CURLOPT_HEADERDATA 7.10
|
||||
CURLOPT_HEADERFUNCTION 7.7.2
|
||||
@ -741,6 +742,7 @@ CURL_GLOBAL_DEFAULT 7.8
|
||||
CURL_GLOBAL_NOTHING 7.8
|
||||
CURL_GLOBAL_SSL 7.8
|
||||
CURL_GLOBAL_WIN32 7.8.1
|
||||
CURL_HET_DEFAULT 7.59.0
|
||||
CURL_HTTPPOST_BUFFER 7.46.0
|
||||
CURL_HTTPPOST_CALLBACK 7.46.0
|
||||
CURL_HTTPPOST_FILENAME 7.46.0
|
||||
|
@ -791,6 +791,11 @@ typedef enum {
|
||||
SSL backends where such behavior is present. */
|
||||
#define CURLSSLOPT_NO_REVOKE (1<<1)
|
||||
|
||||
/* The default connection attempt delay in milliseconds for happy eyeballs.
|
||||
CURLOPT_HAPPY_EYEBALLS_TIMEOUT.3 and happy-eyeballs-timeout-ms.d document
|
||||
this value, keep them in sync. */
|
||||
#define CURL_HET_DEFAULT 200L
|
||||
|
||||
#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
|
||||
the obsolete stuff removed! */
|
||||
|
||||
@ -1825,6 +1830,9 @@ typedef enum {
|
||||
seconds since 1 Jan 1970. */
|
||||
CINIT(TIMEVALUE_LARGE, OFF_T, 270),
|
||||
|
||||
/* Head start in milliseconds to give happy eyeballs. */
|
||||
CINIT(HAPPY_EYEBALLS_TIMEOUT, LONG, 271),
|
||||
|
||||
CURLOPT_LASTENTRY /* the last unused */
|
||||
} CURLoption;
|
||||
|
||||
|
@ -783,7 +783,8 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
|
||||
/* should we try another protocol family? */
|
||||
if(i == 0 && conn->tempaddr[1] == NULL &&
|
||||
Curl_timediff(now, conn->connecttime) >= HAPPY_EYEBALLS_TIMEOUT) {
|
||||
(Curl_timediff(now, conn->connecttime) >=
|
||||
data->set.happy_eyeballs_timeout)) {
|
||||
trynextip(conn, sockindex, 1);
|
||||
}
|
||||
}
|
||||
@ -1206,7 +1207,8 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||
}
|
||||
|
||||
data->info.numconnects++; /* to track the number of connections made */
|
||||
Curl_expire(conn->data, HAPPY_EYEBALLS_TIMEOUT, EXPIRE_HAPPY_EYEBALLS);
|
||||
Curl_expire(conn->data, data->set.happy_eyeballs_timeout,
|
||||
EXPIRE_HAPPY_EYEBALLS);
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
@ -41,8 +41,6 @@ timediff_t Curl_timeleft(struct Curl_easy *data,
|
||||
bool duringconnect);
|
||||
|
||||
#define DEFAULT_CONNECT_TIMEOUT 300000 /* milliseconds == five minutes */
|
||||
#define HAPPY_EYEBALLS_TIMEOUT 200 /* milliseconds to wait between
|
||||
IPv4/IPv6 connection attempts */
|
||||
|
||||
/*
|
||||
* Used to extract socket and connectdata struct for the most recent
|
||||
|
@ -2533,6 +2533,12 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
|
||||
case CURLOPT_SSH_COMPRESSION:
|
||||
data->set.ssh_compression = (0 != va_arg(param, long))?TRUE:FALSE;
|
||||
break;
|
||||
case CURLOPT_HAPPY_EYEBALLS_TIMEOUT:
|
||||
arg = va_arg(param, long);
|
||||
if(arg < 0)
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
data->set.happy_eyeballs_timeout = arg;
|
||||
break;
|
||||
default:
|
||||
/* unknown tag and its companion, just ignore: */
|
||||
result = CURLE_UNKNOWN_OPTION;
|
||||
|
@ -527,6 +527,7 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data)
|
||||
set->expect_100_timeout = 1000L; /* Wait for a second by default. */
|
||||
set->sep_headers = TRUE; /* separated header lists by default */
|
||||
set->buffer_size = READBUFFER_SIZE;
|
||||
set->happy_eyeballs_timeout = CURL_HET_DEFAULT;
|
||||
|
||||
Curl_http2_init_userset(set);
|
||||
return result;
|
||||
|
@ -1520,6 +1520,7 @@ struct UserDefined {
|
||||
long timeout; /* in milliseconds, 0 means no timeout */
|
||||
long connecttimeout; /* in milliseconds, 0 means no timeout */
|
||||
long accepttimeout; /* in milliseconds, 0 means no timeout */
|
||||
long happy_eyeballs_timeout; /* in milliseconds, 0 is a valid value */
|
||||
long server_response_timeout; /* in milliseconds, 0 means no timeout */
|
||||
long tftp_blksize; /* in bytes, 0 means use default */
|
||||
bool tftp_no_options; /* do not send TFTP options requests */
|
||||
|
@ -1322,6 +1322,10 @@
|
||||
d c 00268
|
||||
d CURLOPT_MIMEPOST...
|
||||
d c 10269
|
||||
d CURLOPT_TIMEVALUE_LARGE...
|
||||
d c 30270
|
||||
d CURLOPT_HAPPY_EYEBALLS_TIMEOUT...
|
||||
d c 00271
|
||||
*
|
||||
/if not defined(CURL_NO_OLDIES)
|
||||
d CURLOPT_FILE c 10001
|
||||
|
@ -42,6 +42,7 @@ void config_init(struct OperationConfig* config)
|
||||
config->proto_redir_present = FALSE;
|
||||
config->proto_default = NULL;
|
||||
config->tcp_nodelay = TRUE; /* enabled by default */
|
||||
config->happy_eyeballs_timeout_ms = CURL_HET_DEFAULT;
|
||||
}
|
||||
|
||||
static void free_config_fields(struct OperationConfig *config)
|
||||
|
@ -250,6 +250,8 @@ struct OperationConfig {
|
||||
curl_error synthetic_error; /* if non-zero, it overrides any libcurl
|
||||
error */
|
||||
bool ssh_compression; /* enable/disable SSH compression */
|
||||
long happy_eyeballs_timeout_ms; /* happy eyeballs timeout in milliseconds.
|
||||
0 is valid. default: CURL_HET_DEFAULT. */
|
||||
struct GlobalConfig *global;
|
||||
struct OperationConfig *prev;
|
||||
struct OperationConfig *next; /* Always last in the struct */
|
||||
|
@ -190,6 +190,7 @@ static const struct LongShort aliases[]= {
|
||||
{"$X", "tls-max", ARG_STRING},
|
||||
{"$Y", "suppress-connect-headers", ARG_BOOL},
|
||||
{"$Z", "compressed-ssh", ARG_BOOL},
|
||||
{"$~", "happy-eyeballs-timeout-ms", ARG_STRING},
|
||||
{"0", "http1.0", ARG_NONE},
|
||||
{"01", "http1.1", ARG_NONE},
|
||||
{"02", "http2", ARG_NONE},
|
||||
@ -1111,6 +1112,12 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
|
||||
case 'Z': /* --compressed-ssh */
|
||||
config->ssh_compression = toggle;
|
||||
break;
|
||||
case '~': /* --happy-eyeballs-timeout-ms */
|
||||
err = str2unum(&config->happy_eyeballs_timeout_ms, nextarg);
|
||||
if(err)
|
||||
return err;
|
||||
/* 0 is a valid value for this timeout */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case '#': /* --progress-bar */
|
||||
|
@ -160,6 +160,8 @@ static const struct helptxt helptext[] = {
|
||||
"Put the post data in the URL and use GET"},
|
||||
{"-g, --globoff",
|
||||
"Disable URL sequences and ranges using {} and []"},
|
||||
{" --happy-eyeballs-timeout-ms",
|
||||
"How long to wait in milliseconds for IPv6 before trying IPv4"},
|
||||
{"-I, --head",
|
||||
"Show document info only"},
|
||||
{"-H, --header <header/@file>",
|
||||
|
@ -1440,6 +1440,11 @@ static CURLcode operate_do(struct GlobalConfig *global,
|
||||
if(config->tftp_no_options)
|
||||
my_setopt(curl, CURLOPT_TFTP_NO_OPTIONS, 1L);
|
||||
|
||||
/* new in 7.59.0 */
|
||||
if(config->happy_eyeballs_timeout_ms != CURL_HET_DEFAULT)
|
||||
my_setopt(curl, CURLOPT_HAPPY_EYEBALLS_TIMEOUT,
|
||||
config->happy_eyeballs_timeout_ms);
|
||||
|
||||
/* initialize retry vars for loop below */
|
||||
retry_sleep_default = (config->retry_delay) ?
|
||||
config->retry_delay*1000L : RETRY_SLEEP_DEFAULT; /* ms */
|
||||
|
Loading…
Reference in New Issue
Block a user