X-Git-Url: https://git.distorted.org.uk/~mdw/adns/blobdiff_plain/684420195d60f5421ea0b6350530fbd430ed8146..e062dcae8f9acfc112459cf7b2d8c925cda08249:/src/internal.h diff --git a/src/internal.h b/src/internal.h index 58d4a4c..69eb827 100644 --- a/src/internal.h +++ b/src/internal.h @@ -1,4 +1,26 @@ -/**/ +/* + * internal.h + * - declarations of private objects with external linkage (adns__*) + * - definitons of internal macros + * - comments regarding library data structures + */ +/* + * This file is part of adns, which is Copyright (C) 1997, 1998 Ian Jackson + * + * 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) + * any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ #ifndef ADNS_INTERNAL_H_INCLUDED #define ADNS_INTERNAL_H_INCLUDED @@ -60,10 +82,22 @@ typedef union { typedef struct { adns_rrtype type; - const char *name; + const char *rrtname; + const char *fmtname; int rrsz; - adns_status (*parse)(adns_state ads, adns_query qu, int serv, + void (*makefinal)(adns_query qu, void *data); + /* Change memory management of *data. + * Previously, used alloc_interim, now use alloc_final. + */ + + adns_status (*convstring)(vbuf *vb, const void *data); + /* Converts the RR data to a string representation in vbuf. + * vbuf will be appended to (it must have been initialised), + * and will not be null-terminated by convstring. + */ + + adns_status (*parse)(adns_query qu, int serv, const byte *dgram, int dglen, int cbyte, int max, void *store_r); /* Parse one RR, in dgram of length dglen, starting at cbyte and @@ -75,9 +109,9 @@ typedef struct { * *rdstart to -1; otherwise it may set it to anything else positive. */ - void (*makefinal)(adns_state ads, adns_query qu, void *data); - /* Change memory management of *data. - * Previously, used alloc_interim, now use alloc_final. + int (*diff_needswap)(const void *datap_a, const void *datap_b); + /* Returns >0 if RR a should be strictly after RR b in the sort order, + * 0 otherwise. Must not fail. */ } typeinfo; @@ -95,6 +129,7 @@ union maxalign { } data; struct adns__query { + adns_state ads; enum { query_udp, query_tcpwait, query_tcpsent, query_child, query_done } state; adns_query back, next, parent; struct { adns_query head, tail; } children; @@ -104,7 +139,7 @@ struct adns__query { void *final_allocspace; const typeinfo *typei; - char *query_dgram; + byte *query_dgram; int query_dglen; vbuf vb; @@ -124,6 +159,7 @@ struct adns__query { byte *cname_dgram; int cname_dglen, cname_begin; + /* If non-0, has been allocated using . */ int id, flags, udpretries; int udpnextserver; @@ -200,6 +236,10 @@ struct adns__state { /* From setup.c: */ +int adns__setnonblock(adns_state ads, int fd); /* => errno value */ + +/* From general.c: */ + void adns__vdiag(adns_state ads, const char *pfx, adns_initflags prevent, int serv, adns_query qu, const char *fmt, va_list al); @@ -211,19 +251,63 @@ void adns__diag(adns_state ads, int serv, adns_query qu, const char *fmt, ...) PRINTFFORMAT(4,5); int adns__vbuf_ensure(vbuf *vb, int want); -int adns__vbuf_appendstr(vbuf *vb, const char *data); +int adns__vbuf_appendstr(vbuf *vb, const char *data); /* does not include nul */ int adns__vbuf_append(vbuf *vb, const byte *data, int len); /* 1=>success, 0=>realloc failed */ void adns__vbuf_appendq(vbuf *vb, const byte *data, int len); void adns__vbuf_init(vbuf *vb); void adns__vbuf_free(vbuf *vb); -int adns__setnonblock(adns_state ads, int fd); /* => errno value */ +const char *adns__diag_domain(adns_state ads, int serv, adns_query qu, vbuf *vb, + int flags, const byte *dgram, int dglen, int cbyte); +/* Unpicks a domain in a datagram and returns a string suitable for + * printing it as. Never fails - if an error occurs, it will + * return some kind of string describing the error. + * + * serv may be -1 and qu may be 0. vb must have been initialised, + * and will be left in an arbitrary consistent state. + * + * Returns either vb->buf, or a pointer to a string literal. Do not modify + * vb before using the return value. + */ + +/* From transmit.c: */ -/* From submit.c: */ +adns_status adns__mkquery(adns_state ads, vbuf *vb, int *id_r, + const char *owner, int ol, + const typeinfo *typei, adns_queryflags flags); +/* Assembles a query packet in vb, and returns id at *id_r. */ + +adns_status adns__mkquery_frdgram(adns_state ads, vbuf *vb, int *id_r, + const byte *qd_dgram, int qd_dglen, int qd_begin, + adns_rrtype type, adns_queryflags flags); +/* Same as adns__mkquery, but takes the owner domain from an existing datagram. + * That domain must be correct and untruncated. + */ + +void adns__query_tcp(adns_query qu, struct timeval now); +/* Query must be in state tcpwait/timew; it will be moved to a new state + * if possible and no further processing can be done on it for now. + * (Resulting state is one of tcpwait/timew (if server not connected), + * tcpsent/timew, child/childw or done/output.) + * + * adns__tcp_tryconnect should already have been called - _tcp + * will only use an existing connection (if there is one), which it + * may break. If the conn list lost then the caller is responsible for any + * reestablishment and retry. + */ + +void adns__query_udp(adns_query qu, struct timeval now); +/* Query must be in state udp/NONE; it will be moved to a new state, + * and no further processing can be done on it for now. + * (Resulting state is one of udp/timew, tcpwait/timew (if server not connected), + * tcpsent/timew, child/childw or done/output.) + */ + +/* From query.c: */ int adns__internal_submit(adns_state ads, adns_query *query_r, - adns_rrtype type, vbuf *qumsg_vb, int id, + const typeinfo *typei, vbuf *qumsg_vb, int id, adns_queryflags flags, struct timeval now, adns_status failstat, const qcontext *ctx); /* Submits a query (for internal use, called during external submits). @@ -250,36 +334,36 @@ void *adns__alloc_interim(adns_query qu, size_t sz); * big enough for all these allocations, and then adns__alloc_final * will get memory from this buffer. * - * _alloc_interim can fail, in which case it will fail the query too, - * so nothing more need be done with it. + * _alloc_interim can fail (and return 0). + * The caller must ensure that the query is failed. + * + * adns__alloc_interim_{only,fail}(qu,0) will not return 0, + * but it will not necessarily return a distinct pointer each time. + */ + +void *adns__alloc_mine(adns_query qu, size_t sz); +/* Like _interim, but does not record the length for later + * copying into the answer. This just ensures that the memory + * will be freed when we're done with the query. */ void *adns__alloc_final(adns_query qu, size_t sz); -/* Cannot fail. +/* Cannot fail, and cannot return 0. */ void adns__makefinal_block(adns_query qu, void **blpp, size_t sz); void adns__makefinal_str(adns_query qu, char **strp); -/* From query.c: */ - -void adns__query_udp(adns_state ads, adns_query qu, struct timeval now); -void adns__query_tcp(adns_state ads, adns_query qu, struct timeval now); -adns_status adns__mkquery(adns_state ads, vbuf *vb, - const char *owner, int ol, int *id_r, - const typeinfo *typei, adns_queryflags flags); -/* Assembles a query packet in vb, and returns id at *id_r. */ - -void adns__query_ok(adns_state ads, adns_query qu); -void adns__query_fail(adns_state ads, adns_query qu, adns_status stat); - -void adns__reset_cnameonly(adns_state ads, adns_query qu); +void adns__reset_cnameonly(adns_query qu); /* Resets all of the memory management stuff etc. to * take account of only the CNAME. Used when we find an error somewhere * and want to just report the error (with perhaps CNAME info), and also * when we're halfway through RRs in a datagram and discover that we * need to retry the query. */ + +void adns__query_done(adns_query qu); +void adns__query_fail(adns_query qu, adns_status stat); /* From reply.c: */ @@ -294,24 +378,25 @@ const typeinfo *adns__findtype(adns_rrtype type); typedef struct { adns_state ads; + adns_query qu; int serv; const byte *dgram; int dglen, max, cbyte, namelen; - int *dmend_rlater, *namelen_rlater; + int *dmend_r; } findlabel_state; -void adns__findlabel_start(findlabel_state *fls, - adns_state ads, int serv, +void adns__findlabel_start(findlabel_state *fls, adns_state ads, + int serv, adns_query qu, const byte *dgram, int dglen, int max, int dmbegin, int *dmend_rlater); /* Finds labels in a domain in a datagram. * * Call this routine first. - * endpoint_rlater may be null. + * dmend_rlater may be null. ads (and of course fls) may not be. + * serv may be -1, qu may be null - they are for error reporting. */ -adns_status adns__findlabel_next(findlabel_state *fls, - int *lablen_r, int *labstart_r); +adns_status adns__findlabel_next(findlabel_state *fls, int *lablen_r, int *labstart_r); /* Then, call this one repeatedly. * * It will return adns_s_ok if all is well, and tell you the length @@ -336,20 +421,21 @@ adns_status adns__findlabel_next(findlabel_state *fls, * Do not then call findlabel_next again. */ -adns_status adns__parse_domain(adns_state ads, int serv, vbuf *vb, - const byte *dgram, int dglen, - int *cbyte_io, int max); +adns_status adns__parse_domain(adns_state ads, int serv, adns_query qu, + vbuf *vb, int flags, + const byte *dgram, int dglen, int *cbyte_io, int max); /* vb must already have been initialised; it will be reset if necessary. * If there is truncation, vb->used will be set to 0; otherwise * (if there is no error) vb will be null-terminated. * If there is an error vb and *cbyte_io may be left indeterminate. + * + * serv may be -1 and qu may be 0 - they are used for error reporting only. */ -adns_status adns__findrr(adns_state ads, int serv, +adns_status adns__findrr(adns_query qu, int serv, const byte *dgram, int dglen, int *cbyte_io, int *type_r, int *class_r, int *rdlen_r, int *rdstart_r, - const byte *eo_dgram, int eo_dglen, int eo_cbyte, - int *eo_matched_r); + int *ownermatchedquery_r); /* Finds the extent and some of the contents of an RR in a datagram * and does some checks. The datagram is *dgram, length dglen, and * the RR starts at *cbyte_io (which is updated afterwards to point @@ -359,20 +445,18 @@ adns_status adns__findrr(adns_state ads, int serv, * the corresponding pointer variables are not null. type_r and * class_r may not be null. * - * If the caller thinks they know what the owner of the RR ought to - * be they can pass in details in eo_*: this is another (or perhaps - * the same datagram), and a pointer to where the putative owner - * starts in that datagram. In this case *eo_matched_r will be set - * to 1 if the datagram matched or 0 if it did not. Either - * both eo_dgram and eo_matched_r must both be non-null, or they - * must both be null (in which case eo_dglen and eo_cbyte will be ignored). - * The eo datagram and contained owner domain MUST be valid and - * untruncated. + * If ownermatchedquery_r != 0 then the owner domain of this + * RR will be compared with that in the query (or, if the query + * has gone to a CNAME lookup, with the canonical name). + * In this case, *ownermatchedquery_r will be set to 0 or 1. + * The query datagram (or CNAME datagram) MUST be valid and not truncated. * * If there is truncation then *type_r will be set to -1 and * *cbyte_io, *class_r, *rdlen_r, *rdstart_r and *eo_matched_r will be * undefined. * + * qu must obviously be non-null. + * * If an error is returned then *type_r will be undefined too. */ @@ -382,7 +466,9 @@ int vbuf__append_quoted1035(vbuf *vb, const byte *buf, int len); void adns__tcp_broken(adns_state ads, const char *what, const char *why); void adns__tcp_tryconnect(adns_state ads, struct timeval now); + void adns__autosys(adns_state ads, struct timeval now); +/* Make all the system calls we want to if the application wants us to. */ /* Useful static inline functions: */ @@ -420,16 +506,16 @@ static inline int ctype_alpha(int c) { #define LIST_LINK_TAIL_PART(list,node,part) \ do { \ - (node)->part back= 0; \ - (node)->part next= (list).tail; \ - if ((list).tail) (list).tail->part back= (node); else (list).part head= (node); \ + (node)->part next= 0; \ + (node)->part back= (list).tail; \ + if ((list).tail) (list).tail->part next= (node); else (list).part head= (node); \ (list).tail= (node); \ } while(0) #define LIST_UNLINK(list,node) LIST_UNLINK_PART(list,node,) #define LIST_LINK_TAIL(list,node) LIST_LINK_TAIL_PART(list,node,) -#define GETIL_B(cb) (dgram[(cb)++]) +#define GETIL_B(cb) (((dgram)[(cb)++]) & 0x0ff) #define GET_B(cb,tv) ((tv)= GETIL_B((cb))) #define GET_W(cb,tv) ((tv)=0, (tv)|=(GETIL_B((cb))<<8), (tv)|=GETIL_B(cb), (tv))