Man Linux: Main Page and Category List

NAME

       dns_transmit_* - The dns_transmit library interface

SYNOPSIS

       #include <dns.h>

       dns_transmit_start(&dt, s, flagrecursive, q, t, localip);
       dns_transmit_io(&dt, x, &deadline);
       dns_transmit_get(&dt, x, &stamp);
       dns_transmit_free(&dt);

         struct dns_transmit dt = {0};

         char s[64];
         int flagrecursive;
         char *q;
         char t[2];
         char localip[4];

         iopause_fd x[1];
         struct taia deadline;
         struct taia stamp;

DESCRIPTION

       The  dns_transmit functions send a DNS query to some DNS servers.  They
       save the first useful response inside dt.

       The query asks for Internet records of  type  t  for  the  domain  name
       packet-encoded  in q.  It requests server recursion if flagrecursive is
       nonzero.

       The IP addresses of the DNS servers are listed in s.  The  dns_transmit
       functions  skip  IP  addresses  of  0.0.0.0. The dns_transmit functions
       record only a pointer to the contents of s, not a copy  of  s,  so  you
       must leave s in place and unchanged.

       The  dns_transmit  functions  send  outgoing  packets  from  a local IP
       address of localip.

       The dns_transmit functions act asynchronously. They are designed to  be
       used in an iopause event loop:

         if (dns_transmit_start(&dt,s,flagrecursive,q,t,localip) == -1)
           return -1;

         for (;;) {
           int r;
           taia_now(&stamp);
           taia_addsec(&deadline,&stamp,120);
           dns_transmit_io(&dt,x,&deadline);
           iopause(x,1,&deadline,&stamp);
           r = dns_transmit_get(&dt,x,&stamp);
           if (r == -1) return -1;
           if (r == 1) break;
         }

         dosomething(dt.packet,dt.packetlen);
         dns_transmit_free(&dt);
         return 0;

       dns_transmit_start  begins the query; it returns 0 on success, or -1 on
       failure.  dns_transmit_get continues the query; it  returns  1  if  the
       response  has  arrived, 0 if the response has not yet arrived, or -1 on
       failure.  Here ‘‘failure’’ means a socket creation  failure,  a  memory
       allocation  failure,  a timeout after the final query attempt, an empty
       list of servers (reported as EIO), a  query  longer  than  65535  bytes
       (reported  as  EIO),  a  malformed  response to the final query attempt
       (reported as EIO), or a server declaration of failure  in  response  to
       the final query attempt (reported as EAGAIN).

       The  dns_transmit  functions  communicate through dt.  They dynamically
       allocate a  socket  for  network  communication,  memory  for  the  DNS
       request,  and  memory  for  the DNS response; these resources are freed
       when you call dns_transmit_free, or when  you  call  dns_transmit_start
       again  with  the  same  dt  to  handle  another  query.  You must zero-
       initialize dt before calling dns_transmit_start the first time.

       If dns_transmit_get returns 1, the DNS response is  a  byte  string  of
       length  dt.packetlen;  dt.packet  points  to  the  first  byte.  The IP
       address  of  the  server  that  provided  the  response  is  stored  at
       dt.servers + 4 * dt.curserver.

Transmission details

       The  dns_transmit functions send the query by UDP to the first address,
       wait 1 second for a response, send the  query  by  UDP  to  the  second
       address, wait 1 second for a response, etc.; then send the query by UDP
       to each address again, but waiting 3 seconds for  each  response;  then
       again,  waiting  11  seconds;  then  one last time, waiting 45 seconds.
       Recursive queries skip the 1-second step.

       dns_transmit_get does not always return the first packet it sees:

       1.     If the packet has the wrong ID,  shows  the  wrong  query  name,
              shows  the  wrong  query  type, or has qdcount different from 1:
              dns_transmit_get  discards  the  packet   as   irrelevant,   and
              continues waiting for packets from the same server.

       2.     If  the packet has rcode different from 0 or 3: dns_transmit_get
              discards the packet, and moves immediately to the next server.

       3.     If the packet has the tc bit set: dns_transmit_get tries  a  TCP
              connection   to   each  address,  waiting  10  seconds  for  the
              connection and, if a connection is established, 10 more  seconds
              for a response.

       dns_transmit_get  does not listen to several servers simultaneously for
       responses for the same query.   Each  query  transmission  uses  a  new
       random port number and query ID.

SEE ALSO

       dns_domain(3), dns_ip4(3), dns_ip4_qualify(3), dns_mx(3), dns_name4(3),
       dns_packet(3), dns_random(3), dns_txt(3)

       http://cr.yp.to/djbdns/blurb/library.html

                                                             dns_transmit_*(3)