From: Alberto Leiva Popper Date: Fri, 17 Sep 2021 18:35:59 +0000 (-0500) Subject: HTTP: Patch CURLOPT_LOW_SPEED_LIMIT and CURLOPT_LOW_SPEED_TIME X-Git-Tag: 1.5.3~18 X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=a28c2cc6d01772ce9faf61332fd97b1f2965e29d;p=thirdparty%2FFORT-validator.git HTTP: Patch CURLOPT_LOW_SPEED_LIMIT and CURLOPT_LOW_SPEED_TIME Likely due to some misunderstanding, Fort was managing both of these variables using one command-line argument (--http.idle-timeout). This unnecessarily limited the configurability of minimum transfer speeds for HTTP connections. --http.idle-timeout is now deprecated, and has been replaced by --http.low-speed-limit and --http.low-speed-time, which correlate verbatim to the corresponding curl arguments (CURLOPT_LOW_SPEED_LIMIT and CURLOPT_LOW_SPEED_TIME). Thanks to Koen van Hove for reporting this. --- diff --git a/docs/usage.md b/docs/usage.md index 6db5e276..09d6a8a1 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -52,7 +52,8 @@ description: Guide to use arguments of FORT Validator. 38. [`--http.user-agent`](#--httpuser-agent) 39. [`--http.connect-timeout`](#--httpconnect-timeout) 40. [`--http.transfer-timeout`](#--httptransfer-timeout) - 41. [`--http.idle-timeout`](#--httpidle-timeout) + 41. [`--http.low-speed-limit`](#--httplow-speed-limit) + 41. [`--http.low-speed-time`](#--httplow-speed-time) 42. [`--http.ca-path`](#--httpca-path) 43. [`--output.roa`](#--outputroa) 44. [`--output.bgpsec`](#--outputbgpsec) @@ -81,6 +82,7 @@ description: Guide to use arguments of FORT Validator. 4. [`--rrdp.retry.count`](#--rrdpretrycount) 5. [`--rrdp.retry.interval`](#--rrdpretryinterval) 60. [`init-locations`](#init-locations) + 41. [`--http.idle-timeout`](#--httpidle-timeout) ## Syntax @@ -123,7 +125,8 @@ description: Guide to use arguments of FORT Validator. [--http.user-agent=] [--http.connect-timeout=] [--http.transfer-timeout=] - [--http.idle-timeout=] + [--http.low-speed-limit=] + [--http.low-speed-time=] [--http.ca-path=] [--log.enabled=true|false] [--log.output=syslog|console] @@ -726,20 +729,41 @@ Once the connection is established with the server, the request will last a maxi The value specified (either by the argument or the default value) is utilized in libcurl's option [CURLOPT_TIMEOUT](https://curl.haxx.se/libcurl/c/CURLOPT_TIMEOUT.html). -### `--http.idle-timeout` +### `--http.low-speed-limit` - **Type:** Integer - **Availability:** `argv` and JSON -- **Default:** 15 +- **Default:** 30 - **Range:** 0--[`UINT_MAX`](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html) -_**All requests are made using HTTPS, verifying the peer and the certificate name vs host**_ +The value Fort employs as [CURLOPT_LOW_SPEED_LIMIT](https://curl.haxx.se/libcurl/c/CURLOPT_LOW_SPEED_LIMIT.html) during every HTTP transfer. -Maximum time in seconds (once the connection is established) that a request can be idle before dropping it. +It is the average transfer speed (in bytes per second) that HTTP transfers (between Fort and RPKI repositories) should be below during [`--http.low-speed-time`](#--httplow-speed-time) seconds for Fort to consider it to be too slow. (Slow connections are dropped.) -Once the connection is established with the server, the request can last a maximum of `http.idle-timeout` seconds without receiving data before dropping the connection. A value of 0 disables idle time verification (use with caution). +For example: -The value specified (either by the argument or the default value) is utilized in libcurl's option [CURLOPT_LOW_SPEED_TIME](https://curl.haxx.se/libcurl/c/CURLOPT_LOW_SPEED_TIME.html). +``` +--http.low-speed-limit 30 --http.low-speed-time 60 +``` + +Whenever Fort attempts to retrieve a file from an RPKI repository through HTTP, it will abort the transfer if the connection stays slower than 30 bytes per second, over a period of 60 seconds. + +The intent is to prevent malicious repositories from slowing down Fort. + +Zero disables the validation. + +### `--http.low-speed-time` + +- **Type:** Integer +- **Availability:** `argv` and JSON +- **Default:** 10 +- **Range:** 0--[`UINT_MAX`](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html) + +The value Fort employs as [CURLOPT_LOW_SPEED_TIME](https://curl.haxx.se/libcurl/c/CURLOPT_LOW_SPEED_TIME.html) during every HTTP transfer. + +It is the number of seconds that the transfer speed should be below `--http.low-speed-limit` for the Fort to consider it too slow. (Slow connections are dropped.) + +See [`--http.low-speed-limit`](#--httplow-speed-limit). ### `--http.ca-path` @@ -1310,3 +1334,12 @@ This is a JSON array of objects, where each object has a mandatory `url` member, } ] ``` + +### `--http.idle-timeout` + +- **Type:** Integer +- **Availability:** `argv` and JSON +- **Default:** 10 +- **Range:** 0--[`UINT_MAX`](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html) + +Deprecated alias for [`--http.low-speed-time`](#--httplow-speed-time). diff --git a/src/config.c b/src/config.c index 15a54e32..e01e3876 100644 --- a/src/config.c +++ b/src/config.c @@ -145,12 +145,14 @@ struct rpki_config { } retry; /* User-Agent header set at requests */ char *user_agent; - /* Timeout in seconds for the connect phase */ + /* CURLOPT_CONNECTTIMEOUT for our HTTP transfers. */ unsigned int connect_timeout; - /* Maximum allowed time that a request can take */ + /* CURLOPT_TIMEOUT for our HTTP transfers. */ unsigned int transfer_timeout; - /* Maximum idle time during a request */ - unsigned int idle_timeout; + /* CURLOPT_LOW_SPEED_LIMIT for our HTTP transfers. */ + unsigned int low_speed_limit; + /* CURLOPT_LOW_SPEED_TIME for our HTTP transfers. */ + unsigned int low_speed_time; /* Directory where CA certs to verify peers are found */ char *ca_path; } http; @@ -608,10 +610,28 @@ static const struct option_field options[] = { }, { .id = 9007, - .name = "http.idle-timeout", + .name = "http.idle-timeout", /* TODO DEPRECATED. */ .type = >_uint, - .offset = offsetof(struct rpki_config, http.idle_timeout), - .doc = "Maximum idle time (once the connection is established) during a request before dropping the connection", + .offset = offsetof(struct rpki_config, http.low_speed_time), + .doc = "Deprecated; currently an alias for --http.low-speed-time. Use --http.low-speed-time instead.", + .min = 0, + .max = UINT_MAX, + }, + { + .id = 9009, + .name = "http.low-speed-limit", + .type = >_uint, + .offset = offsetof(struct rpki_config, http.low_speed_limit), + .doc = "Average transfer speed (in bytes per second) that the transfer should be below during --http.low-speed-time seconds for Fort to consider it to be too slow. (Slow connections are dropped.)", + .min = 0, + .max = UINT_MAX, + }, + { + .id = 9010, + .name = "http.low-speed-time", + .type = >_uint, + .offset = offsetof(struct rpki_config, http.low_speed_time), + .doc = "Seconds that the transfer speed should be below --http.low-speed-limit for the Fort to consider it too slow. (Slow connections are dropped.)", .min = 0, .max = UINT_MAX, }, @@ -1033,7 +1053,8 @@ set_default_values(void) } rpki_config.http.connect_timeout = 30; rpki_config.http.transfer_timeout = 0; - rpki_config.http.idle_timeout = 15; + rpki_config.http.low_speed_limit = 30; + rpki_config.http.low_speed_time = 10; rpki_config.http.ca_path = NULL; /* Use system default */ /* @@ -1553,9 +1574,15 @@ config_get_http_transfer_timeout(void) } long -config_get_http_idle_timeout(void) +config_get_http_low_speed_limit(void) +{ + return rpki_config.http.low_speed_limit; +} + +long +config_get_http_low_speed_time(void) { - return rpki_config.http.idle_timeout; + return rpki_config.http.low_speed_time; } char const * diff --git a/src/config.h b/src/config.h index 3a7deca4..1d7cb8c3 100644 --- a/src/config.h +++ b/src/config.h @@ -35,7 +35,8 @@ enum mode config_get_mode(void); char const *config_get_http_user_agent(void); long config_get_http_connect_timeout(void); long config_get_http_transfer_timeout(void); -long config_get_http_idle_timeout(void); +long config_get_http_low_speed_limit(void); +long config_get_http_low_speed_time(void); char const *config_get_http_ca_path(void); bool config_get_rsync_enabled(void); unsigned int config_get_rsync_priority(void); diff --git a/src/http/http.c b/src/http/http.c index b8bd79dd..9a2f3915 100644 --- a/src/http/http.c +++ b/src/http/http.c @@ -83,7 +83,6 @@ static int http_easy_init(struct http_handler *handler) { CURL *result; - long timeout; result = curl_easy_init(); if (result == NULL) @@ -96,9 +95,10 @@ http_easy_init(struct http_handler *handler) setopt_long(result, CURLOPT_TIMEOUT, config_get_http_transfer_timeout()); - timeout = config_get_http_idle_timeout(); - setopt_long(result, CURLOPT_LOW_SPEED_TIME, timeout); - setopt_long(result, CURLOPT_LOW_SPEED_LIMIT, !!timeout); + setopt_long(result, CURLOPT_LOW_SPEED_LIMIT, + config_get_http_low_speed_limit()); + setopt_long(result, CURLOPT_LOW_SPEED_TIME, + config_get_http_low_speed_time()); /* Always expect HTTPS usage */ setopt_long(result, CURLOPT_SSL_VERIFYHOST, 2L);