Commit df69440d authored by Kim Vandry's avatar Kim Vandry Committed by Daniel Stenberg
Browse files

libcurl: New options to bind DNS to local interfaces or IP addresses

parent 345955e8
Loading
Loading
Loading
Loading
+30 −0
Original line number Original line Diff line number Diff line
@@ -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.
supports this operation. The c-ares backend is the only such one.


(Added in 7.24.0)
(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
.IP CURLOPT_ACCEPTTIMEOUT_MS
Pass a long telling libcurl the maximum number of milliseconds to wait for a
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
server to connect back to libcurl when an active FTP connection is used. If no
+3 −0
Original line number Original line Diff line number Diff line
@@ -332,6 +332,9 @@ CURLOPT_DEBUGDATA 7.9.6
CURLOPT_DEBUGFUNCTION           7.9.6
CURLOPT_DEBUGFUNCTION           7.9.6
CURLOPT_DIRLISTONLY             7.17.0
CURLOPT_DIRLISTONLY             7.17.0
CURLOPT_DNS_CACHE_TIMEOUT       7.9.3
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_SERVERS             7.24.0
CURLOPT_DNS_USE_GLOBAL_CACHE    7.9.3         7.11.1
CURLOPT_DNS_USE_GLOBAL_CACHE    7.9.3         7.11.1
CURLOPT_EGDSOCKET               7.7
CURLOPT_EGDSOCKET               7.7
+13 −0
Original line number Original line Diff line number Diff line
@@ -1556,6 +1556,19 @@ typedef enum {
  /* The XOAUTH2 bearer token */
  /* The XOAUTH2 bearer token */
  CINIT(XOAUTH2_BEARER, OBJECTPOINT, 220),
  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 */
  CURLOPT_LASTENTRY /* the last unused */
} CURLoption;
} CURLoption;


+4 −0
Original line number Original line Diff line number Diff line
@@ -265,6 +265,10 @@ _CURL_WARNING(_curl_easy_getinfo_err_curl_slist,
   (option) == CURLOPT_RTSP_STREAM_URI ||                                     \
   (option) == CURLOPT_RTSP_STREAM_URI ||                                     \
   (option) == CURLOPT_RTSP_TRANSPORT ||                                      \
   (option) == CURLOPT_RTSP_TRANSPORT ||                                      \
   (option) == CURLOPT_XOAUTH2_BEARER ||                                      \
   (option) == CURLOPT_XOAUTH2_BEARER ||                                      \
   (option) == CURLOPT_DNS_SERVERS ||                                         \
   (option) == CURLOPT_DNS_INTERFACE ||                                       \
   (option) == CURLOPT_DNS_LOCAL_IP4 ||                                       \
   (option) == CURLOPT_DNS_LOCAL_IP6 ||                                       \
   0)
   0)


/* evaluates to true if option takes a curl_write_callback argument */
/* evaluates to true if option takes a curl_write_callback argument */
+61 −0
Original line number Original line Diff line number Diff line
@@ -623,4 +623,65 @@ CURLcode Curl_set_dns_servers(struct SessionHandle *data,
#endif
#endif
  return result;
  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 */
#endif /* CURLRES_ARES */
Loading