Re: Unit test suite for c-ares

2015-11-25 Thread Daniel Stenberg

On Wed, 25 Nov 2015, David Drysdale wrote:


- Fix double-free from ares__read_line() failure case
https://github.com/daviddrysdale/c-ares/commit/d91d731636f5


+1


- Extend the injection of malloc/free to cover realloc too:
https://github.com/daviddrysdale/c-ares/commit/492a1cc5e4fa


This modifies the public API though so it'll break existing applications. I 
would suggest this is introduced with a new API function to allow new 
applications to use it and yet keep the old ones functional.


- Add ares_set_sortlist() to allow manual specification (and therefore 
testing) of the sort list for ares_gethostbyname() 
https://github.com/daviddrysdale/c-ares/commit/79c719270fb6


Fine by me, but if you only want it for testing purposes I'm less convinced. 
For testing, you could do a separate build that allows you to link and use 
private functions as well.


--

 / daniel.haxx.se


Re: Unit test suite for c-ares

2015-11-25 Thread David Drysdale
On Wed, Nov 25, 2015 at 10:16 AM, Daniel Stenberg  wrote:
> On Wed, 25 Nov 2015, David Drysdale wrote:
>
>> - Fix double-free from ares__read_line() failure case
>> https://github.com/daviddrysdale/c-ares/commit/d91d731636f5
>
>
> +1
>
>> - Extend the injection of malloc/free to cover realloc too:
>> https://github.com/daviddrysdale/c-ares/commit/492a1cc5e4fa
>
>
> This modifies the public API though so it'll break existing applications. I
> would suggest this is introduced with a new API function to allow new
> applications to use it and yet keep the old ones functional.

Well, it only modifies the ares_library_init_mem() function that I added
in my commit b017d2664283, and that's not yet in the official repo/branch.
So there can't be anything using it yet (other than my test code), so it's
safe to adjust.

(Obviously, I'd agree with you if a) the test changes were merged into
the master repo and b) there had been an official release since then.)

>> - Add ares_set_sortlist() to allow manual specification (and therefore
>> testing) of the sort list for ares_gethostbyname()
>> https://github.com/daviddrysdale/c-ares/commit/79c719270fb6
>
>
> Fine by me, but if you only want it for testing purposes I'm less convinced.
> For testing, you could do a separate build that allows you to link and use
> private functions as well.

I could certainly do that, but it seemed slightly odd to have a bunch of
address sorting functionality that's only accessibly via an /etc/resolv.conf
option, and not via any other method.  I've never used the sortlist
functionality myself, but if it's in resolv.conf I assume it's useful to
someone, and in that case it would be nice to be able to configure an
instance of the library independently of the system-wide configuration.
WDYT?

> --
>
>  / daniel.haxx.se


[PATCH] Use libresolv to initialize cares on iPhone targets

2015-11-25 Thread Gregor Jasny

Hello,

this is a reworked version of Yury Kirpichev's patch to add iOS support 
to cares. Compared to the former version the following has been added:


* IPv6 name server now work properly. The ones ones in nsaddr_list have
  their address family set to AF_UNSPEC. As a work-around we call
  res_getservers instead.

* More options like search domains, ndots, etc. are applied

* Added autoconf magic to detect iPhone (iOS, tvOS, and watchOS)
  presence and use libresolv there.

In theory we could use the libresolv code also on OSX. But to avoid 
possible regressions I decided against it for a start.


Patch is attached and also in this PR:
https://github.com/bagder/c-ares/pull/29

Thanks,
Gregor
From 4e30c6ed3f9513c493729ed426f1a8885baf04fa Mon Sep 17 00:00:00 2001
From: Gregor Jasny 
Date: Wed, 25 Nov 2015 15:03:26 +0100
Subject: [PATCH] Use libresolv to initialize cares on iPhone targets

On iPhone targets like iOS, watchOS or tvOS the file
/etc/resolv.conf cannot be used to configure cares.

Instead the resolver library is queried for configuration
values.

CC: Yury Kirpichev 
---
 ares_init.c  | 71 +++-
 configure.ac | 24 
 2 files changed, 90 insertions(+), 5 deletions(-)

diff --git a/ares_init.c b/ares_init.c
index 05bb941..f5aa49e 100644
--- a/ares_init.c
+++ b/ares_init.c
@@ -49,6 +49,10 @@
 #define MAX_DNS_PROPERTIES8
 #endif
 
+#if defined(CARES_USE_LIBRESOLV)
+#include 
+#endif
+
 #include "ares.h"
 #include "ares_inet_net_pton.h"
 #include "ares_library_init.h"
@@ -77,7 +81,7 @@ static const char *try_option(const char *p, const char *q, 
const char *opt);
 static int init_id_key(rc4_key* key,int key_data_len);
 
 #if !defined(WIN32) && !defined(WATT32) && \
-!defined(ANDROID) && !defined(__ANDROID__)
+!defined(ANDROID) && !defined(__ANDROID__) && !defined(CARES_USE_LIBRESOLV)
 static int sortlist_alloc(struct apattern **sortlist, int *nsort,
   struct apattern *pat);
 static int ip_addr(const char *s, ssize_t len, struct in_addr *addr);
@@ -1058,7 +1062,8 @@ static int get_DNS_Windows(char **outptr)
 
 static int init_by_resolv_conf(ares_channel channel)
 {
-#if !defined(ANDROID) && !defined(__ANDROID__) && !defined(WATT32)
+#if !defined(ANDROID) && !defined(__ANDROID__) && !defined(WATT32) && \
+!defined(CARES_USE_LIBRESOLV)
   char *line = NULL;
 #endif
   int status = -1, nservers = 0, nsort = 0;
@@ -1150,6 +1155,61 @@ static int init_by_resolv_conf(ares_channel channel)
   break;
 status = ARES_EOF;
   }
+#elif defined(CARES_USE_LIBRESOLV)
+  struct __res_state res;
+  memset(, 0, sizeof(res));
+  int result = res_ninit();
+  if (result == 0 && (res.options & RES_INIT)) {
+status = ARES_EOF;
+
+if (channel->nservers == -1) {
+  union res_sockaddr_union addr[MAXNS];
+  int nscount = res_getservers(, addr, MAXNS);
+  for (int i = 0; i < nscount; ++i) {
+char str[INET6_ADDRSTRLEN];
+int config_status;
+sa_family_t family = addr[i].sin.sin_family;
+if (family == AF_INET) {
+  ares_inet_ntop(family, [i].sin.sin_addr, str, sizeof(str));
+} else if (family == AF_INET6) {
+  ares_inet_ntop(family, [i].sin6.sin6_addr, str, sizeof(str));
+} else {
+  continue;
+}
+
+config_status = config_nameserver(, , str);
+if (config_status != ARES_SUCCESS) {
+  status = config_status;
+  break;
+}
+  }
+}
+if (channel->ndomains == -1) {
+  int entries = 0;
+  while ((entries < MAXDNSRCH) && res.dnsrch[entries])
+entries++;
+
+  channel->domains = malloc(entries * sizeof(char *));
+  if (!channel->domains) {
+status = ARES_ENOMEM;
+  } else {
+channel->ndomains = entries;
+for (int i = 0; i < channel->ndomains; ++i) {
+  channel->domains[i] = strdup(res.dnsrch[i]);
+}
+  }
+}
+if (channel->ndots == -1)
+  channel->ndots = res.ndots;
+if (channel->tries == -1)
+  channel->tries = res.retry;
+if (channel->rotate == -1)
+  channel->rotate = res.options & RES_ROTATE;
+if (channel->timeout == -1)
+  channel->timeout = res.retrans * 1000;
+
+res_ndestroy();
+  }
 #else
   {
 char *p;
@@ -1470,7 +1530,7 @@ static int init_by_defaults(ares_channel channel)
 }
 
 #if !defined(WIN32) && !defined(WATT32) && \
-!defined(ANDROID) && !defined(__ANDROID__)
+!defined(ANDROID) && !defined(__ANDROID__) && !defined(CARES_USE_LIBRESOLV)
 static int config_domain(ares_channel channel, char *str)
 {
   char *q;
@@ -1583,7 +1643,8 @@ static int config_nameserver(struct server_state 
**servers, int *nservers,
   return ARES_SUCCESS;
 }
 
-#if !defined(WIN32) && !defined(ANDROID) && !defined(__ANDROID__)
+#if !defined(WIN32) && !defined(ANDROID) && !defined(__ANDROID__) && \
+