altsvc: cap the list at 5,000 entries
No binary (build failed)
—
(log yok)
| @@ -144,6 +144,20 @@ static struct altsvc *altsvc_create(struct Curl_str *srchost, | |
| srcport, dstport); | |
| } | |
| + | /* append the new entry to the list after possibly removing an old entry |
| + | first */ |
| + | static void altsvc_append(struct altsvcinfo *asi, struct altsvc *as) |
| + | { |
| + | while(Curl_llist_count(&asi->list) >= MAX_ALTSVC_ENTRIES) { |
| + | /* It's full. Remove the first entry in the list */ |
| + | struct Curl_llist_node *e = Curl_llist_head(&asi->list); |
| + | struct altsvc *oldas = Curl_node_elem(e); |
| + | Curl_node_remove(e); |
| + | altsvc_free(oldas); |
| + | } |
| + | Curl_llist_append(&asi->list, as, &as->node); |
| + | } |
| + | |
| /* only returns SERIOUS errors */ | |
| static CURLcode altsvc_add(struct altsvcinfo *asi, const char *line) | |
| { | |
| @@ -180,7 +194,6 @@ static CURLcode altsvc_add(struct altsvcinfo *asi, const char *line) | |
| curlx_str_newline(&line)) | |
| ; | |
| else { | |
| - | struct altsvc *as; |
| char dbuf[MAX_ALTSVC_DATELEN + 1]; | |
| time_t expires = 0; | |
| time_t now = time(NULL); | |
| @@ -192,12 +205,12 @@ static CURLcode altsvc_add(struct altsvcinfo *asi, const char *line) | |
| Curl_getdate_capped(dbuf, &expires); | |
| if(now < expires) { | |
| - | as = altsvc_create(&srchost, &dsthost, &srcalpn, &dstalpn, |
| - | (size_t)srcport, (size_t)dstport); |
| + | struct altsvc *as = altsvc_create(&srchost, &dsthost, &srcalpn, &dstalpn, |
| + | (size_t)srcport, (size_t)dstport); |
| if(as) { | |
| as->expires = expires; | |
| as->persist = persist ? 1 : 0; | |
| - | Curl_llist_append(&asi->list, as, &as->node); |
| + | altsvc_append(asi, as); |
| } | |
| else | |
| return CURLE_OUT_OF_MEMORY; | |
| @@ -594,7 +607,7 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data, | |
| else | |
| as->expires = maxage + secs; | |
| as->persist = persist; | |
| - | Curl_llist_append(&asi->list, as, &as->node); |
| + | altsvc_append(asi, as); |
| infof(data, "Added alt-svc: %.*s:%d over %s", | |
| (int)curlx_strlen(&dsthost), curlx_str(&dsthost), | |
| dstport, Curl_alpnid2str(dstalpnid)); | |
| @@ -28,6 +28,9 @@ | |
| #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_ALTSVC) | |
| #include "llist.h" | |
| + | /* the maximum number of alt-svc entries kept in a single cache */ |
| + | #define MAX_ALTSVC_ENTRIES 5000 |
| + | |
| struct althost { | |
| char *host; | |
| uint16_t port; | |
| @@ -221,7 +221,7 @@ test1638 test1639 test1640 test1641 test1642 test1643 test1644 \ | |
| \ | |
| test1650 test1651 test1652 test1653 test1654 test1655 test1656 test1657 \ | |
| test1658 test1659 test1660 test1661 test1662 test1663 test1664 test1665 \ | |
| - | test1666 test1667 test1668 \ |
| + | test1666 test1667 test1668 test1669 \ |
| \ | |
| test1670 test1671 test1672 test1673 \ | |
| \ | |
| @@ -0,0 +1,37 @@ | |
| + | <?xml version="1.0" encoding="US-ASCII"?> |
| + | <testcase> |
| + | <info> |
| + | <keywords> |
| + | unittest |
| + | Alt-Svc |
| + | </keywords> |
| + | </info> |
| + | |
| + | <client> |
| + | <features> |
| + | unittest |
| + | alt-svc |
| + | </features> |
| + | |
| + | # This date is exactly "20190124 22:34:21" UTC |
| + | <setenv> |
| + | CURL_TIME=1548369261 |
| + | </setenv> |
| + | <name> |
| + | alt-svc load cache with >5000 entries |
| + | </name> |
| + | <command> |
| + | %LOGDIR/%TESTNUMBER |
| + | </command> |
| + | <file name="%LOGDIR/%TESTNUMBER" mode="text"> |
| + | %repeat[5010 x h2 example.com 443 h3 shiny.example.com 8443 "20191231 00:00:00" 0 0%0a]% |
| + | </file> |
| + | </client> |
| + | |
| + | <verify> |
| + | <limits> |
| + | Allocations: 5100 |
| + | Maximum allocated: 600000 |
| + | </limits> |
| + | </verify> |
| + | </testcase> |
| @@ -41,7 +41,7 @@ TESTS_C = \ | |
| unit1636.c \ | |
| unit1650.c unit1651.c unit1652.c unit1653.c unit1654.c unit1655.c unit1656.c \ | |
| unit1657.c unit1658.c unit1660.c unit1661.c unit1663.c unit1664.c \ | |
| - | unit1666.c unit1667.c unit1668.c \ |
| + | unit1666.c unit1667.c unit1668.c unit1669.c \ |
| unit1979.c unit1980.c \ | |
| unit2600.c unit2601.c unit2602.c unit2603.c unit2604.c unit2605.c \ | |
| unit3200.c unit3205.c \ | |
| @@ -0,0 +1,58 @@ | |
| + | /*************************************************************************** |
| + | * _ _ ____ _ |
| + | * Project ___| | | | _ \| | |
| + | * / __| | | | |_) | | |
| + | * | (__| |_| | _ <| |___ |
| + | * \___|\___/|_| \_\_____| |
| + | * |
| + | * Copyright (C) Daniel Stenberg, <[email protected]>, 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.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. |
| + | * |
| + | * SPDX-License-Identifier: curl |
| + | * |
| + | ***************************************************************************/ |
| + | #include "unitcheck.h" |
| + | |
| + | #include "urldata.h" |
| + | #include "altsvc.h" |
| + | |
| + | static CURLcode test_unit1669(const char *arg) |
| + | { |
| + | UNITTEST_BEGIN_SIMPLE |
| + | |
| + | #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_ALTSVC) |
| + | char outname[256]; |
| + | CURL *curl; |
| + | CURLcode result; |
| + | struct altsvcinfo *asi = Curl_altsvc_init(); |
| + | abort_if(!asi, "Curl_altsvc_init"); |
| + | result = Curl_altsvc_load(asi, arg); |
| + | fail_if(result, "Curl_altsvc_load"); |
| + | if(result) |
| + | goto fail; |
| + | curl_global_init(CURL_GLOBAL_ALL); |
| + | curl = curl_easy_init(); |
| + | fail_if(!curl, "curl_easy_init"); |
| + | if(!curl) |
| + | goto fail; |
| + | fail_unless(Curl_llist_count(&asi->list) == MAX_ALTSVC_ENTRIES, |
| + | "wrong number of entries"); |
| + | curl_msnprintf(outname, sizeof(outname), "%s-out", arg); |
| + | |
| + | curl_easy_cleanup(curl); |
| + | fail: |
| + | Curl_altsvc_cleanup(&asi); |
| + | #endif |
| + | |
| + | UNITTEST_END(curl_global_cleanup()) |
| + | } |