libar(3)                   Library Functions Manual                   libar(3)

       ar_init(), ar_addquery(), ar_waitreply(), ar_cancelquery(),
       ar_resend(), ar_recycle(), ar_shutdown() -- asynchronous DNS resolver

       #include <ar.h>

       typedef void * ar_malloc_t (void *, size_t);

       typedef void ar_free_t (void *, void *);

       AR_LIB ar_init (ar_malloc_t mallocf, ar_free_t freef, void *
       memclosure, int flags );

       int ar_shutdown (AR_LIB lib );

       void ar_setretry (AR_LIB lib, struct timeval * new, struct timeval *
       old );

       void ar_setmaxretry (AR_LIB lib, int new, int * old);

       AR_QUERY ar_addquery (AR_LIB lib, const char * query, int class, int
       type, int depth, unsigned char * buf, size_t buflen, int * err, struct
       timeval * timeout );

       int ar_waitreply (AR_LIB lib, AR_QUERY query, int * len, struct timeval
       * timeout );

       int ar_cancelquery (AR_LIB lib, AR_QUERY query );

       void ar_recycle (AR_LIB lib, AR_QUERY query );

       int ar_resend (AR_LIB lib, AR_QUERY query );

       char * ar_strerror (int err );

       These functions are an interface to an asynchronous resolver facility.
       The functions provided by resolver(3) and the gethostbyxxx(3) functions
       are not thread-safe since they use static storage, don't multiplex
       efficiently, and don't have timeouts associated with them.  This
       library of functions was drafted to provide those facilities.

       An application first initializes the package by calling ar_init().  The
       optional mallocf parameter is a caller-provided memory allocation
       function taking a pointer to a caller-provided opaque data structure
       (the memclosure parameter) and a number of bytes to allocate.  If
       mallocf is not provided, the default system memory allocator function
       malloc(3) is used.  The optional freef parameter specifies a matching
       caller-provided memory deallocator function, taking a pointer to a
       caller-provided opaque data structure (the memclosure parameter) and a
       pointer to the memory to be released.  If freef is not provided, the
       default system memory release function free(3) is used.  The flags
       parameter is a bitwise OR of a set of available flags to tailor the
       operation of the package.  Currently the only supported flags are
       AR_FLAG_USETCP, which instructs the package to submit its queries via a
       TCP connection rather than the default (UDP), and AR_FLAG_TRUNCCHECK
       which upon receiving a reply with the "truncation" bit set will
       suppress the automatic upgrade to TCP mode if at least one answer was
       received in a reply (by default, truncation of any kind causes an
       upgrade to the connection channel and retransmission of all pending
       queries).  The handle returned by ar_init() is passed to later
       functions in order to share resources among transactions.

       By default the package will not retransmit queries for which no reply
       has arrived until requested to do so with ar_resend().  Moreover, that
       function re-uses the same nameserver as the previous attempt.  Instead,
       the caller can use ar_setretry() to define (or retrieve) a time
       interval after which, if no reply has been received, the query will be
       re-sent to the next nameserver in the list of nameservers.  In the TCP
       case, this will disconnect from the nameserver, reconnect, and re-send
       all pending queries.  A time of {0, 0} disables this feature.  The
       default is the same as whatever the local resolver uses.  To leave the
       current value unchanged, specify a value of NULL for new.  If the
       current value is not of interest, specify a value of NULL for old.

       The ar_setmaxretry() function gets and/or sets the maximum number of
       times a query can be attempted before the package will give up trying.
       The default is the same as whatever the local resolver uses.  To
       retrieve the current value but leave it unchanged, specify a value of
       -1 for new.  If the current value is not of interest, specify a value
       of NULL for old.

       To submit a new query to the nameserver, the application calls
       ar_addquery().  The lib parameter is the handle returned from
       ar_init().  The query, class and type parameters specify the query that
       is to be performed.  buf specifies where the result should be written
       when a reply is received, and buflen indicates how many bytes are
       available there.  err is an optional pointer to an integer which will
       receive the value of errno if there is a transmission error between
       this package and the nameserver.  (See also the ERROR CODES section
       below.)  depth indicates how many CNAME references will be re-queried
       before the package gives up and returns whatever result is current.
       Finally, timeout is an optional pointer to a timeval structure that
       indicates the total time allowed for this query to resolve.  If NULL,
       this query never times out.

       To wait for a query result, the application calls ar_waitreply().  lib
       is again the library handle as returned by ar_init().  query is the
       query handle returned by ar_addquery().  len is a pointer to an integer
       which will receive the number of bytes that were contained in the
       reply.  It can be NULL if that information is not of interest to the
       caller.  This number may be larger than the value of buflen in the call
       to ar_addquery(), in which case there was not enough space in the
       provided buffer to receive the reply and the application should
       resubmit with a bigger buffer.  timeout specifies how long this
       particular call should wait for a reply before returning.  If the reply
       has already arrived (even if it's an NXDOMAIN reply), this function
       will return immediately, otherwise it will wait until either the
       requested timeout expires, or the timeout set on the ar_addquery() call

       When a reply has been retrieved, the query handle needs to be recycled
       via a call to ar_recycle().

       To abort a query, use ar_cancelquery().  This implicitly recycles the
       query handle passed to it.

       To arrange to re-send a query for which a reply has not yet arrived,
       use ar_resend().

       When all queries are done and the facility is no longer desired, a call
       to ar_shutdown() will close down the service and release related

       The function ar_strerror() is provided to handle error codes returned
       by the library.  Positive error codes are standard POSIX error codes
       and will be passed to strerror(3) while negative error codes are
       internal to the library and will be translated to a human-readable form
       by this function.

       In addition to the system-defined error codes defined in the intro(2)
       man page, the following error codes may be returned using the err
       parameter to ar_addquery():

              The query was retried too many times, and the resolver has given
              up trying to get an answer.

              No contact could be made with any configured nameserver, and
              ar_waitreply() has returned with this information to give the
              caller a chance to abort the query.  The library will re-attempt
              contact after a brief pause, at which time all pending queries
              will be re-submitted to the nameserver if contact can be re-
              established.  The caller may re-enter ar_waitreply() with the
              same query handle if desired to wait for the results of the
              continued attempts.

              The query generated by res_mkquery() was too large to be sent
              (exceeded 32Kb).

       ar_lib() returns a handle to a newly-initialized instantiation of the
       library.  If operating in TCP mode, a TCP connection now exists to a
       nameserver.  NULL is returned if any of this initialization fails, with
       errno set to indicate the error.

       ar_shutdown() returns 0 on success, or an errno value on failure.

       ar_addquery() returns a newly-initialized AR_QUERY handle on success,
       or NULL on failure with errno set to indicate the error.  EINVAL will
       be used if the query submitted was malformed (i.e. contained invalid
       characters or character sequences).

       ar_cancelquery() returns 0 on success or 1 on error (i.e. invalid query
       handle specified).

       ar_waitreply() returns AR_STAT_SUCCESS (0) on success, indicating a
       reply is available for processing; AR_STAT_NOREPLY (1) if a timeout is
       specified on the call but expired, indicating no reply is available yet
       but there might be one later; AR_STAT_EXPIRED (2) if the timeout
       specified on the call to ar_addquery() has expired; or AR_STAT_ERROR
       (-1) on error with errno set to indicate the error.

       ar_resend() returns 0 on success or -1 on error with errno set to
       indicate the error.

       This system uses pthreads for synchronization and signalling.
       Applications that use another threading mechanism may not work with
       this library.

       If operating in TCP mode and the remote nameserver disconnects, the
       library will attempt to connect to each of the nameservers published in
       resolv.conf(4) before giving up.  Once it gives up, all pending and
       future calls to ar_waitreply() or ar_addquery() will fail.  The only
       option after that is to shut down the library and start again.

       CNAME recursion is done at most depth times while evaluating the result
       of a query.  The time specified in the call to ar_addquery() should
       allow for recursion time, since that defines the total amount of time
       the entire query, including recursion, is allowed to take.

       The buffer provided in the call to ar_addquery() is sometimes used for
       temporary storage, specifically when chasing CNAME references.  If a
       particular CNAME recursion is too large for the buffer, the search will
       be interrupted and returned as-is, and the len value returned will
       indicate that a lack of buffer space caused the recursion to terminate
       (see above).

       ar_strerror() returns a pointer to a character string representing the
       supplied error code.

       Copyright (c) 2004, 2005, Sendmail, Inc. and its suppliers.  All rights

       Copyright (c) 2009, The OpenDKIM Project.  All rights reserved.

       gethostbyaddr(3), gethostbyname(3), resolv.conf(4), resolver(3)