X-Git-Url: https://git.distorted.org.uk/~mdw/adns/blobdiff_plain/74c948317bd4785fbfa8b6047b8da2e1705b1863..2ac463bf7da8bafbcc48cc7e1dcf24770fb42aa1:/src/adns.h diff --git a/src/adns.h b/src/adns.h index 14bd971..7b7b25f 100644 --- a/src/adns.h +++ b/src/adns.h @@ -19,16 +19,22 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * $Id: adns.h,v 1.50 1999/07/05 01:51:04 ian Exp $ + * $Id: adns.h,v 1.59 1999/09/25 16:13:03 ian Exp $ */ #ifndef ADNS_H_INCLUDED #define ADNS_H_INCLUDED +#ifdef __cplusplus +extern "C" { /* I really dislike this - iwj. */ +#endif #include #include #include +#include +#include +#include /* All struct in_addr anywhere in adns are in NETWORK byte order. */ @@ -43,18 +49,21 @@ typedef enum { adns_if_noautosys= 0x0010, /* do not make syscalls at every opportunity */ adns_if_eintr= 0x0020, /* allow _wait and _synchronous to return EINTR */ adns_if_nosigpipe= 0x0040, /* applic has SIGPIPE set to SIG_IGN, do not protect */ + adns_if_checkc_entex= 0x0100, /* do consistency checks on entry/exit to adns funcs */ + adns_if_checkc_freq= 0x0300, /* do consistency checks very frequently (slow!) */ } adns_initflags; typedef enum { - adns_qf_search= 0x000001, /* use the searchlist */ - adns_qf_usevc= 0x000002, /* use a virtual circuit (TCP connection) */ - adns_qf_owner= 0x000004, /* fill in the owner field in the answer */ - adns_qf_quoteok_query= 0x000010, /* allow quote-requiring chars in query domain */ - adns_qf_quoteok_cname= 0x000020, /* allow ... in CNAME we go via */ - adns_qf_quoteok_anshost= 0x000040, /* allow ... in answers expected to be hostnames */ - adns_qf_cname_loose= 0x000100, /* allow refs to CNAMEs - without, get _s_cname */ - adns_qf_cname_forbid= 0x000200, /* don't follow CNAMEs, instead give _s_cname */ - adns__qf_internalmask= 0x0ff000 + adns_qf_search= 0x00000001, /* use the searchlist */ + adns_qf_usevc= 0x00000002, /* use a virtual circuit (TCP connection) */ + adns_qf_owner= 0x00000004, /* fill in the owner field in the answer */ + adns_qf_quoteok_query= 0x00000010, /* allow quote-requiring chars in query domain */ + adns_qf_quoteok_cname= 0x00000000, /* allow ... in CNAME we go via - now default */ + adns_qf_quoteok_anshost= 0x00000040, /* allow ... in things supposed to be hostnames */ + 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_internalmask= 0x0ff00000 } adns_queryflags; typedef enum { @@ -91,18 +100,57 @@ typedef enum { } adns_rrtype; -/* In queries without qf_quoteok_*, all domains must have standard - * legal syntax. In queries _with_ qf_quoteok_*, domains in the query - * or response may contain any characters, quoted according to RFC1035 - * 5.1. On input to adns, the char* is a pointer to the interior of a - * " delimited string, except that " may appear in it, and on output, +/* + * In queries without qf_quoteok_*, all domains must have standard + * legal syntax, or you get adns_s_querydomainvalid (if the query + * domain contains bad characters) or adns_s_answerdomaininvalid (if + * the answer contains bad characters). + * + * In queries _with_ qf_quoteok_*, domains in the query or response + * may contain any characters, quoted according to RFC1035 5.1. On + * input to adns, the char* is a pointer to the interior of a " + * delimited string, except that " may appear in it, and on output, * the char* is a pointer to a string which would be legal either * inside or outside " delimiters, and any characters not usually * legal in domain names will be quoted as \X (if the character is * 33-126 except \ and ") or \DDD. * - * Do not ask for _raw records containing mailboxes without - * specifying _qf_anyquote. + * If the query goes via a CNAME then the canonical name (ie, the + * thing that the CNAME record refers to) is usually allowed to + * contain any characters, which will be quoted as above. With + * adns_qf_quotefail_cname you get adns_s_answerdomaininvalid when + * this happens. (This is a change from version 0.4 and earlier, in + * which failing the query was the default, and you had to say + * adns_qf_quoteok_cname to avoid this; that flag is now deprecated.) + * + * In version 0.4 and earlier, asking for _raw records containing + * mailboxes without specifying _qf_quoteok_anshost was silly. This + * is no longer the case. In this version only parts of responses + * that are actually supposed to be hostnames will be refused by + * default if quote-requiring characters are found. + */ + +/* + * If you ask for an RR which contains domains which are actually + * encoded mailboxes, and don't ask for the _raw version, then adns + * returns the mailbox formatted suitably for an RFC822 recipient + * header field. The particular format used is that if the mailbox + * requires quoting according to the rules in RFC822 then the + * local-part is quoted in double quotes, which end at the next + * unescaped double quote. (\ is the escape char, and is doubled, and + * is used to escape only \ and ".) Otherwise the local-part is + * presented as-is. In any case this is followed by an @ and the + * domain. The domain will not contain any characters not legal in + * hostnames. adns will protect the application from local parts + * containing control characters - these appear to be legal according + * to RFC822 but are clearly a bad idea. + * + * If you ask for the domain with _raw then _no_ checking is done + * (even on the host part, regardless of adns_qf_quoteok_anshost), and + * you just get the domain name in master file format. + * + * If no mailbox is supplied the returned string will be `.' in either + * caswe. */ typedef enum { @@ -204,7 +252,7 @@ typedef struct { char *owner; /* only set if requested in query flags */ adns_rrtype type; /* guaranteed to be same as in query */ time_t expires; /* expiry time, defined only if _s_ok, nxdomain or nodata. NOT TTL! */ - int nrrs, rrsz; + int nrrs, rrsz; /* nrrs is 0 if an error occurs */ union { void *untyped; unsigned char *bytes; @@ -297,26 +345,47 @@ void adns_cancel(adns_query query); * first adns_submit or _transact call using the same adns_state after * it became invalid, so you may compare it for equality with other * query handles until you next call _query or _transact. + * + * _submit and _synchronous return ENOSYS if they don't understand the + * query type. */ +int adns_submit_reverse(adns_state ads, + const struct sockaddr *addr, + adns_rrtype type, + adns_queryflags flags, + void *context, + adns_query *query_r); +/* type must be _r_ptr or _r_ptr_raw. _qf_search is ignored. */ + void adns_finish(adns_state ads); /* You may call this even if you have queries outstanding; * they will be cancelled. */ -struct adns_query adns_forallqueries_begin(adns_state ads, void **context_r); -struct adns_query adns_forallqueries_next(adns_state ads, adns_query, void **context_r); +void adns_forallqueries_begin(adns_state ads); +adns_query adns_forallqueries_next(adns_state ads, void **context_r); /* Iterator functions, which you can use to loop over the outstanding - * (submitted but not yet successfuly checked/waited) queries. Each - * function returns a query handle and a corresponding context pointer, - * or returns 0 setting *context_r to 0 if there are no (more) queries. - * There is no need to explicitly finish an iteration. context_r may be 0. - * - * IMPORTANT: you MUST NOT call ANY other adns function with the same - * adns_state, or with a query in the same adns_state, while you are - * doing one of these iterations. After such a call the iterator - * value has undefined meaning and must not be used. + * (submitted but not yet successfuly checked/waited) queries. + * + * You can only have one iteration going at once. You may call _begin + * at any time; after that, an iteration will be in progress. You may + * only call _next when an iteration is in progress - anything else + * may coredump. The iteration remains in progress until _next + * returns 0, indicating that all the queries have been walked over, + * or ANY other adns function is called with the same adns_state (or a + * query in the same adns_state). There is no need to explicitly + * finish an iteration. + * + * context_r may be 0. *context_r may not be set when _next returns 0. + */ + +void adns_checkconsistency(adns_state ads, adns_query qu); +/* Checks the consistency of adns's internal data structures. + * If any error is found, the program will abort(). + * You may pass 0 for qu; if you pass non-null then additional checks + * are done to make sure that qu is a valid query. */ /* @@ -479,30 +548,35 @@ int adns_beforepoll(adns_state ads, struct pollfd *fds, int *nfds_io, int *timeo * listen for more structs then *nfds_io will be set to the number * required and _beforepoll will return ERANGE. * - * NOTE that if now is 0, adns may acquire additional fds from one - * call to the next, so you must put adns_beforepoll in a loop, rather - * than assuming that the second call (with the buffer size requested - * by the first) will not return ERANGE. - * * You may call _beforepoll with fds==0 and *nfds_io 0, in which case * adns will fill in the number of fds that it might be interested in - * in *nfds_io, and always return 0. + * in *nfds_io, and always return either 0 (if it is not interested in + * any fds) or ERANGE (if it is). + * + * NOTE that (unless timeout_io is 0) adns may acquire additional fds + * from one call to the next, so you must put adns_beforepoll in a + * loop, rather than assuming that the second call (with the buffer + * size requested by the first) will not return ERANGE. * * adns only ever sets POLLIN, POLLOUT and POLLPRI in its pollfd * structs, and only ever looks at those bits. POLLPRI is required to - * detect TCP Urgent Data, which should not be used by a DNS server, + * detect TCP Urgent Data (which should not be used by a DNS server) * so that adns can know that the TCP stream is now useless. * * In any case, *timeout_io should be a timeout value as for poll(2), * which adns will modify downwards as required. If the caller does - * not plan to block then *timeout_io should be 0 on entry. + * not plan to block then *timeout_io should be 0 on entry, or + * alternatively, timeout_io may be 0. (Alternatively, the caller may + * use _beforeselect with timeout_io==0 to find out about file + * descriptors, and use _firsttimeout is used to find out when adns + * might want to time something out.) * * adns_beforepoll will return 0 on success, and will not fail for any * reason other than the fds buffer being too small (ERANGE). * - * If *now is not 0 then this call will never actually do any I/O, or - * change the fds that adns is using or the timeouts it wants. In any - * case it won't block. + * This call will never actually do any I/O, or change the fds that + * adns is using or the timeouts it wants; and in any case it won't + * block. */ #define ADNS_POLLFDS_RECOMMENDED 2 @@ -524,21 +598,23 @@ adns_status adns_rr_info(adns_rrtype type, const char **rrtname_r, const char **fmtname_r, int *len_r, const void *datap, char **data_r); -/* Gets information in human-readable (but non-i18n) form - * for eg debugging purposes. type must be specified, - * and the official name of the corresponding RR type will - * be returned in *rrtname_r, and information about the processing - * style in *fmtname_r. The length of the table entry in an answer - * for that type will be returned in in *len_r. - * Any or all of rrtname_r, fmtname_r and len_r may be 0. - * If fmtname_r is non-null then *fmtname_r may be - * null on return, indicating that no special processing is - * involved. - * - * data_r be must be non-null iff datap is. In this case - * *data_r will be set to point to a human-readable text - * string representing the RR data. The text will have - * been obtained from malloc() and must be freed by the caller. +/* + + * Get information about a query type, or convert reply data to a + * textual form. type must be specified, and the official name of the + * corresponding RR type will be returned in *rrtname_r, and + * information about the processing style in *fmtname_r. The length + * of the table entry in an answer for that type will be returned in + * in *len_r. Any or all of rrtname_r, fmtname_r and len_r may be 0. + * If fmtname_r is non-null then *fmtname_r may be null on return, + * indicating that no special processing is involved. + * + * data_r be must be non-null iff datap is. In this case *data_r will + * be set to point to a string pointing to a representation of the RR + * data in master file format. (The owner name, timeout, class and + * type will not be present - only the data part of the RR.) The + * memory will have been obtained from malloc() and must be freed by + * the caller. * * Usually this routine will succeed. Possible errors include: * adns_s_nomemory @@ -546,6 +622,37 @@ adns_status adns_rr_info(adns_rrtype type, * adns_s_invaliddata (*datap contained garbage) * If an error occurs then no memory has been allocated, * and *rrtname_r, *fmtname_r, *len_r and *data_r are undefined. + * + * There are some adns-invented data formats which are not official + * master file formats. These include: + * + * Mailboxes if __qtf_mail822: these are just included as-is. + * + * Addresses (adns_rr_addr): these may be of pretty much any type. + * The representation is in two parts: first, a word for the address + * family (ie, in AF_XXX, the XXX), and then one or more items for the + * address itself, depending on the format. For an IPv4 address the + * syntax is INET followed by the dotted quad (from inet_ntoa). + * Currently only IPv4 is supported. + * + * Text strings (as in adns_rr_txt) appear inside double quotes, and + * use \" and \\ to represent " and \, and \xHH to represent + * characters not in the range 32-126. + * + * Hostname with addresses (adns_rr_hostaddr): this consists of the + * hostname, as usual, followed by the adns_status value, as an + * abbreviation, and then a descriptive string (encoded as if it were + * a piece of text), for the address lookup, followed by zero or more + * addresses enclosed in ( and ). If the result was a permanent + * failure, then a single ? appears instead of the ( ). If the + * result was a temporary failure then an empty pair of parentheses + * appears (which a space in between). For example, one of the NS + * records for greenend.org.uk comes out like + * ns.chiark.greenend.org.uk ok "OK" ( INET 195.224.76.132 ) + * an MX referring to a nonexistent host might come out like: + * 50 sun2.nsfnet-relay.ac.uk nxdomain "No such domain" ( ) + * and if nameserver information is not available you might get: + * dns2.spong.dyn.ml.org timeout "DNS query timed out" ? */ const char *adns_strerror(adns_status st); @@ -556,4 +663,7 @@ const char *adns_errabbrev(adns_status st); * not returned by the same adns library. */ +#ifdef __cplusplus +} /* end of extern "C" */ +#endif #endif