Annotation of embedaddon/curl/tests/unit/unit1609.c, revision 1.1
1.1 ! misho 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>