=pod

=head1 NAME

I<query_send()>, I<response_rcv()>, I<get()> - 
send queries and receive responses from a DNS name server.

I<clone_ns()>, I<clone_ns_list()>, I<free_name_server()>,
I<free_name_servers()> - manage name server lists

I<print_response()> - display answers returned from the name server

=head1 SYNOPSIS

  #include <resolver.h>

  int query_send(const char    *name,
            const unsigned short type,
            const unsigned short class,
            struct name_server  *nslist,
            int                 edns0_size,
            int                 *trans_id);

  int response_recv(int         *trans_id,
            fd_set              *pending_desc,
            struct timeval      *closest_event,
            struct name_server  **respondent,
            unsigned char       **response,
            size_t              *response_length);

  int get(const char          *name_n,
          const unsigned short type_h,
          const unsigned short class_h,
          struct name_server  *nslist,
          struct name_server  **respondent,
          unsigned char       **response,
          size_t              *response_length);

  int clone_ns(struct name_server **cloned_ns, 
          struct name_server *ns);

  int clone_ns_list(struct name_server **ns_list,
		    struct name_server *orig_ns_list);

  void free_name_server(struct name_server **ns);

  void free_name_servers(struct name_server **ns);

  void print_response(unsigned char *response, 
            size_t response_length);

=head1 DESCRIPTION

The I<query_send()> function sends a query to the name servers specified in
I<nslist>.  The query is comprised of the <I<name, class, type>> tuple and
I<trans_id> provides a handle to this transaction within the I<libsres> library. 
The buffer size advertised in the EDNS0 option can be set using the I<ends0_size>
argument.

The I<response_recv()> function returns the answers, if available, from the
name server that responds for the query identified by I<trans_id>.
The response is available in I<response> and the responding name server is
returned in I<respondent>.  The length of the response in bytes is returned
in I<response_length>.

The I<get()> function provides a wrapper around the I<query_send()> and
I<response_recv()> functions.  After sending a request, it blocks until
a response is received from some name server or until the request times out.
The I<libsres> library does not automatically follow referrals; responses
containing referrals are treated as valid responses.

The memory pointed to by I<*respondent> is internally allocated by the
I<libsres> library and must be freed by the invoker using
I<free_name_server()>.  An entire list of name servers can be freed using
I<free_name_servers()>.  A copy of the name server can be created using
I<clone_ns()> and a copy of a name server list can be made using
I<clone_ns_list()>.

I<print_response()> provides a convenient way to display answers returned
in I<response> by the name server.

The I<name_server> structure is defined in B<resolver.h> as follows:

    #define NS_MAXCDNAME    255
    struct name_server
    {
        unsigned char ns_name_n[NS_MAXCDNAME];
        void *ns_tsig;
        unsigned int ns_security_options;
        unsigned int ns_status;
        unsigned long ns_options;
        int ns_retry;
        int ns_retrans;
        struct name_server *ns_next;
        int ns_number_of_addresses;
        struct sockaddr_storage **ns_address;
    };

=over 4

=item I<ns_name_n>

The name of the zone for which this name server is authoritative.  

=item I<ns_tsig>

The I<tsig> key that should be used to protect messages sent to this name
server. This field is currently unused and must be set to NULL.

=item I<ns_security_options>

The security options for the zone.  This field is currently unused and must be
set to B<ZONE_USE_NOTHING>.

=item I<ns_status>

The status of the zone.  This field indicates how the zone information was
obtained. The invoker must set this value to B<SR_ZI_STATUS_UNSET>. Zone
information obtained through referrals have a value of
B<SR_ZI_STATUS_LEARNED> for this field.

=item I<ns_options>

Specifies additional resolver flags.  Currently defined flags are
B<SR_QUERY_RECURSE>, which sets the "Recursion Desired" flag; B<SR_QUERY_SET_DO>,
which sets the "DNSSEC OK" bit in the EDNS0 header; 
B<SR_QUERY_SET_CD>, which sets the "DNSSEC CD" bit in the EDNS0 header;
and B<SR_QUERY_DEBUG>, which enables debugging. B<SR_QUERY_VALIDATING_STUB_FLAGS> sets
both B<SR_QUERY_SET_DO> and B<SR_QUERY_SET_CD>.

=item I<ns_retry>

Specifies the maximum number of attempts that must be made to obtain a name
from an unresponsive name server before giving up.

=item I<ns_retrans>

Specifies the retransmission interval in seconds for queries sent to
unresponsive name servers.

=item I<ns_next>

The address of the next name server in the list.

=item I<ns_number_of_addresses>

The number of elements in the array I<ns_addresses>.  This field is
currently unused.

=item I<ns_addresses>

The IP address of the name server.  

=back

=head1 OTHER SYMBOLS EXPORTED

The I<libsres> library also exports the following BIND functions,
documentation for which can be found in the BIND sources and documentation
manuals:

  res_nametoclass
  res_nametotype
  ns_name_ntop
  ns_name_pton
  ns_name_unpack
  ns_parse_ttl
  p_class
  p_section
  p_type

The I<p_type()> function exported from I<libsres> has been augmented such that 
it recognizes the various DNSSEC type codes such DNSKEY, RRSIG, NSEC, 
NSEC3 and DLV.

=head1 RETURN VALUES

=over 4

=item B<SR_UNSET>

No error.

=item B<SR_CALL_ERROR>

An invalid parameter was passed to I<get()>, I<query_send()>, or
I<response_recv()>.

=item B<SR_INTERNAL_ERROR>

The resolver encountered some internal error.

=item B<SR_TSIG_ERROR>

The resolver encountered some TSIG-related error.  This is currently
not implemented.

=item B<SR_NO_ANSWER>

No answers were received from any name server.

=item B<SR_NO_ANSWER_YET>

No answer currently available; the query is still active.

=item B<SR_HEADER_ERROR>

The length and count of records in the header were incorrect.

=item B<SR_NXDOMAIN>

The queried name did not exist.

=item B<SR_FORMERR>

The name server was not able to parse the query message.

=item B<SR_SERVFAIL>

The name server was not reachable.

=item B<SR_NOTIMPL>

A particular functionality is not yet implemented.

=item B<SR_REFUSED>

The name server refused to answer this query.

=item B<SR_DNS_GENERIC_FAILURE>

Other failure returned by the name server and reflected in the
returned message B<RCODE>.

=item B<SR_EDNS_VERSION_ERROR>

The EDNS version was not recognized

=item B<SR_NAME_EXPANSION_FAILURE>

A failure was encountered while trying to expand a compressed domain name.

=back

=head1 CURRENT STATUS

There is currently no support for IPv6.

There is limited support for specifying resolver policy; members of the
I<struct name_server> are still subject to change.

=head1 COPYRIGHT

Copyright 2004-2013 SPARTA, Inc.  All rights reserved.
See the COPYING file included with the dnssec-tools package for details.

=head1 SEE ALSO

I<libval(3)>

http://www.dnssec-tools.org

=cut
