Discussion:
ares_reinit patch
(too old to reply)
Dima Tisnek
2011-02-15 08:11:10 UTC
Permalink
Cross-posting this to curl list because I've got some comments here
and no comments on c-ares list.

This patch:
* adds an ares_reinit functon, which reinitializes the channel same
way as ares_init.
* patches ares_gethostbyname and ares_gethostbyaddr with automatic updates.
* ares_getnameinfo is essentially patched as it calls either of the
above functions.
* ares_query and ares-search functions are not patched because they
can be called from ares_gethostbyxxxx and changing channel in the
middle could break things.
* If dns settings have changed all outstanding requests on a given
channel are cancelled.
* I didn't add ares_reinit_options() and I don't try to save old
options in ares_reinit().

In practice my patch only does the right thing in the following case:
* channel is intialized with ares_init(), without options
* only gethostbyname, gethostbyaddr and getnameinfo are used.
* dns settings change reasonably infrequently -- otherwise many
resolvs could be dropped
* dns settings are not overly complex -- otherwise reinit overhead
might be noticeable

Basically it works for my case, that is roaming between wireless networks.

Comments and suggestions are welcome.

Dima Tisnek
Daniel Stenberg
2011-02-15 08:37:00 UTC
Permalink
Post by Dima Tisnek
Cross-posting this to curl list because I've got some comments here
and no comments on c-ares list.
The libcurl list is still not the right place so I'll respond only on the
c-ares list.
Post by Dima Tisnek
* adds an ares_reinit functon, which reinitializes the channel same
way as ares_init.
Nit: you're not following the code style accurately. We don't do multiple
statements on the same code line for example.
Post by Dima Tisnek
* patches ares_gethostbyname and ares_gethostbyaddr with automatic updates.
I think we need a new option to enable this. Or possibly one that instead
disables it for those who have a reason for not wanting this - primarily I
would think of performance reasons.
--
/ daniel.haxx.se
Dima Tisnek
2011-02-15 09:18:12 UTC
Permalink
sorry about code style...

of course there should be an option, I wasn't sure if it should be
configure opt or run-time opt and I didn't want to go into that,
because, well, I'm not so good with c-ares yet.

I solved my case and I hope to get you all started. I can code a bit
more, if I have some directions :)

Reasons for having auto-dns-update disabled are potentially more than
peformance.
* it doesn't work correctly if user sets custom flags or servers or whatever
* it would leak fd's if user sets keep sockets open flag
* it cancels outstanding requests, that's far from perfect if the only
change in dns config is an extra server added, or a vpn connection
that bounces on/offline.
* reading all dns stuff again could lead to poor performance on some
systems, file timestamps or registry keys could be tracked instead,
but that means a separate chunk of code for every api/os.
* it polls dns config every timeout, default timeout is 5 seconds,
normal queries complete much faster, downtime may therefore be
significant.

Now that I look at it, my issue was to update dns config in a
long-running python program, perhaps it would have been easier to hack
at pycurl bindings instead and supply libcurl with callbacks into
python for name resolution perhaps. There are nice async/non-blocking
name resolvers in pure python or with bindings for python out there.

d.
Post by Daniel Stenberg
Post by Dima Tisnek
Cross-posting this to curl list because I've got some comments here
and no comments on c-ares list.
The libcurl list is still not the right place so I'll respond only on the
c-ares list.
Post by Dima Tisnek
* adds an ares_reinit functon, which reinitializes the channel same
way as ares_init.
Nit: you're not following the code style accurately. We don't do multiple
statements on the same code line for example.
Post by Dima Tisnek
* patches ares_gethostbyname and ares_gethostbyaddr with automatic updates.
I think we need a new option to enable this. Or possibly one that instead
disables it for those who have a reason for not wanting this - primarily I
would think of performance reasons.
--
 / daniel.haxx.se
Daniel Stenberg
2011-02-21 21:57:03 UTC
Permalink
Post by Dima Tisnek
sorry about code style...
of course there should be an option, I wasn't sure if it should be configure
opt or run-time opt and I didn't want to go into that, because, well, I'm
not so good with c-ares yet.
Run-time, no question about it. It seems like something a particular
application should be able to change/customize - and then I also include the
timeout period not just ON/OFF.
Post by Dima Tisnek
Now that I look at it, my issue was to update dns config in a long-running
python program, perhaps it would have been easier to hack at pycurl bindings
instead and supply libcurl with callbacks into python for name resolution
perhaps.
Well, you're asking on the c-ares list so of course we don't discuss or really
have opinions about other projects here, but I know the maintainer of libcurl
and he would not have liked that layering violation too much...
--
/ daniel.haxx.se
Dima Tisnek
2011-02-23 23:01:06 UTC
Permalink
Post by Daniel Stenberg
Post by Dima Tisnek
sorry about code style...
of course there should be an option, I wasn't sure if it should be
configure opt or run-time opt and I didn't want to go into that, because,
well, I'm not so good with c-ares yet.
Run-time, no question about it. It seems like something a particular
application should be able to change/customize - and then I also include the
timeout period not just ON/OFF.
is it reasonable to include some options in ares_init() where it
currently calls ares_init_options() without any options? or is this
some convention that should stay there?
Dima Tisnek
2011-03-22 17:39:54 UTC
Permalink
It seems there are two classes of c-ares users, those who initialize
it by calling ares_init, never set any options and use c-ares as a
simple asynchronous resolver, and those who call ares_init_options,
set loads of options (and often set servers explicitely) and thus use
c-ares as a toolbox for various name resolution problems.

So in a way, c-ares serves two distinct purposes.
Is it so, or am I missing something?

Currently ares_init(ch) and ares_init_options(ch, NULL, 0) mean the
same, and it appears to be a good convention.
This gets tricky if we are to include automatic reinitialization for
simple users without quietly introducing a change to toolbox users.

One way is to break init/init_options equality and include reinit
option (and possibly some default timeout) into ares_init call and
document that in the man page.

Another option is to split c-ares into two separate entities, say
c-ares-simple and c-ares-toolbox, projects like libcurl and iftop
would use simple and projects like lwip and xymon use the toolbox.

Comments, please!

Thanks,
Dima Tisnek
Daniel Stenberg
2011-03-22 21:43:13 UTC
Permalink
It seems there are two classes of c-ares users, those who initialize it by
calling ares_init, never set any options and use c-ares as a simple
asynchronous resolver, and those who call ares_init_options, set loads of
options (and often set servers explicitely) and thus use c-ares as a toolbox
for various name resolution problems.
So in a way, c-ares serves two distinct purposes. Is it so, or am I missing
something?
I think you're right and that the majority of users is in one of these camps.
Currently ares_init(ch) and ares_init_options(ch, NULL, 0) mean the
same, and it appears to be a good convention.
This gets tricky if we are to include automatic reinitialization for
simple users without quietly introducing a change to toolbox users.
Yes, and I think it is a reason as good as any to not introduce this feature
by default.
One way is to break init/init_options equality and include reinit option
(and possibly some default timeout) into ares_init call and document that in
the man page.
Right. It will also make apps not suddently start working differently when
they upgrade to the future c-ares version with reinit-capabilities.
Another option is to split c-ares into two separate entities, say
c-ares-simple and c-ares-toolbox, projects like libcurl and iftop would use
simple and projects like lwip and xymon use the toolbox.
I wouldn't like that and I fail to see how that would benefit us very much now
or in the future.
--
/ daniel.haxx.se
Steinar H. Gunderson
2011-02-15 09:20:19 UTC
Permalink
Post by Dima Tisnek
* patches ares_gethostbyname and ares_gethostbyaddr with automatic updates.
What does this mean?

/* Steinar */
--
Software Engineer, Google Switzerland
Dima Tisnek
2011-02-15 17:48:43 UTC
Permalink
ares__maybe_reinit() call is added in the start of ares_gethostbyxxxx functions.
this checks if it is time to call ares_reinit.
when ares_reinit is called it loads new system dns info, and if it is
different, swaps it into current ares channel.

what this means in practice is that if your dns settings have changed
(e.g. you visit another network), they will be refreshed by c-ares
when you call gethostbyxxxx, at most once per timeout, default in
c-ares is 5 seconds.
Post by Steinar H. Gunderson
Post by Dima Tisnek
* patches ares_gethostbyname and ares_gethostbyaddr with automatic updates.
What does this mean?
/* Steinar */
--
Software Engineer, Google Switzerland
Loading...