How to use "dns_new()" (I get "dns_new: Assertion `(copy->dnsc_flags & DNS_INITED)' failed")

Michael Tokarev mjt at tls.msk.ru
Fri Feb 4 22:35:42 MSK 2011


04.02.2011 21:39, Iñaki Baz Castillo wrote:
> Hi, the following very simple program fails:
> 
> --------------------------------------------------
> int main(int argc, char **argv) {
>   struct dns_ctx *dns_context;
> 
>   dns_context = dns_new(NULL);
> }
> --------------------------------------------------
> 
> When running it:
> 
>   dns_new: Assertion `(copy->dnsc_flags & DNS_INITED)' failed.
> 
> From the documentation:
> 
> ---------------------------
> dns_new() allocates new resolver context and copies all parameters for
> a given resolver context copy, or default context if copy is NULL, and
> returns pointer to the newly allocated context. The context being
> copied should be initialized.
> ---------------------------
> 
> So it says "The context being copied should be initialized". But in
> case I pass NULL as argument, how to initialite it? Well, then I've
> tryed to run "dns_init(NULL, 0)" before:

Yes, that's how it was designed to work.  The idea is that all
the real initialization is done in dns_init() -- this include
reading of /etc/resolv.conf, checking environment variables and
so on.  This is done _only_ for the default context.  Later on
you're free to copy the already initialized context as many times
as you need, -- for example to create addition threads.  The
operation is very cheap and fast.  Different context can have
different options, different nameserver list, different
search order, but the initial state is initialized only once
for the "default" context.

> --------------------------
>   struct dns_ctx *dns_context;
> 
>   dns_init(NULL, 0);
>   dns_context = dns_new(NULL);
> --------------------------
> 
> And yes, it works. But I don't understand how it makes sense. It means
> "first initialize the default context and then copy it to a new one".
> Why is needed to initialize the default context if I won't use it?
> (just wondering).

You need to initialize the library.  Additional contexts
created by dns_new() are not initialized the same way as
the default context is.

I'm not sure this makes good sense for a _library_ that's
using libudns, maybe I just never thought about that.
Because for a library there's no "default context" per se,
especially if there will be more than one library used by
application which uses udns.  So - it looks like - there
should be a way to call dns_init() more than once (so that
each library will call it without worrying about multiple
inits), or there should be a way to determine if udns is
already initialized (to omit dns_init() call), or dns_new()
should initialize the library implicitly if it's not already
inited.

So I'm not really sure where to go from here.  Maybe I'll
implement all 3 variants - letting multiple dns_init(),
introducing dns_inited() and letting use dns_copy() before
dns_init().

In any case, this requires a modification, and hence a new
version.  For now you can assume your code is the only code
which uses libudns.

Thanks!

/mjt


More information about the udns mailing list