From ffbda80c54147d112c125f208f6611daf09358b3 Mon Sep 17 00:00:00 2001 From: ian Date: Tue, 10 Nov 1998 02:09:32 +0000 Subject: [PATCH] Remove NULL queries. Remove _mf queries (master file format conversion). Split invaliddomain error into invalidquerydomain and invalidanswerdomain. Make several query types in test program. Implement ns_raw, ptr_raw, cname queries (but not cname-following). --- client/adnstest.c | 61 ++++++++++++++++++++++++++++++----------------- src/adns.h | 21 +++------------- src/event.c | 12 +++++----- src/general.c | 37 ++++++++++++++-------------- src/parse.c | 5 ++-- src/query.c | 2 +- src/reply.c | 3 ++- src/transmit.c | 24 +++++++++---------- src/types.c | 61 ++++++++++++++++++++++++++++++++++++++++------- 9 files changed, 138 insertions(+), 88 deletions(-) diff --git a/client/adnstest.c b/client/adnstest.c index 46a0258..56cf45f 100644 --- a/client/adnstest.c +++ b/client/adnstest.c @@ -34,52 +34,69 @@ static void failure(const char *what, adns_status st) { static const char *defaultargv[]= { "ns.chiark.greenend.org.uk", 0 }; +static const adns_rrtype defaulttypes[]= { + adns_r_a, + adns_r_ns_raw, + adns_r_cname, + adns_r_ptr_raw, + adns_r_none +}; + int main(int argc, const char *const *argv) { adns_state ads; adns_query *qus, qu; adns_answer *ans; const char *rrtn, *fmtn; char *show; - int len, i, qc, qi; + int len, i, qc, qi, tc, ti; adns_status r, ri; + const adns_rrtype *types; if (argv[0] && argv[1]) argv++; else argv= defaultargv; + types= defaulttypes; + for (qc=0; qc[argv]; qc++); - qus= malloc(sizeof(qus)*qc); + for (tc=0; types[tc] != adns_r_none; tc++); + qus= malloc(sizeof(qus)*qc*tc); if (!qus) { perror("malloc qus"); exit(3); } r= adns_init(&ads,adns_if_debug|adns_if_noautosys,0); if (r) failure("init",r); for (qi=0; qitype, &rrtn,&fmtn,&len, 0,0); - fprintf(stdout, "%s: %s; nrrs=%d; cname=%s; ", - argv[qi], adns_strerror(ans->status), - ans->nrrs, ans->cname ? ans->cname : "$"); - fprintf(stdout, "type %s(%s) %s\n", - ri ? "?" : rrtn, ri ? "?" : fmtn ? fmtn : "-", - adns_strerror(ri)); - if (ans->nrrs) { - assert(!ri); - for (i=0; inrrs; i++) { - r= adns_rr_info(ans->type, 0,0,0, ans->rrs.bytes+i*len,&show); - if (r) failure("info",r); - printf(" %s\n",show); - free(show); + ri= adns_rr_info(ans->type, &rrtn,&fmtn,&len, 0,0); + fprintf(stdout, "%s: %s; nrrs=%d; cname=%s; ", + argv[qi], adns_strerror(ans->status), + ans->nrrs, ans->cname ? ans->cname : "$"); + fprintf(stdout, "type %s(%s) %s\n", + ri ? "?" : rrtn, ri ? "?" : fmtn ? fmtn : "-", + adns_strerror(ri)); + if (ans->nrrs) { + assert(!ri); + for (i=0; inrrs; i++) { + r= adns_rr_info(ans->type, 0,0,0, ans->rrs.bytes+i*len,&show); + if (r) failure("info",r); + printf(" %s\n",show); + free(show); + } } + free(ans); } - free(ans); } free(qus); diff --git a/src/adns.h b/src/adns.h index a800813..5e8cf80 100644 --- a/src/adns.h +++ b/src/adns.h @@ -53,44 +53,31 @@ typedef enum { adns__rrt_typemask= 0x0ffff, adns__qtf_deref= 0x10000, /* dereference domains and perhaps produce extra data */ adns__qtf_mail822= 0x20000, /* make mailboxes be in RFC822 rcpt field format */ - adns__qtf_masterfmt= 0x80000, /* convert RRs to master file format, return as str */ adns_r_none= 0, adns_r_a= 1, - adns_r_a_mf= adns_r_a|adns__qtf_masterfmt, adns_r_ns_raw= 2, adns_r_ns= adns_r_ns_raw|adns__qtf_deref, - adns_r_ns_mf= adns_r_ns_raw|adns__qtf_masterfmt, adns_r_cname= 5, - adns_r_cname_mf= adns_r_cname|adns__qtf_masterfmt, adns_r_soa_raw= 6, adns_r_soa= adns_r_soa_raw|adns__qtf_mail822, - adns_r_soa_mf= adns_r_soa_raw|adns__qtf_masterfmt, - - adns_r_null= 10, - adns_r_null_mf= adns_r_null|adns__qtf_masterfmt, adns_r_ptr_raw= 12, adns_r_ptr= adns_r_ptr_raw|adns__qtf_deref, - adns_r_ptr_mf= adns_r_ptr_raw|adns__qtf_masterfmt, adns_r_hinfo= 13, - adns_r_hinfo_mf= adns_r_hinfo|adns__qtf_masterfmt, adns_r_mx_raw= 15, adns_r_mx= adns_r_mx_raw|adns__qtf_deref, - adns_r_mx_mf= adns_r_mx_raw|adns__qtf_masterfmt, adns_r_txt= 16, - adns_r_txt_mf= adns_r_txt|adns__qtf_masterfmt, adns_r_rp_raw= 17, adns_r_rp= adns_r_rp_raw|adns__qtf_mail822, - adns_r_rp_mf= adns_r_rp_raw|adns__qtf_masterfmt } adns_rrtype; @@ -104,8 +91,6 @@ typedef enum { * not usually legal in domain names will be quoted as \X * (if the character is 33-126 except \ and ") or \DDD. * - * _qtf_anyquote is ignored for _mf queries. - * * Do not ask for _raw records containing mailboxes without * specifying _qf_anyquote. */ @@ -126,11 +111,12 @@ typedef enum { adns_s_max_tempfail= 99, adns_s_inconsistent, /* PTR gives domain whose A does not match */ adns_s_cname, /* CNAME found where data eg A expected (not if _qf_loosecname) */ + adns_s_invalidanswerdomain, /* fixme: implement _s_cname */ adns_s_max_remotemisconfig= 199, adns_s_nxdomain, adns_s_nodata, - adns_s_invaliddomain, + adns_s_invalidquerydomain, adns_s_domaintoolong, } adns_status; @@ -168,14 +154,13 @@ typedef struct { union { void *untyped; unsigned char *bytes; - char *(*str); /* ns_raw, cname, ptr, ptr_raw, txt, _mf */ + char *(*str); /* ns_raw, cname, ptr, ptr_raw, txt */ struct in_addr *inaddr; /* a */ adns_rr_dmaddr *dmaddr; /* ns */ adns_rr_strpair *strpair; /* hinfo, rp, rp_raw */ adns_rr_intdmaddr *intdmaddr; /* mx */ adns_rr_intstr *intstr; /* mx_raw */ adns_rr_soa *soa; /* soa, soa_raw */ - /* NULL is empty */ } rrs; } adns_answer; diff --git a/src/event.c b/src/event.c index 8329ff4..778c776 100644 --- a/src/event.c +++ b/src/event.c @@ -125,16 +125,16 @@ static void inter_maxto(struct timeval **tv_io, struct timeval *tvbuf, } else { if (timercmp(rbuf,&maxto,>)) *rbuf= maxto; } -fprintf(stderr,"inter_maxto maxto=%ld.%06ld result=%ld.%06ld\n", - maxto.tv_sec,maxto.tv_usec,(**tv_io).tv_sec,(**tv_io).tv_usec); +/*fprintf(stderr,"inter_maxto maxto=%ld.%06ld result=%ld.%06ld\n", + maxto.tv_sec,maxto.tv_usec,(**tv_io).tv_sec,(**tv_io).tv_usec);*/ } static void inter_maxtoabs(struct timeval **tv_io, struct timeval *tvbuf, struct timeval now, struct timeval maxtime) { ldiv_t dr; -fprintf(stderr,"inter_maxtoabs now=%ld.%06ld maxtime=%ld.%06ld\n", - now.tv_sec,now.tv_usec,maxtime.tv_sec,maxtime.tv_usec); +/*fprintf(stderr,"inter_maxtoabs now=%ld.%06ld maxtime=%ld.%06ld\n", + now.tv_sec,now.tv_usec,maxtime.tv_sec,maxtime.tv_usec);*/ if (!tv_io) return; maxtime.tv_sec -= (now.tv_sec+2); maxtime.tv_usec -= (now.tv_usec-2000000); @@ -177,9 +177,9 @@ void adns_interest(adns_state ads, int *maxfd, struct timeval tvto_lr; int r; -fprintf(stderr,"adns_interest\n"); +/*fprintf(stderr,"adns_interest\n");*/ -r= gettimeofday(&now,0); + r= gettimeofday(&now,0); if (r) { adns__warn(ads,-1,0,"gettimeofday failed - will sleep for a bit: %s", strerror(errno)); diff --git a/src/general.c b/src/general.c index 37edfa3..3f4c8c8 100644 --- a/src/general.c +++ b/src/general.c @@ -199,24 +199,25 @@ static const struct sinfo { adns_status st; const char *string; } sinfos[]= { - SINFO( ok, "OK" ), - SINFO( timeout, "Timed out" ), - SINFO( nolocalmem, "Out of memory" ), - SINFO( allservfail, "No working nameservers" ), - SINFO( servfail, "Nameserver failure" ), - SINFO( notimplemented, "Query not implemented" ), - SINFO( refused, "Refused by nameserver" ), - SINFO( reasonunknown, "Reason unknown" ), - SINFO( norecurse, "Recursion denied by nameserver" ), - SINFO( serverfaulty, "Nameserver sent bad data" ), - SINFO( unknownreply, "Reply from nameserver not understood" ), - SINFO( invaliddata, "Invalid data" ), - SINFO( inconsistent, "Inconsistent data" ), - SINFO( cname, "RR refers to an alias" ), - SINFO( nxdomain, "No such domain" ), - SINFO( nodata, "No such data" ), - SINFO( invaliddomain, "Domain syntactically invalid" ), - SINFO( domaintoolong, "Domain name too long" ) + SINFO( ok, "OK" ), + SINFO( timeout, "Timed out" ), + SINFO( nolocalmem, "Out of memory" ), + SINFO( allservfail, "No working nameservers" ), + SINFO( servfail, "Nameserver failure" ), + SINFO( notimplemented, "Query not implemented" ), + SINFO( refused, "Refused by nameserver" ), + SINFO( reasonunknown, "Reason unknown" ), + SINFO( norecurse, "Recursion denied by nameserver" ), + SINFO( serverfaulty, "Nameserver sent bad data" ), + SINFO( unknownreply, "Reply from nameserver not understood" ), + SINFO( invaliddata, "Invalid data" ), + SINFO( inconsistent, "Inconsistent data" ), + SINFO( cname, "RR refers to an alias" ), + SINFO( invalidanswerdomain, "Received syntactically invalid domain" ), + SINFO( nxdomain, "No such domain" ), + SINFO( nodata, "No such data" ), + SINFO( invalidquerydomain, "Domain syntactically invalid" ), + SINFO( domaintoolong, "Domain name too long" ) }; static int si_compar(const void *key, const void *elem) { diff --git a/src/parse.c b/src/parse.c index 46d76fa..d516d24 100644 --- a/src/parse.c +++ b/src/parse.c @@ -131,11 +131,12 @@ adns_status adns__parse_domain(adns_state ads, int serv, adns_query qu, if (!vbuf__append_quoted1035(vb,dgram+labstart,lablen)) return adns_s_nolocalmem; } else { - if (!ctype_alpha(dgram[labstart])) return adns_s_invaliddomain; + ch= dgram[labstart]; + if (!ctype_alpha(ch) && !ctype_digit(ch)) return adns_s_invalidanswerdomain; for (i= labstart+1; iDNS_MAXDOMAIN+1) { stat= adns_s_invaliddomain; goto xit; } + if (ol<=1 || ol>DNS_MAXDOMAIN+1) { stat= adns_s_domaintoolong; goto xit; } if (owner[ol-1]=='.' && owner[ol-2]!='\\') { flags &= ~adns_qf_search; ol--; } diff --git a/src/reply.c b/src/reply.c index 5ed6581..673196e 100644 --- a/src/reply.c +++ b/src/reply.c @@ -23,7 +23,8 @@ #include "internal.h" static void cname_recurse(adns_query qu, adns_queryflags xflags) { - assert(!"cname not implemented"); /* FIXME */ + adns__diag(qu->ads,-1,qu,"cname following not implemented fixme"); + adns__query_fail(qu,adns_s_notimplemented); } void adns__procdgram(adns_state ads, const byte *dgram, int dglen, diff --git a/src/transmit.c b/src/transmit.c index cac933a..c3ae94d 100644 --- a/src/transmit.c +++ b/src/transmit.c @@ -54,35 +54,35 @@ adns_status adns__mkquery(adns_state ads, vbuf *vb, int *id_r, MKQUERY_ADDW(0); /* ARCOUNT=0 */ p= owner; pe= owner+ol; nlabs= 0; - if (!*p) return adns_s_invaliddomain; + if (!*p) return adns_s_invalidquerydomain; do { ll= 0; while (p!=pe && (c= *p++)!='.') { if (c=='\\') { - if (!(flags & adns_qf_anyquote)) return adns_s_invaliddomain; + if (!(flags & adns_qf_anyquote)) return adns_s_invalidquerydomain; if (ctype_digit(p[0])) { if (ctype_digit(p[1]) && ctype_digit(p[2])) { c= (*p++ - '0')*100 + (*p++ - '0')*10 + (*p++ - '0'); - if (c >= 256) return adns_s_invaliddomain; + if (c >= 256) return adns_s_invalidquerydomain; } else { - return adns_s_invaliddomain; + return adns_s_invalidquerydomain; } } else if (!(c= *p++)) { - return adns_s_invaliddomain; + return adns_s_invalidquerydomain; } } if (!(flags & adns_qf_anyquote)) { - if (ctype_digit(c) || c == '-') { - if (!ll) return adns_s_invaliddomain; - } else if (!ctype_alpha(c)) { - return adns_s_invaliddomain; + if (c == '-') { + if (!ll) return adns_s_invalidquerydomain; + } else if (!ctype_alpha(c) && !ctype_digit(c)) { + return adns_s_invalidquerydomain; } } - if (ll == sizeof(label)) return adns_s_invaliddomain; + if (ll == sizeof(label)) return adns_s_invalidquerydomain; label[ll++]= c; } - if (!ll) return adns_s_invaliddomain; - if (nlabs++ > 63) return adns_s_invaliddomain; + if (!ll) return adns_s_invalidquerydomain; + if (nlabs++ > 63) return adns_s_domaintoolong; MKQUERY_ADDB(ll); memcpy(rqp,label,ll); rqp+= ll; } while (p!=pe); diff --git a/src/types.c b/src/types.c index 436cc87..66f7f52 100644 --- a/src/types.c +++ b/src/types.c @@ -42,17 +42,61 @@ static adns_status cs_inaddr(vbuf *vb, const void *data) { return adns__vbuf_appendstr(vb,ia) ? adns_s_ok : adns_s_nolocalmem; } -static void fr_null(adns_query qu, void *data) { } +static adns_status pa_domain_raw(adns_query qu, int serv, + const byte *dgram, int dglen, int cbyte, int max, + void *store_r) { + char **dpp= store_r; + adns_status st; + vbuf vb; + char *dp; -#define TYPE_SF(size,func,cp,free) size, pa_##func, fr_##free, cs_##cp -#define TYPE_SN(size,func,cp) size, pa_##func, fr_null, cs_##cp + adns__vbuf_init(&vb); + st= adns__parse_domain(qu->ads,serv,qu,&vb,qu->flags, + dgram,dglen, &cbyte,max); + if (st) goto x_error; + + dp= adns__alloc_interim(qu,vb.used+1); + if (!dp) { st= adns_s_nolocalmem; goto x_error; } + + dp[vb.used]= 0; + memcpy(dp,vb.buf,vb.used); + + if (cbyte != max) { st= adns_s_invaliddata; goto x_error; } + + st= adns_s_ok; + *dpp= dp; + + x_error: + adns__vbuf_free(&vb); + return st; +} + +static void mf_str(adns_query qu, void *data) { + char **ddp= data; + + adns__makefinal_str(qu,ddp); +} + +static adns_status cs_str(vbuf *vb, const void *data) { + const char *const *ddp= data; + const char *dp= *ddp; + + return (adns__vbuf_append(vb,"\"",1) && + adns__vbuf_appendstr(vb,dp) && + adns__vbuf_append(vb,"\"",1)) + ? adns_s_ok : adns_s_nolocalmem; +} + +static void mf_flat(adns_query qu, void *data) { } + +#define TYPE_SF(size,func,cp,free) size, pa_##func, mf_##free, cs_##cp +#define TYPE_SN(size,func,cp) size, pa_##func, mf_flat, cs_##cp #define TYPESZ_M(member) (sizeof(((adns_answer*)0)->rrs.member)) #define TYPE_MF(memb,parse) TYPE_SF(TYPESZ_M(memb),parse,memb,memb) #define TYPE_MN(memb,parse) TYPE_SN(TYPESZ_M(memb),parse,memb) -#define DEEP_MEMB(memb) TYPESZ_M(memb), fr_##memb, cs_##memb -#define FLAT_MEMB(memb) TYPESZ_M(memb), fr_null, cs_##memb -#define NULL_MEMB 0, fr_null, cs_null +#define DEEP_MEMB(memb) TYPESZ_M(memb), mf_##memb, cs_##memb +#define FLAT_MEMB(memb) TYPESZ_M(memb), mf_flat, cs_##memb /* TYPE_ * ms is M specify member name @@ -66,12 +110,13 @@ static const typeinfo typeinfos[] = { /* rr type code rrt fmt mem.mgmt member parser */ { adns_r_a, "A", 0, FLAT_MEMB(inaddr), pa_inaddr }, -#if 0 /*fixme*/ { adns_r_ns_raw, "NS", "raw", DEEP_MEMB(str), pa_domain_raw }, { adns_r_cname, "CNAME", 0, DEEP_MEMB(str), pa_domain_raw }, +#if 0 /*fixme*/ { adns_r_soa_raw, "SOA", "raw", DEEP_MEMB(soa), pa_soa }, - { adns_r_null, "NULL", 0, NULL_MEMB, pa_null }, +#endif { adns_r_ptr_raw, "PTR", "raw", DEEP_MEMB(str), pa_domain_raw }, +#if 0 /*fixme*/ { adns_r_hinfo, "HINFO", 0, DEEP_MEMB(strpair), pa_hinfo }, { adns_r_mx_raw, "MX", "raw", DEEP_MEMB(intstr), pa_mx_raw }, { adns_r_txt, "TXT", 0, DEEP_MEMB(str), pa_txt }, -- 2.30.2