X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fadns.h;h=08033cba5201492e944beef05e269a8eb572237b;hb=940356bdf463f1decefb2c8d63dd33d7276d5991;hp=4f25dc7246529a5e6e711ea568767539f4b6faa2;hpb=958ad1f072aa889debf6bdde8f042678f5335952;p=adns.git diff --git a/src/adns.h b/src/adns.h index 4f25dc7..08033cb 100644 --- a/src/adns.h +++ b/src/adns.h @@ -24,11 +24,17 @@ #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; @@ -288,6 +336,12 @@ int adns_wait(adns_state ads, adns_answer **answer_r, void **context_r); +/* same as adns_wait but uses poll(2) internally */ +int adns_wait_poll(adns_state ads, + adns_query *query_io, + adns_answer **answer_r, + void **context_r); + void adns_cancel(adns_query query); /* The adns_query you get back from _submit is valid (ie, can be @@ -297,8 +351,19 @@ 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. @@ -306,7 +371,7 @@ void adns_finish(adns_state ads); void adns_forallqueries_begin(adns_state ads); -struct adns_query adns_forallqueries_next(adns_state ads, void **context_r); +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. * @@ -319,7 +384,14 @@ struct adns_query adns_forallqueries_next(adns_state ads, void **context_r); * query in the same adns_state). There is no need to explicitly * finish an iteration. * - * context_r may be 0. + * 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. */ /* @@ -487,7 +559,7 @@ int adns_beforepoll(adns_state ads, struct pollfd *fds, int *nfds_io, int *timeo * 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 + * NOTE that (unless 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. @@ -508,9 +580,11 @@ int adns_beforepoll(adns_state ads, struct pollfd *fds, int *nfds_io, int *timeo * adns_beforepoll will return 0 on success, and will not fail for any * reason other than the fds buffer being too small (ERANGE). * - * 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. + * This call will never actually do any I/O. If you supply the + * current time it will not change the fds that adns is using or the + * timeouts it wants. + * + * In any case this call won't block. */ #define ADNS_POLLFDS_RECOMMENDED 2 @@ -532,21 +606,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 @@ -554,6 +630,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); @@ -564,4 +671,7 @@ const char *adns_errabbrev(adns_status st); * not returned by the same adns library. */ +#ifdef __cplusplus +} /* end of extern "C" */ +#endif #endif