1
2udns(3)                    Library Functions Manual                    udns(3)
3
4
5

NAME

7       udns - stub DNS resolver library
8
9

SYNOPSYS

11       #include <udns.h>
12       struct dns_ctx;
13       struct dns_query;
14       extern struct dns_ctx dns_defctx;
15       struct dns_ctx *ctx;
16       typedef void dns_query_fn(ctx, void *result, void *data);
17       typedef int
18       dns_parse_fn(const unsigned char *qnd,
19              const unsigned char *pkt,
20              const unsigned char *cur,
21              const unsigned char *end,
22              void **resultp);
23
24       cc ... -ludns
25
26

DESCRIPTION

28       The  DNS  library, udns, implements thread-safe stub DNS resolver func‐
29       tionality, which may be used both traditional, syncronous way and asyn‐
30       cronously, with application-supplied event loop.
31
32
33       While  DNS  works with both TCP and UDP, performing UDP query first and
34       if the result does not fit in UDP buffer (512 bytes  max  for  original
35       DNS  protocol), retrying the query over TCP, the library uses UDP only,
36       but uses EDNS0 (RFC2671) extensions which allows larger UDP buffers.
37
38
39       The library uses single UDP socket to perform all operations even  when
40       asking  multiple  nameservers.   This way, it is very simple to use the
41       library in asyncronous event-loop applications: an  application  should
42       add  only  single  socket to the set of filedescriptors it monitors for
43       I/O.
44
45
46       The  library  uses  two  main  objects,  resolver   context   of   type
47       struct dns_ctx,  and query structure of type struct dns_query, both are
48       opaque for an application.  Resolver context holds  global  information
49       about  the resolver, such as list of nameservers to use, list of active
50       requests and the like.  Query objects holds information about a  single
51       DNS query in progress and are allocated/processed/freed by the library.
52       Pointer to query structure may be treated as an identifier  of  an  in-
53       progress  query  and  may be used to cancel the asyncronous query or to
54       wait for it to complete.
55
56
57       Asyncronous interface works as  follows.   An  application  initializes
58       resolver  context,  submits  any  number of queries for it using one of
59       supplied dns_submit_XXX() routines (each return the query identifier as
60       pointer  to query structure), waits for input on the UDP socket used by
61       the  library,  and  gives  some  control  to  the  library  by  calling
62       dns_ioevent()   and  dns_timeouts()  routines  when  appropriate.   The
63       library performs all necessary processing and executes application sup‐
64       plied  callback routine when a query completes (either successefully or
65       not), giving it the result if any,  pointer  to  the  resolver  context
66       (from  which  completion  status may be obtained), and the data pointer
67       supplied by an application when the query  has  been  submitted.   When
68       submitting  a query, an application requests how to handle the reply --
69       to either return raw DNS reply packet for its own low-level processing,
70       or it may provide an address of parsing routine of type dns_parse_fn to
71       perform conversion of on-wire format into easy to  use  data  structure
72       (the  library  provides  parsing  routines  for  several  commonly used
73       resource record types, as well as type-safe higher-level inteface  that
74       requests  parsing  automatically).  The I/O monitoring and timeout han‐
75       dling may be either traditional select() or poll() based, or any  call‐
76       back-driven technique may be used.
77
78
79       Additionally,  the  library  provides traditional syncronous interface,
80       which may be intermixed with asyncronous calls (during syncronous query
81       processing,  other  asyncronous  queries  for the same resolver context
82       continued to be processed as usual).  An application uses one of numer‐
83       ous  dns_resolve_XXX()  routines  provided  by the library to perform a
84       query.  As  with  asyncronous  interface,  an  application  may  either
85       request  to  return  raw  DNS packet or type-specific data structure by
86       providing the parsing routine to handle the reply.  Every routine  from
87       dns_resolve_XXX()  series  return  pointer to result or NULL in case of
88       any error.  Query completion status (or length of the raw  DNS  packet)
89       is  available from the resolver context using dns_status() routine, the
90       same way as for the asyncronous interface.
91
92
93       Internally, library uses on-wire format of domain names, referred to as
94       DN format in this manual page.  This is a series of domain labels whith
95       preceeding length byte, terminated by zero-length label wich  is  inte‐
96       gral  part  of  the  DN format.  There are several routines provided to
97       convert from traditional asciiz string to DN  and  back.   Higher-level
98       type-specific query interface hides the DN format from an application.
99
100

COMMON DEFINITIONS

102       Every  DNS  Resource  Record  (RR) has a type and a class.  The library
103       defines several integer constants, DNS_C_XXX and DNS_T_XXX, to  use  as
104       symbolic  names for RR classes and types, such as DNS_C_IN for Internet
105       class, DNS_T_A for IPv4 address record type  and  so  on.   See  udns.h
106       header file for complete list of all such constants.
107
108
109       The following constants are defined in udns.h header file:
110
111       DNS_MAXDN (255 bytes)
112              Maximum  length of the domain name in internal (on-wire) DN for‐
113              mat.
114
115       DNS_MAXLABEL (63 bytes)
116              Maximum length of a single label in DN format.
117
118       DNS_MAXNAME (1024 bytes)
119              Maximum length of asciiz format of a domain name.
120
121       DNS_HSIZE (12 bytes)
122              Size of header in DNS packet.
123
124       DNS_PORT (53)
125              Default port to use when contacting a DNS server.
126
127       DNS_MAXSERV (6 servers)
128              Maximum number of DNS servers to use.
129
130       DNS_MAXPACKET (512 bytes)
131              Maximum length of DNS UDP packet as specified  by  original  DNS
132              protocol
133
134       DNS_EDNS0PACKET (4096 bytes)
135              Default  length  of  DNS  UDP packet (with EDNS0 extensions) the
136              library uses.  Note that recursive nameservers  usually  resides
137              near  the  client asking them to resolve names, e.g. on the same
138              LAN segment or even on the same host, so UDP  packet  fragmenta‐
139              tion  isn't a problem in most cases.  Note also that the size of
140              actual packets will be  as  many  bytes  as  actual  reply  size
141              requires, which is smaller than this value in almost all cases.
142
143
144       Additionally,  several  constants are defined to simplify work with raw
145       DNS packets, such as DNS response codes (DNS_R_XXX), DNS header  layout
146       (DNS_H_XXX)  and others.  Again, see udns.h for complete list.  Library
147       error codes (DNS_E_XXX) are described later in this manual page.
148
149

RESOLVER CONTEXT

151       Resolver context, of type struct dns_ctx, is an object which is  opaque
152       to  an  application.   Several routines provided by the library to ini‐
153       tialize, copy and free resolver contexts.  Most other  high-level  rou‐
154       tines  in  this  library expects a pointer to resolver context, ctx, as
155       the first argument.  There is a  default  resolver  context  available,
156       named  dns_defctx.  When the context pointer ctx passed to a routine is
157       NULL, dns_defctx is used.  Several resolver contexts may be  active  at
158       the  same  time, for example, when an application is multi-threaded and
159       each thread uses resolver.
160
161       In order to use the library, an application should initialize and  open
162       one  or more resolver context objects.  These are two separate actions,
163       performed by dns_init() (or dns_reset()), and dns_open().  Between  the
164       two calls, an application is free to pefrorm additional initialisation,
165       such as setting custom nameservers, options  or  domain  search  lists.
166       Optionally,  in  case  no additional custom initialisation is required,
167       dns_init() may open the context if do_open argument (see below) is non-
168       zero.
169
170       When  initializing  resolver context, the library uses information from
171       system file /etc/resolv.conf (see resolv.conf(5)), consults environment
172       variables  $LOCALDOMAIN, $NSCACHEIP, $NAMESERVERS and $RES_OPTIONS, and
173       local host name to obtain list of local nameservers, domain name search
174       list and various resolver options.
175
176       The following routines to initialize resolver context are available:
177
178       void dns_reset(ctx)
179       int dns_init(ctx, int do_open)
180              dns_reset()  resets  a given resolver context to default values,
181              preparing it to be opened by dns_open().  It is ok to call  this
182              routine  against  opened and active context - all active queries
183              will be dropped, sockets will be closed and so on.  This routine
184              does  not  initialize  any  parameters from system configuration
185              files, use dns_init() for this.  There's no error return - oper‐
186              ation  always  succeeds.  dns_init() does everything dns_reset()
187              does, plus initializes various parameters of the context accord‐
188              ing  to  system configuration and process environment variables.
189              If do_open is non-zero, dns_init() calls dns_open(), so that the
190              whole library initialisation is performed in a single step.
191
192       struct dns_ctx *dns_new(struct dns_ctx *copy)
193       void dns_free(ctx)
194              dns_new()  allocates new resolver context and copies all parame‐
195              ters for a given resolver context copy, or  default  context  if
196              copy  is  NULL,  and returns pointer to the newly allocated con‐
197              text.   The  context  being  copied   should   be   initialized.
198              dns_new() may fail if there's no memory available to make a copy
199              of copy, in which case the routine  will  return  NULL  pointer.
200              dns_free()  is used to close assotiated socket and free resolver
201              context resources and cancelling (abandoming) all active queries
202              assotiated  with  it.   It's  an  error to free dns_defctx, only
203              dynamically allocated contexts returned by dns_new() are allowed
204              to be freed by dns_free().
205
206       int dns_add_serv(ctx, const char *servaddr)
207       int dns_add_serv_s(ctx, const struct sockaddr *sa)
208       int dns_add_srch(ctx, const char *srch)
209              Add  an  element  to  list  of  nameservers  (dns_add_serv(), as
210              asciiz-string servaddr with an IP address of the nameserver, and
211              dns_add_serv_s(),  as  initialized socket address sa), or search
212              list (dns_add_srch(), as a pointer to domain name) for the given
213              context ctx.  If the last argument is a NULL pointer, the corre‐
214              sponding list (search or nameserver)  is  reset  instead.   Upon
215              successeful  completion, each routine returns new number of ele‐
216              ments in the list in question.   On  error,  negative  value  is
217              returned  and global variable errno is set appropriately.  It is
218              an error to call any of this functions if the context is  opened
219              (after dns_open() or dns_init() with non-zero argument).
220
221       int dns_set_opts(ctx, const char *opts)
222              set  resolver  context options from opts string, in the same way
223              as processing options statement in resolv.conf and  $RES_OPTIONS
224              environment  variable.   Return  number  of unrecognized/invalid
225              options found (all recognized and valid options gets processed).
226
227       void dns_set_opt(ctx, int opt, val)
228              TODO The flags argument is a bitmask  with  the  following  bits
229              defined:
230
231              DNS_NOSRCH
232                     do not perform domain name search in search list.
233
234              DNS_NORD
235                     do  not  request  recursion when performing queries (i.e.
236                     don't set RD flag in querues).
237
238              DNS_AAONLY
239                     request authoritative answers only (i.e. set AA  flag  in
240                     queries).
241
242
243       int dns_open(ctx)
244       int dns_sock(const ctx)
245       void dns_close(ctx)
246              dns_open()  opens the UDP socket used for queries if not already
247              open, and return assotiated filedescriptor (or negative value in
248              case  of error).  Before any query can be submitted, the context
249              should be opened using this routine.  And  before  opening,  the
250              context should be initialized.  dns_sock() return the UDP socket
251              if open, or -1 if not.  dns_close() closes the UDP socket if  it
252              was open, and drops all active queries if any.
253
254
255       int dns_active(const ctx)
256              return  number  of  active  queries queued for the given context
257              ctx, or zero if none.
258
259
260       int dns_status(const ctx)
261              return status code from last operation.  When  using  syncronous
262              interface,  this  is  the  query  completion  status of the last
263              query.  With asyncronous interface,  from  within  the  callback
264              routine,  this  is  the query completion status of the query for
265              which the callback  is  being  called.   When  query  submission
266              fails,  this  is  the error code indicating failure reason.  All
267              error codes are negative and are represented by  DNS_E_XXX  con‐
268              stants described below.
269
270
271       void dns_ioevent(ctx, time_t now)
272              this  routine  may  be  called  by an application to process I/O
273              events on the UDP socket used by the  library,  as  returned  by
274              dns_sock().   The routine tries to receive incoming UDP datagram
275              from the socket and process it.  The socket is set up to be non-
276              blocking,  so  it is safe to call the routine even if there's no
277              data to read.  The routine will process as many datagrams as are
278              queued  for  the  socket,  so  it  is safe to use it with either
279              level-triggered or edge-triggered I/O monitoring model.  The now
280              argument  is  either a current time as returned by time(), or 0,
281              in which case the routine will obtain current time by it's own.
282
283
284       int dns_timeouts(ctx, int maxwait, time_t now)
285              process any pending timeouts and return number of secounds  from
286              current  time  (now if it is not 0) to the time when the library
287              wants the application to pass it control to process more  queued
288              requests.  In case when there are no requests pending, this time
289              is -1.  The routine will not request a time larger than  maxwait
290              secounds  if  it is greather or equal to zero.  If now is 0, the
291              routine will obtain current time by it's own; when it is not  0,
292              it should contain current time as returned by time().
293
294
295       typedef void dns_utm_fn(ctx, int timeout, void *data)
296       void dns_set_tmcbck(ctx, dns_utm_fn *utmfn, void *data)
297              An  application  may  use custom callback-based I/O multiplexing
298              mechanism.  Usually such a mechanism have concept  of  a  timer,
299              and an ability to register a timer event in a form of a callback
300              routine which will be executed after certain amount of time.  In
301              order  to  use such an event mechanism, udns provides an ability
302              to register and de-register timer events necessary for  internal
303              processing  using  whatever event mechanism an application uses.
304              For this to work, it is possible to assotiate  a  pointer  to  a
305              routine  that  will  perform  necessary work for (de)registering
306              timer events with a given resolver context, and udns  will  call
307              that  routine at appropriate times.  Prototype of such a routine
308              is shown by dns_utm_fn typedef above.  Libudns assotiates single
309              timer  with  resolver context.  User-supplied utmfn routine will
310              be called by the library with the following arguments:
311
312              ctx == NULL
313                     delete user timer, at context free time or when an appli‐
314                     cation   changes   user   timer   request  routine  using
315                     dns_set_tmcbck();
316
317              ctx != NULL, timeout < 0
318                     don't fire  timer  anymore,  when  there  are  no  active
319                     requests;
320
321              ctx != NULL, timeout == 0
322                     fire timer at the next possibility, but not immediately;
323
324              ctx != NULL, timeout > 0
325                     fire timer after timeout seconds after now.
326
327              The  data  argument  passed  to  the routine will be the same as
328              passed to dns_set_tmcbck().
329
330              When a timer expires, an application should call  dns_timeouts()
331              routine (see below).  Non-callback timer usage is provided too.
332
333
334       XXXX  TODO:  some  more resolver context routines, like dns_set_dbgfn()
335       etc.
336
337

QUERY INTERFACE

339       There are two ways to perform DNS queries: traditional syncronous  way,
340       when  udns  performs all the necessary processing and return control to
341       the application only when the query  completes,  and  asyncronous  way,
342       when  an  application  submits one or more queries to the library using
343       given  resolver  context,  and  waits  for  completion  by   monitoring
344       filedescriptor  used by library and calling library routines to process
345       input on that filedescriptor.  Asyncronous  mode  works  with  callback
346       routines:  an  application  supplies an address of a routine to execute
347       when the query completes, and a data pointer, which is  passed  to  the
348       callback routine.
349
350
351       Queries are submitted to the library in a form of struct dns_query.  To
352       perform asyncronous query, an application calls  one  of  the  dns_sub‐
353       mit_XXX()  rounines, and provides necessary information for a callback,
354       together with all the query  parameters.   When  the  query  completes,
355       library  will call application-supplied callback routine, giving it the
356       resolver context (wich  holds  query  completion  status),  dynamically
357       allocated result (which will be either raw DNS packet or, if applicatin
358       requested parsing the result  by  specifying  non-NULL  parse  routine,
359       ready-to-use  type-specific  structure), and a data pointer provided by
360       an application when it submitted the  query.   It  is  the  application
361       who's responsible for freeing the result memory.
362
363       Generic query callback routine looks like this:
364       typedef void
365       dns_query_fn(ctx, void *result, void *data)
366       Type-specific  query interface expects similar form of callback routine
367       with the only difference in type of  result  argument,  which  will  be
368       pointer to specific data structure (decoded reply) instead of this void
369       pointer to raw DNS packet data.
370
371
372       Result parsing routine looks like this:
373       typedef int
374       dns_parse_fn(const unsigned char *qdn,
375             const unsigned char *pkt,
376             const unsigned char *cur,
377             const unsigned char *end,
378             void **resultp);
379       When called by the library, the arguments are as follows: pkt points to
380       the start of the packet received; end points past the end of the packet
381       received; cur points past the query DN in  the  query  section  of  the
382       packet;  qdn points to the original query DN.  The routine should allo‐
383       cate a single buffer to hold the result, parse the reply filling in the
384       buffer,  and return the buffer using resultp argument.  It returns 0 in
385       case of error, or udns error code  (DNS_E_XXX  constants)  in  case  of
386       error.   Note  that by the time when the parse routine is called by the
387       library, packet is already verified to  be  a  reply  to  the  original
388       query, by matching query DN, query class and query type.
389
390
391       Type-specific  query inteface supplies necessary parsing routines auto‐
392       matically.
393
394
395       In case of error, query  completion  status  as  returned  by  dns_sta‐
396       tus(ctx), will contain one of the following values:
397
398       positive value
399              length of raw DNS packet if parsing is not requested.
400
401       0      the  query was successeful and the reply points to type-specific
402              data structure.
403
404       DNS_E_TEMPFAIL
405              temporary error, the resolver nameserver was not able to process
406              our query or timed out.
407
408       DNS_E_PROTOCOL
409              protocol error, a nameserver returned malformed reply.
410
411       DNS_E_NXDOMAIN
412              the domain name does not exist.
413
414       DNS_E_NODATA
415              there is no data of requested type found.
416
417       DNS_E_NOMEM
418              out of memory while processing request.
419
420       DNS_E_BADQUERY
421              some  aspect  of  the  query  (most common is the domain name in
422              question) is invalid, and the library can't even start a query.
423
424
425       Library provides two series of routines which uses similar interface --
426       one  for asyncronous queries and another for syncronous queries.  There
427       are two general low-level routines in  each  series  to  submit  (asyn‐
428       cronous  interface) and resolve (syncronous interface) queries, as well
429       as several type-specific routines with more easy-to-use interfaces.  To
430       submit  an asyncronous query, use one of dns_submit_XXX() routine, each
431       of which accepts query parameters, pointers to callback routine and  to
432       callback  data,  and  optional  current  time hint.  Note type-specific
433       dns_submit_XXX() routines expects specific type of the callback routine
434       as  well,  which accepts reply as a pointer to corresponding structure,
435       not a void pointer).  Every dns_submit_XXX() routine return pointer  to
436       internal  query  structure of type struct dns_query, used as an identi‐
437       fier for the given query.
438
439
440       To resolve a query syncronously, use one of dns_resolve_XXX() routines,
441       which accepts the same query parameters (but not the callback pointers)
442       as corresponding dns_submit_XXX(), and return the query  result,  which
443       is  the  same  as passed to the callback routine in case of asyncronous
444       interface.
445
446
447       In either case, the result memory (if  the  query  completed  successe‐
448       fully)  is dynamically allocated and should be freed by an application.
449       If the query failed for any reason, the result will be NULL, and  error
450       status will be available from dns_status(ctx) routine as shown above.
451
452
453       struct dns_query *
454       dns_submit_dn(ctx,
455            const unsigned char *dn, qcls, qtyp, flags,
456            parse, cbck, data)
457       struct dns_query *
458       dns_submit_p(ctx,
459            const char *name, qcls, qtyp, flags,
460            parse, cbck, data)
461          enum dns_class qcls;
462          enum dns_type qtyp;
463          int flags;
464          dns_parse_fn *parse;
465          dns_query_fn *cbck;
466          void *data;
467              submit  a  query  for  processing for the given resolver context
468              ctx.  Two routines differs only in 3rd argument, which is domain
469              name  in DN format (dn) or asciiz string (name).  The query will
470              be performed for the given domain name, with type qtyp in  class
471              qcls,  using  option  bits  in  flags,  using RR parsing routine
472              pointed by parse if not-NULL, and upon completion, cbck function
473              will  be  called with the data argument.  In case of successeful
474              query submission, the routine return pointer to  internal  query
475              structure  which may be treated as an identifier of the query as
476              used by the library, and may be used as an argument for dns_can‐
477              cel()  routine.   In  case  of error, NULL will be returned, and
478              context error status (available using dns_status() routine) will
479              be  set  to  corresponding error code, which in this case may be
480              DNS_E_BADQUERY if the name of  dn  is  invalid,  DNS_E_NOMEM  if
481              there's  no  memory  available  to  allocate query structure, or
482              DNS_E_TEMPFAIL if an internal error occured.
483
484
485       void *dns_resolve_dn(ctx,
486            const unsigned char *dn, qcls, qtyp, flags, parse);
487       void *dns_resolve_p(ctx,
488            const char *name, qcls, qtyp, flags, parse)
489          enum dns_class qcls;
490          enum dns_type qtyp;
491          int flags;
492          dns_parse_fn *parse;
493              syncronous interface.  The routines perform all the steps neces‐
494              sary  to  resolve  the  given  query  and return the result.  If
495              there's no positive result for  any  reason,  all  the  routines
496              return  NULL,  and  set  context  error  status (available using
497              dns_status() routine) to indicate the error code.  If the  query
498              was  successeful,  context  status  code will contain either the
499              length of the raw DNS reply packet if parse  argument  was  NULL
500              (in  which  case  the  return  value is pointer to the reply DNS
501              packet), or 0 (in which case the return value is the  result  of
502              parse  routine).   If the query successeful (return value is not
503              NULL), the memory returned  was  dynamically  allocated  by  the
504              library and should be free()d by application after use.
505
506
507       void *dns_resolve(ctx, struct dns_query *q)
508              wait  for  the  given  query  q,  as returned by one of dns_sub‐
509              mit_XXX() routines, for completion, and return the result.   The
510              callback  routine will not be called for this query.  After com‐
511              pletion,  the  query   identifier   q   is   not   valid.   Both
512              dns_resolve_dn()  and  dns_resolve_p()  are just wrappers around
513              corresponding submit routines and this dns_resolve() routine.
514
515
516       void dns_cancel(ctx, struct dns_query *q)
517              cancel an active query q, without calling  a  callback  routine.
518              After completion, the query identifier q is not valid.
519
520

TYPE-SPECIFIC QUERIES

522       In  addition to the generic low-level query interface, the library pro‐
523       vides a set of routines to perform specific queries in a type-safe man‐
524       ner,  as  well as parsers for several well-known resource record types.
525       The library implements high-level interface for A, AAAA,  PTR,  MX  and
526       TXT  records and DNSBL and RHSBL functionality.  These routines returns
527       specific types as result of a query, instead of raw DNS  packets.   The
528       following types and routines are available.
529
530
531       struct dns_rr_null {
532         char *dnsn_qname;     /* original query name */
533         char *dnsn_cname;     /* canonical name */
534         unsigned dnsn_ttl;    /* Time-To-Live (TTL) value */
535         int dnsn_nrr;         /* number of records in the set */
536       };
537
538       NULL RR set, used as a base for all other RR type structures.  Every RR
539       structure as used by the  library  have  four  standard  fields  as  in
540       struct dns_rr_null.
541
542
543   IN A Queries
544       struct dns_rr_a4 {       /* IN A RRset */
545         char *dnsa4_qname;     /* original query name */
546         char *dnsa4_cname;     /* canonical name */
547         unsigned dnsa4_ttl;    /* Time-To-Live (TTL) value */
548         int dnsa4_nrr;         /* number of addresses in the set */
549         struct in_addr dnsa4_addr[]; /* array of addresses */
550       };
551       typedef void
552         dns_query_a4_fn(ctx, struct dns_rr_a4 *result, data)
553       dns_parse_fn dns_parse_a4;
554       struct dns_query *
555       dns_submit_a4(ctx, const char *name, int flags,
556          dns_query_a4_fn *cbck, data);
557       struct dns_rr_a4 *
558       dns_resolve_a4(ctx, const char *name, int flags);
559
560       The  dns_rr_a4  structure  holds a result of an IN A query, which is an
561       array of IPv4 addresses.  Callback routine for IN A queries expected to
562       be  of  type dns_query_a4_fn, which expects pointer to dns_rr_a4 struc‐
563       ture as query result instead of raw DNS packet.  The dns_parse_a4()  is
564       used  to  convert  raw DNS reply packet into dns_rr_a4 structure (it is
565       used internally and may be used directly too with generic query  inter‐
566       face).   Routines dns_submit_a4() and dns_resolve_a4() are used to per‐
567       form A IN queries in a type-safe manner.  The  name  parameter  is  the
568       domain  name  in  question,  and flags is query flags bitmask, with one
569       bit, DNS_NOSRCH, of practical interest (if the name is  absolute,  that
570       is, it ends up with a dot, DNS_NOSRCH flag will be set automatically).
571
572
573   IN AAAA Queries
574       struct dns_rr_a6 {       /* IN AAAA RRset */
575         char *dnsa6_qname;     /* original query name */
576         char *dnsa6_cname;     /* canonical name */
577         unsigned dnsa6_ttl;    /* Time-To-Live (TTL) value */
578         int dnsa6_nrr;         /* number of addresses in the set */
579         struct in6_addr dnsa6_addr[]; /* array of addresses */
580       };
581       typedef void
582         dns_query_a6_fn(ctx, struct dns_rr_a6 *result, data)
583       dns_parse_fn dns_parse_a6;
584       struct dns_query *
585       dns_submit_a6(ctx, const char *name, int flags,
586          dns_query_a6_fn *cbck, data);
587       struct dns_rr_a6 *
588       dns_resolve_a6(ctx, const char *name, int flags);
589
590       The dns_rr_a6 structure holds a result of an IN AAAA query, which is an
591       array of IPv6 addresses.  Callback routine for IN AAAA queries expected
592       to  be  of  type  dns_query_a6_fn,  which  expects pointer to dns_rr_a6
593       structure  as  query  result  instead   of   raw   DNS   packet.    The
594       dns_parse_a6()  is  used to convert raw DNS reply packet into dns_rr_a6
595       structure (it is used internally and may  be  used  directly  too  with
596       generic     query    interface).     Routines    dns_submit_a6()    and
597       dns_resolve_a6() are used to perform AAAA IN  queries  in  a  type-safe
598       manner.   The  name parameter is the domain name in question, and flags
599       is query flags bitmask, with one bit, DNS_NOSRCH, of practical interest
600       (if  the  name  is absolute, that is, it ends up with a dot, DNS_NOSRCH
601       flag will be set automatically).
602
603
604   IN PTR Queries
605       struct dns_rr_ptr {       /* IN PTR RRset */
606         char *dnsptr_qname;     /* original query name */
607         char *dnsptr_cname;     /* canonical name */
608         unsigned dnsptr_ttl;    /* Time-To-Live (TTL) value */
609         int dnsptr_nrr;         /* number of domain name pointers */
610         char *dnsptr_ptr[];     /* array of domain name pointers */
611       };
612       typedef void
613         dns_query_ptr_fn(ctx, struct dns_rr_ptr *result, data)
614       dns_parse_fn dns_parse_ptr;
615       struct dns_query *
616       dns_submit_a4ptr(ctx, const struct in_addr *addr,
617          dns_query_ptr_fn *cbck, data);
618       struct dns_rr_ptr *
619       dns_resolve_a4ptr(ctx, const struct in_addr *addr);
620       struct dns_query *
621       dns_submit_a6ptr(ctx, const struct in6_addr *addr,
622          dns_query_ptr_fn *cbck, data);
623       struct dns_rr_ptr *
624       dns_resolve_a6ptr(ctx, const struct in6_addr *addr);
625
626       The dns_rr_ptr structure holds a result of an IN PTR query, which is an
627       array  of domain name pointers for a given IPv4 or IPv6 address.  Call‐
628       back  routine  for  IN   PTR   queries   expected   to   be   of   type
629       dns_query_ptr_fn,  which  expects  pointer  to  dns_rr_ptr structure as
630       query result instead of raw DNS packet.  The dns_parse_ptr() is used to
631       convert  raw  DNS  reply  packet  into dns_rr_ptr structure (it is used
632       internally and may be used directly too with generic query  interface).
633       Routines dns_submit_a4ptr() and dns_resolve_a4ptr() are used to perform
634       IN PTR queries for IPv4  addresses  in  a  type-safe  manner.  Routines
635       dns_submit_a6ptr()  and  dns_resolve_a6ptr() are used to perform IN PTR
636       queries for IPv6 addresses.
637
638
639   IN MX Queries
640       struct dns_mx {          /* single MX record */
641         int priority;          /* priority value of this MX */
642         char *name;            /* domain name of this MX */
643       };
644       struct dns_rr_mx {       /* IN MX RRset */
645         char *dnsmx_qname;     /* original query name */
646         char *dnsmx_cname;     /* canonical name */
647         unsigned dnsmx_ttl;    /* Time-To-Live (TTL) value */
648         int dnsmx_nrr;         /* number of mail exchangers in the set */
649         struct dns_mx dnsmx_mx[]; /* array of mail exchangers */
650       };
651       typedef void
652         dns_query_mx_fn(ctx, struct dns_rr_mx *result, data)
653       dns_parse_fn dns_parse_mx;
654       struct dns_query *
655       dns_submit_mx(ctx, const char *name, int flags,
656          dns_query_mx_fn *cbck, data);
657       struct dns_rr_mx *
658       dns_resolve_mx(ctx, const char *name, int flags);
659
660       The dns_rr_mx structure holds a result of an IN MX query, which  is  an
661       array  of  mail exchangers for a given domain.  Callback routine for IN
662       MX queries expected  to  be  of  type  dns_query_mx_fn,  which  expects
663       pointer  to  dns_rr_mx  structure  as  query  result instead of raw DNS
664       packet.  The dns_parse_mx() is used to convert  raw  DNS  reply  packet
665       into  dns_rr_mx  structure  (it  is  used  internally  and  may be used
666       directly too with generic query interface).   Routines  dns_submit_mx()
667       and  dns_resolve_mx()  are used to perform IN MX queries in a type-safe
668       manner.  The name parameter is the domain name in question,  and  flags
669       is query flags bitmask, with one bit, DNS_NOSRCH, of practical interest
670       (if the name is absolute, that is, it ends up with  a  dot,  DNS_NOSRCH
671       flag will be set automatically).
672
673
674   TXT Queries
675       struct dns_txt {          /* single TXT record */
676         int len;                /* length of the text */
677         unsigned char *txt;     /* pointer to the text */
678       };
679       struct dns_rr_txt {       /* TXT RRset */
680         char *dnstxt_qname;     /* original query name */
681         char *dnstxt_cname;     /* canonical name */
682         unsigned dnstxt_ttl;    /* Time-To-Live (TTL) value */
683         int dnstxt_nrr;         /* number of text records in the set */
684         struct dns_txt dnstxt_txt[]; /* array of TXT records */
685       };
686       typedef void
687         dns_query_txt_fn(ctx, struct dns_rr_txt *result, data)
688       dns_parse_fn dns_parse_txt;
689       struct dns_query *
690       dns_submit_txt(ctx, const char *name, enum dns_class qcls,
691          int flags, dns_query_txt_fn *cbck, data);
692       struct dns_rr_txt *
693       dns_resolve_txt(ctx, const char *name,
694                    enum dns_class qcls, int flags);
695
696       The  dns_rr_txt  structure  holds  a result of a TXT query, which is an
697       array of text records for a given domain name.   Callback  routine  for
698       TXT  queries  expected  to  be  of type dns_query_txt_fn, which expects
699       pointer to dns_rr_txt structure as query  result  instead  of  raw  DNS
700       packet.   The  dns_parse_txt()  is used to convert raw DNS reply packet
701       into dns_rr_txt structure (it  is  used  internally  and  may  be  used
702       directly  too with generic query interface).  Routines dns_submit_txt()
703       and dns_resolve_txt() are used to perform IN MX queries in a  type-safe
704       manner.   The  name parameter is the domain name in question, and flags
705       is query flags bitmask, with one bit, DNS_NOSRCH, of practical interest
706       (if  the  name  is absolute, that is, it ends up with a dot, DNS_NOSRCH
707       flag will be set automatically).  Note that each TXT string  is  repre‐
708       sented  by  struct dns_txt, while zero-terminated (and the len field of
709       the structure does not include the terminator),  may  contain  embedded
710       null  characters  --  content  of TXT records is not interpreted by the
711       library in any way.
712
713
714   SRV Queries
715       struct dns_srv {          /* single SRV record */
716         int priority;           /* priority of the record */
717         int weight;             /* weight of the record */
718         int port;               /* the port number to connect to */
719         char *name;             /* target host name */
720       };
721       struct dns_rr_srv {       /* SRV RRset */
722         char *dnssrv_qname;     /* original query name */
723         char *dnssrv_cname;     /* canonical name */
724         unsigned dnssrv_ttl;    /* Time-To-Live (TTL) value */
725         int dnssrv_nrr;         /* number of text records in the set */
726         struct dns_srv dnssrv_srv[]; /* array of SRV records */
727       };
728       typedef void
729         dns_query_srv_fn(ctx, struct dns_rr_srv *result, data)
730       dns_parse_fn dns_parse_srv;
731       struct dns_query *
732       dns_submit_srv(ctx, const char *name, const char *service, const char *protocol,
733          int flags, dns_query_txt_fn *cbck, data);
734       struct dns_rr_srv *
735       dns_resolve_srv(ctx, const char *name, const char *service, const char *protocol,
736                    int flags);
737
738       The dns_rr_srv structure holds a result of an IN SRV  (rfc2782)  query,
739       which  is  an  array  of servers (together with port numbers) which are
740       performing operations for a given service using  given  protocol  on  a
741       target domain name.  Callback routine for IN SRV queries expected to be
742       of type dns_query_srv_fn, which expects pointer to dns_rr_srv structure
743       as query result instead of raw DNS packet.  The dns_parse_srv() is used
744       to convert raw DNS reply packet into dns_rr_srv structure (it  is  used
745       internally  and may be used directly too with generic query interface).
746       Routines dns_submit_srv() and dns_resolve_srv() are used to perform  IN
747       SRV  queries  in  a type-safe manner.  The name parameter is the domain
748       name in question, service and protocl specifies  the  service  and  the
749       protocol  in question (the library will construct query DN according to
750       rfc2782 rules) and may be NULL (in this case the library  assumes  name
751       parameter  holds the complete SRV query), and flags is query flags bit‐
752       mask, with one bit, DNS_NOSRCH, of practical interest (if the  name  is
753       absolute,  that  is, it ends up with a dot, DNS_NOSRCH flag will be set
754       automatically).
755
756
757   NAPTR Queries
758       struct dns_naptr {        /* single NAPTR record */
759         int order;              /* record order */
760         int preference;         /* preference of this record */
761         char *flags;            /* application-specific flags */
762         char *service;          /* service parameter */
763         char *regexp;           /* substitutional regular expression */
764         char *replacement;      /* replacement string */
765       };
766       struct dns_rr_naptr {     /* NAPTR RRset */
767         char *dnsnaptr_qname;   /* original query name */
768         char *dnsnaptr_cname;   /* canonical name */
769         unsigned dnsnaptr_ttl;  /* Time-To-Live (TTL) value */
770         int dnsnaptr_nrr;       /* number of text records in the set */
771         struct dns_naptr dnsnaptr_naptr[]; /* array of NAPTR records */
772       };
773       typedef void
774         dns_query_naptr_fn(ctx, struct dns_rr_naptr *result, data)
775       dns_parse_fn dns_parse_naptr;
776       struct dns_query *
777       dns_submit_naptr(ctx, const char *name, int flags,
778          dns_query_txt_fn *cbck, data);
779       struct dns_rr_naptr *
780       dns_resolve_naptr(ctx, const char *name, int flags);
781
782       The dns_rr_naptr structure holds a result  of  an  IN  NAPTR  (rfc3403)
783       query.   Callback  routine  for IN NAPTR queries expected to be of type
784       dns_query_naptr_fn, expects pointer to dns_rr_naptr structure as  query
785       result  instead  of  raw  DNS packet.  The dns_parse_naptr() is used to
786       convert raw DNS reply packet into dns_rr_naptr structure  (it  is  used
787       internally  and may be used directly too with generic query interface).
788       Routines dns_submit_naptr() and dns_resolve_naptr() are used to perform
789       IN  NAPTR  queries  in  a  type-safe manner.  The name parameter is the
790       domain name in question, and flags is query  flags  bitmask,  with  one
791       bit,  DNS_NOSRCH,  of practical interest (if the name is absolute, that
792       is, it ends up with a dot, DNS_NOSRCH flag will be set automatically).
793
794
795   DNSBL Interface
796       A DNS-based blocklists, or a DNSBLs, are in wide  use  nowadays,  espe‐
797       cially  to  protect  mailservers  from  spammers.  The library provides
798       DNSBL interface, a set of routines to perform queries  against  DNSBLs.
799       Routines accepts an IP address (IPv4 and IPv6 are both supported) and a
800       base DNSBL zone as query parameters, and returns  either  dns_rr_a4  or
801       dns_rr_txt structure.  Note that IPv6 interface return IPv4 RRset.
802
803       struct dns_query *
804       dns_submit_a4dnsbl(ctx,
805         const struct in_addr *addr, const char *dnsbl,
806         dns_query_a4_fn *cbck, void *data);
807       struct dns_query *
808       dns_submit_a4dnsbl_txt(ctx,
809         const struct in_addr *addr, const char *dnsbl,
810         dns_query_txt_fn *cbck, void *data);
811       struct dns_query *
812       dns_submit_a6dnsbl(ctx,
813         const struct in6_addr *addr, const char *dnsbl,
814         dns_query_a4_fn *cbck, void *data);
815       struct dns_query *
816       dns_submit_a6dnsbl_txt(ctx,
817         const struct in6_addr *addr, const char *dnsbl,
818         dns_query_txt_fn *cbck, void *data);
819       struct dns_rr_a4 *dns_resolve_a4dnsbl(ctx,
820         const struct in_addr *addr, const char *dnsbl)
821       struct dns_rr_txt *dns_resolve_a4dnsbl_txt(ctx,
822         const struct in_addr *addr, const char *dnsbl)
823       struct dns_rr_a4 *dns_resolve_a6dnsbl(ctx,
824         const struct in6_addr *addr, const char *dnsbl)
825       struct dns_rr_txt *dns_resolve_a6dnsbl_txt(ctx,
826         const struct in6_addr *addr, const char *dnsbl)
827       Perform  (submit  or  resolve) a DNSBL query for the given dnsbl domain
828       and an IP addr in question, requesting either A or TXT records.
829
830
831   RHSBL Interface
832       RHSBL is similar to DNSBL, but instead of an IP address, the  parameter
833       is a domain name.
834
835       struct dns_query *
836       dns_submit_rhsbl(ctx, const char *name, const char *rhsbl,
837         dns_query_a4_fn *cbck, void *data);
838       struct dns_query *
839       dns_submit_rhsbl_txt(ctx, const char *name, const char *rhsbl,
840         dns_query_txt_fn *cbck, void *data);
841       struct dns_rr_a4 *
842       dns_resolve_rhsbl(ctx, const char *name, const char *rhsbl);
843       struct dns_rr_txt *
844       dns_resolve_rhsbl_txt(ctx, const char *name, const char *rhsbl);
845       Perform  (submit  or  resolve) a RHSBL query for the given rhsbl domain
846       and name in question, requesting either A or TXT records.
847
848
849

LOW-LEVEL INTERFACE

851   Domain Names (DNs)
852       A DN is a series of domain name labels each starts  with  length  byte,
853       followed  by  empty label (label with zero length).  The following rou‐
854       tines to work with DNs are provided.
855
856
857       unsigned dns_dnlen(const unsigned char *dn)
858              return length of the domain name dn, including  the  terminating
859              label.
860
861
862       unsigned dns_dnlabels(const unsigned char *dn)
863              return number of non-zero labels in domain name dn.
864
865
866       unsigned dns_dnequal(dn1, dn2)
867         const unsigned char *dn1, *dn2;
868              test  whenever  the  two  domain  names,  dn1 and dn2, are equal
869              (case-insensitive).  Return domain name length if equal or 0  if
870              not.
871
872
873       unsigned dns_dntodn(sdn, ddn, dnsiz)
874         const unsigned char *sdn;
875         unsigned char *ddn;
876         unsigned dnsiz;
877              copies  the  source domain name sdn to destination buffer ddn of
878              size dnsiz.  Return domain name length or 0 if ddn is too small.
879
880
881       int dns_ptodn(name, namelen, dn, dnsiz, isabs)
882       int dns_sptodn(name, dn, dnsiz)
883         const char *name; unsigned namelen;
884         unsigned char *dn; unsigned dnsiz;
885         int *isabs;
886              convert asciiz name name of length namelen to DN format, placing
887              result into buffer dn of size dnsiz.  Return length of the DN if
888              successeful, 0 if the dn buffer supplied is too small, or  nega‐
889              tive value if name is invalid.  If isabs is non-NULL and conver‐
890              sion was successeful, *isabs will  be  set  to  either  1  or  0
891              depending whenever name was absolute (i.e. ending with a dot) or
892              not.  Name length,  namelength,  may  be  zero,  in  which  case
893              strlen(name) will be used.  Second form, dns_sptodn(), is a sim‐
894              plified form of dns_ptodn(), equivalent to
895              dns_ptodn(name, 0, dn, dnlen, 0).
896
897
898       extern const unsigned char dns_inaddr_arpa_dn[]
899       int dns_a4todn(const struct in_addr *addr, const unsigned char *tdn,
900             unsigned char *dn, unsigned dnsiz)
901       int dns_a4ptodn(const struct in_addr *addr, const char *tname,
902             unsigned char *dn, unsigned dnsiz)
903       extern const unsigned char dns_ip6_arpa_dn[]
904       int dns_a6todn(const struct in6_addr *addr, const unsigned char *tdn,
905             unsigned char *dn, unsigned dnsiz)
906       int dns_a6ptodn(const struct in6_addr *addr, const char *tname,
907             unsigned char *dn, unsigned dnsiz)
908              several variants of routines to convert IPv4  and  IPv6  address
909              addr  into  reverseDNS-like  domain  name  in DN format, storing
910              result in dn of size dnsiz.  tdn (or tname)  is  the  base  zone
911              name,  like  in-addr.arpa for IPv4 or in6.arpa for IPv6.  If tdn
912              (or tname) is NULL, dns_inaddr_arpa_dn (or dns_ip6_arpa_dn) will
913              be used.  The routines may be used to construct a DN for a DNSBL
914              lookup for example.  All routines return length of the resulting
915              DN  on  success,  -1  if resulting DN is invalid, or 0 if the dn
916              buffer (dnsiz) is too small.  To hold standard rDNS DN, a buffer
917              of  size DNS_A4RSIZE (30 bytes) for IPv4 address, or DNS_A6RSIZE
918              (74 bytes) for IPv6 address, is sufficient.
919
920
921       int dns_dntop(dn, name, namesiz)
922          const unsigned char *dn;
923          const char *name; unsigned namesiz;
924              convert domain name dn in DN format to  asciiz  string,  placing
925              result  into  name  buffer  of  size namesiz.  Maximum length of
926              asciiz representation  of  domain  name  is  DNS_MAXNAME  (1024)
927              bytes.   Root  domain  is  represented  as empty string.  Return
928              length of the resulting name (including  terminating  character,
929              i.e.  strlen(name)+1)  on  success,  0 if the name buffer is too
930              small, or negative value if dn  is  invalid  (last  case  should
931              never  happen  since  all routines in this library which produce
932              domain names ensure the DNs generated are valid).
933
934
935       const char *dns_dntosp(const unsigned char *dn)
936              convert domain name dn in  DN  format  to  asciiz  string  using
937              static buffer.  Return the resulting asciiz string on success or
938              NULL on failure.  Note since this routine uses static buffer, it
939              is not thread-safe.
940
941
942       unsigned dns_dntop_size(const unsigned char *dn)
943              return  the  buffer size needed to convert the dn domain name in
944              DN format to asciiz string, for dns_dntop().  The routine return
945              either  the size of buffer required, including the trailing zero
946              byte, or 0 if dn is invalid.
947
948
949   Working with DNS Packets
950       The following routines are provided to encode and  decode  DNS  on-wire
951       packets.  This is low-level interface.
952
953
954       DNS  response  codes  (returned  by dns_rcode() routine) are defined as
955       constants prefixed with DNS_R_.  See udns.h header file  for  the  com‐
956       plete  list.   In  particular, constants DNS_R_NOERROR (0), DNS_R_SERV‐
957       FAIL, DNS_R_NXDOMAIN may be of interest to an application.
958
959
960       unsigned dns_get16(const unsigned char *p)
961       unsigned dns_get32(const unsigned char *p)
962              helper routines, convert 16-bit or  32-bit  integer  in  on-wire
963              format pointed to by p to unsigned.
964
965
966       unsigned char *dns_put16(unsigned char *d, unsigned n)
967       unsigned char *dns_put32(unsigned char *d, unsigned n)
968              helper  routine,  convert unsigned 16-bit or 32-bit integer n to
969              on-wire format to buffer pointed to by d, return d+2 or d+4.
970
971
972       DNS_HSIZE (12)
973              defines size of DNS header.  Data  section  in  the  DNS  packet
974              immediately  follows the header.  In the header, there are query
975              identifier (id), various flags and codes, and number of resource
976              records  in  various  data sections.  See udns.h header file for
977              complete list of DNS header definitions.
978
979
980       unsigned dns_qid(const unsigned char *pkt)
981       int dns_rd(const unsigned char *pkt)
982       int dns_tc(const unsigned char *pkt)
983       int dns_aa(const unsigned char *pkt)
984       int dns_qr(const unsigned char *pkt)
985       int dns_ra(const unsigned char *pkt)
986       unsigned dns_opcode(const unsigned char *pkt)
987       unsigned dns_rcode(const unsigned char *pkt)
988       unsigned dns_numqd(const unsigned char *pkt)
989       unsigned dns_numan(const unsigned char *pkt)
990       unsigned dns_numns(const unsigned char *pkt)
991       unsigned dns_numar(const unsigned char *pkt)
992       const unsigned char *dns_payload(const unsigned char *pkt)
993              return various parts from the DNS packet header pkt: query iden‐
994              tifier  (qid),  recursion  desired (rd) flag, truncation occured
995              (tc) flag, authoritative answer (aa) flag, query  response  (qr)
996              flag,  recursion  available  (ra) flag, operation code (opcode),
997              result code (rcode),  number  of  entries  in  question  section
998              (numqd),  number of answers (numan), number of authority records
999              (numns), number of additional records (numar), and  the  pointer
1000              to the packet data (payload).
1001
1002
1003       int dns_getdn(pkt, curp, pkte, dn, dnsiz)
1004       const unsigned char *dns_skipdn(cur, pkte)
1005          const unsigned char *pkt, *pkte, **curp, *cur;
1006          unsigned char *dn; unsigned dnsiz;
1007              dns_getdn()  extract  DN  from  DNS packet pkt which ends before
1008              pkte starting at position *curp into buffer pointed to by dn  of
1009              size  dnsiz.   Upon  successeful completion, *curp will point to
1010              the next byte in the packet after the extracted domain name.  It
1011              return positive number (length of the DN if dn) upon successeful
1012              completion, negative value on error (when  the  packet  contains
1013              invalid data), or zero if the dnsiz is too small (maximum length
1014              of a domain name is DNS_MAXDN).  dns_skipdn() return pointer  to
1015              the  next  byte  in DNS packet which ends up before pkte after a
1016              domain name which starts at the cur byte, or NULL if the  packet
1017              is  invalid.   dns_skipdn()  is  more or less equivalent to what
1018              dns_getdn() does, except it does not actually extract the domain
1019              name in question, and uses simpler interface.
1020
1021
1022       struct dns_rr {
1023         unsigned char dnsrr_dn[DNS_MAXDN]; /* the RR DN name */
1024         enum dns_class dnsrr_cls;          /* class of the RR */
1025         enum dns_type  dnsrr_typ;          /* type of the RR */
1026         unsigned dnsrr_ttl;                /* TTL value */
1027         unsigned dnsrr_dsz;                /* size of data in bytes */
1028         const unsigned char *dnsrr_dptr;   /* pointer to the first data byte */
1029         const unsigned char *dnsrr_dend;   /* next byte after RR */
1030       };
1031              The  dns_rr  structure  is used to hold information about single
1032              DNS Resource Record (RR) in an easy to use form.
1033
1034
1035       struct dns_parse {
1036         const unsigned char *dnsp_pkt; /* pointer to the packet being parsed */
1037         const unsigned char *dnsp_end; /* end of the packet pointer */
1038         const unsigned char *dnsp_cur; /* current packet positionn */
1039         const unsigned char *dnsp_ans; /* pointer to the answer section */
1040         int dnsp_rrl;                  /* number of RRs left */
1041         int dnsp_nrr;                  /* number of relevant RRs seen so far */
1042         unsigned dnsp_ttl;             /* TTL value so far */
1043         const unsigned char *dnsp_qdn; /* the domain of interest or NULL */
1044         enum dns_class dnsp_qcls;      /* class of interest or 0 for any */
1045         enum dns_type  dnsp_qtyp;      /* type of interest or 0 for any */
1046         unsigned char dnsp_dnbuf[DNS_MAXDN]; /* domain name buffer */
1047       };
1048              The dns_parse structure is used to parse DNS reply  packet.   It
1049              holds  information  about  the  packet  being  parsed (dnsp_pkt,
1050              dnsp_end and dnsp_cur fields), number of RRs in the current sec‐
1051              tion  left  to  do,  and the information about specific RR which
1052              we're looking for (dnsp_qdn, dnsp_qcls and dnsp_qtyp fields).
1053
1054
1055       int dns_initparse(struct dns_parse *p,
1056         const unsigned char *qdn,
1057         const unsigned char *pkt,
1058         const unsigned char *cur,
1059         const unsigned char *end)
1060              initializes the RR parsing structure p.  Arguments pkt, cur  and
1061              end should describe the received packet: pkt is the start of the
1062              packet, end points to the next byte after the end of the packet,
1063              and  cur  points  past  the  query DN in query section (to query
1064              class+type information).  And qdn points to the query DN.   This
1065              is  the  arguments  passed  to dns_parse_fn() routine. dns_init‐
1066              parse() initializes dnsp_pkt, dnsp_end and  dnsp_qdn  fields  to
1067              the  corresponding arguments, extracts and initializes dnsp_qcls
1068              and dnsp_qtyp fields to the values found at  cur  pointer,  ini‐
1069              tializes  dnsp_cur and dnsp_ans fields to be cur+4 (to the start
1070              of answer section), and initializes dnsp_rrl field to be  number
1071              of  entries  in  answer section. dnsp_ttl will be set to max TTL
1072              value, 0xffffffff, and dnsp_nrr to 0.
1073
1074
1075       int dns_nextrr(struct dns_parse *p, struct dns_rr *rr);
1076              searches for next RR in the packet based on  the  criteria  pro‐
1077              vided  in  the  p  structure,  filling  in  the rr structure and
1078              advancing p->dnsp_cur to the next RR in the packet.   RR  selec‐
1079              tion is based on dnsp_qdn, dnsp_qcls and dnsp_qtyp fields in the
1080              dns_parse structure.  Any (or all) of the 3  fields  may  be  0,
1081              which  means any actual value from the packet is acceptable.  In
1082              case the field isn't 0 (or NULL for  dnsp_qdn),  only  RRs  with
1083              corresponding  characteristics  are  acceptable.   Additionally,
1084              when dnsp_qdn is non-NULL, dns_nextrr() performs automatic CNAME
1085              expansion.   Routine will return positive value on success, 0 in
1086              case it reached  the  end  of  current  section  in  the  packet
1087              (p->dnsp_rrl  is  zero), or negative value if next RR can not be
1088              decoded  (packet  format  is  invalid).   The  routine   updates
1089              p->dnsp_qdn  automatically  when  this  field is non-NULL and it
1090              encounters  appropriate  CNAME  RRs  (saving  CNAME  target   in
1091              p->dnsp_dnbuf),  so  after  end of the process, p->dnsp_qdn will
1092              point to canonical name of the domain in question.  The  routine
1093              updates  p->dnsp_ttl  value  to  be  the  minimum TTL of all RRs
1094              found.
1095
1096
1097       void dns_rewind(struct dns_parse *p, const unsigned char *qdn)
1098              this routine "rewinds" the packet parse state structure to be at
1099              the  same state as after a call to dns_initparse(), i.e. reposi‐
1100              tion the parse structure p to the start of  answer  section  and
1101              initialize  p->dnsp_rrl  to the number of entries in answer sec‐
1102              tion.
1103
1104
1105       int dns_stdrr_size(const struct dns_parse *p);
1106              return size to hold standard  RRset  structure  information,  as
1107              shown  in  dns_rr_null  structure  (for  the query and canonical
1108              names).  Used to calculate amount of memory to allocate for com‐
1109              mon part of type-specific RR structures in parsing routines.
1110
1111
1112       void *dns_stdrr_finish(struct dns_rr_null *ret, char *cp,
1113         const struct dns_parse *p);
1114              initializes  standard RRset fields in ret structure using buffer
1115              pointed to by cp, which should have at least as  many  bytes  as
1116              dns_stdrr_size(p)  returned.   Used  to  finalize common part of
1117              type-specific RR structures in parsing routines.
1118
1119
1120       See library source for usage examples of all the above  low-level  rou‐
1121       tines, especially source of the parsing routines.
1122
1123
1124   Auxilary Routines
1125       int dns_pton(int af, const char *src, void *dst);
1126              privides  functionality similar to standard inet_pton() routine,
1127              to convert printable representation of an IP address  of  family
1128              af  (either  AF_INET  or AF_INET6) pointed to by src into binary
1129              form suitable for socket addresses and  transmission  over  net‐
1130              work,  in  buffer  pointed  to  by  dst.  The destination buffer
1131              should be of size 4 for AF_INET family or 16 for AF_INET6.   The
1132              return  value  is  positive  on success, 0 if src is not a valid
1133              text representation of an address of family af, or  negative  if
1134              the given address family is not supported.
1135
1136
1137       const char *dns_ntop(int af, const void *src,
1138           char *dst, int dstsize)
1139              privides  functionality similar to standard inet_ntop() routine,
1140              to convert binary representation of an IP address of  family  af
1141              (either  AF_INET  or AF_INET6) pointed to by src (either 4 or 16
1142              bytes) into printable form in buffer in buffer pointed to by dst
1143              of  size  dstsize.  The destination buffer should be at least of
1144              size 16 bytes for AF_INET family or 46 bytes for AF_INET6.   The
1145              return  value  is  either dst, or NULL pointer if dstsize is too
1146              small to hold this address or if the given address family is not
1147              supported.
1148
1149

AUTHOR

1151       The    udns    library   has   been   written   by   Michael   Tokarev,
1152       mjt+udns@tls.msk.ru.
1153
1154

VERSION

1156       This manual page corresponds to udns version 0.4, released Jan-2014.
1157
1158
1159
1160Library Functions                  Jan 2014                            udns(3)
Impressum