quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

unit1609.c (6587B)


      1 /***************************************************************************
      2  *                                  _   _ ____  _
      3  *  Project                     ___| | | |  _ \| |
      4  *                             / __| | | | |_) | |
      5  *                            | (__| |_| |  _ <| |___
      6  *                             \___|\___/|_| \_\_____|
      7  *
      8  * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
      9  *
     10  * This software is licensed as described in the file COPYING, which
     11  * you should have received as part of this distribution. The terms
     12  * are also available at https://curl.se/docs/copyright.html.
     13  *
     14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
     15  * copies of the Software, and permit persons to whom the Software is
     16  * furnished to do so, under the terms of the COPYING file.
     17  *
     18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
     19  * KIND, either express or implied.
     20  *
     21  * SPDX-License-Identifier: curl
     22  *
     23  ***************************************************************************/
     24 #include "unitcheck.h"
     25 
     26 #include "urldata.h"
     27 #include "connect.h"
     28 #include "share.h"
     29 
     30 #include "memdebug.h" /* LAST include file */
     31 
     32 static CURLcode t1609_setup(void)
     33 {
     34   CURLcode res = CURLE_OK;
     35   global_init(CURL_GLOBAL_ALL);
     36   return res;
     37 }
     38 
     39 /* CURLOPT_RESOLVE address parsing test - to test the following defect fix:
     40 
     41  1) if there is already existing host:port pair in the DNS cache and
     42  we call CURLOPT_RESOLVE, it should also replace addresses.
     43  for example, if there is "test.com:80" with address "1.1.1.1"
     44  and we called CURLOPT_RESOLVE with address "2.2.2.2", then DNS entry needs to
     45  reflect that.
     46 
     47  2) when cached address is already there and close to expire, then by the
     48  time request is made, it can get expired.  This happens because, when
     49  we set address using CURLOPT_RESOLVE,
     50  it usually marks as permanent (by setting timestamp to zero). However,
     51  if address already exists
     52 in the cache, then it does not mark it, but just leaves it as it is.
     53  So we fixing this by timestamp to zero if address already exists too.
     54 
     55 Test:
     56 
     57  - insert new entry
     58  - verify that timestamp is not zero
     59  - call set options with CURLOPT_RESOLVE
     60  - then, call Curl_loadhostpairs
     61 
     62  expected result: cached address has zero timestamp.
     63 
     64  - call set options with CURLOPT_RESOLVE with same host:port pair,
     65    different address.
     66  - then, call Curl_loadhostpairs
     67 
     68  expected result: cached address has zero timestamp and new address
     69 */
     70 
     71 static CURLcode test_unit1609(char *arg)
     72 {
     73   UNITTEST_BEGIN(t1609_setup())
     74 
     75   struct testcase {
     76     /* host:port:address[,address]... */
     77     const char *optval;
     78 
     79     /* lowercase host and port to retrieve the addresses from hostcache */
     80     const char *host;
     81     int port;
     82 
     83     /* 0 to 9 addresses expected from hostcache */
     84     const char *address[10];
     85   };
     86 
     87   static const struct testcase tests[] = {
     88     /* spaces aren't allowed, for now */
     89     { "test.com:80:127.0.0.1",
     90       "test.com", 80, { "127.0.0.1", }
     91     },
     92     { "test.com:80:127.0.0.2",
     93       "test.com", 80, { "127.0.0.2", }
     94     },
     95   };
     96 
     97   int i;
     98   struct Curl_multi *multi = NULL;
     99   struct Curl_easy *easy = NULL;
    100   struct curl_slist *list = NULL;
    101 
    102   /* important: we setup cache outside of the loop
    103      and also clean cache after the loop. In contrast,for example,
    104      test 1607 sets up and cleans cache on each iteration. */
    105 
    106   for(i = 0; i < (int)CURL_ARRAYSIZE(tests); ++i) {
    107     int j;
    108     int addressnum = CURL_ARRAYSIZE(tests[i].address);
    109     struct Curl_addrinfo *addr;
    110     struct Curl_dns_entry *dns;
    111     void *entry_id;
    112     bool problem = false;
    113     easy = curl_easy_init();
    114     if(!easy) {
    115       curl_global_cleanup();
    116       return CURLE_OUT_OF_MEMORY;
    117     }
    118     /* create a multi handle and add the easy handle to it so that the
    119        hostcache is setup */
    120     multi = curl_multi_init();
    121     if(!multi)
    122       goto error;
    123     curl_multi_add_handle(multi, easy);
    124 
    125     list = curl_slist_append(NULL, tests[i].optval);
    126     if(!list)
    127       goto error;
    128 
    129     curl_easy_setopt(easy, CURLOPT_RESOLVE, list);
    130 
    131     if(Curl_loadhostpairs(easy))
    132       goto error;
    133 
    134     entry_id = (void *)curl_maprintf("%s:%d", tests[i].host, tests[i].port);
    135     if(!entry_id)
    136       goto error;
    137 
    138     dns = Curl_hash_pick(&multi->dnscache.entries,
    139                          entry_id, strlen(entry_id) + 1);
    140     free(entry_id);
    141     entry_id = NULL;
    142 
    143     addr = dns ? dns->addr : NULL;
    144 
    145     for(j = 0; j < addressnum; ++j) {
    146       int port = 0;
    147       char ipaddress[MAX_IPADR_LEN] = {0};
    148 
    149       if(!addr && !tests[i].address[j])
    150         break;
    151 
    152       if(addr && !Curl_addr2string(addr->ai_addr, addr->ai_addrlen,
    153                                    ipaddress, &port)) {
    154         curl_mfprintf(stderr,
    155                       "%s:%d tests[%d] failed. Curl_addr2string failed.\n",
    156                       __FILE__, __LINE__, i);
    157         problem = true;
    158         break;
    159       }
    160 
    161       if(addr && !tests[i].address[j]) {
    162         curl_mfprintf(stderr, "%s:%d tests[%d] failed. the retrieved addr "
    163                       "is %s but tests[%d].address[%d] is NULL.\n",
    164                       __FILE__, __LINE__, i, ipaddress, i, j);
    165         problem = true;
    166         break;
    167       }
    168 
    169       if(!addr && tests[i].address[j]) {
    170         curl_mfprintf(stderr, "%s:%d tests[%d] failed. the retrieved addr "
    171                       "is NULL but tests[%d].address[%d] is %s.\n",
    172                       __FILE__, __LINE__, i, i, j, tests[i].address[j]);
    173         problem = true;
    174         break;
    175       }
    176 
    177       if(!curl_strequal(ipaddress, tests[i].address[j])) {
    178         curl_mfprintf(stderr, "%s:%d tests[%d] failed. the retrieved addr "
    179                       "%s is not equal to tests[%d].address[%d] %s.\n",
    180                       __FILE__, __LINE__, i, ipaddress, i, j,
    181                       tests[i].address[j]);
    182         problem = true;
    183         break;
    184       }
    185 
    186       if(port != tests[i].port) {
    187         curl_mfprintf(stderr, "%s:%d tests[%d] failed. the retrieved port "
    188                       "for tests[%d].address[%d] is %d "
    189                       "but tests[%d].port is %d.\n",
    190                       __FILE__, __LINE__, i, i, j, port, i, tests[i].port);
    191         problem = true;
    192         break;
    193       }
    194 
    195       addr = addr->ai_next;
    196     }
    197 
    198     curl_easy_cleanup(easy);
    199     easy = NULL;
    200     curl_multi_cleanup(multi);
    201     multi = NULL;
    202     curl_slist_free_all(list);
    203     list = NULL;
    204 
    205     if(problem) {
    206       unitfail++;
    207       continue;
    208     }
    209   }
    210   goto unit_test_abort;
    211 error:
    212   curl_easy_cleanup(easy);
    213   curl_multi_cleanup(multi);
    214   curl_slist_free_all(list);
    215 
    216   UNITTEST_END(curl_global_cleanup())
    217 }