Loading docs/cmdline-opts/resolve.d +3 −1 Original line number Diff line number Diff line Long: resolve Arg: <host:port:address> Arg: <host:port:address[,address]...> Help: Resolve the host+port to this address Added: 7.21.3 --- Loading @@ -16,4 +16,6 @@ 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. This option can be used many times to add many host names to resolve. docs/libcurl/opts/CURLOPT_RESOLVE.3 +8 −4 Original line number Diff line number Diff line Loading @@ -37,10 +37,12 @@ list of \fBstruct curl_slist\fP structs properly filled in. Use to clean up an entire list. Each single name resolve string should be written using the format HOST:PORT:ADDRESS where HOST is the name libcurl will try to resolve, PORT is the port number of the service where libcurl wants to connect to the HOST and ADDRESS is the numerical IP address. If libcurl is built to support IPv6, ADDRESS can of course be either IPv4 or IPv6 style addressing. HOST:PORT:ADDRESS[,ADDRESS]... where HOST is the name libcurl will try to resolve, PORT is the port number of the service where libcurl wants to connect to the HOST and ADDRESS is one or more numerical IP addresses. If you specify multiple ip addresses they need to be separated by comma. If libcurl is built to support IPv6, each of the ADDRESS entries can of course be either IPv4 or IPv6 style addressing. This option effectively pre-populates the DNS cache with entries for the host+port pair so redirects and everything that operations against the Loading @@ -57,6 +59,8 @@ by including a string in the linked list that uses the format and port number must exactly match what was already added previously. Support for providing the ADDRESS within [brackets] was added in 7.57.0. Support for providing multiple IP addresses per entry was added in 7.59.0. .SH DEFAULT NULL .SH PROTOCOLS Loading lib/connect.c +8 −8 Original line number Diff line number Diff line Loading @@ -619,7 +619,7 @@ void Curl_persistconninfo(struct connectdata *conn) /* retrieves ip address and port from a sockaddr structure. note it calls Curl_inet_ntop which sets errno on fail, not SOCKERRNO. */ static bool getaddressinfo(struct sockaddr *sa, char *addr, bool Curl_getaddressinfo(struct sockaddr *sa, char *addr, long *port) { unsigned short us_port; Loading Loading @@ -700,7 +700,7 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd) return; } if(!getaddressinfo((struct sockaddr*)&ssrem, if(!Curl_getaddressinfo((struct sockaddr*)&ssrem, conn->primary_ip, &conn->primary_port)) { failf(data, "ssrem inet_ntop() failed with errno %d: %s", errno, Curl_strerror(conn, errno)); Loading @@ -708,7 +708,7 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd) } memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN); if(!getaddressinfo((struct sockaddr*)&ssloc, if(!Curl_getaddressinfo((struct sockaddr*)&ssloc, conn->local_ip, &conn->local_port)) { failf(data, "ssloc inet_ntop() failed with errno %d: %s", errno, Curl_strerror(conn, errno)); Loading Loading @@ -1005,7 +1005,7 @@ static CURLcode singleipconnect(struct connectdata *conn, return CURLE_OK; /* store remote address and port used in this connection attempt */ if(!getaddressinfo((struct sockaddr*)&addr.sa_addr, if(!Curl_getaddressinfo((struct sockaddr*)&addr.sa_addr, ipaddress, &port)) { /* malformed address or bug in inet_ntop, try next address */ failf(data, "sa_addr inet_ntop() failed with errno %d: %s", Loading lib/connect.h +5 −0 Original line number Diff line number Diff line Loading @@ -77,6 +77,11 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd); void Curl_persistconninfo(struct connectdata *conn); int Curl_closesocket(struct connectdata *conn, curl_socket_t sock); /* * Get presentation format IP address and port from a sockaddr. */ bool Curl_getaddressinfo(struct sockaddr *sa, char *addr, long *port); /* * The Curl_sockaddr_ex structure is basically libcurl's external API * curl_sockaddr structure with enough space available to directly hold any Loading lib/hostip.c +89 −27 Original line number Diff line number Diff line Loading @@ -781,7 +781,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) { struct curl_slist *hostp; char hostname[256]; int port; int port = 0; for(hostp = data->change.resolve; hostp; hostp = hostp->next) { if(!hostp->data) Loading Loading @@ -819,32 +819,95 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) } else { struct Curl_dns_entry *dns; Curl_addrinfo *addr; Curl_addrinfo *head = NULL, *tail = NULL; char *entry_id; size_t entry_len; char buffer[256]; char *address = &buffer[0]; char address[64]; char *addresses; char *addr_begin; char *addr_end; char *port_ptr; char *end_ptr; char *host_end; unsigned long tmp_port; bool error = true; host_end = strchr(hostp->data, ':'); if(!host_end || ((host_end - hostp->data) >= (ptrdiff_t)sizeof(hostname))) goto err; memcpy(hostname, hostp->data, host_end - hostp->data); hostname[host_end - hostp->data] = '\0'; port_ptr = host_end + 1; tmp_port = strtoul(port_ptr, &end_ptr, 10); if(end_ptr == port_ptr || tmp_port > USHRT_MAX || *end_ptr != ':') goto err; port = (int)tmp_port; addresses = end_ptr + 1; while(*end_ptr) { size_t alen; 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; if(3 != sscanf(hostp->data, "%255[^:]:%d:%255s", hostname, &port, address)) { infof(data, "Couldn't parse CURLOPT_RESOLVE entry '%s'!\n", hostp->data); continue; /* allow IP(v6) address within [brackets] */ if(*addr_begin == '[') { if(addr_end == addr_begin || *(addr_end - 1) != ']') goto err; ++addr_begin; --addr_end; } /* allow IP(v6) address within [brackets] */ if(address[0] == '[') { size_t alen = strlen(address); if(address[alen-1] != ']') /* it needs to also end with ] to be valid */ alen = addr_end - addr_begin; if(!alen) continue; if(alen >= sizeof(address)) goto err; memcpy(address, addr_begin, alen); address[alen] = '\0'; #ifndef ENABLE_IPV6 if(strchr(address, ':')) { infof(data, "Ignoring resolve address '%s', missing IPv6 support.\n", address); continue; address[alen-1] = 0; /* zero terminate there */ address++; /* pass the open bracket */ } #endif addr = Curl_str2addr(address, port); if(!addr) { infof(data, "Address in '%s' found illegal!\n", hostp->data); ai = Curl_str2addr(address, port); if(!ai) { infof(data, "Resolve address '%s' found illegal!\n", address); goto err; } if(tail) { tail->ai_next = ai; tail = tail->ai_next; } else { head = tail = ai; } } if(!head) goto err; error = false; err: if(error) { infof(data, "Couldn't parse CURLOPT_RESOLVE entry '%s'!\n", hostp->data); Curl_freeaddrinfo(head); continue; } Loading @@ -852,10 +915,9 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) entry_id = create_hostcache_id(hostname, port); /* If we can't create the entry id, fail */ if(!entry_id) { Curl_freeaddrinfo(addr); Curl_freeaddrinfo(head); return CURLE_OUT_OF_MEMORY; } entry_len = strlen(entry_id); if(data->share) Loading @@ -869,7 +931,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) if(!dns) { /* if not in the cache already, put this host in the cache */ dns = Curl_cache_addr(data, addr, hostname, port); dns = Curl_cache_addr(data, head, hostname, port); if(dns) { dns->timestamp = 0; /* mark as added by CURLOPT_RESOLVE */ /* release the returned reference; the cache itself will keep the Loading @@ -880,19 +942,19 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) else { /* this is a duplicate, free it again */ infof(data, "RESOLVE %s:%d is already cached, %s not stored!\n", hostname, port, address); Curl_freeaddrinfo(addr); hostname, port, addresses); Curl_freeaddrinfo(head); } if(data->share) Curl_share_unlock(data, CURL_LOCK_DATA_DNS); if(!dns) { Curl_freeaddrinfo(addr); Curl_freeaddrinfo(head); return CURLE_OUT_OF_MEMORY; } infof(data, "Added %s:%d:%s to DNS cache\n", hostname, port, address); hostname, port, addresses); } } data->change.resolve = NULL; /* dealt with now */ Loading Loading
docs/cmdline-opts/resolve.d +3 −1 Original line number Diff line number Diff line Long: resolve Arg: <host:port:address> Arg: <host:port:address[,address]...> Help: Resolve the host+port to this address Added: 7.21.3 --- Loading @@ -16,4 +16,6 @@ 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. This option can be used many times to add many host names to resolve.
docs/libcurl/opts/CURLOPT_RESOLVE.3 +8 −4 Original line number Diff line number Diff line Loading @@ -37,10 +37,12 @@ list of \fBstruct curl_slist\fP structs properly filled in. Use to clean up an entire list. Each single name resolve string should be written using the format HOST:PORT:ADDRESS where HOST is the name libcurl will try to resolve, PORT is the port number of the service where libcurl wants to connect to the HOST and ADDRESS is the numerical IP address. If libcurl is built to support IPv6, ADDRESS can of course be either IPv4 or IPv6 style addressing. HOST:PORT:ADDRESS[,ADDRESS]... where HOST is the name libcurl will try to resolve, PORT is the port number of the service where libcurl wants to connect to the HOST and ADDRESS is one or more numerical IP addresses. If you specify multiple ip addresses they need to be separated by comma. If libcurl is built to support IPv6, each of the ADDRESS entries can of course be either IPv4 or IPv6 style addressing. This option effectively pre-populates the DNS cache with entries for the host+port pair so redirects and everything that operations against the Loading @@ -57,6 +59,8 @@ by including a string in the linked list that uses the format and port number must exactly match what was already added previously. Support for providing the ADDRESS within [brackets] was added in 7.57.0. Support for providing multiple IP addresses per entry was added in 7.59.0. .SH DEFAULT NULL .SH PROTOCOLS Loading
lib/connect.c +8 −8 Original line number Diff line number Diff line Loading @@ -619,7 +619,7 @@ void Curl_persistconninfo(struct connectdata *conn) /* retrieves ip address and port from a sockaddr structure. note it calls Curl_inet_ntop which sets errno on fail, not SOCKERRNO. */ static bool getaddressinfo(struct sockaddr *sa, char *addr, bool Curl_getaddressinfo(struct sockaddr *sa, char *addr, long *port) { unsigned short us_port; Loading Loading @@ -700,7 +700,7 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd) return; } if(!getaddressinfo((struct sockaddr*)&ssrem, if(!Curl_getaddressinfo((struct sockaddr*)&ssrem, conn->primary_ip, &conn->primary_port)) { failf(data, "ssrem inet_ntop() failed with errno %d: %s", errno, Curl_strerror(conn, errno)); Loading @@ -708,7 +708,7 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd) } memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN); if(!getaddressinfo((struct sockaddr*)&ssloc, if(!Curl_getaddressinfo((struct sockaddr*)&ssloc, conn->local_ip, &conn->local_port)) { failf(data, "ssloc inet_ntop() failed with errno %d: %s", errno, Curl_strerror(conn, errno)); Loading Loading @@ -1005,7 +1005,7 @@ static CURLcode singleipconnect(struct connectdata *conn, return CURLE_OK; /* store remote address and port used in this connection attempt */ if(!getaddressinfo((struct sockaddr*)&addr.sa_addr, if(!Curl_getaddressinfo((struct sockaddr*)&addr.sa_addr, ipaddress, &port)) { /* malformed address or bug in inet_ntop, try next address */ failf(data, "sa_addr inet_ntop() failed with errno %d: %s", Loading
lib/connect.h +5 −0 Original line number Diff line number Diff line Loading @@ -77,6 +77,11 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd); void Curl_persistconninfo(struct connectdata *conn); int Curl_closesocket(struct connectdata *conn, curl_socket_t sock); /* * Get presentation format IP address and port from a sockaddr. */ bool Curl_getaddressinfo(struct sockaddr *sa, char *addr, long *port); /* * The Curl_sockaddr_ex structure is basically libcurl's external API * curl_sockaddr structure with enough space available to directly hold any Loading
lib/hostip.c +89 −27 Original line number Diff line number Diff line Loading @@ -781,7 +781,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) { struct curl_slist *hostp; char hostname[256]; int port; int port = 0; for(hostp = data->change.resolve; hostp; hostp = hostp->next) { if(!hostp->data) Loading Loading @@ -819,32 +819,95 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) } else { struct Curl_dns_entry *dns; Curl_addrinfo *addr; Curl_addrinfo *head = NULL, *tail = NULL; char *entry_id; size_t entry_len; char buffer[256]; char *address = &buffer[0]; char address[64]; char *addresses; char *addr_begin; char *addr_end; char *port_ptr; char *end_ptr; char *host_end; unsigned long tmp_port; bool error = true; host_end = strchr(hostp->data, ':'); if(!host_end || ((host_end - hostp->data) >= (ptrdiff_t)sizeof(hostname))) goto err; memcpy(hostname, hostp->data, host_end - hostp->data); hostname[host_end - hostp->data] = '\0'; port_ptr = host_end + 1; tmp_port = strtoul(port_ptr, &end_ptr, 10); if(end_ptr == port_ptr || tmp_port > USHRT_MAX || *end_ptr != ':') goto err; port = (int)tmp_port; addresses = end_ptr + 1; while(*end_ptr) { size_t alen; 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; if(3 != sscanf(hostp->data, "%255[^:]:%d:%255s", hostname, &port, address)) { infof(data, "Couldn't parse CURLOPT_RESOLVE entry '%s'!\n", hostp->data); continue; /* allow IP(v6) address within [brackets] */ if(*addr_begin == '[') { if(addr_end == addr_begin || *(addr_end - 1) != ']') goto err; ++addr_begin; --addr_end; } /* allow IP(v6) address within [brackets] */ if(address[0] == '[') { size_t alen = strlen(address); if(address[alen-1] != ']') /* it needs to also end with ] to be valid */ alen = addr_end - addr_begin; if(!alen) continue; if(alen >= sizeof(address)) goto err; memcpy(address, addr_begin, alen); address[alen] = '\0'; #ifndef ENABLE_IPV6 if(strchr(address, ':')) { infof(data, "Ignoring resolve address '%s', missing IPv6 support.\n", address); continue; address[alen-1] = 0; /* zero terminate there */ address++; /* pass the open bracket */ } #endif addr = Curl_str2addr(address, port); if(!addr) { infof(data, "Address in '%s' found illegal!\n", hostp->data); ai = Curl_str2addr(address, port); if(!ai) { infof(data, "Resolve address '%s' found illegal!\n", address); goto err; } if(tail) { tail->ai_next = ai; tail = tail->ai_next; } else { head = tail = ai; } } if(!head) goto err; error = false; err: if(error) { infof(data, "Couldn't parse CURLOPT_RESOLVE entry '%s'!\n", hostp->data); Curl_freeaddrinfo(head); continue; } Loading @@ -852,10 +915,9 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) entry_id = create_hostcache_id(hostname, port); /* If we can't create the entry id, fail */ if(!entry_id) { Curl_freeaddrinfo(addr); Curl_freeaddrinfo(head); return CURLE_OUT_OF_MEMORY; } entry_len = strlen(entry_id); if(data->share) Loading @@ -869,7 +931,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) if(!dns) { /* if not in the cache already, put this host in the cache */ dns = Curl_cache_addr(data, addr, hostname, port); dns = Curl_cache_addr(data, head, hostname, port); if(dns) { dns->timestamp = 0; /* mark as added by CURLOPT_RESOLVE */ /* release the returned reference; the cache itself will keep the Loading @@ -880,19 +942,19 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) else { /* this is a duplicate, free it again */ infof(data, "RESOLVE %s:%d is already cached, %s not stored!\n", hostname, port, address); Curl_freeaddrinfo(addr); hostname, port, addresses); Curl_freeaddrinfo(head); } if(data->share) Curl_share_unlock(data, CURL_LOCK_DATA_DNS); if(!dns) { Curl_freeaddrinfo(addr); Curl_freeaddrinfo(head); return CURLE_OUT_OF_MEMORY; } infof(data, "Added %s:%d:%s to DNS cache\n", hostname, port, address); hostname, port, addresses); } } data->change.resolve = NULL; /* dealt with now */ Loading