summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKim Vandry <vandry@TZoNE.ORG>2013-09-07 12:45:50 -0400
committerDaniel Stenberg <daniel@haxx.se>2013-09-12 21:11:47 +0200
commitdf69440d05f1133a9053e19a9bf576c8b13514b9 (patch)
treecfe02627be58fea1a429efa2112dfa3969a981c1
parent345955e87e21769e917cf407c5c794a05c4f2612 (diff)
downloadcurl-df69440d05f1133a9053e19a9bf576c8b13514b9.tar.gz
libcurl: New options to bind DNS to local interfaces or IP addresses
-rw-r--r--docs/libcurl/curl_easy_setopt.330
-rw-r--r--docs/libcurl/symbols-in-versions3
-rw-r--r--include/curl/curl.h13
-rw-r--r--include/curl/typecheck-gcc.h4
-rw-r--r--lib/asyn-ares.c61
-rw-r--r--lib/asyn-thread.c24
-rw-r--r--lib/hostip.h21
-rw-r--r--lib/hostsyn.c36
-rw-r--r--lib/url.c9
9 files changed, 201 insertions, 0 deletions
diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3
index f4084823d..b370855f9 100644
--- a/docs/libcurl/curl_easy_setopt.3
+++ b/docs/libcurl/curl_easy_setopt.3
@@ -2298,6 +2298,36 @@ This option requires that libcurl was built with a resolver backend that
supports this operation. The c-ares backend is the only such one.
(Added in 7.24.0)
+.IP CURLOPT_DNS_INTERFACE
+Pass a char * as parameter. Set the name of the network interface that
+the DNS resolver should bind to. This must be an interface name (not an
+address). Set this option to NULL to use the default setting (don't
+bind to a specific interface).
+
+This option requires that libcurl was built with a resolver backend that
+supports this operation. The c-ares backend is the only such one.
+
+(Added in 7.33.0)
+.IP CURLOPT_DNS_LOCAL_IP4
+Set the local IPv4 address that the resolver should bind to. The argument
+should be of type char * and contain a single IPv4 address as a string.
+Set this option to NULL to use the default setting (don't
+bind to a specific IP address).
+
+This option requires that libcurl was built with a resolver backend that
+supports this operation. The c-ares backend is the only such one.
+
+(Added in 7.33.0)
+.IP CURLOPT_DNS_LOCAL_IP6
+Set the local IPv6 address that the resolver should bind to. The argument
+should be of type char * and contain a single IPv6 address as a string.
+Set this option to NULL to use the default setting (don't
+bind to a specific IP address).
+
+This option requires that libcurl was built with a resolver backend that
+supports this operation. The c-ares backend is the only such one.
+
+(Added in 7.33.0)
.IP CURLOPT_ACCEPTTIMEOUT_MS
Pass a long telling libcurl the maximum number of milliseconds to wait for a
server to connect back to libcurl when an active FTP connection is used. If no
diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions
index 3e20cd657..7c362cde7 100644
--- a/docs/libcurl/symbols-in-versions
+++ b/docs/libcurl/symbols-in-versions
@@ -332,6 +332,9 @@ CURLOPT_DEBUGDATA 7.9.6
CURLOPT_DEBUGFUNCTION 7.9.6
CURLOPT_DIRLISTONLY 7.17.0
CURLOPT_DNS_CACHE_TIMEOUT 7.9.3
+CURLOPT_DNS_INTERFACE 7.33.0
+CURLOPT_DNS_LOCAL_IP4 7.33.0
+CURLOPT_DNS_LOCAL_IP6 7.33.0
CURLOPT_DNS_SERVERS 7.24.0
CURLOPT_DNS_USE_GLOBAL_CACHE 7.9.3 7.11.1
CURLOPT_EGDSOCKET 7.7
diff --git a/include/curl/curl.h b/include/curl/curl.h
index 239cecbf5..4e09cf728 100644
--- a/include/curl/curl.h
+++ b/include/curl/curl.h
@@ -1556,6 +1556,19 @@ typedef enum {
/* The XOAUTH2 bearer token */
CINIT(XOAUTH2_BEARER, OBJECTPOINT, 220),
+ /* Set the interface string to use as outgoing network
+ * interface for DNS requests.
+ * Only supported by the c-ares DNS backend */
+ CINIT(DNS_INTERFACE, OBJECTPOINT, 221),
+
+ /* Set the local IPv4 address to use for outgoing DNS requests.
+ * Only supported by the c-ares DNS backend */
+ CINIT(DNS_LOCAL_IP4, OBJECTPOINT, 222),
+
+ /* Set the local IPv4 address to use for outgoing DNS requests.
+ * Only supported by the c-ares DNS backend */
+ CINIT(DNS_LOCAL_IP6, OBJECTPOINT, 223),
+
CURLOPT_LASTENTRY /* the last unused */
} CURLoption;
diff --git a/include/curl/typecheck-gcc.h b/include/curl/typecheck-gcc.h
index a9fee0c84..e8f1dff9a 100644
--- a/include/curl/typecheck-gcc.h
+++ b/include/curl/typecheck-gcc.h
@@ -265,6 +265,10 @@ _CURL_WARNING(_curl_easy_getinfo_err_curl_slist,
(option) == CURLOPT_RTSP_STREAM_URI || \
(option) == CURLOPT_RTSP_TRANSPORT || \
(option) == CURLOPT_XOAUTH2_BEARER || \
+ (option) == CURLOPT_DNS_SERVERS || \
+ (option) == CURLOPT_DNS_INTERFACE || \
+ (option) == CURLOPT_DNS_LOCAL_IP4 || \
+ (option) == CURLOPT_DNS_LOCAL_IP6 || \
0)
/* evaluates to true if option takes a curl_write_callback argument */
diff --git a/lib/asyn-ares.c b/lib/asyn-ares.c
index 081667dc3..fa12f21de 100644
--- a/lib/asyn-ares.c
+++ b/lib/asyn-ares.c
@@ -623,4 +623,65 @@ CURLcode Curl_set_dns_servers(struct SessionHandle *data,
#endif
return result;
}
+
+CURLcode Curl_set_dns_interface(struct SessionHandle *data,
+ const char *interface)
+{
+#if (ARES_VERSION >= 0x010704)
+ if(!interface) interface = "";
+ ares_set_local_dev((ares_channel)data->state.resolver, interface);
+ return CURLE_OK;
+#else /* c-ares version too old! */
+ (void)data;
+ (void)interface;
+ return CURLE_NOT_BUILT_IN;
+#endif
+}
+
+CURLcode Curl_set_dns_local_ip4(struct SessionHandle *data,
+ const char *local_ip4)
+{
+#if (ARES_VERSION >= 0x010704)
+ uint32_t a4;
+
+ if((!local_ip4) || (local_ip4[0] == 0)) {
+ a4 = 0; /* disabled: do not bind to a specific address */
+ }
+ else {
+ if(Curl_inet_pton(AF_INET, local_ip4, &a4) != 1) {
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ }
+ }
+ ares_set_local_ip4((ares_channel)data->state.resolver, ntohl(a4));
+ return CURLE_OK;
+#else /* c-ares version too old! */
+ (void)data;
+ (void)local_ip4;
+ return CURLE_NOT_BUILT_IN;
+#endif
+}
+
+CURLcode Curl_set_dns_local_ip6(struct SessionHandle *data,
+ const char *local_ip6)
+{
+#if (ARES_VERSION >= 0x010704)
+ unsigned char a6[INET6_ADDRSTRLEN];
+
+ if((!local_ip6) || (local_ip6[0] == 0)) {
+ /* disabled: do not bind to a specific address */
+ memset(a6, 0, sizeof(a6));
+ }
+ else {
+ if(Curl_inet_pton(AF_INET6, local_ip6, a6) != 1) {
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ }
+ }
+ ares_set_local_ip6((ares_channel)data->state.resolver, a6);
+ return CURLE_OK;
+#else /* c-ares version too old! */
+ (void)data;
+ (void)local_ip6;
+ return CURLE_NOT_BUILT_IN;
+#endif
+}
#endif /* CURLRES_ARES */
diff --git a/lib/asyn-thread.c b/lib/asyn-thread.c
index 81d1d5d5d..206dcdb1f 100644
--- a/lib/asyn-thread.c
+++ b/lib/asyn-thread.c
@@ -635,4 +635,28 @@ CURLcode Curl_set_dns_servers(struct SessionHandle *data,
}
+CURLcode Curl_set_dns_interface(struct SessionHandle *data,
+ const char *interface)
+{
+ (void)data;
+ (void)interface;
+ return CURLE_NOT_BUILT_IN;
+}
+
+CURLcode Curl_set_dns_local_ip4(struct SessionHandle *data,
+ const char *local_ip4)
+{
+ (void)data;
+ (void)local_ip4;
+ return CURLE_NOT_BUILT_IN;
+}
+
+CURLcode Curl_set_dns_local_ip6(struct SessionHandle *data,
+ const char *local_ip6)
+{
+ (void)data;
+ (void)local_ip6;
+ return CURLE_NOT_BUILT_IN;
+}
+
#endif /* CURLRES_THREADED */
diff --git a/lib/hostip.h b/lib/hostip.h
index a38f732a4..997800a88 100644
--- a/lib/hostip.h
+++ b/lib/hostip.h
@@ -201,6 +201,27 @@ extern sigjmp_buf curl_jmpenv;
CURLcode Curl_set_dns_servers(struct SessionHandle *data, char *servers);
/*
+ * Function provided by the resolver backend to set
+ * outgoing interface to use for DNS requests
+ */
+CURLcode Curl_set_dns_interface(struct SessionHandle *data,
+ const char *interface);
+
+/*
+ * Function provided by the resolver backend to set
+ * local IPv4 address to use as source address for DNS requests
+ */
+CURLcode Curl_set_dns_local_ip4(struct SessionHandle *data,
+ const char *local_ip4);
+
+/*
+ * Function provided by the resolver backend to set
+ * local IPv6 address to use as source address for DNS requests
+ */
+CURLcode Curl_set_dns_local_ip6(struct SessionHandle *data,
+ const char *local_ip6);
+
+/*
* Clean off entries from the cache
*/
void Curl_hostcache_clean(struct SessionHandle *data, struct curl_hash *hash);
diff --git a/lib/hostsyn.c b/lib/hostsyn.c
index 65a403545..24f8dd82c 100644
--- a/lib/hostsyn.c
+++ b/lib/hostsyn.c
@@ -72,4 +72,40 @@ CURLcode Curl_set_dns_servers(struct SessionHandle *data,
}
+/*
+ * Function provided by the resolver backend to set
+ * outgoing interface to use for DNS requests
+ */
+CURLcode Curl_set_dns_interface(struct SessionHandle *data,
+ const char *interface)
+{
+ (void)data;
+ (void)interface;
+ return CURLE_NOT_BUILT_IN;
+}
+
+/*
+ * Function provided by the resolver backend to set
+ * local IPv4 address to use as source address for DNS requests
+ */
+CURLcode Curl_set_dns_local_ip4(struct SessionHandle *data,
+ const char *local_ip4)
+{
+ (void)data;
+ (void)local_ip4;
+ return CURLE_NOT_BUILT_IN;
+}
+
+/*
+ * Function provided by the resolver backend to set
+ * local IPv6 address to use as source address for DNS requests
+ */
+CURLcode Curl_set_dns_local_ip6(struct SessionHandle *data,
+ const char *local_ip6)
+{
+ (void)data;
+ (void)local_ip6;
+ return CURLE_NOT_BUILT_IN;
+}
+
#endif /* truly sync */
diff --git a/lib/url.c b/lib/url.c
index 50ce80df4..c1672d08b 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -2455,6 +2455,15 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
case CURLOPT_DNS_SERVERS:
result = Curl_set_dns_servers(data, va_arg(param, char *));
break;
+ case CURLOPT_DNS_INTERFACE:
+ result = Curl_set_dns_interface(data, va_arg(param, char *));
+ break;
+ case CURLOPT_DNS_LOCAL_IP4:
+ result = Curl_set_dns_local_ip4(data, va_arg(param, char *));
+ break;
+ case CURLOPT_DNS_LOCAL_IP6:
+ result = Curl_set_dns_local_ip6(data, va_arg(param, char *));
+ break;
case CURLOPT_TCP_KEEPALIVE:
data->set.tcp_keepalive = (0 != va_arg(param, long))?TRUE:FALSE;