From: ian Date: Sun, 8 Nov 1998 16:16:09 +0000 (+0000) Subject: Compiles but does not link. X-Git-Tag: abandon.1999-04-10.multithread~49 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=adns.git;a=commitdiff_plain;h=3955725ceceb330041f8e7a27e6629a2e8a9b5ba;hp=e576be5096ae358bebe2e9b6ad07c49f74aef616 Compiles but does not link. --- diff --git a/regress/junk b/regress/junk deleted file mode 100644 index 7992f49..0000000 --- a/regress/junk +++ /dev/null @@ -1,6 +0,0 @@ - -#include -#include -#include - -#include diff --git a/src/adns.h b/src/adns.h index 7268381..9f9cb12 100644 --- a/src/adns.h +++ b/src/adns.h @@ -234,7 +234,7 @@ int adns_wait(adns_state ads, void **context_r); /* Might return EINTR - if so, try again */ -void adns_cancel(adns_state ads, adns_query query); +void adns_cancel(adns_query query); int adns_finish(adns_state); /* You may call this even if you have queries outstanding; diff --git a/src/event.c b/src/event.c index dcf0adb..8329ff4 100644 --- a/src/event.c +++ b/src/event.c @@ -51,7 +51,7 @@ void adns__tcp_broken(adns_state ads, const char *what, const char *why) { qu->tcpfailed |= (1<tcpfailed == (1<nservers)-1) { LIST_UNLINK(ads->timew,qu); - adns__query_fail(ads,qu,adns_s_allservfail); + adns__query_fail(qu,adns_s_allservfail); } } @@ -68,7 +68,7 @@ static void tcp_connected(adns_state ads, struct timeval now) { nqu= qu->next; if (qu->state == query_udp) continue; assert (qu->state == query_tcpwait); - adns__query_tcp(ads,qu,now); + adns__query_tcp(qu,now); } } @@ -160,9 +160,9 @@ static void checktimeouts(adns_state ads, struct timeval now, if (timercmp(&now,&qu->timeout,>)) { LIST_UNLINK(ads->timew,qu); if (qu->state != query_udp) { - adns__query_fail(ads,qu,adns_s_timeout); + adns__query_fail(qu,adns_s_timeout); } else { - adns__query_udp(ads,qu,now); + adns__query_udp(qu,now); } } else { inter_maxtoabs(tv_io,tvbuf,now,qu->timeout); diff --git a/src/general.c b/src/general.c index 7c42eb6..2ced4c0 100644 --- a/src/general.c +++ b/src/general.c @@ -21,12 +21,16 @@ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include + +#include + #include "internal.h" /* Core diagnostic functions */ void adns__vdiag(adns_state ads, const char *pfx, adns_initflags prevent, - int serv, const char *fmt, adns_query qu, va_list al) { + int serv, adns_query qu, const char *fmt, va_list al) { const char *bef, *aft; vbuf vb; if (!(ads->iflags & adns_if_debug) && (!prevent || (ads->iflags & prevent))) return; @@ -42,7 +46,8 @@ void adns__vdiag(adns_state ads, const char *pfx, adns_initflags prevent, adns__vbuf_init(&vb); fprintf(stderr,"%sQNAME=%s, QTYPE=%s", bef, - adns__diag_domain(ads,-1,0,&vb,qu->query_dgram,qu->query_dglen,DNS_HDRSIZE), + adns__diag_domain(qu->ads,-1,0, &vb,qu->flags, + qu->query_dgram,qu->query_dglen,DNS_HDRSIZE), qu->typei ? qu->typei->name : ""); bef=", "; aft=")\n"; } @@ -123,8 +128,8 @@ const char *adns__diag_domain(adns_state ads, int serv, adns_query qu, vbuf *vb, int flags, const byte *dgram, int dglen, int cbyte) { adns_status st; - st= adns__parse_domain(ads,serv,vb,qu->flags, dgram,dglen, &cbyte,dglen); - if (st == adns_s_nomemory) { + st= adns__parse_domain(ads,serv,qu,vb, flags,dgram,dglen,&cbyte,dglen); + if (st == adns_s_nolocalmem) { return ""; } if (st) { @@ -136,7 +141,7 @@ const char *adns__diag_domain(adns_state ads, int serv, adns_query qu, vbuf *vb, return ""; } } - if (!vb.used) { + if (!vb->used) { adns__vbuf_appendstr(vb,""); adns__vbuf_append(vb,"",1); } diff --git a/src/internal.h b/src/internal.h index 61f2ff7..24e69a8 100644 --- a/src/internal.h +++ b/src/internal.h @@ -85,7 +85,7 @@ typedef struct { const char *name; int rrsz; - adns_status (*parse)(adns_state ads, adns_query qu, int serv, + 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 @@ -97,7 +97,7 @@ typedef struct { * *rdstart to -1; otherwise it may set it to anything else positive. */ - void (*makefinal)(adns_state ads, adns_query qu, void *data); + void (*makefinal)(adns_query qu, void *data); /* Change memory management of *data. * Previously, used alloc_interim, now use alloc_final. */ @@ -117,6 +117,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; @@ -146,6 +147,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; @@ -250,7 +252,7 @@ const char *adns__diag_domain(adns_state ads, int serv, adns_query qu, vbuf *vb, * printing it as. Never fails - if an error occurs, it will * return some kind of string describing the error. * - * serv may be -1, qu may be 0. vb must have been initialised, + * 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 @@ -259,12 +261,12 @@ const char *adns__diag_domain(adns_state ads, int serv, adns_query qu, vbuf *vb, /* From transmit.c: */ -adns_status adns__mkquery(adns_state ads, vbuf *vb, - const char *owner, int ol, int *id_r, +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. */ -void adns__query_tcp(adns_state ads, adns_query qu, struct timeval now); +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), @@ -276,7 +278,7 @@ void adns__query_tcp(adns_state ads, adns_query qu, struct timeval now); * reestablishment and retry. */ -void adns__query_udp(adns_state ads, adns_query qu, struct timeval now); +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), @@ -286,7 +288,7 @@ void adns__query_udp(adns_state ads, adns_query qu, struct timeval now); /* 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). @@ -317,6 +319,12 @@ void *adns__alloc_interim(adns_query qu, size_t sz); * so nothing more need be done with it. */ +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. */ @@ -324,7 +332,7 @@ void *adns__alloc_final(adns_query qu, size_t sz); void adns__makefinal_block(adns_query qu, void **blpp, size_t sz); void adns__makefinal_str(adns_query qu, char **strp); -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 @@ -332,8 +340,8 @@ void adns__reset_cnameonly(adns_state ads, adns_query qu); * need to retry the query. */ -void adns__query_done(adns_state ads, adns_query qu); -void adns__query_fail(adns_state ads, adns_query qu, adns_status stat); +void adns__query_done(adns_query qu); +void adns__query_fail(adns_query qu, adns_status stat); /* From reply.c: */ @@ -348,24 +356,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 @@ -390,20 +399,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 @@ -413,20 +423,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. */ diff --git a/src/parse.c b/src/parse.c index bf04d4d..099deb7 100644 --- a/src/parse.c +++ b/src/parse.c @@ -46,11 +46,12 @@ int vbuf__append_quoted1035(vbuf *vb, const byte *buf, int len) { return 1; } -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) { fls->ads= ads; + fls->qu= qu; fls->serv= serv; fls->dgram= dgram; fls->dglen= dglen; @@ -58,23 +59,23 @@ void adns__findlabel_start(findlabel_state *fls, fls->cbyte= dmbegin; fls->namelen= 0; fls->dmend_r= dmend_rlater; - fls->namelen_r= namelen_rlater; } -adns_status adns__findlabel_next(findlabel_state fls, +adns_status adns__findlabel_next(findlabel_state *fls, int *lablen_r, int *labstart_r) { int lablen, jumped; + const char *dgram; jumped= 0; + dgram= fls->dgram; for (;;) { - fls->cbyte += 2; - if (fls->cbyte > fls->dglen) goto x_truncated; - if (fls->cbyte > fls->max) goto x_serverfaulty; - GET_W(fls->cbyte-2,lablen); + if (fls->cbyte+2 > fls->dglen) goto x_truncated; + if (fls->cbyte+2 > fls->max) goto x_serverfaulty; + GET_W(fls->cbyte,lablen); if (!(lablen & 0x0c000)) break; if ((lablen & 0x0c000) != 0x0c000) return adns_s_unknownreply; if (jumped++) { - adns__diag(ads,fls->serv,fls->qu,"compressed datagram contains loop"); + adns__diag(fls->ads,fls->serv,fls->qu,"compressed datagram contains loop"); return adns_s_serverfaulty; } if (fls->dmend_r) *(fls->dmend_r)= fls->cbyte; @@ -90,7 +91,6 @@ adns_status adns__findlabel_next(findlabel_state fls, if (fls->cbyte > fls->max) goto x_serverfaulty; } else { if (fls->dmend_r) *(fls->dmend_r)= fls->cbyte; - if (fls->namelen_r) *(fls->namelen_r)= fls->namelen; } if (labstart_r) *labstart_r= fls->cbyte; *lablen_r= lablen; @@ -101,19 +101,19 @@ adns_status adns__findlabel_next(findlabel_state fls, return adns_s_ok; x_serverfaulty: - adns__diag(ads,fls->serv,fls->qu,"label in domain runs beyond end of domain"); + adns__diag(fls->ads,fls->serv,fls->qu,"label in domain runs beyond end of domain"); return adns_s_serverfaulty; } -adns_status adns__parse_domain(adns_state ads, int serv, vbuf *vb, int flags, - 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) { findlabel_state fls; - int cbyte, lablen, labstart, namelen, i, ch; + int lablen, labstart, i, ch; adns_status st; - ands__findlabel_start(&fls,ads,serv, dgram,dglen,max, *cbyte_io,cbyte_io); + adns__findlabel_start(&fls,ads, serv,qu, dgram,dglen,max, *cbyte_io,cbyte_io); vb->used= 0; for (;;) { st= adns__findlabel_next(&fls,&lablen,&labstart); @@ -121,9 +121,9 @@ adns_status adns__parse_domain(adns_state ads, int serv, vbuf *vb, int flags, if (lablen<0) { vb->used=0; return adns_s_ok; } if (!lablen) break; if (vb->used) - if (!adns__vbuf_append(&qu->ans,".",1)) return adns_s_nolocalmem; + if (!adns__vbuf_append(vb,".",1)) return adns_s_nolocalmem; if (flags & adns_qf_anyquote) { - if (!vbuf__append_quoted1035(&qu->ans,dgram+labstart,lablen)) + if (!vbuf__append_quoted1035(vb,dgram+labstart,lablen)) return adns_s_nolocalmem; } else { if (!ctype_alpha(dgram[labstart])) return adns_s_invaliddomain; @@ -132,27 +132,21 @@ adns_status adns__parse_domain(adns_state ads, int serv, vbuf *vb, int flags, if (ch != '-' && !ctype_alpha(ch) && !ctype_digit(ch)) return adns_s_invaliddomain; } - if (!adns__vbuf_append(&qu->ans,dgram+labstart,lablen)) + if (!adns__vbuf_append(vb,dgram+labstart,lablen)) return adns_s_nolocalmem; } } - if (!adns__vbuf_append(&qu->ans,"",1)) return adns_s_nolocalmem; + if (!adns__vbuf_append(vb,"",1)) return adns_s_nolocalmem; return adns_s_ok; } -adns_status adns__findrr(adns_state ads, 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) { - /* 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 - * to the end of the RR). - * - * The type, class and RRdata length and start are returned iff - * the corresponding pointer variables are not null. type_r and - * class_r may not be null. +static adns_status findrr_intern(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) { + /* Like adns__findrr_checked, except that the datagram to compare + * with can be specified explicitly. * * 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 @@ -163,26 +157,20 @@ adns_status adns__findrr(adns_state ads, int serv, * 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 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. - * - * If an error is returned then *type_r will be undefined too. */ findlabel_state fls, eo_fls; int cbyte; int tmp, rdlen, mismatch; - int max, lablen, labstart, namelen, ch; - int eo_max, eo_lablen, eo_labstart, eo_namelen, eo_ch; + int lablen, labstart, ch; + int eo_lablen, eo_labstart, eo_ch; adns_status st; cbyte= *cbyte_io; - ands__findlabel_start(&fls,ads,serv, dgram,dglen,dglen,cbyte,&cbyte); + adns__findlabel_start(&fls,qu->ads, serv,qu, dgram,dglen,dglen,cbyte,&cbyte); if (eo_dgram) { - ands__findlabel_start(&eo_fls,ads,serv, eo_dgram,eo_dglen,eo_dglen,eo_cbyte,0); + adns__findlabel_start(&eo_fls,qu->ads, -1,0, eo_dgram,eo_dglen,eo_dglen,eo_cbyte,0); mismatch= 0; } else { mismatch= 1; @@ -221,3 +209,27 @@ adns_status adns__findrr(adns_state ads, int serv, *type_r= -1; return 0;; } + +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, + int *ownermatchedquery_r) { + if (!ownermatchedquery_r) { + return findrr_intern(qu,serv, + dgram,dglen,cbyte_io, + type_r,class_r,rdlen_r,rdstart_r, + 0,0,0, 0); + } else if (!qu->cname_dgram) { + return findrr_intern(qu,serv, + dgram,dglen,cbyte_io, + type_r,class_r,rdlen_r,rdstart_r, + qu->query_dgram,qu->query_dglen,DNS_HDRSIZE, + ownermatchedquery_r); + } else { + return findrr_intern(qu,serv, + dgram,dglen,cbyte_io, + type_r,class_r,rdlen_r,rdstart_r, + qu->cname_dgram,qu->cname_dglen,qu->cname_begin, + ownermatchedquery_r); + } +} diff --git a/src/query.c b/src/query.c index 7f65bc1..f8feef7 100644 --- a/src/query.c +++ b/src/query.c @@ -33,28 +33,24 @@ #include "internal.h" 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) { adns_query qu; - adns_status stat; - int ol, id, r; - struct timeval now; - const typeinfo *typei; - adns_query qu; qu= malloc(sizeof(*qu)); if (!qu) goto x_nomemory; qu->answer= malloc(sizeof(*qu->answer)); if (!qu->answer) goto x_freequ_nomemory; + qu->ads= ads; qu->state= query_udp; qu->back= qu->next= qu->parent= 0; LIST_INIT(qu->children); qu->siblings.next= qu->siblings.back= 0; qu->allocations= 0; qu->interim_allocd= 0; - qu->perm_used= 0; + qu->final_allocspace= 0; - qu->typei= adns__findtype(type); + qu->typei= typei; adns__vbuf_init(&qu->vb); qu->cname_dgram= 0; @@ -67,46 +63,39 @@ int adns__internal_submit(adns_state ads, adns_query *query_r, qu->udpsent= qu->tcpfailed= 0; timerclear(&qu->timeout); memcpy(&qu->context,ctx,sizeof(qu->context)); - memcpy(qu->owner,owner,ol); qu->owner[ol]= 0; qu->answer->status= adns_s_ok; qu->answer->cname= 0; - qu->answer->type= type; + qu->answer->type= typei->type; qu->answer->nrrs= 0; qu->answer->rrs= 0; - - if (qu->typei) { - qu->answer->rrsz= qu->rrsz; - } else { - qu->answer->rrsz= -1; - failstat= adns_s_notimplemented; - } + qu->answer->rrsz= typei->rrsz; *query_r= qu; qu->query_dgram= malloc(qumsg_vb->used); if (!qu->query_dgram) { - adns__query_fail(ads,qu,adns_s_nomemory); - return; + adns__query_fail(qu,adns_s_nolocalmem); + return adns_s_ok; } memcpy(qu->query_dgram,qumsg_vb->buf,qumsg_vb->used); qu->vb= *qumsg_vb; adns__vbuf_init(qumsg_vb); if (failstat) { - adns__query_fail(ads,qu,failstat); - return; + adns__query_fail(qu,failstat); + return adns_s_ok; } - adns__query_udp(ads,qu,now); + adns__query_udp(qu,now); adns__autosys(ads,now); - return 0; + return adns_s_ok; x_freequ_nomemory: free(qu); x_nomemory: - free(query_dgram); - return adns_s_nomemory; + adns__vbuf_free(qumsg_vb); + return adns_s_nolocalmem; } int adns_submit(adns_state ads, @@ -116,9 +105,15 @@ int adns_submit(adns_state ads, void *context, adns_query *query_r) { qcontext ctx; - int id; + int id, r, ol; vbuf vb; + adns_status stat; + const typeinfo *typei; + struct timeval now; + typei= adns__findtype(type); + if (!typei) return adns_s_notimplemented; + ctx.ext= context; r= gettimeofday(&now,0); if (r) return errno; id= 0; @@ -130,10 +125,10 @@ int adns_submit(adns_state ads, if (owner[ol-1]=='.' && owner[ol-2]!='\\') { flags &= ~adns_qf_search; ol--; } - stat= adns__mkquery(ads,&vb, &id, owner,ol, typei,flags); + stat= adns__mkquery(ads,&vb,&id, owner,ol, typei,flags); xit: - return adns__internal_submit(ads,query_r, type,&vb,id, flags,now, stat,&ctx); + return adns__internal_submit(ads,query_r, typei,&vb,id, flags,now, stat,&ctx); } int adns_synchronous(adns_state ads, @@ -150,25 +145,25 @@ int adns_synchronous(adns_state ads, do { r= adns_wait(ads,&qu,answer_r,0); } while (r==EINTR); - if (r) adns_cancel(ads,qu); + if (r) adns_cancel(qu); return r; } -void adns_cancel(adns_state ads, adns_query query) { +void adns_cancel(adns_query query) { abort(); /* fixme */ } -void *adns__alloc_interim(adns_state ads, adns_query qu, size_t sz) { +void *adns__alloc_interim(adns_query qu, size_t sz) { allocnode *an; assert(!qu->final_allocspace); sz= MEM_ROUND(sz); an= malloc(MEM_ROUND(MEM_ROUND(sizeof(*an)) + sz)); if (!an) { - adns__query_fail(ads,qu,adns_s_nolocalmem); + adns__query_fail(qu,adns_s_nolocalmem); return 0; } - qu->permalloclen += sz; + qu->interim_allocd += sz; an->next= qu->allocations; qu->allocations= an; return (byte*)an + MEM_ROUND(sizeof(*an)); @@ -190,14 +185,14 @@ void *adns__alloc_final(adns_query qu, size_t sz) { return rp; } -void adns__reset_cnameonly(adns_state ads, adns_query qu) { +void adns__reset_cnameonly(adns_query qu) { assert(qu->final_allocspace); qu->answer->nrrs= 0; qu->answer->rrs= 0; qu->interim_allocd= qu->answer->cname ? MEM_ROUND(strlen(qu->answer->cname)+1) : 0; } -static void adns__query_done(adns_state ads, adns_query qu) { +void adns__query_done(adns_query qu) { adns_answer *ans; allocnode *an, *ann; int i; @@ -211,7 +206,7 @@ static void adns__query_done(adns_state ads, adns_query qu) { if (ans->nrrs) { adns__makefinal_block(qu,&ans->rrs.untyped,ans->rrsz*ans->nrrs); for (i=0; inrrs; i++) - qu->typei->makefinal(ads,qu,ans->rrs.bytes+ans->rrsz*i); + qu->typei->makefinal(qu,ans->rrs.bytes+ans->rrsz*i); } for (an= qu->allocations; an; an= ann) { ann= an->next; free(an); } @@ -219,13 +214,13 @@ static void adns__query_done(adns_state ads, adns_query qu) { adns__vbuf_free(&qu->vb); qu->id= -1; - LIST_LINK_TAIL(ads->output,qu); + LIST_LINK_TAIL(qu->ads->output,qu); } -void adns__query_fail(adns_state ads, adns_query qu, adns_status stat) { - adns__reset_cnameonly(ads,qu); +void adns__query_fail(adns_query qu, adns_status stat) { + adns__reset_cnameonly(qu); qu->answer->status= stat; - adns__query_done(ads,qu); + adns__query_done(qu); } void adns__makefinal_str(adns_query qu, char **strp) { @@ -239,7 +234,7 @@ void adns__makefinal_str(adns_query qu, char **strp) { *strp= after; } -void adns__makefinal_block(adns__query qu, void **blpp, size_t sz) { +void adns__makefinal_block(adns_query qu, void **blpp, size_t sz) { void *after; after= adns__alloc_final(qu,sz); diff --git a/src/reply.c b/src/reply.c index 337d3f8..2317954 100644 --- a/src/reply.c +++ b/src/reply.c @@ -22,23 +22,23 @@ #include "internal.h" -static void cname_recurse(adns_state ads, adns_query qu, adns_queryflags xflags) { +static void cname_recurse(adns_query qu, adns_queryflags xflags) { abort(); /* FIXME */ } void adns__procdgram(adns_state ads, const byte *dgram, int dglen, int serv, struct timeval now) { int cbyte, rrstart, wantedrrs, rri, foundsoa, foundns; - int id, f1, f2, qdcount, ancount, nscount, arcount, flg_ra, flg_rd, flg_tc, opcode; - int rrtype, rrclass, rdlength, rdstart, ownermatched, ownerstart; + int id, f1, f2, qdcount, ancount, nscount, arcount; + int flg_ra, flg_rd, flg_tc, flg_qr, opcode; + int rrtype, rrclass, rdlength, rdstart, ownermatched, l; int anstart, nsstart, arstart; - int currentrrs; adns_query qu, nqu; dns_rcode rcode; adns_status st; if (dglen1) { - adns__diag(ads,serv,"server claimed to answer %d questions with one message", + adns__diag(ads,serv,0,"server claimed to answer %d questions with one message", qdcount); return; } for (qu= ads->timew.head; qu; qu= nqu) { nqu= qu->next; if (qu->id != id) continue; - if (dglen < qu->querylen) continue; - if (memcmp(qu->querymsg+DNS_HDRSIZE,dgram+DNS_HDRSIZE,qu->querylen-DNS_HDRSIZE)) + if (dglen < qu->query_dglen) continue; + if (memcmp(qu->query_dgram+DNS_HDRSIZE, + dgram+DNS_HDRSIZE, + qu->query_dglen-DNS_HDRSIZE)) continue; break; } - assert(qu->cnameoff == -1); - anstart= qu->querylen; + anstart= qu->query_dglen; if (!qu) { - adns__debug(ads,serv,"reply not found (id=%02x)",id); + adns__debug(ads,serv,0,"reply not found (id=%02x)",id); return; } @@ -97,22 +98,22 @@ void adns__procdgram(adns_state ads, const byte *dgram, int dglen, break; case rcode_formaterror: adns__warn(ads,serv,qu,"server cannot understand our query (Format Error)"); - adns__query_fail(ads,qu,adns_s_serverfaulty); + adns__query_fail(qu,adns_s_serverfaulty); return; case rcode_servfail: - adns__query_fail(ads,qu,adns_s_servfail); + adns__query_fail(qu,adns_s_servfail); return; case rcode_notimp: adns__warn(ads,serv,qu,"server claims not to implement our query"); - adns__query_fail(ads,qu,adns_s_notimplemented); + adns__query_fail(qu,adns_s_notimplemented); return; case rcode_refused: adns__warn(ads,serv,qu,"server refused our query"); - adns__query_fail(ads,qu,adns_s_refused); + adns__query_fail(qu,adns_s_refused); return; default: adns__warn(ads,serv,qu,"server gave unknown response code %d",rcode); - adns__query_fail(ads,qu,adns_s_reasonunknown); + adns__query_fail(qu,adns_s_reasonunknown); return; } @@ -122,16 +123,10 @@ void adns__procdgram(adns_state ads, const byte *dgram, int dglen, wantedrrs= 0; for (rri= 0; rricname_dgram >= 0) { - st= adns__findrr(ads,serv, dgram,dglen,&cbyte, - &rrtype,&rrclass,&rdlength,&rdstart, - qu->cname_dgram,qu->cname_dglen,qu->cname_begin, &ownermatched); - } else { - st= adns__findrr(ads,serv, dgram,dglen,&cbyte, - &rrtype,&rrclass,&rdlength,&rdstart, - qu->querymsg,qu->querylen,DNS_HDRSIZE, &ownermatched); - } - if (st) adns__query_fail(ads,qu,st); + st= adns__findrr(qu,serv, dgram,dglen,&cbyte, + &rrtype,&rrclass,&rdlength,&rdstart, + &ownermatched); + if (st) adns__query_fail(qu,st); if (rrtype == -1) goto x_truncated; if (rrclass != DNS_CLASS_IN) { @@ -142,23 +137,26 @@ void adns__procdgram(adns_state ads, const byte *dgram, int dglen, if (!ownermatched) { if (ads->iflags & adns_if_debug) { adns__debug(ads,serv,qu,"ignoring RR with an unexpected owner %s", - adns__diag_domain(ads,serv,&qu->vb,qu->flags, - dgram,dglen,rrstart,dglen)); + adns__diag_domain(ads,serv,qu, &qu->vb,qu->flags, + dgram,dglen,rrstart)); } continue; } if (rrtype == adns_r_cname && (qu->typei->type & adns__rrt_typemask) != adns_r_cname) { - if (!qu->cname_str) { /* Ignore second and subsequent CNAMEs */ + if (!qu->cname_dgram) { /* Ignore second and subsequent CNAMEs */ + qu->cname_dgram= adns__alloc_mine(qu,dglen); + if (!qu->cname_dgram) return; qu->cname_begin= rdstart; - qu->cname_dgram= dgram; qu->cname_dglen= dglen; - st= adns__parse_domain(ads,serv,&qu->vb,qu->flags, + st= adns__parse_domain(ads,serv,qu, &qu->vb,qu->flags, dgram,dglen, &rdstart,rdstart+rdlength); - if (!vb.used) goto x_truncated; - if (st) { adns__query_fail(ads,qu,st); return; } - qu->answer->cname= adns__savestring(qu); + if (!qu->vb.used) goto x_truncated; + if (st) { adns__query_fail(qu,st); return; } + l= strlen(qu->vb.buf)+1; + qu->answer->cname= adns__alloc_interim(qu,l); if (!qu->answer->cname) return; + memcpy(qu->answer->cname,qu->vb.buf,l); /* If we find the answer section truncated after this point we restart * the query at the CNAME; if beforehand then we obviously have to use * TCP. If there is no truncation we can use the whole answer if @@ -166,9 +164,9 @@ void adns__procdgram(adns_state ads, const byte *dgram, int dglen, */ } else { adns__debug(ads,serv,qu,"ignoring duplicate CNAME (%s, as well as %s)", - adns__diag_domain(ads,serv,&qu->vb,qu->flags, - dgram,dglen, rdstart,rdstart+rdlength), - qu->cname_str); + adns__diag_domain(ads,serv,qu, &qu->vb,qu->flags, + dgram,dglen,rdstart), + qu->answer->cname); } } else if (rrtype == (qu->typei->type & adns__rrt_typemask)) { wantedrrs++; @@ -184,7 +182,7 @@ void adns__procdgram(adns_state ads, const byte *dgram, int dglen, /* Oops, NODATA or NXDOMAIN or perhaps a referral (which would be a problem) */ if (rcode == rcode_nxdomain) { - adns__query_finish(ads,qu,adns_s_nxdomain); + adns__query_fail(qu,adns_s_nxdomain); return; } @@ -192,10 +190,9 @@ void adns__procdgram(adns_state ads, const byte *dgram, int dglen, foundsoa= 0; foundns= 0; for (rri= 0; rricname_dgram == dgram) { cname_recurse(ads,qu,0); return; } + if (qu->cname_dgram == dgram) { cname_recurse(qu,0); return; } /* Bloody hell, I thought we asked for recursion ? */ if (flg_rd) { @@ -226,41 +223,35 @@ void adns__procdgram(adns_state ads, const byte *dgram, int dglen, } if (!flg_ra) { adns__diag(ads,serv,qu,"server is not willing to do recursive lookups for us"); - adns__query_fail(ads,qu,adns_s_norecurse); + adns__query_fail(qu,adns_s_norecurse); } else { adns__diag(ads,serv,qu,"server claims to do recursion, but gave us a referral"); - adns__query_fail(ads,qu,adns_s_serverfaulty); + adns__query_fail(qu,adns_s_serverfaulty); } return; } /* Now, we have some RRs which we wanted. */ - qu->ans->rrs= adns__alloc_interim(qu,qu->typei->rrsz*wantedrrs); - if (!qu->ans->rrs) return; + qu->answer->rrs.untyped= adns__alloc_interim(qu,qu->typei->rrsz*wantedrrs); + if (!qu->answer->rrs.untyped) return; cbyte= anstart; arstart= -1; for (rri=0; rricname_dgram >= 0) { - st= adns__findrr(ads,serv, dgram,dglen,&cbyte, - &rrtype,&rrclass,&rdlength,&rdstart, - qu->cname_dgram,qu->cname_dglen,qu->cname_begin, &ownermatched); - } else { - st= adns__findrr(ads,serv, dgram,dglen,&cbyte, - &rrtype,&rrclass,&rdlength,&rdstart, - qu->querymsg,qu->querylen,DNS_HDRSIZE, &ownermatched); - } + st= adns__findrr(qu,serv, dgram,dglen,&cbyte, + &rrtype,&rrclass,&rdlength,&rdstart, + &ownermatched); assert(!st); assert(rrtype != -1); if (rrclass != DNS_CLASS_IN || rrtype != (qu->typei->type & adns__rrt_typemask) || !ownermatched) continue; - assert(qu->ans->nrrstypei->parse(ads,qu,serv, - dgram,dglen, &rdstart,rdstart+rdlength, - qu->ans->rrs.bytes+qu->ans->nrrs*quj->typei->rrsz); - if (st) { adns__query_fail(ads,qu,st); return; } + assert(qu->answer->nrrstypei->parse(qu,serv, + dgram,dglen, rdstart,rdstart+rdlength, + qu->answer->rrs.bytes+qu->answer->nrrs*qu->typei->rrsz); + if (st) { adns__query_fail(qu,st); return; } if (rdstart==-1) goto x_truncated; } @@ -271,17 +262,17 @@ void adns__procdgram(adns_state ads, const byte *dgram, int dglen, return; } - adns__query_finish(ads,qu,adns_s_ok); + adns__query_done(qu); return; x_truncated: if (!flg_tc) { adns__diag(ads,serv,qu,"server sent datagram which points outside itself"); - adns__query_fail(ads,qu,adns_s_serverfaulty); + adns__query_fail(qu,adns_s_serverfaulty); return; } - if (qu->cname_dgram) { cname_recurse(ads,qu,adns_qf_usevc); return; } - adns__reset_cnameonly(ads,qu); + if (qu->cname_dgram) { cname_recurse(qu,adns_qf_usevc); return; } + adns__reset_cnameonly(qu); qu->flags |= adns_qf_usevc; - adns__query_udp(ads,qu,now); + adns__query_udp(qu,now); } diff --git a/src/setup.c b/src/setup.c index 78b8fb3..3852603 100644 --- a/src/setup.c +++ b/src/setup.c @@ -38,13 +38,13 @@ static void addserver(adns_state ads, struct in_addr addr) { for (i=0; inservers; i++) { if (ads->servers[i].addr.s_addr == addr.s_addr) { - adns__debug(ads,-1,"duplicate nameserver %s ignored",inet_ntoa(addr)); + adns__debug(ads,-1,0,"duplicate nameserver %s ignored",inet_ntoa(addr)); return; } } if (ads->nservers>=MAXSERVERS) { - adns__diag(ads,-1,"too many nameservers, ignoring %s",inet_ntoa(addr)); + adns__diag(ads,-1,0,"too many nameservers, ignoring %s",inet_ntoa(addr)); return; } @@ -73,22 +73,22 @@ static void ccf_nameserver(adns_state ads, const char *fn, int lno, const char * configparseerr(ads,fn,lno,"invalid nameserver address `%s'",buf); return; } - adns__debug(ads,-1,"using nameserver %s",inet_ntoa(ia)); + adns__debug(ads,-1,0,"using nameserver %s",inet_ntoa(ia)); addserver(ads,ia); } static void ccf_search(adns_state ads, const char *fn, int lno, const char *buf) { if (!buf) return; - adns__diag(ads,-1,"warning - `search' ignored fixme"); + adns__diag(ads,-1,0,"warning - `search' ignored fixme"); } static void ccf_sortlist(adns_state ads, const char *fn, int lno, const char *buf) { - adns__diag(ads,-1,"warning - `sortlist' ignored fixme"); + adns__diag(ads,-1,0,"warning - `sortlist' ignored fixme"); } static void ccf_options(adns_state ads, const char *fn, int lno, const char *buf) { if (!buf) return; - adns__diag(ads,-1,"warning - `options' ignored fixme"); + adns__diag(ads,-1,0,"warning - `options' ignored fixme"); } static void ccf_clearnss(adns_state ads, const char *fn, int lno, const char *buf) { @@ -117,10 +117,10 @@ static void readconfig(adns_state ads, const char *filename) { file= fopen(filename,"r"); if (!file) { if (errno == ENOENT) { - adns__debug(ads,-1,"configuration file `%s' does not exist",filename); + adns__debug(ads,-1,0,"configuration file `%s' does not exist",filename); return; } - adns__diag(ads,-1,"cannot open configuration file `%s': %s", + adns__diag(ads,-1,0,"cannot open configuration file `%s': %s", filename,strerror(errno)); return; } @@ -129,7 +129,7 @@ static void readconfig(adns_state ads, const char *filename) { l= strlen(linebuf); if (!l) continue; if (linebuf[l-1] != '\n' && !feof(file)) { - adns__diag(ads,-1,"%s:%d: line too long",filename,lno); + adns__diag(ads,-1,0,"%s:%d: line too long",filename,lno); while ((c= getc(file)) != EOF && c != '\n') { } if (c == EOF) break; continue; @@ -145,7 +145,7 @@ static void readconfig(adns_state ads, const char *filename) { ccip->name && strncmp(ccip->name,p,q-p); ccip++); if (!ccip->name) { - adns__diag(ads,-1,"%s:%d: unknown configuration directive `%.*s'", + adns__diag(ads,-1,0,"%s:%d: unknown configuration directive `%.*s'", filename,lno,q-p,p); continue; } @@ -153,7 +153,7 @@ static void readconfig(adns_state ads, const char *filename) { ccip->fn(ads,filename,lno,q); } if (ferror(file)) { - adns__diag(ads,-1,"%s:%d: read error: %s",filename,lno,strerror(errno)); + adns__diag(ads,-1,0,"%s:%d: read error: %s",filename,lno,strerror(errno)); } fclose(file); } @@ -162,8 +162,8 @@ static const char *instrum_getenv(adns_state ads, const char *envvar) { const char *value; value= getenv(envvar); - if (!value) adns__debug(ads,-1,"environment variable %s not set",envvar); - else adns__debug(ads,-1,"environment variable %s set to `%s'",envvar,value); + if (!value) adns__debug(ads,-1,0,"environment variable %s not set",envvar); + else adns__debug(ads,-1,0,"environment variable %s set to `%s'",envvar,value); return value; } @@ -171,7 +171,7 @@ static void readconfigenv(adns_state ads, const char *envvar) { const char *filename; if (ads->iflags & adns_if_noenv) { - adns__debug(ads,-1,"not checking environment variable `%s'",envvar); + adns__debug(ads,-1,0,"not checking environment variable `%s'",envvar); return; } filename= instrum_getenv(ads,envvar); @@ -202,7 +202,6 @@ int adns_init(adns_state *ads_r, adns_initflags flags, FILE *diagfile) { LIST_INIT(ads->output); ads->nextid= 0x311f; ads->udpsocket= ads->tcpsocket= -1; - adns__vbuf_init(&ads->rqbuf); adns__vbuf_init(&ads->tcpsend); adns__vbuf_init(&ads->tcprecv); ads->nservers= ads->tcpserver= 0; diff --git a/src/transmit.c b/src/transmit.c index 2633bdc..cac933a 100644 --- a/src/transmit.c +++ b/src/transmit.c @@ -21,10 +21,15 @@ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include +#include + +#include + #include "internal.h" -adns_status adns__mkquery(adns_state ads, vbuf *vb, - const char *owner, int ol, int *id_r, +adns_status adns__mkquery(adns_state ads, vbuf *vb, int *id_r, + const char *owner, int ol, const typeinfo *typei, adns_queryflags flags) { int ll, c, nlabs, id; byte label[255], *rqp; @@ -92,16 +97,18 @@ adns_status adns__mkquery(adns_state ads, vbuf *vb, return adns_s_ok; } -void adns__query_tcp(adns_state ads, adns_query qu, struct timeval now) { +void adns__query_tcp(adns_query qu, struct timeval now) { byte length[2]; struct iovec iov[2]; int wr, r; + adns_state ads; - if (ads->tcpstate != server_ok) return; + if (qu->ads->tcpstate != server_ok) return; length[0]= (qu->query_dglen&0x0ff00U) >>8; length[1]= (qu->query_dglen&0x0ff); - + + ads= qu->ads; if (!adns__vbuf_ensure(&ads->tcpsend,ads->tcpsend.used+qu->query_dglen+2)) return; timevaladd(&now,TCPMS); @@ -116,7 +123,7 @@ void adns__query_tcp(adns_state ads, adns_query qu, struct timeval now) { iov[0].iov_len= 2; iov[1].iov_base= qu->query_dgram; iov[1].iov_len= qu->query_dglen; - wr= writev(ads->tcpsocket,iov,2); + wr= writev(qu->ads->tcpsocket,iov,2); if (wr < 0) { if (!(errno == EAGAIN || errno == EINTR || errno == ENOSPC || errno == ENOBUFS || errno == ENOMEM)) { @@ -138,38 +145,41 @@ void adns__query_tcp(adns_state ads, adns_query qu, struct timeval now) { } } -static void query_usetcp(adns_state ads, adns_query qu, struct timeval now) { +static void query_usetcp(adns_query qu, struct timeval now) { timevaladd(&now,TCPMS); qu->timeout= now; qu->state= query_tcpwait; - LIST_LINK_TAIL(ads->timew,qu); - adns__query_tcp(ads,qu,now); - adns__tcp_tryconnect(ads,now); + LIST_LINK_TAIL(qu->ads->timew,qu); + adns__query_tcp(qu,now); + adns__tcp_tryconnect(qu->ads,now); } -void adns__query_udp(adns_state ads, adns_query qu, struct timeval now) { +void adns__query_udp(adns_query qu, struct timeval now) { struct sockaddr_in servaddr; int serv, r; + adns_state ads; assert(qu->state == query_udp); if ((qu->flags & adns_qf_usevc) || (qu->query_dglen > DNS_MAXUDP)) { - query_usetcp(ads,qu,now); + query_usetcp(qu,now); return; } if (qu->udpretries >= UDPMAXRETRIES) { - adns__query_fail(ads,qu,adns_s_timeout); + adns__query_fail(qu,adns_s_timeout); return; } serv= qu->udpnextserver; memset(&servaddr,0,sizeof(servaddr)); + + ads= qu->ads; servaddr.sin_family= AF_INET; servaddr.sin_addr= ads->servers[serv].addr; servaddr.sin_port= htons(DNS_PORT); r= sendto(ads->udpsocket,qu->query_dgram,qu->query_dglen,0,&servaddr,sizeof(servaddr)); - if (r<0 && errno == EMSGSIZE) { query_usetcp(ads,qu,now); return; } + if (r<0 && errno == EMSGSIZE) { query_usetcp(qu,now); return; } if (r<0) adns__warn(ads,serv,0,"sendto failed: %s",strerror(errno)); timevaladd(&now,UDPRETRYMS);