Current File : //usr/include/udns.h
/* udns.h
   header file for the UDNS library.

   Copyright (C) 2005  Michael Tokarev <[email protected]>
   This file is part of UDNS library, an async DNS stub resolver.

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with this library, in file named COPYING.LGPL; if not,
   write to the Free Software Foundation, Inc., 59 Temple Place,
   Suite 330, Boston, MA  02111-1307  USA

 */

#ifndef UDNS_VERSION	/* include guard */

#define UDNS_VERSION "0.4"

#ifdef WINDOWS
# ifdef UDNS_DYNAMIC_LIBRARY
#  ifdef DNS_LIBRARY_BUILD
#   define UDNS_API __declspec(dllexport)
#   define UDNS_DATA_API __declspec(dllexport)
#  else
#   define UDNS_API __declspec(dllimport)
#   define UDNS_DATA_API __declspec(dllimport)
#  endif
# endif
#endif

#ifndef UDNS_API
# define UDNS_API
#endif
#ifndef UDNS_DATA_API
# define UDNS_DATA_API
#endif

#include <sys/types.h>		/* for time_t */

#ifdef __cplusplus
extern "C" {
#endif

/* forward declarations if sockets stuff isn't #include'd */
struct in_addr;
struct in6_addr;
struct sockaddr;

/**************************************************************************/
/**************** Common definitions **************************************/

UDNS_API const char *
dns_version(void);

struct dns_ctx;
struct dns_query;

/* shorthand for [const] unsigned char */
typedef unsigned char dnsc_t;
typedef const unsigned char dnscc_t;

#define DNS_MAXDN	255	/* max DN length */
#define DNS_DNPAD	1	/* padding for DN buffers */
#define DNS_MAXLABEL	63	/* max DN label length */
#define DNS_MAXNAME	1024	/* max asciiz domain name length */
#define DNS_HSIZE	12	/* DNS packet header size */
#define DNS_PORT	53	/* default domain port */
#define DNS_MAXSERV	6	/* max servers to consult */
#define DNS_MAXPACKET	512	/* max traditional-DNS UDP packet size */
#define DNS_EDNS0PACKET	4096	/* EDNS0 packet size to use */

enum dns_class {	/* DNS RR Classes */
  DNS_C_INVALID	= 0,	/* invalid class */
  DNS_C_IN	= 1,	/* Internet */
  DNS_C_CH	= 3,	/* CHAOS */
  DNS_C_HS	= 4,	/* HESIOD */
  DNS_C_ANY	= 255	/* wildcard */
};

enum dns_type {		/* DNS RR Types */
  DNS_T_INVALID		= 0,	/* Cookie. */
  DNS_T_A		= 1,	/* Host address. */
  DNS_T_NS		= 2,	/* Authoritative server. */
  DNS_T_MD		= 3,	/* Mail destination. */
  DNS_T_MF		= 4,	/* Mail forwarder. */
  DNS_T_CNAME		= 5,	/* Canonical name. */
  DNS_T_SOA		= 6,	/* Start of authority zone. */
  DNS_T_MB		= 7,	/* Mailbox domain name. */
  DNS_T_MG		= 8,	/* Mail group member. */
  DNS_T_MR		= 9,	/* Mail rename name. */
  DNS_T_NULL		= 10,	/* Null resource record. */
  DNS_T_WKS		= 11,	/* Well known service. */
  DNS_T_PTR		= 12,	/* Domain name pointer. */
  DNS_T_HINFO		= 13,	/* Host information. */
  DNS_T_MINFO		= 14,	/* Mailbox information. */
  DNS_T_MX		= 15,	/* Mail routing information. */
  DNS_T_TXT		= 16,	/* Text strings. */
  DNS_T_RP		= 17,	/* Responsible person. */
  DNS_T_AFSDB		= 18,	/* AFS cell database. */
  DNS_T_X25		= 19,	/* X_25 calling address. */
  DNS_T_ISDN		= 20,	/* ISDN calling address. */
  DNS_T_RT		= 21,	/* Router. */
  DNS_T_NSAP		= 22,	/* NSAP address. */
  DNS_T_NSAP_PTR	= 23,	/* Reverse NSAP lookup (deprecated). */
  DNS_T_SIG		= 24,	/* Security signature. */
  DNS_T_KEY		= 25,	/* Security key. */
  DNS_T_PX		= 26,	/* X.400 mail mapping. */
  DNS_T_GPOS		= 27,	/* Geographical position (withdrawn). */
  DNS_T_AAAA		= 28,	/* Ip6 Address. */
  DNS_T_LOC		= 29,	/* Location Information. */
  DNS_T_NXT		= 30,	/* Next domain (security). */
  DNS_T_EID		= 31,	/* Endpoint identifier. */
  DNS_T_NIMLOC		= 32,	/* Nimrod Locator. */
  DNS_T_SRV		= 33,	/* Server Selection. */
  DNS_T_ATMA		= 34,	/* ATM Address */
  DNS_T_NAPTR		= 35,	/* Naming Authority PoinTeR */
  DNS_T_KX		= 36,	/* Key Exchange */
  DNS_T_CERT		= 37,	/* Certification record */
  DNS_T_A6		= 38,	/* IPv6 address (deprecates AAAA) */
  DNS_T_DNAME		= 39,	/* Non-terminal DNAME (for IPv6) */
  DNS_T_SINK		= 40,	/* Kitchen sink (experimentatl) */
  DNS_T_OPT		= 41,	/* EDNS0 option (meta-RR) */
  DNS_T_DS		= 43,	/* DNSSEC */
  DNS_T_SSHFP		= 44,
  DNS_T_IPSECKEY	= 45,
  DNS_T_RRSIG		= 46,	/* DNSSEC */
  DNS_T_NSEC		= 47,	/* DNSSEC */
  DNS_T_DNSKEY		= 48,
  DNS_T_DHCID		= 49,
  DNS_T_NSEC3		= 50,
  DNS_T_NSEC3PARAMS	= 51,
  DNS_T_TALINK		= 58, /* draft-ietf-dnsop-trust-history */
  DNS_T_SPF		= 99,
  DNS_T_UINFO		= 100,
  DNS_T_UID		= 101,
  DNS_T_GID		= 102,
  DNS_T_UNSPEC		= 103,
  DNS_T_TSIG		= 250,	/* Transaction signature. */
  DNS_T_IXFR		= 251,	/* Incremental zone transfer. */
  DNS_T_AXFR		= 252,	/* Transfer zone of authority. */
  DNS_T_MAILB		= 253,	/* Transfer mailbox records. */
  DNS_T_MAILA		= 254,	/* Transfer mail agent records. */
  DNS_T_ANY		= 255,	/* Wildcard match. */
  DNS_T_ZXFR		= 256,	/* BIND-specific, nonstandard. */
  DNS_T_DLV		= 32769, /* RFC 4431, 5074, DNSSEC Lookaside Validation */
  DNS_T_MAX		= 65536
};

/**************************************************************************/
/**************** Domain Names (DNs) **************************************/

/* return length of the DN */
UDNS_API unsigned
dns_dnlen(dnscc_t *dn);

/* return #of labels in a DN */
UDNS_API unsigned
dns_dnlabels(dnscc_t *dn);

/* lower- and uppercase single DN char */
#define DNS_DNLC(c) ((c) >= 'A' && (c) <= 'Z' ? (c) - 'A' + 'a' : (c))
#define DNS_DNUC(c) ((c) >= 'a' && (c) <= 'z' ? (c) - 'a' + 'A' : (c))

/* compare the DNs, return dnlen of equal or 0 if not */
UDNS_API unsigned
dns_dnequal(dnscc_t *dn1, dnscc_t *dn2);

/* copy one DN to another, size checking */
UDNS_API unsigned
dns_dntodn(dnscc_t *sdn, dnsc_t *ddn, unsigned ddnsiz);

/* convert asciiz string of length namelen (0 to use strlen) to DN */
UDNS_API int
dns_ptodn(const char *name, unsigned namelen,
          dnsc_t *dn, unsigned dnsiz, int *isabs);

/* simpler form of dns_ptodn() */
#define dns_sptodn(name,dn,dnsiz) dns_ptodn((name),0,(dn),(dnsiz),0)

UDNS_DATA_API extern dnscc_t dns_inaddr_arpa_dn[14];
#define DNS_A4RSIZE	30
UDNS_API int
dns_a4todn(const struct in_addr *addr, dnscc_t *tdn,
           dnsc_t *dn, unsigned dnsiz);
UDNS_API int
dns_a4ptodn(const struct in_addr *addr, const char *tname,
            dnsc_t *dn, unsigned dnsiz);
UDNS_API dnsc_t *
dns_a4todn_(const struct in_addr *addr, dnsc_t *dn, dnsc_t *dne);

UDNS_DATA_API extern dnscc_t dns_ip6_arpa_dn[10];
#define DNS_A6RSIZE	74
UDNS_API int
dns_a6todn(const struct in6_addr *addr, dnscc_t *tdn,
           dnsc_t *dn, unsigned dnsiz);
UDNS_API int
dns_a6ptodn(const struct in6_addr *addr, const char *tname,
            dnsc_t *dn, unsigned dnsiz);
UDNS_API dnsc_t *
dns_a6todn_(const struct in6_addr *addr, dnsc_t *dn, dnsc_t *dne);

/* convert DN into asciiz string */
UDNS_API int
dns_dntop(dnscc_t *dn, char *name, unsigned namesiz);

/* convert DN into asciiz string, using static buffer (NOT thread-safe!) */
UDNS_API const char *
dns_dntosp(dnscc_t *dn);

/* return buffer size (incl. null byte) required for asciiz form of a DN */
UDNS_API unsigned
dns_dntop_size(dnscc_t *dn);

/* either wrappers or reimplementations for inet_ntop() and inet_pton() */
UDNS_API const char *dns_ntop(int af, const void *src, char *dst, int size);
UDNS_API int dns_pton(int af, const char *src, void *dst);

/**************************************************************************/
/**************** DNS raw packet layout ***********************************/

enum dns_rcode {	/* reply codes */
  DNS_R_NOERROR		= 0,	/* ok, no error */
  DNS_R_FORMERR		= 1,	/* format error */
  DNS_R_SERVFAIL	= 2,	/* server failed */
  DNS_R_NXDOMAIN	= 3,	/* domain does not exists */
  DNS_R_NOTIMPL		= 4,	/* not implemented */
  DNS_R_REFUSED		= 5,	/* query refused */
  /* these are for BIND_UPDATE */
  DNS_R_YXDOMAIN	= 6,	/* Name exists */
  DNS_R_YXRRSET		= 7,	/* RRset exists */
  DNS_R_NXRRSET		= 8,	/* RRset does not exist */
  DNS_R_NOTAUTH		= 9,	/* Not authoritative for zone */
  DNS_R_NOTZONE		= 10,	/* Zone of record different from zone section */
  /*ns_r_max = 11,*/
  /* The following are TSIG extended errors */
  DNS_R_BADSIG		= 16,
  DNS_R_BADKEY		= 17,
  DNS_R_BADTIME		= 18
};

static __inline unsigned dns_get16(dnscc_t *s) {
  return ((unsigned)s[0]<<8) | s[1];
}
static __inline unsigned dns_get32(dnscc_t *s) {
  return ((unsigned)s[0]<<24) | ((unsigned)s[1]<<16)
        | ((unsigned)s[2]<<8) | s[3];
}
static __inline dnsc_t *dns_put16(dnsc_t *d, unsigned n) {
  *d++ = (dnsc_t)((n >> 8) & 255); *d++ = (dnsc_t)(n & 255); return d;
}
static __inline dnsc_t *dns_put32(dnsc_t *d, unsigned n) {
  *d++ = (dnsc_t)((n >> 24) & 255); *d++ = (dnsc_t)((n >> 16) & 255);
  *d++ = (dnsc_t)((n >>  8) & 255); *d++ = (dnsc_t)(n & 255);
  return d;
}

/* DNS Header layout */
enum {
 /* bytes 0:1 - query ID */
  DNS_H_QID1	= 0,
  DNS_H_QID2	= 1,
  DNS_H_QID	= DNS_H_QID1,
#define dns_qid(pkt)	dns_get16((pkt)+DNS_H_QID)
 /* byte 2: flags1 */
  DNS_H_F1	= 2,
  DNS_HF1_QR	= 0x80,	/* query response flag */
#define dns_qr(pkt)	((pkt)[DNS_H_F1]&DNS_HF1_QR)
  DNS_HF1_OPCODE = 0x78, /* opcode, 0 = query */
#define dns_opcode(pkt)	(((pkt)[DNS_H_F1]&DNS_HF1_OPCODE)>>3)
  DNS_HF1_AA	= 0x04,	/* auth answer */
#define dns_aa(pkt)	((pkt)[DNS_H_F1]&DNS_HF1_AA)
  DNS_HF1_TC	= 0x02,	/* truncation flag */
#define dns_tc(pkt)	((pkt)[DNS_H_F1]&DNS_HF1_TC)
  DNS_HF1_RD	= 0x01,	/* recursion desired (may be set in query) */
#define dns_rd(pkt)	((pkt)[DNS_H_F1]&DNS_HF1_RD)
 /* byte 3: flags2 */
  DNS_H_F2	= 3,
  DNS_HF2_RA	= 0x80,	/* recursion available */
#define dns_ra(pkt)	((pkt)[DNS_H_F2]&DNS_HF2_RA)
  DNS_HF2_Z	= 0x40,	/* reserved */
  DNS_HF2_AD	= 0x20, /* DNSSEC: authentic data */
#define dns_ad(pkt)	((pkt)[DNS_H_F2]&DNS_HF2_AD)
  DNS_HF2_CD	= 0x10, /* DNSSEC: checking disabled */
#define dns_cd(pkt)	((pkt)[DNS_H_F2]&DNS_HF2_CD)
  DNS_HF2_RCODE	= 0x0f,	/* response code, DNS_R_XXX above */
#define dns_rcode(pkt)	((pkt)[DNS_H_F2]&DNS_HF2_RCODE)
 /* bytes 4:5: qdcount, numqueries */
  DNS_H_QDCNT1	= 4,
  DNS_H_QDCNT2	= 5,
  DNS_H_QDCNT	= DNS_H_QDCNT1,
#define dns_numqd(pkt)	dns_get16((pkt)+4)
 /* bytes 6:7: ancount, numanswers */
  DNS_H_ANCNT1	= 6,
  DNS_H_ANCNT2	= 7,
  DNS_H_ANCNT	= DNS_H_ANCNT1,
#define dns_numan(pkt)	dns_get16((pkt)+6)
 /* bytes 8:9: nscount, numauthority */
  DNS_H_NSCNT1	= 8,
  DNS_H_NSCNT2	= 9,
  DNS_H_NSCNT	= DNS_H_NSCNT1,
#define dns_numns(pkt)	dns_get16((pkt)+8)
 /* bytes 10:11: arcount, numadditional */
  DNS_H_ARCNT1	= 10,
  DNS_H_ARCNT2	= 11,
  DNS_H_ARCNT	= DNS_H_ARCNT1,
#define dns_numar(pkt)	dns_get16((pkt)+10)
#define dns_payload(pkt) ((pkt)+DNS_HSIZE)
  /* EDNS0 (OPT RR) flags (Ext. Flags) */
  DNS_EF1_DO	= 0x80, /* DNSSEC OK */
};

/* packet buffer: start at pkt, end before pkte, current pos *curp.
 * extract a DN and set *curp to the next byte after DN in packet.
 * return -1 on error, 0 if dnsiz is too small, or dnlen on ok.
 */
UDNS_API int
dns_getdn(dnscc_t *pkt, dnscc_t **curp, dnscc_t *end,
          dnsc_t *dn, unsigned dnsiz);

/* skip the DN at position cur in packet ending before pkte,
 * return pointer to the next byte after the DN or NULL on error */
UDNS_API dnscc_t *
dns_skipdn(dnscc_t *end, dnscc_t *cur);

struct dns_rr {		/* DNS Resource Record */
  dnsc_t dnsrr_dn[DNS_MAXDN];	/* the DN of the RR */
  enum dns_class dnsrr_cls;	/* Class */
  enum dns_type  dnsrr_typ;	/* Type */
  unsigned dnsrr_ttl;		/* Time-To-Live (TTL) */
  unsigned dnsrr_dsz;		/* data size */
  dnscc_t *dnsrr_dptr;		/* pointer to start of data */
  dnscc_t *dnsrr_dend;		/* past end of data */
};

struct dns_parse {	/* RR/packet parsing state */
  dnscc_t *dnsp_pkt;		/* start of the packet */
  dnscc_t *dnsp_end;		/* end of the packet */
  dnscc_t *dnsp_cur;		/* current packet position */
  dnscc_t *dnsp_ans;		/* start of answer section */
  int dnsp_rrl;			/* number of RRs left to go */
  int dnsp_nrr;			/* RR count so far */
  unsigned dnsp_ttl;		/* TTL value so far */
  dnscc_t *dnsp_qdn;		/* the RR DN we're looking for */
  enum dns_class dnsp_qcls;	/* RR class we're looking for or 0 */
  enum dns_type  dnsp_qtyp;	/* RR type we're looking for or 0 */
  dnsc_t dnsp_dnbuf[DNS_MAXDN];	/* domain buffer */
};

/* initialize the parse structure */
UDNS_API void
dns_initparse(struct dns_parse *p, dnscc_t *qdn,
              dnscc_t *pkt, dnscc_t *cur, dnscc_t *end);

/* search next RR, <0=error, 0=no more RRs, >0 = found. */
UDNS_API int
dns_nextrr(struct dns_parse *p, struct dns_rr *rr);

UDNS_API void
dns_rewind(struct dns_parse *p, dnscc_t *qdn);


/**************************************************************************/
/**************** Resolver Context ****************************************/

/* default resolver context */
UDNS_DATA_API extern struct dns_ctx dns_defctx;

/* reset resolver context to default state, close it if open, drop queries */
UDNS_API void
dns_reset(struct dns_ctx *ctx);

/* reset resolver context and read in system configuration */
UDNS_API int
dns_init(struct dns_ctx *ctx, int do_open);

/* return new resolver context with the same settings as copy */
UDNS_API struct dns_ctx *
dns_new(const struct dns_ctx *copy);

/* free resolver context returned by dns_new(); all queries are dropped */
UDNS_API void
dns_free(struct dns_ctx *ctx);

/* add nameserver for a resolver context (or reset nslist if serv==NULL) */
UDNS_API int
dns_add_serv(struct dns_ctx *ctx, const char *serv);

/* add nameserver using struct sockaddr structure (with ports) */
UDNS_API int
dns_add_serv_s(struct dns_ctx *ctx, const struct sockaddr *sa);

/* add search list element for a resolver context (or reset it if srch==NULL) */
UDNS_API int
dns_add_srch(struct dns_ctx *ctx, const char *srch);

/* set options for a resolver context */
UDNS_API int
dns_set_opts(struct dns_ctx *ctx, const char *opts);

enum dns_opt {		/* options */
  DNS_OPT_FLAGS,	/* flags, DNS_F_XXX */
  DNS_OPT_TIMEOUT,	/* timeout in secounds */
  DNS_OPT_NTRIES,	/* number of retries */
  DNS_OPT_NDOTS,	/* ndots */
  DNS_OPT_UDPSIZE,	/* EDNS0 UDP size */
  DNS_OPT_PORT,		/* port to use */
};

/* set or get (if val<0) an option */
UDNS_API int
dns_set_opt(struct dns_ctx *ctx, enum dns_opt opt, int val);

enum dns_flags {
  DNS_NOSRCH	= 0x00010000,	/* do not perform search */
  DNS_NORD	= 0x00020000,	/* request no recursion */
  DNS_AAONLY	= 0x00040000,	/* set AA flag in queries */
  DNS_SET_DO	= 0x00080000,	/* set EDNS0 "DO" bit (DNSSEC OK) */
  DNS_SET_CD	= 0x00100000,	/* set CD bit (DNSSEC: checking disabled) */
};

/* set the debug function pointer */
typedef void
(dns_dbgfn)(int code, const struct sockaddr *sa, unsigned salen,
            dnscc_t *pkt, int plen,
            const struct dns_query *q, void *data);
UDNS_API void
dns_set_dbgfn(struct dns_ctx *ctx, dns_dbgfn *dbgfn);

/* open and return UDP socket */
UDNS_API int
dns_open(struct dns_ctx *ctx);

/* return UDP socket or -1 if not open */
UDNS_API int
dns_sock(const struct dns_ctx *ctx);

/* close the UDP socket */
UDNS_API void
dns_close(struct dns_ctx *ctx);

/* return number of requests queued */
UDNS_API int
dns_active(const struct dns_ctx *ctx);

/* return status of the last operation */
UDNS_API int
dns_status(const struct dns_ctx *ctx);
UDNS_API void
dns_setstatus(struct dns_ctx *ctx, int status);

/* handle I/O event on UDP socket */
UDNS_API void
dns_ioevent(struct dns_ctx *ctx, time_t now);

/* process any timeouts, return time in secounds to the
 * next timeout (or -1 if none) but not greather than maxwait */
UDNS_API int
dns_timeouts(struct dns_ctx *ctx, int maxwait, time_t now);

/* define timer requesting routine to use */
typedef void dns_utm_fn(struct dns_ctx *ctx, int timeout, void *data);
UDNS_API void
dns_set_tmcbck(struct dns_ctx *ctx, dns_utm_fn *fn, void *data);

/**************************************************************************/
/**************** Making Queries ******************************************/

/* query callback routine */
typedef void dns_query_fn(struct dns_ctx *ctx, void *result, void *data);

/* query parse routine: raw DNS => application structure */
typedef int
dns_parse_fn(dnscc_t *qdn, dnscc_t *pkt, dnscc_t *cur, dnscc_t *end,
             void **res);

enum dns_status {
  DNS_E_NOERROR		= 0,	/* ok, not an error */
  DNS_E_TEMPFAIL	= -1,	/* timeout, SERVFAIL or similar */
  DNS_E_PROTOCOL	= -2,	/* got garbled reply */
  DNS_E_NXDOMAIN	= -3,	/* domain does not exists */
  DNS_E_NODATA		= -4,	/* domain exists but no data of reqd type */
  DNS_E_NOMEM		= -5,	/* out of memory while processing */
  DNS_E_BADQUERY	= -6	/* the query is malformed */
};

/* submit generic DN query */
UDNS_API struct dns_query *
dns_submit_dn(struct dns_ctx *ctx,
              dnscc_t *dn, int qcls, int qtyp, int flags,
              dns_parse_fn *parse, dns_query_fn *cbck, void *data);
/* submit generic name query */
UDNS_API struct dns_query *
dns_submit_p(struct dns_ctx *ctx,
             const char *name, int qcls, int qtyp, int flags,
             dns_parse_fn *parse, dns_query_fn *cbck, void *data);

/* cancel the given async query in progress */
UDNS_API int
dns_cancel(struct dns_ctx *ctx, struct dns_query *q);

/* resolve a generic query, return the answer */
UDNS_API void *
dns_resolve_dn(struct dns_ctx *ctx,
               dnscc_t *qdn, int qcls, int qtyp, int flags,
               dns_parse_fn *parse);
UDNS_API void *
dns_resolve_p(struct dns_ctx *ctx,
              const char *qname, int qcls, int qtyp, int flags,
              dns_parse_fn *parse);
UDNS_API void *
dns_resolve(struct dns_ctx *ctx, struct dns_query *q);


/* Specific RR handlers */

#define dns_rr_common(prefix)						\
  char *prefix##_cname;		/* canonical name */			\
  char *prefix##_qname;		/* original query name */		\
  unsigned prefix##_ttl;	/* TTL value */				\
  int prefix##_nrr		/* number of records */

struct dns_rr_null {		/* NULL RRset, aka RRset template */
  dns_rr_common(dnsn);
};

UDNS_API int
dns_stdrr_size(const struct dns_parse *p);
UDNS_API void *
dns_stdrr_finish(struct dns_rr_null *ret, char *cp, const struct dns_parse *p);

struct dns_rr_a4 {		/* the A RRset */
  dns_rr_common(dnsa4);
  struct in_addr *dnsa4_addr;	/* array of addresses, naddr elements */
};

UDNS_API dns_parse_fn dns_parse_a4;	/* A RR parsing routine */
typedef void				/* A query callback routine */
dns_query_a4_fn(struct dns_ctx *ctx, struct dns_rr_a4 *result, void *data);

/* submit A IN query */
UDNS_API struct dns_query *
dns_submit_a4(struct dns_ctx *ctx, const char *name, int flags,
              dns_query_a4_fn *cbck, void *data);

/* resolve A IN query */
UDNS_API struct dns_rr_a4 *
dns_resolve_a4(struct dns_ctx *ctx, const char *name, int flags);


struct dns_rr_a6 {		/* the AAAA RRset */
  dns_rr_common(dnsa6);
  struct in6_addr *dnsa6_addr;	/* array of addresses, naddr elements */
};

UDNS_API dns_parse_fn dns_parse_a6;	/* A RR parsing routine */
typedef void				/* A query callback routine */
dns_query_a6_fn(struct dns_ctx *ctx, struct dns_rr_a6 *result, void *data);

/* submit AAAA IN query */
UDNS_API struct dns_query *
dns_submit_a6(struct dns_ctx *ctx, const char *name, int flags,
              dns_query_a6_fn *cbck, void *data);

/* resolve AAAA IN query */
UDNS_API struct dns_rr_a6 *
dns_resolve_a6(struct dns_ctx *ctx, const char *name, int flags);


struct dns_rr_ptr {		/* the PTR RRset */
  dns_rr_common(dnsptr);
  char **dnsptr_ptr;		/* array of PTRs */
};

UDNS_API dns_parse_fn dns_parse_ptr;	/* PTR RR parsing routine */
typedef void				/* PTR query callback */
dns_query_ptr_fn(struct dns_ctx *ctx, struct dns_rr_ptr *result, void *data);
/* submit PTR IN in-addr.arpa query */
UDNS_API struct dns_query *
dns_submit_a4ptr(struct dns_ctx *ctx, const struct in_addr *addr,
                 dns_query_ptr_fn *cbck, void *data);
/* resolve PTR IN in-addr.arpa query */
UDNS_API struct dns_rr_ptr *
dns_resolve_a4ptr(struct dns_ctx *ctx, const struct in_addr *addr);

/* the same as above, but for ip6.arpa */
UDNS_API struct dns_query *
dns_submit_a6ptr(struct dns_ctx *ctx, const struct in6_addr *addr,
                 dns_query_ptr_fn *cbck, void *data);
UDNS_API struct dns_rr_ptr *
dns_resolve_a6ptr(struct dns_ctx *ctx, const struct in6_addr *addr);


struct dns_mx {		/* single MX RR */
  int priority;		/* MX priority */
  char *name;		/* MX name */
};
struct dns_rr_mx {		/* the MX RRset */
  dns_rr_common(dnsmx);
  struct dns_mx *dnsmx_mx;	/* array of MXes */
};
UDNS_API dns_parse_fn dns_parse_mx;	/* MX RR parsing routine */
typedef void				/* MX RR callback */
dns_query_mx_fn(struct dns_ctx *ctx, struct dns_rr_mx *result, void *data);
/* submit MX IN query */
UDNS_API struct dns_query *
dns_submit_mx(struct dns_ctx *ctx, const char *name, int flags,
              dns_query_mx_fn *cbck, void *data);
/* resolve MX IN query */
UDNS_API struct dns_rr_mx *
dns_resolve_mx(struct dns_ctx *ctx, const char *name, int flags);


struct dns_txt {	/* single TXT record */
  int len;		/* length of the text */
  dnsc_t *txt;	/* pointer to text buffer. May contain nulls. */
};
struct dns_rr_txt {		/* the TXT RRset */
  dns_rr_common(dnstxt);
  struct dns_txt *dnstxt_txt;	/* array of TXT records */
};
UDNS_API dns_parse_fn dns_parse_txt;	/* TXT RR parsing routine */
typedef void				/* TXT RR callback */
dns_query_txt_fn(struct dns_ctx *ctx, struct dns_rr_txt *result, void *data);
/* submit TXT query */
UDNS_API struct dns_query *
dns_submit_txt(struct dns_ctx *ctx, const char *name, int qcls, int flags,
               dns_query_txt_fn *cbck, void *data);
/* resolve TXT query */
UDNS_API struct dns_rr_txt *
dns_resolve_txt(struct dns_ctx *ctx, const char *name, int qcls, int flags);


struct dns_srv {	/* single SRV RR */
  int priority;		/* SRV priority */
  int weight;		/* SRV weight */
  int port;		/* SRV port */
  char *name;		/* SRV name */
};
struct dns_rr_srv {		/* the SRV RRset */
  dns_rr_common(dnssrv);
  struct dns_srv *dnssrv_srv;	/* array of SRVes */
};
UDNS_API dns_parse_fn dns_parse_srv;	/* SRV RR parsing routine */
typedef void				/* SRV RR callback */
dns_query_srv_fn(struct dns_ctx *ctx, struct dns_rr_srv *result, void *data);
/* submit SRV IN query */
UDNS_API struct dns_query *
dns_submit_srv(struct dns_ctx *ctx,
               const char *name, const char *srv, const char *proto,
               int flags, dns_query_srv_fn *cbck, void *data);
/* resolve SRV IN query */
UDNS_API struct dns_rr_srv *
dns_resolve_srv(struct dns_ctx *ctx,
                const char *name, const char *srv, const char *proto,
                int flags);

/* NAPTR (RFC3403) RR type */
struct dns_naptr {	/* single NAPTR RR */
  int order;		/* NAPTR order */
  int preference;	/* NAPTR preference */
  char *flags;		/* NAPTR flags */
  char *service;	/* NAPTR service */
  char *regexp;		/* NAPTR regexp */
  char *replacement;	/* NAPTR replacement */
};

struct dns_rr_naptr {		/* the NAPTR RRset */
  dns_rr_common(dnsnaptr);
  struct dns_naptr *dnsnaptr_naptr;	/* array of NAPTRes */
};
UDNS_API dns_parse_fn dns_parse_naptr;	/* NAPTR RR parsing routine */
typedef void				/* NAPTR RR callback */
dns_query_naptr_fn(struct dns_ctx *ctx,
                   struct dns_rr_naptr *result, void *data);
/* submit NAPTR IN query */
UDNS_API struct dns_query *
dns_submit_naptr(struct dns_ctx *ctx, const char *name, int flags,
                 dns_query_naptr_fn *cbck, void *data);
/* resolve NAPTR IN query */
UDNS_API struct dns_rr_naptr *
dns_resolve_naptr(struct dns_ctx *ctx, const char *name, int flags);


UDNS_API struct dns_query *
dns_submit_a4dnsbl(struct dns_ctx *ctx,
                   const struct in_addr *addr, const char *dnsbl,
                   dns_query_a4_fn *cbck, void *data);
UDNS_API struct dns_query *
dns_submit_a4dnsbl_txt(struct dns_ctx *ctx,
                       const struct in_addr *addr, const char *dnsbl,
                       dns_query_txt_fn *cbck, void *data);
UDNS_API struct dns_rr_a4 *
dns_resolve_a4dnsbl(struct dns_ctx *ctx,
                    const struct in_addr *addr, const char *dnsbl);
UDNS_API struct dns_rr_txt *
dns_resolve_a4dnsbl_txt(struct dns_ctx *ctx,
                        const struct in_addr *addr, const char *dnsbl);

UDNS_API struct dns_query *
dns_submit_a6dnsbl(struct dns_ctx *ctx,
                   const struct in6_addr *addr, const char *dnsbl,
                   dns_query_a4_fn *cbck, void *data);
UDNS_API struct dns_query *
dns_submit_a6dnsbl_txt(struct dns_ctx *ctx,
                       const struct in6_addr *addr, const char *dnsbl,
                       dns_query_txt_fn *cbck, void *data);
UDNS_API struct dns_rr_a4 *
dns_resolve_a6dnsbl(struct dns_ctx *ctx,
                    const struct in6_addr *addr, const char *dnsbl);
UDNS_API struct dns_rr_txt *
dns_resolve_a6dnsbl_txt(struct dns_ctx *ctx,
                        const struct in6_addr *addr, const char *dnsbl);

UDNS_API struct dns_query *
dns_submit_rhsbl(struct dns_ctx *ctx,
                 const char *name, const char *rhsbl,
                 dns_query_a4_fn *cbck, void *data);
UDNS_API struct dns_query *
dns_submit_rhsbl_txt(struct dns_ctx *ctx,
                     const char *name, const char *rhsbl,
                     dns_query_txt_fn *cbck, void *data);
UDNS_API struct dns_rr_a4 *
dns_resolve_rhsbl(struct dns_ctx *ctx, const char *name, const char *rhsbl);
UDNS_API struct dns_rr_txt *
dns_resolve_rhsbl_txt(struct dns_ctx *ctx, const char *name, const char *rhsbl);

/**************************************************************************/
/**************** Names, Names ********************************************/

struct dns_nameval {
  int val;
  const char *name;
};

UDNS_DATA_API extern const struct dns_nameval dns_classtab[];
UDNS_DATA_API extern const struct dns_nameval dns_typetab[];
UDNS_DATA_API extern const struct dns_nameval dns_rcodetab[];
UDNS_API int
dns_findname(const struct dns_nameval *nv, const char *name);
#define dns_findclassname(cls) dns_findname(dns_classtab, (cls))
#define dns_findtypename(type) dns_findname(dns_typetab, (type))
#define dns_findrcodename(rcode) dns_findname(dns_rcodetab, (rcode))

UDNS_API const char *dns_classname(enum dns_class cls);
UDNS_API const char *dns_typename(enum dns_type type);
UDNS_API const char *dns_rcodename(enum dns_rcode rcode);
const char *_dns_format_code(char *buf, const char *prefix, int code);

UDNS_API const char *dns_strerror(int errnum);

/* simple pseudo-random number generator, code by Bob Jenkins */

struct udns_jranctx {	/* the context */
  unsigned a, b, c, d;
};

/* initialize the RNG with a given seed */
UDNS_API void
udns_jraninit(struct udns_jranctx *x, unsigned seed);

/* return next random number.  32bits on most platforms so far. */
UDNS_API unsigned
udns_jranval(struct udns_jranctx *x);

#ifdef __cplusplus
} /* extern "C" */
#endif

#endif	/* include guard */
blog

blog

Gioco Plinko nei casinò online in Italia.313

Gioco Plinko nei casinò online in Italia ▶️ GIOCARE Содержимое Le caratteristiche del gioco Le strategie per vincere al Plinko nei casinò online in Italia Le migliori opzioni per giocare online Il gioco Plinko è uno dei più popolari tra i giocatori di casinò online in Italia, e non è …

Read More »

1Win Azerbaijan – İdman Mərcləri və Casino saytı.4109

1Win Azerbaijan – İdman Mərcləri və Casino saytı ▶️ OYNA Содержимое İdman Mərcələrindən İstifadə Etmək Casino Saytı Haqqında Məlumatlar 1Win indir və ya 1win скачать komandalarını istifadə etmək istəyən məbədillər 1Win Azerbaijan saytınıza əsasən əlverişli şərtlərdə giriş edə bilər. 1Win oyna və ya 1win вход komandalarını daxil edərək məlumatları daxil …

Read More »

Amon Casino Avis 2025 et bonus de 400 + 100 FS.982

Amon Casino Avis 2025 Offre Exclusive 400€ et 100 Tours Gratuits ▶️ JOUER Содержимое Amon Casino : Présentation générale Découvrez l’univers d’Amon Casino Les avantages du bonus 400€ + 100 FS Comment maximiser vos gains avec cette offre Expérience utilisateur sur Amon Casino Interface et navigation simplifiées Jeux disponibles en …

Read More »

91 Club Online Casino in India Real Money Play.595

91 Club Online Casino in India – Real Money Play ▶️ PLAY Содержимое Secure and Reliable Gaming Experience at 91 Club India Wide Range of Games and Bonuses at 91 Club India The world of online casinos is vast and exciting, with numerous options available to players from all over …

Read More »

91 Club Online Casino in India Bonus Offers.800

91 Club Online Casino in India – Bonus Offers ▶️ PLAY Содержимое Exclusive Welcome Package for New Players Regular Promotions and Tournaments for Existing Members Weekly Tournaments Other Regular Promotions How to Claim Your Bonus and Start Playing What to Expect After Claiming Your Bonus In the rapidly growing online …

Read More »

Sweet Bonanza Oyna — Sweet bonanza slot güvenilir siteleri.8266

Sweet Bonanza Oyna — Sweet bonanza slot güvenilir siteleri ▶️ OYNAMAK Содержимое Güvenilir Sweet Bonanza Oynama Siteleri Seçimi Sweet Bonanza Slot Oyunları Sweet Bonanza Oyunu Nedir? Sweet Bonanza Oyunlarında Güvenli Para Yatırma Yönergeleri Güvenli Para Yatırma Adımları Sweet Bonanza Slot oyunu, oyun dünyasında büyük bir bonanza olarak kabul edilir. Bu …

Read More »

Казино онлайн

Казино онлайн ▶️ ИГРАТЬ Содержимое Преимущества онлайн-казино Как выбрать лучшее онлайн-казино Основные правила игры в онлайн-казино Основные правила игры в онлайн-казино: Безопасность и конфиденциальность в онлайн-казино В наше время казино онлайн стало одним из самых популярных способов играть в азартные игры. Многие игроки предпочитают играть в интернете, потому что это …

Read More »

Vavada Зеркало Вход на официальный сайт.2652

Вавада казино | Vavada Зеркало Вход на официальный сайт ▶️ ИГРАТЬ Содержимое Вавада казино – надежный партнер для игроков Официальный сайт Vavada – доступ к играм и бонусам Преимущества и функции казино Vavada – почему игроки выбирают это казино Вавада казино – это место, где вы можете испытать на себе …

Read More »

Казино Официальный сайт Pin Up Casino играть онлайн – Вход, Зеркало.1027 (2)

Пин Ап Казино Официальный сайт | Pin Up Casino играть онлайн – Вход, Зеркало ▶️ ИГРАТЬ Содержимое Pin Up Casino: Официальный Сайт Вход в Казино Pin Up Зеркало Казино Как Играть Онлайн в Пин Ап Казино Шаг 2: Депозит Преимущества игроков Pin Up Casino Удобство и доступность Отзывы Игроков Положительные …

Read More »

казино и ставки в БК – зеркало сайта Mostbet.4078

Мостбет – онлайн казино и ставки в БК – зеркало сайта Mostbet ▶️ ИГРАТЬ Содержимое Преимущества онлайн-казино Mostbet Как сделать ставку в Mostbet Зеркало сайта Mostbet: безопасность и доступность Отзывы игроков о Mostbet Преимущества Mostbet Недостатки Mostbet В современном мире игроки имеют доступ к широкому спектру онлайн-казино и букмекерских компаний, …

Read More »