CURLcode Curl_loadhostpairs(struct Curl_easy *data)
{
struct curl_slist *hostp;
- const char *host_end;
/* Default is no wildcard found */
data->state.wildcard_resolve = FALSE;
for(hostp = data->state.resolve; hostp; hostp = hostp->next) {
char entry_id[MAX_HOSTCACHE_LEN];
- if(!hostp->data)
+ const char *host = hostp->data;
+ struct Curl_str source;
+ if(!host)
continue;
- if(hostp->data[0] == '-') {
+ if(*host == '-') {
curl_off_t num = 0;
size_t entry_len;
- size_t hlen = 0;
- host_end = strchr(&hostp->data[1], ':');
-
- if(host_end) {
- hlen = host_end - &hostp->data[1];
- host_end++;
- if(Curl_str_number(&host_end, &num, 0xffff))
- host_end = NULL;
+ host++;
+ if(!Curl_str_single(&host, '[')) {
+ if(Curl_str_until(&host, &source, MAX_IPADR_LEN, ']') ||
+ Curl_str_single(&host, ']') ||
+ Curl_str_single(&host, ':'))
+ continue;
}
- if(!host_end) {
- infof(data, "Bad syntax CURLOPT_RESOLVE removal entry '%s'",
- hostp->data);
- continue;
+ else {
+ if(Curl_str_until(&host, &source, 4096, ':') ||
+ Curl_str_single(&host, ':')) {
+ continue;
+ }
}
- /* Create an entry id, based upon the hostname and port */
- entry_len = create_hostcache_id(&hostp->data[1], hlen, (int)num,
- entry_id, sizeof(entry_id));
- if(data->share)
- Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
- /* delete entry, ignore if it did not exist */
- Curl_hash_delete(data->dns.hostcache, entry_id, entry_len + 1);
+ if(!Curl_str_number(&host, &num, 0xffff)) {
+ /* Create an entry id, based upon the hostname and port */
+ entry_len = create_hostcache_id(source.str, source.len, (int)num,
+ entry_id, sizeof(entry_id));
+ if(data->share)
+ Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
- if(data->share)
- Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
+ /* delete entry, ignore if it did not exist */
+ Curl_hash_delete(data->dns.hostcache, entry_id, entry_len + 1);
+
+ if(data->share)
+ Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
+ }
}
else {
struct Curl_dns_entry *dns;
#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
const char *addresses = NULL;
#endif
- const char *addr_begin;
- const char *addr_end;
- const char *port_ptr;
curl_off_t port = 0;
- const char *end_ptr;
bool permanent = TRUE;
bool error = TRUE;
- char *host_begin = hostp->data;
- size_t hlen = 0;
- if(host_begin[0] == '+') {
- host_begin++;
+ if(*host == '+') {
+ host++;
permanent = FALSE;
}
- host_end = strchr(host_begin, ':');
- if(!host_end)
- goto err;
- hlen = host_end - host_begin;
-
- port_ptr = host_end + 1;
- if(Curl_str_number(&port_ptr, &port, 0xffff) ||
- (*port_ptr != ':'))
+ if(!Curl_str_single(&host, '[')) {
+ if(Curl_str_until(&host, &source, MAX_IPADR_LEN, ']') ||
+ Curl_str_single(&host, ']'))
+ continue;
+ }
+ else {
+ if(Curl_str_until(&host, &source, 4096, ':'))
+ continue;
+ }
+ if(Curl_str_single(&host, ':') ||
+ Curl_str_number(&host, &port, 0xffff) ||
+ Curl_str_single(&host, ':'))
goto err;
- end_ptr = port_ptr;
#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
- addresses = end_ptr + 1;
+ addresses = host;
#endif
- while(*end_ptr) {
- size_t alen;
+ /* start the address section */
+ while(*host) {
+ struct Curl_str target;
struct Curl_addrinfo *ai;
- addr_begin = end_ptr + 1;
- addr_end = strchr(addr_begin, ',');
- if(!addr_end)
- addr_end = addr_begin + strlen(addr_begin);
- end_ptr = addr_end;
-
- /* allow IP(v6) address within [brackets] */
- if(*addr_begin == '[') {
- if(addr_end == addr_begin || *(addr_end - 1) != ']')
+ if(!Curl_str_single(&host, '[')) {
+ if(Curl_str_until(&host, &target, MAX_IPADR_LEN, ']') ||
+ Curl_str_single(&host, ']'))
goto err;
- ++addr_begin;
- --addr_end;
}
-
- alen = addr_end - addr_begin;
- if(!alen)
- continue;
-
- if(alen >= sizeof(address))
- goto err;
-
- memcpy(address, addr_begin, alen);
- address[alen] = '\0';
-
+ else {
+ if(Curl_str_until(&host, &target, 4096, ',')) {
+ if(Curl_str_single(&host, ','))
+ goto err;
+ /* survive nothing but just a comma */
+ continue;
+ }
+ }
#ifndef USE_IPV6
- if(strchr(address, ':')) {
+ if(memchr(target.str, ':', target.len)) {
infof(data, "Ignoring resolve address '%s', missing IPv6 support.",
address);
+ if(Curl_str_single(&host, ','))
+ goto err;
continue;
}
#endif
+ if(target.len >= sizeof(address))
+ goto err;
+
+ memcpy(address, target.str, target.len);
+ address[target.len] = '\0';
+
ai = Curl_str2addr(address, (int)port);
if(!ai) {
infof(data, "Resolve address '%s' found illegal", address);
else {
head = tail = ai;
}
+ if(Curl_str_single(&host, ','))
+ break;
}
if(!head)
}
/* Create an entry id, based upon the hostname and port */
- entry_len = create_hostcache_id(host_begin, hlen, (int)port,
+ entry_len = create_hostcache_id(source.str, source.len, (int)port,
entry_id, sizeof(entry_id));
if(data->share)
if(dns) {
infof(data, "RESOLVE %.*s:%" CURL_FORMAT_CURL_OFF_T
- " - old addresses discarded", (int)hlen, host_begin, port);
+ " - old addresses discarded", (int)source.len, source.str, port);
/* delete old entry, there are two reasons for this
1. old entry may have different addresses.
2. even if entry with correct addresses is already in the cache,
}
/* put this new host in the cache */
- dns = Curl_cache_addr(data, head, host_begin, hlen, (int)port,
+ dns = Curl_cache_addr(data, head, source.str, source.len, (int)port,
permanent);
if(dns) {
/* release the returned reference; the cache itself will keep the
}
#ifndef CURL_DISABLE_VERBOSE_STRINGS
infof(data, "Added %.*s:%" CURL_FORMAT_CURL_OFF_T ":%s to DNS cache%s",
- (int)hlen, host_begin, port, addresses,
+ (int)source.len, source.str, port, addresses,
permanent ? "" : " (non-permanent)");
#endif
/* Wildcard hostname */
- if((hlen == 1) && (host_begin[0] == '*')) {
+ if((source.len == 1) && (source.str[0] == '*')) {
infof(data, "RESOLVE *:%" CURL_FORMAT_CURL_OFF_T " using wildcard",
port);
data->state.wildcard_resolve = TRUE;