Skip to content

Commit

Permalink
hostip: support wildcard hosts
Browse files Browse the repository at this point in the history
This adds support for wildcard hosts in CURLOPT_RESOLVE. These are
try-last so any non-wildcard entry is resolved first. If specified,
any host not matched by another CURLOPT_RESOLVE config will use this
as fallback.

Example send a.com to 10.0.0.1 and everything else to 10.0.0.2:
  curl --resolve *:443:10.0.0.2 --resolve a.com:443:10.0.0.1 \
       https://a.com https://b.com

This is probably quite similar to using:
  --connect-to a.com:443:10.0.0.1:443 --connect-to :443:10.0.0.2:443

Closes #3406
Reviewed-by: Daniel Stenberg <daniel@haxx.se>
  • Loading branch information
claesjac authored and danielgustafsson committed Dec 27, 2018
1 parent ba266b3 commit d8cae79
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 1 deletion.
6 changes: 6 additions & 0 deletions docs/cmdline-opts/resolve.d
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,17 @@ the number used for the specific protocol the host will be used for. It means
you need several entries if you want to provide address for the same host but
different ports.

By specifying '*' as host you can tell curl to resolve any host and specific
port pair to the specified address. Wildcard is resolved last so any --resolve
with a specific host and port will be used first.

The provided address set by this option will be used even if --ipv4 or --ipv6
is set to make curl use another IP version.

Support for providing the IP address within [brackets] was added in 7.57.0.

Support for providing multiple IP addresses per entry was added in 7.59.0.

Support for resolving with wildcard was added in 7.64.0.

This option can be used many times to add many host names to resolve.
30 changes: 30 additions & 0 deletions lib/hostip.c
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,26 @@ fetch_addr(struct connectdata *conn,
/* See if its already in our dns cache */
dns = Curl_hash_pick(data->dns.hostcache, entry_id, entry_len + 1);

/* No entry found in cache, check if we might have a wildcard entry */
if(!dns && data->change.wildcard_resolve) {
/*
* Free the previous entry_id before requesting a new one to avoid leaking
* memory
*/
free(entry_id);

entry_id = create_hostcache_id("*", port);

/* If we can't create the entry id, fail */
if(!entry_id)
return dns;

entry_len = strlen(entry_id);

/* See if it's already in our dns cache */
dns = Curl_hash_pick(data->dns.hostcache, entry_id, entry_len + 1);
}

if(dns && (data->set.dns_cache_timeout != -1)) {
/* See whether the returned entry is stale. Done before we release lock */
struct hostcache_prune_data user;
Expand Down Expand Up @@ -872,6 +892,9 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
char hostname[256];
int port = 0;

/* Default is no wildcard found */
data->change.wildcard_resolve = false;

for(hostp = data->change.resolve; hostp; hostp = hostp->next) {
if(!hostp->data)
continue;
Expand Down Expand Up @@ -1052,6 +1075,13 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
}
infof(data, "Added %s:%d:%s to DNS cache\n",
hostname, port, addresses);

/* Wildcard hostname */
if(hostname[0] == '*' && hostname[1] == '\0') {
infof(data, "RESOLVE %s:%d is wildcard, enabling wildcard checks\n",
hostname, port);
data->change.wildcard_resolve = true;
}
}
}
data->change.resolve = NULL; /* dealt with now */
Expand Down
1 change: 1 addition & 0 deletions lib/urldata.h
Original file line number Diff line number Diff line change
Expand Up @@ -1397,6 +1397,7 @@ struct DynamicStatic {
curl_easy_setopt(COOKIEFILE) calls */
struct curl_slist *resolve; /* set to point to the set.resolve list when
this should be dealt with in pretransfer */
bool wildcard_resolve; /* Set to true if any resolve change is a wildcard */
};

/*
Expand Down
2 changes: 1 addition & 1 deletion tests/data/Makefile.inc
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ test1424 test1425 test1426 test1427 \
test1428 test1429 test1430 test1431 test1432 test1433 test1434 test1435 \
test1436 test1437 test1438 test1439 test1440 test1441 test1442 test1443 \
test1444 test1445 test1446 test1447 test1448 test1449 test1450 test1451 \
test1452 test1453 test1454 test1455 test1456 test1457 \
test1452 test1453 test1454 test1455 test1456 test1457 test1458\
test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1507 \
test1508 test1509 test1510 test1511 test1512 test1513 test1514 test1515 \
test1516 test1517 test1518 test1519 test1520 test1521 test1522 \
Expand Down
56 changes: 56 additions & 0 deletions tests/data/test1458
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<testcase>
<info>
<keywords>
HTTP
HTTP GET
--resolve
</keywords>
</info>

#
# Server-side
<reply>
<data>
HTTP/1.1 200 OK
Date: Thu, 09 Nov 2010 14:49:00 GMT
Server: test-server/fake
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
ETag: "21025-dc7-39462498"
Accept-Ranges: bytes
Content-Length: 6
Connection: close
Content-Type: text/html
Funny-head: yesyes

-foo-
</data>
</reply>

#
# Client-side
<client>
<server>
http
</server>
<name>
HTTP with wildcard --resolve
</name>
<command>
--resolve *:%HTTPPORT:%HOSTIP http://example.com:%HTTPPORT/1458
</command>
</client>

#
# Verify data after the test has been "shot"
<verify>
<strip>
^User-Agent:.*
</strip>
<protocol>
GET /1458 HTTP/1.1
Host: example.com:%HTTPPORT
Accept: */*

</protocol>
</verify>
</testcase>

0 comments on commit d8cae79

Please sign in to comment.