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