X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fadns.h;h=245833360bf873d5cd4987403c8c0abd2a113b85;hb=ff225555f031392f24b2f88a496ee4ddd6d5a12f;hp=1a7d1dce2f71248215fdce43540c0086652deb07;hpb=deb1edb6350a3b2b30f811098ddb13314c008bd2;p=adns.git diff --git a/src/adns.h b/src/adns.h index 1a7d1dc..2458333 100644 --- a/src/adns.h +++ b/src/adns.h @@ -1,16 +1,17 @@ /* * adns.h - * - adns user-visible API (single-threaded, without any locking) + * - adns user-visible API */ /* * * This file is - * Copyright (C) 1997-2000 Ian Jackson + * Copyright (C) 1997-2000,2003,2006 Ian Jackson * * It is part of adns, which is - * Copyright (C) 1997-2000 Ian Jackson - * Copyright (C) 1999-2000 Tony Finch - * + * Copyright (C) 1997-2000,2003,2006 Ian Jackson + * Copyright (C) 1999-2000,2003,2006 Tony Finch + * Copyright (C) 1991 Massachusetts Institute of Technology + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) @@ -65,6 +66,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { /* I really dislike this - iwj. */ @@ -100,14 +102,41 @@ typedef enum { /* In general, or together the desired flags: */ adns_qf_quotefail_cname=0x00000080,/* refuse if quote-req chars in CNAME we go via */ adns_qf_cname_loose= 0x00000100,/* allow refs to CNAMEs - without, get _s_cname */ adns_qf_cname_forbid= 0x00000200,/* don't follow CNAMEs, instead give _s_cname */ + adns_qf_addrlit_scope_forbid=0x00002000,/* forbid % in IPv6 literals */ + adns_qf_addrlit_scope_numeric=0x00004000,/* % may only be numeric */ + adns_qf_addrlit_ipv4_quadonly=0x00008000,/* reject non-dotted-quad ipv4 */ adns__qf_internalmask= 0x0ff00000 } adns_queryflags; typedef enum { - adns__rrt_typemask=0x0ffff, - adns__qtf_deref= 0x10000, /* dereference domains; perhaps get extra data */ - adns__qtf_mail822= 0x20000, /* return mailboxes in RFC822 rcpt field fmt */ - + adns_rrt_typemask= 0x0ffff, + adns_rrt_reprmask= 0xffffff, + adns__qtf_deref_bit=0x10000,/* internal version of ..._deref below */ + adns__qtf_mail822= 0x20000,/* return mailboxes in RFC822 rcpt field fmt */ + + adns__qtf_bigaddr=0x1000000,/* use the new larger sockaddr union */ + + adns__qtf_deref= adns__qtf_deref_bit|adns__qtf_bigaddr + ,/* dereference domains; perhaps get extra data */ + + adns_r_unknown= 0x40000, + /* To use this, ask for records of type |adns_r_unknown. + * adns will not process the RDATA - you'll get adns_rr_byteblocks, + * where the int is the length and the unsigned char* points to the + * data. String representation of the RR data (by adns_rrinfo) is as in + * RFC3597. adns_rr_info will not return the type name in *rrtname_r + * (due to memory management problems); *fmtname_r will be set to + * "unknown". + * + * Do not specify adns_r_unknown along with a known RR type which + * requires domain name uncompression (see RFC3597 s4); domain names + * will not be uncompressed and the resulting data would be useless. + * Asking for meta-RR types via adns_r_unknown will not work properly + * either and may make adns complain about server misbehaviour, so don't + * do that. + * + * Don't forget adns_qf_quoteok if that's what you want. */ + adns_r_none= 0, adns_r_a= 1, @@ -132,6 +161,14 @@ typedef enum { adns_r_rp_raw= 17, adns_r_rp= adns_r_rp_raw|adns__qtf_mail822, + + adns_r_aaaa= 28, + + /* For SRV records, query domain without _qf_quoteok_query must look + * as expected from SRV RFC with hostname-like Name. _With_ + * _quoteok_query, any query domain is allowed. */ + adns_r_srv_raw= 33, + adns_r_srv= adns_r_srv_raw|adns__qtf_deref, adns_r_addr= adns_r_a|adns__qtf_deref @@ -257,14 +294,29 @@ typedef enum { } adns_status; +typedef union { + struct sockaddr sa; + struct sockaddr_in inet; +} adns_sockaddr_v4only; + +typedef union { + struct sockaddr sa; + struct sockaddr_in inet; + struct sockaddr_in6 inet6; +} adns_sockaddr; + typedef struct { int len; - union { - struct sockaddr sa; - struct sockaddr_in inet; - } addr; + adns_sockaddr addr; } adns_rr_addr; +typedef struct { + /* the old v4-only structure; handy if you have complicated binary + * compatibility problems. */ + int len; + adns_sockaddr_v4only addr; +} adns_rr_addr_v4only; + typedef struct { char *host; adns_status astatus; @@ -301,6 +353,21 @@ typedef struct { unsigned long serial, refresh, retry, expire, minimum; } adns_rr_soa; +typedef struct { + int priority, weight, port; + char *host; +} adns_rr_srvraw; + +typedef struct { + int priority, weight, port; + adns_rr_hostaddr ha; +} adns_rr_srvha; + +typedef struct { + int len; + unsigned char *data; +} adns_rr_byteblock; + typedef struct { adns_status status; char *cname; /* always NULL if query was for CNAME records */ @@ -315,12 +382,16 @@ typedef struct { adns_rr_intstr *(*manyistr); /* txt (list strs ends with i=-1, str=0)*/ adns_rr_addr *addr; /* addr */ struct in_addr *inaddr; /* a */ + struct in6_addr *in6addr; /* aaaa */ adns_rr_hostaddr *hostaddr; /* ns */ adns_rr_intstrpair *intstrpair; /* hinfo */ adns_rr_strpair *strpair; /* rp, rp_raw */ adns_rr_inthostaddr *inthostaddr;/* mx */ adns_rr_intstr *intstr; /* mx_raw */ adns_rr_soa *soa; /* soa, soa_raw */ + adns_rr_srvraw *srvraw; /* srv_raw */ + adns_rr_srvha *srvha;/* srv */ + adns_rr_byteblock *byteblock; /* ...|unknown */ } rrs; } adns_answer; @@ -340,7 +411,8 @@ typedef struct { * * For _init, _init_strcfg, _submit and _synchronous, system errors * (eg, failure to create sockets, malloc failure, etc.) return errno - * values. + * values. EINVAL from _init et al means the configuration file + * is erroneous and cannot be parsed. * * For _wait and _check failures are reported in the answer * structure, and only 0, ESRCH or (for _check) EAGAIN is @@ -357,6 +429,18 @@ typedef struct { * requested. */ +/* Threads: + * adns does not use any static modifiable state, so it + * is safe to call adns_init several times and then use the + * resulting adns_states concurrently. + * However, it is NOT safe to make simultaneous calls into + * adns using the same adns_state; a single adns_state must be used + * only by one thread at a time. You can solve this problem by + * having one adns_state per thread, or if that isn't feasible, you + * could maintain a pool of adns_states. Unfortunately neither of + * these approaches has optimal performance. + */ + int adns_init(adns_state *newstate_r, adns_initflags flags, FILE *diagfile /*0=>stderr*/); @@ -554,6 +638,60 @@ void adns_finish(adns_state ads); * they will be cancelled. */ +#define ADNS_ADDR2TEXT_BUFLEN \ + (INET6_ADDRSTRLEN + 1/*%*/ \ + + ((IF_NAMESIZE-1) > 9 ? (IF_NAMESIZE-1) : 9/*uint32*/) \ + + 1/* nul; included in IF_NAMESIZE */) + +int adns_text2addr(const char *text, uint16_t port, adns_queryflags flags, + struct sockaddr *sa_r, + socklen_t *salen_io /* updated iff OK or ENOSPC */); +int adns_addr2text(const struct sockaddr *sa, adns_queryflags flags, + char *buffer, int *buflen_io /* updated ONLY on ENOSPC */, + int *port_r /* may be 0 */); + /* + * port is always in host byte order and is simply copied to and + * from the appropriate sockaddr field (byteswapped as necessary). + * + * The only flags supported are adns_qf_addrlit_...; others are + * ignored. + * + * Error return values are: + * + * ENOSPC Output buffer is too small. Can only happen if + * *buflen_io < ADNS_ADDR2TEXT_BUFLEN or + * *salen_io < sizeof(adns_sockaddr). On return, + * *buflen_io or *salen_io has been updated by adns. + * + * EINVAL text has invalid syntax. + * + * text represents an address family not supported by + * this version of adns. + * + * Scoped address supplied (text contained "%" or + * sin6_scope_id nonzero) but caller specified + * adns_qf_addrlit_scope_forbid. + * + * Scope name (rather than number) supplied in text but + * caller specified adns_qf_addrlit_scope_numeric. + * + * EAFNOSUPPORT sa->sa_family is not supported (addr2text only). + * + * Only if neither adns_qf_addrlit_scope_forbid nor + * adns_qf_addrlit_scope_numeric are set: + * + * ENOSYS Scope name supplied in text but IPv6 address part of + * sockaddr is not a link local address. + * + * ENXIO Scope name supplied in text but if_nametoindex + * said it wasn't a valid local interface name. + * + * EIO Scoped address supplied but if_nametoindex failed + * in an unexpected way; adns has printed a message to + * stderr. + * + * any other if_nametoindex failed in a more-or-less expected way. + */ void adns_forallqueries_begin(adns_state ads); adns_query adns_forallqueries_next(adns_state ads, void **context_r); @@ -774,7 +912,7 @@ int adns_beforepoll(adns_state ads, struct pollfd *fds, * In any case this call won't block. */ -#define ADNS_POLLFDS_RECOMMENDED 2 +#define ADNS_POLLFDS_RECOMMENDED 3 /* If you allocate an fds buf with at least RECOMMENDED entries then * you are unlikely to need to enlarge it. You are recommended to do * so if it's convenient. However, you must be prepared for adns to