File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / curl / tests / unit / unit1609.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Jun 3 10:01:16 2020 UTC (5 years ago) by misho
Branches: curl, MAIN
CVS tags: v7_70_0p4, HEAD
curl

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>