Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
libgetdns(3)			    getdns			  libgetdns(3)

NAME
       libgetdns  -- an	implementation of a modern asynchronous	DNS API	by and
       for application developers

LIBRARY
       DNS Resolver library (libgetdns,	-lgetdns)

SYNOPSIS
       libgetdns

       This man	page describes the getdns library, the general concepts	behind
       the  API	and some of the	common elements	of the public interface	to the
       library.	 Each of the public entry points and more complex  data	 types
       are captured in separate	man pages.

DESCRIPTION
       getdns is modern	asynchronous DNS API intended to be useful to applica-
       tion developers and operating system distributors as a  way  of	making
       all  types  of  DNS  information	easily available in many types of pro-
       grams. The major	features of this new API are:

	      Full support for event-driven programming
	      Supports DNSSEC in multiple ways
	      Mirroring	of the resolution in getaddrinfo()
	      Easily supports all RRtypes, even	those yet to be	defined

       Each of the entry points	is offered with	both asynchronous and synchro-
       nous signatures.	 The asynchronous functions rely on event handling and
       callback	via libevent.  Functions are thread safe.

       A context structure maintains DNS query and response data and  is  used
       to maintain state during	calls to the public entry points.

       The project page	for this implementation	is at

	      http://getdnsapi.net

       The specification is maintained at

	      http://getdnsapi.net/spec

       The git repository for this implementation is at

	      http://github.com/getdnsapi/getdns

DATA STRUCTURES
       The  API	 uses  a few data structures to	pass data into and return data
       from the	public entry points.

       list   an ordered list, the members of the list can be any of the  four
	      data types.

       dict   a	 name-value  pair. The name is a string	literal, and the value
	      can be any of the	four data types. The order of  the  name-value
	      pairs in a dict is not important.

       int    an integer compatible with uint32_t.

       bindata
	      a	 struct	 used  to  hold	 binary	data defined as	{ size_t size;
	      uint8_t *binary_stuff; }.

ASYNCHRONOUS USE
       The getdns specification	emphasizes the asynchronous nature of the  API
       and allows implementations to define their own approach.	This page doc-
       uments this implementation's decisions and facilities provided  to  the
       developer.

       This  implementation  provides  asynchronous  support via the following
       mechanisms:

	  File Descriptor Polling
	  Event	Loop Integrations:
	     libevent
	     libuv
	     libev
	  Custom Event Loop Integrations

       All functions  and  types  discussed  in	 this  page  are  declared  in
       getdns_extra.h

   Build-in Event loop
       The  library has	an built in event loop that can	be used	if none	of the
       extensions for external event loops are used. The library will  execute
       requests	 and  dispatch	callbacks with a call to getdns_context_run().
       If an event loop	extension is  used,  this  will	 run  the  extension's
       eventloop.

       void getdns_context_run(getdns_context *context)

	  Run the context's event loop until nothing more to do.

       uint32_t	 getdns_context_get_num_pending_requests(getdns_context*  con-
	  text,	struct timeval*	next_timeout)

	  Get the number of outstanding	asynchronous requests for a given con-
	  text	as well	as the the amount of time until	the next timeout.  The
	  next_timeout struct can be NULL.  If supplied	and the	number of out-
	  standing  requests  is > 0, then the timeout represents the relative
	  time until the next timeout.

       getdns_return_t getdns_context_process_async(getdns_context* context)

	  Inform the context  to  process  its	outstanding  requests.	 Users
	  should  call this when either	a timeout has occurred or the file de-
	  scriptor signals that	it is ready.  User callbacks are fired	during
	  this call.

   Included Event Loop Integrations
       A  number  of  applications achieve asynchronous	behavior by leveraging
       event loop abstraction libraries. If the	build system discovers a  sup-
       ported event loop, the event loop extension is built in addition	to the
       getdns library. Extensions are built as an additional  shared  library.
       The following event loop	libraries are supported:

       libevent1 and libevent2

       The  libevent extension allows a	context	to attach to a event_base. The
       event loop is then run like any other application  using	 libevent  via
       event_base_dispatch  or	event_base_loop	and expect getdns callbacks to
       fire.

       Note that if both libevent1 and libevent2 reside	on system, the	exten-
       sion uses libevent2.

	  Extension library: libgetdns_ext_event.[shared_lib_ext]
	  Extension header: getdns/getdns_ext_libevent.h

       libuv

       The  libuv  extension  allows  a	 context to attach to a	uv_loop_s. The
       event loop can then be run like any other application using  libuv  via
       uv_run and expect getdns	callbacks to fire.

	  Extension library: libgetdns_ext_uv.[shared_lib_ext]
	  Extension header: getdns_ext_libuv.h

       libev

       The  libev extension allows a context to	attach to a ev_loop. The event
       loop can	then be	run like any other application using libev via	ev_run
       and expect getdns callbacks to fire.

	  Extension library: libgetdns_ext_ev.[shared_lib_ext]
	  Extension header: getdns_ext_libev.h

   getdns_context event	loop extension functions
       The following are functions used	by the extension entry point to	attach
       to a particular context.

       The application sets an event loop extension on a context.  The	exten-
       sion_data  is  optional data that is passed into	the extension methods.
       If an event loop	is already set on a context then  it  is  cleaned  up.
       All outstanding requests	are also canceled.

	      getdns_return_t		 getdns_extension_set_eventloop(struct
	      getdns_context* context, getdns_eventloop_extension*  extension,
	      void* extension_data);

       The application gets the	extension data associated with a context.

	      void*  getdns_context_get_extension_data(struct  getdns_context*
	      context);

       When no more work must be done the application detaches an  event  loop
       from a context

	      getdns_return_t	      getdns_extension_detach_eventloop(struct
	      getdns_context* context);

SYNCHRONOUS USE
       There are four synchronous functions parallel to	the four getdns	 async
       functions, except that there is no callback parameter. When an applica-
       tion calls one of these synchronous functions, the API gathers all  the
       required	information and	then returns the result. The value returned is
       exactly the same	as the response	returned in the	callback  if  you  had
       used the	async version of the function.

       When   you   are	  done	 with	the   data   in	  the  response,  call
       getdns_free_sync_request_memory so that the API	can  free  the	memory
       from its	internal pool.

EXTENSIONS
       Applications may	populate an extension dictionary when making a call to
       the public entry	points.	 To use	an extension add it to	the  extension
       dictionary  prior  to making the	call to	the public entry point and set
       the value depending on the behavior you expect.	These  extensions  in-
       clude:

       "dnssec_return_status" (int)

	  Set  to  GETDNS_EXTENSION_TRUE to include the	DNSSEC status for each
	  DNS record in	the replies_tree

       "dnssec_return_only_secure" (int)

	  Set to GETDNS_EXTENSION_TRUE to cause	only records that the API  can
	  validate  as	secure	with DNSSEC to be returned in the replies_tree
	  and replies_full lists

       "dnssec_return_validation_chain"	(int)

	  Set to GETDNS_EXTENSION_TRUE to cause	the set	of additional  DNSSEC-
	  related records needed for validation	to be returned in the response
	  object as the	list named additional_dnssec at	the top	level  of  the
	  response object

       "return_both_v4_and_v6" (int)

	  Set to GETDNS_EXTENSION_TRUE to cause	the results of both A and AAAA
	  records for the queried name to be included in the response object.

       "add_opt_parameters" (dict)

	  TBD (complicated)

       "add_warning_for_bad_dns"

	  Set to GETDNS_EXTENSION_TRUE to cause	each reply in the replies_tree
	  to  contain  an  additional  name whose data type is a list, bad_dns
	  which	contains zero or more ints that	indicate the types of bad  DNS
	  found	in the reply.
	     GETDNS_BAD_DNS_CNAME_IN_TARGET: query type	does not allow a CNAME
	     pointed to	a CNAME
	     GETDNS_BAD_DNS_ALL_NUMERIC_LABEL: one or more labels is  all  nu-
	     meric
	     GETDNS_BAD_DNS_CNAME_RETURNED_FOR_OTHER_TYPE:   query   type  for
	     other than	CNAME returned a CNAME

       "specify_class" (int)

	  Set to the DNS class number (other than Internet (IN)	class  desired
	  in query.

       "return_call_reporting" (int)

	  Set  to  GETDNS_EXTENSION_TRUE to add	the name call_reporting	(list)
	  to the top level of the response object that	includes  a  dict  for
	  each call made to the	API.  TBD: more	detail

       This  implementation  of	 the  getdns API is licensed under the BSD li-
       cense.

DNSSEC
       If an application wants the API to do DNSSEC validation for a  request,
       it  must	 set  one or more DNSSEC-related extensions. Note that the de-
       fault is	for none of these extensions to	be set and the	API  will  not
       perform	DNSSEC.	 Note that getting DNSSEC results can take longer in a
       few circumstances.

       To return the DNSSEC status for each DNS	 record	 in  the  replies_tree
       list, use the dnssec_return_status extension. The extension's value (an
       int) is set to GETDNS_EXTENSION_TRUE to cause the  returned  status  to
       have  the  name	dnssec_status (an int) added to	the other names	in the
       record's	dict ("header",	"question", and	so on).	The  values  for  that
       name are	GETDNS_DNSSEC_SECURE, GETDNS_DNSSEC_BOGUS, GETDNS_DNSSEC_INDE-
       TERMINATE, and GETDNS_DNSSEC_INSECURE.  Thus, a reply might look	like:

       {     # This is the first reply
	     "dnssec_status": GETDNS_DNSSEC_INDETERMINATE,
	     "header": { "id": 23456, "qr": 1, "opcode": 0, ...	},
	     . . .

       If instead of returning the status, you want to	only  see  secure  re-
       sults,  use  the	 dnssec_return_only_secure  extension. The extension's
       value (an int) is set to	GETDNS_EXTENSION_TRUE to  cause	 only  records
       that  the  API can validate as secure with DNSSEC to be returned	in the
       replies_tree and	replies_full lists.  No	additional names are added  to
       the  dict  of the record; the change is that some records might not ap-
       pear in the results. When this context option is	set, if	 the  API  re-
       ceives DNS replies but none are determined to be	secure,	the error code
       at the top level	of the	response  object  is  GETDNS_RESPSTATUS_NO_SE-
       CURE_ANSWERS.

       Applications that want to do their own validation will want to have the
       DNSSEC-related records for a particular response.  Use  the  dnssec_re-
       turn_validation_chain  extension. The extension's value (an int)	is set
       to GETDNS_EXTENSION_TRUE	to cause a set	of  additional	DNSSEC-related
       records	needed	for  validation	to be returned in the response object.
       This set	comes as validation_chain (a list) at the top level of the re-
       sponse object. This list	includes all resource record dicts for all the
       resource	records	(DS, DNSKEY and	their RRSIGs) that are needed to  per-
       form the	validation from	the root up. Thus, a reply might look like:

       {     # This is the response object
	   "validation_chain":
	   [ { "name": <bindata	for .>,
	   "type": GETDNS_RRTYPE_DNSKEY,
	   "rdata": { "flags": 256, . .	. },
	     . . .
	   },
	   { "name": <bindata for .>,
	     "type": GETDNS_RRTYPE_DNSKEY,
	     "rdata": {	"flags": 257, .	. . },
	     . . .
	   },
	   { "name": <bindata for .>,
	     "type": GETDNS_RRTYPE_RRSIG,
	     "rdata": {	"signers_name":	<bindata for .>,
			"type_covered":	GETDNS_RRTYPE_DNSKEY,
			. . .
		      },
	   },
	   { "name": <bindata for com.>,
	     "type": GETDNS_RRTYPE_DS,
	     . . .
	   },
	   { "name": <bindata for com.>,
	     "type": GETDNS_RRTYPE_RRSIG
	     "rdata": {	"signers_name":	<bindata for .>,
			"type_covered":	GETDNS_RRTYPE_DS,
			. . .
		      },
	     . . .
	   },
	   { "name": <bindata for com.>,
	     "type": GETDNS_RRTYPE_DNSKEY
	     "rdata": {	"flags": 256, .	. . },
	     . . .
	   },
	   { "name": <bindata for com.>,
	     "type": GETDNS_RRTYPE_DNSKEY
	     "rdata": {	"flags": 257, .	. . },
	     . . .
	   },
	   { "name": <bindata for com.>,
	     "type": GETDNS_RRTYPE_RRSIG
	     "rdata": {	"signers_name":	<bindata for com.>,
			"type_covered":	GETDNS_RRTYPE_DNSKEY,
			. . .
		      },
	     . . .
	   },
	   { "name": <bindata for example.com.>,
	     "type": GETDNS_RRTYPE_DS,
	     . . .
	   },
	   { "name": <bindata for example.com.>,
	     "type": GETDNS_RRTYPE_RRSIG
	     "rdata": {	"signers_name":	<bindata for com.>,
			"type_covered":	GETDNS_RRTYPE_DS,
			. . .
		      },
	     . . .
	   },
	   { "name": <bindata for example.com.>,
	     "type": GETDNS_RRTYPE_DNSKEY
	     "rdata": {	"flags": 257, ... },
	     . . .
	   },
	   . . .
	 ]
	 "replies_tree":
	 [
	 . . .

       If  a  request  is using	a context in which stub	resolution is set, and
       that request also  has  any  of	the  dnssec_return_status,  dnssec_re-
       turn_only_secure,  or  dnssec_return_validation_chain extensions	speci-
       fied, the API will not perform the request and will instead  return  an
       error of	GETDNS_RETURN_DNSSEC_WITH_STUB_DISALLOWED.

OPT RESOURCE RECORDS
       For  lookups  that  need	 an OPT	resource record	in the Additional Data
       section,	use the	add_opt_parameters extension. The extension's value (a
       dict)  contains	the  parameters; these are described in	more detail in
       RFC 2671. They are:

       maximum_udp_payload_size	(an int) between 512 and 65535;	if not	speci-
	  fied,	this defaults to those from the	DNS context

       extended_rcode  (an  int) between 0 and 255; if not specified, this de-
	  faults to those from the DNS context

       version (an int)	between	0 and 255; if not specified, this defaults  to
	  0

       do_bit  (an  int)  between  0 and 1; if not specified, this defaults to
	  those	from the DNS context

       options (a list)	contains dicts for each	option to be  specified.  Each
	  list	time  contains two names: option_code (an int) and option_data
	  (a bindata). The API marshalls the entire  set  of  options  into  a
	  properly-formatted RDATA for the resource record.

       It  is very important to	note that the OPT resource record specified in
       the add_opt_parameters extension	might not be the same the one that the
       API  sends  in the query. For example, if the application also includes
       any of the DNSSEC extensions, the API will make sure that the  OPT  re-
       source record sets the resource record appropriately, making the	needed
       changes to the settings from the	add_opt_parameters extension.

       The use of this extension can conflict with the values in the DNS  con-
       text.  For  example,  the  default for an OS might be a maximum payload
       size of 65535, but the extension	might specify 1550. In	such  a	 case,
       the  API	 will honor the	values stated in the extension,	but will honor
       the values from the DNS context if values are not given in  the	exten-
       sion.

RESPONSE DATA
       The  callback  function	contains a pointer to a	response object. A re-
       sponse object is	always a dict. The response object always contains  at
       least three names: replies_full (a list)	and replies_tree (a list), and
       status (an int).	 replies_full is  a  list  of  DNS  replies  (each  is
       bindata)	 as  they  appear  on  the wire. replies_tree is a list	of DNS
       replies (each is	a dict)	with the various part of the reply parsed out.
       status is a status code for the query.

       Because	the  API  might	 be  extended in the future, a response	object
       might also contain names	other  than  replies_full,  replies_tree,  and
       status. Similarly, any of the dicts described here might	be extended in
       later versions of the API.  Thus, an application	using the API must not
       assume that it knows all	possible names in a dict.

       The  following  lists the status	codes for response objects. Note that,
       if the status is	that there are no responses for	the query,  the	 lists
       in replies_full and replies_tree	will have zero length.

       GETDNS_RESPSTATUS_GOOD At least one response was	returned

       GETDNS_RESPSTATUS_NO_NAME Queries for the name yielded all negative re-
	  sponses

       GETDNS_RESPSTATUS_ALL_TIMEOUT All queries for the name timed out

       GETDNS_RESPSTATUS_NO_SECURE_ANSWERS The	context	 setting  for  getting
	  only	secure	responses was specified, and at	least one DNS response
	  was received,	but no	DNS  response  was  determined	to  be	secure
	  through DNSSEC.

       The  top	level of replies_tree can optionally have the following	names:
       canonical_name  (a  bindata),  intermediate_aliases   (a	  list),   an-
       swer_ipv4_address (a bindata), answer_ipv6_address (a bindata), and an-
       swer_type (an int).

       The value of canonical_name is the name	that  the  API	used  for  its
       lookup.	It is in FQDN presentation format.  The	values in the interme-
       diate_aliases list are domain names from	 any  CNAME  or	 unsynthesized
       DNAME found when	resolving the original query. The list might have zero
       entries if there	were no	CNAMEs in the path. These may be  useful,  for
       example,	 for  name  comparisons	 when following	the rules in RFC 6125.
       The value of answer_ipv4_address	and answer_ipv6_address	 are  the  ad-
       dresses of the server from which	the answer was received.  The value of
       answer_type is the type of name service that  generated	the  response.
       The values are:

	      GETDNS_NAMETYPE_DNS
	      Normal DNS (RFC 1035)
	      GETDNS_NAMETYPE_WINS
	      The WINS name service (some reference needed)

       If the call was getdns_address or getdns_address_sync, the top level of
       replies_tree has	an additional name, just_address_answers (a list). The
       value  of just_address_answers is a list	that contains all of the A and
       AAAA records from the answer sections of	any of the replies, in the or-
       der they	appear in the replies. Each item in the	list is	a dict with at
       least two names:	address_type (whose value is a	bindata;  it  is  cur-
       rently  either  "IPv4"  or  "IPv6")  and	address_data (whose value is a
       bindata). Note that  the	 dnssec_return_only_secure  extension  affects
       what  will  appear in the just_address_answers list. If the DNS returns
       other address types, those types	will appear in this list as well.

       The API can make	service	discovery through SRV records easier.  If  the
       call  was  getdns_service  or  getdns_service_sync,  the	 top  level of
       replies_tree has	an additional name, srv_addresses (a list).  The  list
       is  ordered  by priority	and weight based on the	weighting algorithm in
       RFC 2782, lowest	priority value first. Each element of the list is dict
       has  at	least  two names: port and domain_name.	If the API was able to
       determine the address of	the target domain name (such as	from its cache
       or  from	 the Additional	section	of responses), the dict	for an element
       will also contain address_type (whose value is a	bindata;  it  is  cur-
       rently  either  "IPv4"  or  "IPv6")  and	address_data (whose value is a
       bindata). Note that  the	 dnssec_return_only_secure  extension  affects
       what will appear	in the srv_addresses list.

STRUCTURE OF DNS REPLIES_TREE
       The  names in each entry	in the the replies_tree	list for DNS responses
       include header (a dict),	question (a dict), answer (a list),  authority
       (a list), and additional	(a list), corresponding	to the sections	in the
       DNS message format.  The	answer,	authority, and additional  lists  each
       contain	zero or	more dicts, with each dict in each list	representing a
       resource	record.

       The names in the	header dict are	all the	fields from Section 4.1.1.  of
       RFC  1035. They are: id,	qr, opcode, aa,	tc, rd,	ra, z, rcode, qdcount,
       ancount,	nscount, and arcount. All are ints.

       The names in the	question dict are the three fields from	Section	4.1.2.
       of RFC 1035: qname (a bindata), qtype (an int), and qclass (an int).

       Resource	records	are a bit different than headers and question sections
       in that the RDATA portion often has its own structure. The other	 names
       in the resource record dicts are	name (a	bindata), type (an int), class
       (an int), ttl (an int) and rdata	(a dict); there	is no name  equivalent
       to the RDLENGTH field.

       The  rdata  dict	has different names for	each response type. There is a
       complete	list of	the types defined in the API. For names	 that  end  in
       "-obsolete"  or	"-unknown", the	bindata	is the entire RDATA field. For
       example,	the rdata for an A record has a	name ipv4_address (a bindata);
       the rdata for an	SRV record has the names priority (an int), weight (an
       int), port (an int), and	target (a bindata).

       Each rdata dict also has	a rdata_raw field (a bindata). This is	useful
       for  types  not defined in this version of the API. It also might be of
       value if	a later	version	of the	API  allows  for  additional  parsers.
       Thus,  doing a query for	types not known	by the API still will return a
       result: an rdata	with just a rdata_raw.

       It is expected that later extensions to the  API	 will  give  some  DNS
       types  different	 names.	It is also possible that later extensions will
       change the names	for some of the	DNS types listed above.

CALLBACK FUNCTIONS
       A call to the async getdns functions typically returns before any  net-
       work  or	file I/O occurs. After the API marshalls all the needed	infor-
       mation, it calls	the callback function that was passed by the  applica-
       tion.  The  callback  function might be called at any time, even	before
       the calling function has	returned. The API guarantees that the callback
       will be called exactly once unless the calling function returned	an er-
       ror, in which case the callback function	is never called.

       The getdns calling function calls the callback with the parameters  de-
       fined as	follows:

       typedef void (*getdns_callback_t)(
	  getdns_context_t context,
	  uint16_t callback_type,
	  getdns_dict *response,
	  void *userarg,
	  getdns_transaction_t transaction_id)

       context see getdns_context (3)

       callback_type Supplies the reason for the callback.

	  GETDNS_CALLBACK_COMPLETE The response	has the	requested data in it

	  GETDNS_CALLBACK_CANCEL  The  calling	program	canceled the callback;
	  response is NULL

	  GETDNS_CALLBACK_TIMEOUT The requested	action timed out; response  is
	  NULL

	  GETDNS_CALLBACK_ERROR	The requested action had an error; response is
	  NULL

       response	A response object with the response data. This is described in
	  the  section	titled	"RESPONSE DATA"	elsewhere in this manual page.
	  The response object is part of the API's memory space, and  will  be
	  freed	by the API with	the callback returns.

       userarg Identical to the	userarg	passed to the calling function.

       transaction_id The transaction identified assigned by the calling func-
	  tion,	used to	associate a DNS	response to a specific DNS request.

       To cancel an outstanding	callback, use the following function.

	  getdns_return_t
	  getdns_cancel_callback  (getdns_context_t  context,  getdns_transac-
	  tion_t transaction_id)

       This  causes  the  API  to  call	 the  callback with a callback_type of
       GETDNS_CALLBACK_CANCEL if the callback for this transaction_id has  not
       already been called. The	callback code for cancellation should clean up
       any memory related to the identified call, such as  to  deallocate  the
       memory  for  the	 userarg.  getdns_cancel_callback() may	return immedi-
       ately, even before the callback finishes	its work and returns.  Calling
       getdns_cancel_callback()	 with  a transaction_id	of a callback that has
       already been called or an  unknown  transaction_id  returns  GETDNS_RE-
       TURN_UNKNOWN_TRANSACTION;  otherwise,  getdns_cancel_callback() returns
       GETDNS_RETURN_GOOD.

FILES
EXAMPLES
       TBD

DIAGNOSTICS
       TBD

SEE ALSO
       getdns_address(3),  getdns_bindata(3),  getdns_context(3),  getdns_con-
       vert(3),	   getdns_dict(3),    getdns_general(3),   getdns_hostname(3),
       getdns_list(3),	    getdns_root_trust_anchor(3)	     getdns_service(3)
       getdns_validate_dnssec(3)

REPORTING PROBLEMS
       Bug reports should be sent to the getdns-bugs@getdns.net

AUTHORS
       The  getdns API was documented by Paul Hoffman.	This implementation of
       the getdns API was written by:

	  Craig	Despeaux, Verisign Inc.
	  John Dickinson, Sinodun
	  Sara Dickinson, Sinodun
	  Neel Goyal, Verisign Inc.
	  Shumon Huque,	Verisign Labs
	  Olaf Kolkman,	NLnet Labs
	  Allison Mankin, Verisign Inc.	- Verisign Labs.
	  Melinda Shore, No Mountain Software LLC
	  Willem Toorop, NLnet Labs
	  Gowri	Visweswaran, Verisign Labs
	  Wouter Wijngaards, NLnet Labs
	  Glen Wiley, Verisign Inc.

getdns 1.1.1			 December 2015			  libgetdns(3)

NAME | LIBRARY | SYNOPSIS | DESCRIPTION | DATA STRUCTURES | ASYNCHRONOUS USE | SYNCHRONOUS USE | EXTENSIONS | DNSSEC | OPT RESOURCE RECORDS | RESPONSE DATA | STRUCTURE OF DNS REPLIES_TREE | CALLBACK FUNCTIONS | FILES | EXAMPLES | DIAGNOSTICS | SEE ALSO | REPORTING PROBLEMS | AUTHORS

Want to link to this manual page? Use this URL:
<https://www.freebsd.org/cgi/man.cgi?query=libgetdns&sektion=3&manpath=FreeBSD+12.0-RELEASE+and+Ports>

home | help