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).
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; qi<qc; qi++) {
- r= adns_submit(ads,argv[qi],adns_r_a,0,0,&qus[qi]);
- if (r) failure("submit",r);
+ for (ti=0; ti<tc; ti++) {
+ fprintf(stdout,"submitting %s %d\n",argv[qi],types[ti]);
+ r= adns_submit(ads,argv[qi],types[ti],0,0,&qus[qi*tc+ti]);
+ if (r) failure("submit",r);
+ }
}
for (qi=0; qi<qc; qi++) {
- qu= qus[qi];
- r= adns_wait(ads,&qu,&ans,0);
- if (r) failure("wait",r);
+ for (ti=0; ti<tc; ti++) {
+ qu= qus[qi*tc+ti];
+ r= adns_wait(ads,&qu,&ans,0);
+ if (r) failure("wait",r);
- 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; i<ans->nrrs; 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; i<ans->nrrs; 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);
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;
* 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.
*/
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;
union {
void *untyped;
unsigned char *bytes;
- char *(*str); /* ns_raw, cname, ptr, ptr_raw, txt, <any>_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;
} 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);
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));
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) {
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; i<labstart+lablen; i++) {
ch= dgram[i];
if (ch != '-' && !ctype_alpha(ch) && !ctype_digit(ch))
- return adns_s_invaliddomain;
+ return adns_s_invalidanswerdomain;
}
if (!adns__vbuf_append(vb,dgram+labstart,lablen))
return adns_s_nolocalmem;
adns__vbuf_init(&vb);
ol= strlen(owner);
- if (ol<=1 || ol>DNS_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--; }
#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,
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);
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><nf>
* ms is M specify member name
/* 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 },