struct timeval now;
} parseinfo;
+union checklabel_state {
+ int dummy;
+};
+
typedef struct {
void *ext;
void (*callback)(adns_query parent, adns_query child);
* 0 otherwise. Must not fail.
*/
- adns_status (*qdparselabel)(adns_state ads,
- const char **p_io, const char *pe, int labelnum,
- char label_r[DNS_MAXDOMAIN], int *ll_io,
- adns_queryflags flags,
- const struct typeinfo *typei);
- /* Parses one label from the query domain string. On entry, *p_io
- * points to the next character to parse and *ll_io is the size of
- * the buffer. pe points just after the end of the query domain
- * string. On successful return, label_r[] and *ll_io are filled in
- * and *p_io points to *pe or just after the label-ending `.'. */
+ adns_status (*checklabel)(adns_state ads, adns_queryflags flags,
+ union checklabel_state *cls, qcontext *ctx,
+ int labnum, const char *label, int lablen);
+ /* Check a label from the query domain string. The label is not
+ * necessarily null-terminated. The hook can refuse the query's submission
+ * by returning a nonzero status. State can be stored in *cls between
+ * calls, and useful information can be stashed in ctx->tinfo, to be stored
+ * with the query (e.g., it will be available to the parse hook). This
+ * hook can detect a first call because labnum is zero, and a final call
+ * because lablen is zero.
+ */
void (*postsort)(adns_state ads, void *array, int nrrs,
const struct typeinfo *typei);
*/
} typeinfo;
-adns_status adns__qdpl_normal(adns_state ads,
- const char **p_io, const char *pe, int labelnum,
- char label_r[], int *ll_io,
- adns_queryflags flags,
- const typeinfo *typei);
- /* implemented in transmit.c, used by types.c as default
- * and as part of implementation for some fancier types */
+adns_status adns__ckl_hostname(adns_state ads, adns_queryflags flags,
+ union checklabel_state *cls,
+ qcontext *ctx, int labnum,
+ const char *label, int lablen);
+ /* implemented in query.c, used by types.c as default
+ * and as part of implementation for some fancier types
+ * doesn't require any state */
typedef struct allocnode {
struct allocnode *next, *back;
adns__query_send(qu,now);
}
+adns_status adns__ckl_hostname(adns_state ads, adns_queryflags flags,
+ union checklabel_state *cls,
+ qcontext *ctx, int labnum,
+ const char *label, int lablen)
+{
+ int i, c;
+
+ if (flags & adns_qf_quoteok_query) return adns_s_ok;
+ for (i=0; i<lablen; i++) {
+ c= label[i];
+ if (c == '-') {
+ if (!i) return adns_s_querydomaininvalid;
+ } else if (!ctype_alpha(c) && !ctype_digit(c)) {
+ return adns_s_querydomaininvalid;
+ }
+ }
+ return adns_s_ok;
+}
+
+static adns_status check_domain_name(adns_state ads, adns_queryflags flags,
+ qcontext *ctx, const typeinfo *typei,
+ const byte *dgram, int dglen)
+{
+ findlabel_state fls;
+ adns_status err;
+ int labnum= 0, labstart, lablen;
+ union checklabel_state cls;
+
+ adns__findlabel_start(&fls,ads, -1,0, dgram,dglen,dglen, DNS_HDRSIZE,0);
+ do {
+ err= adns__findlabel_next(&fls, &lablen,&labstart);
+ assert(!err); assert(lablen >= 0);
+ err= typei->checklabel(ads,flags, &cls,ctx,
+ labnum++, dgram+labstart,lablen);
+ if (err) return err;
+ } while (lablen);
+ return adns_s_ok;
+}
+
adns_status adns__internal_submit(adns_state ads, adns_query *query_r,
const typeinfo *typei, vbuf *qumsg_vb,
int id,
adns_queryflags flags, struct timeval now,
qcontext *ctx) {
adns_query qu;
+ adns_status err;
+ err= check_domain_name(ads, flags,ctx,typei, qumsg_vb->buf,qumsg_vb->used);
+ if (err) goto x_err;
qu= query_alloc(ads,typei,typei->typekey,flags,now);
- if (!qu) { adns__vbuf_free(qumsg_vb); return adns_s_nomemory; }
+ if (!qu) { err = adns_s_nomemory; goto x_err; }
*query_r= qu;
memcpy(&qu->ctx,ctx,sizeof(qu->ctx));
query_submit(ads,qu, typei,qumsg_vb,id,flags,now);
return adns_s_ok;
+
+x_err:
+ adns__vbuf_free(qumsg_vb);
+ return err;
}
static void query_simple(adns_state ads, adns_query qu,
}
}
+ stat= check_domain_name(ads, flags,&qu->ctx,typei, qu->vb.buf,qu->vb.used);
+ if (stat) { adns__query_fail(qu,stat); return; }
+
vb_new= qu->vb;
adns__vbuf_init(&qu->vb);
query_submit(ads,qu, typei,&vb_new,id, flags,now);
return adns_s_ok;
}
-adns_status adns__qdpl_normal(adns_state ads,
- const char **p_io, const char *pe, int labelnum,
- char label_r[], int *ll_io,
- adns_queryflags flags,
- const typeinfo *typei) {
+static adns_status qdparselabel(adns_state ads,
+ const char **p_io, const char *pe,
+ char label_r[], int *ll_io,
+ adns_queryflags flags) {
int ll, c;
const char *p;
return adns_s_querydomaininvalid;
}
}
- if (!(flags & adns_qf_quoteok_query)) {
- if (c == '-') {
- if (!ll) return adns_s_querydomaininvalid;
- } else if (!ctype_alpha(c) && !ctype_digit(c)) {
- return adns_s_querydomaininvalid;
- }
- }
if (ll == *ll_io) return adns_s_querydomaininvalid;
label_r[ll++]= c;
}
const char *owner, int ol,
const typeinfo *typei, adns_rrtype type,
adns_queryflags flags) {
- int labelnum, ll, nbytes;
+ int ll, nbytes;
byte label[255];
byte *rqp;
const char *p, *pe;
p= owner; pe= owner+ol;
nbytes= 0;
- labelnum= 0;
while (p!=pe) {
ll= sizeof(label);
- st= typei->qdparselabel(ads, &p,pe, labelnum++, label, &ll, flags, typei);
+ st= qdparselabel(ads, &p,pe, label, &ll, flags);
if (st) return st;
if (!ll) return adns_s_querydomaininvalid;
if (ll > DNS_MAXLABEL) return adns_s_querydomaintoolong;
* _mailbox (pap,csp +pap_mailbox822)
* _rp (pa,cs)
* _soa (pa,mf,cs)
- * _srv* (qdpl,(pap),pa*2,mf*2,di,(csp),cs*2,postsort)
+ * _srv* (ckl,(pap),pa*2,mf*2,di,(csp),cs*2,postsort)
* _byteblock (mf)
* _opaque (pa,cs)
* _flat (mf)
*
* within each section:
- * qdpl_*
+ * ckl_*
* pap_*
* pa_*
* dip_*
}
/*
- * _srv* (qdpl,(pap),pa*2,mf*2,di,(csp),cs*2,postsort)
+ * _srv* (ckl,(pap),pa*2,mf*2,di,(csp),cs*2,postsort)
*/
-static adns_status qdpl_srv(adns_state ads,
- const char **p_io, const char *pe, int labelnum,
- char label_r[DNS_MAXDOMAIN], int *ll_io,
- adns_queryflags flags,
- const typeinfo *typei) {
- int useflags;
- const char *p_orig;
- adns_status st;
-
- if (labelnum < 2 && !(flags & adns_qf_quoteok_query)) {
- useflags= adns_qf_quoteok_query;
- p_orig= *p_io;
- } else {
- useflags= flags;
- p_orig= 0;
+static adns_status ckl_srv(adns_state ads, adns_queryflags flags,
+ union checklabel_state *cls, qcontext *ctx,
+ int labnum, const char *label, int lablen) {
+ if (labnum < 2 && !(flags & adns_qf_quoteok_query)) {
+ if (!lablen || label[0] != '_') return adns_s_querydomaininvalid;
+ return adns_s_ok;
}
- st= adns__qdpl_normal(ads, p_io,pe, labelnum,label_r, ll_io, useflags,typei);
- if (st) return st;
-
- if (p_orig) {
- int ll= *ll_io;
- if (!ll || label_r[0]!='_')
- return adns_s_querydomaininvalid;
- if (memchr(p_orig+1, '\\', pe - (p_orig+1)))
- return adns_s_querydomaininvalid;
- }
- return adns_s_ok;
+ return adns__ckl_hostname(ads, flags, cls, ctx, labnum, label, lablen);
}
static adns_status pap_srv_begin(const parseinfo *pai, int *cbyte_io, int max,
#define DEEP_TYPE(code,rrt,fmt,memb,parser,comparer,/*printer*/...) \
{ adns_r_##code, rrt,fmt,TYPESZ_M(memb), mf_##memb, \
GLUE(cs_, CAR(__VA_ARGS__)),pa_##parser,di_##comparer, \
- adns__qdpl_normal, CDR(__VA_ARGS__) }
+ adns__ckl_hostname, CDR(__VA_ARGS__) }
#define FLAT_TYPE(code,rrt,fmt,memb,parser,comparer,/*printer*/...) \
{ adns_r_##code, rrt,fmt,TYPESZ_M(memb), mf_flat, \
GLUE(cs_, CAR(__VA_ARGS__)),pa_##parser,di_##comparer, \
- adns__qdpl_normal, CDR(__VA_ARGS__) }
+ adns__ckl_hostname, CDR(__VA_ARGS__) }
#define di_0 0
DEEP_TYPE(txt, "TXT", 0, manyistr, txt, 0, txt ),
DEEP_TYPE(rp_raw, "RP", "raw",strpair, rp, 0, rp ),
DEEP_TYPE(srv_raw,"SRV", "raw",srvraw , srvraw, srv, srvraw,
- .qdparselabel= qdpl_srv, .postsort= postsort_srv),
+ .checklabel= ckl_srv, .postsort= postsort_srv),
FLAT_TYPE(addr, "A", "addr", addr, addr, addr, addr ),
DEEP_TYPE(ns, "NS", "+addr",hostaddr, hostaddr,hostaddr,hostaddr ),
DEEP_TYPE(ptr, "PTR","checked",str, ptr, 0, domain ),
DEEP_TYPE(mx, "MX", "+addr",inthostaddr,mx, mx, inthostaddr, ),
DEEP_TYPE(srv, "SRV","+addr",srvha, srvha, srv, srvha,
- .qdparselabel= qdpl_srv, .postsort= postsort_srv),
+ .checklabel= ckl_srv, .postsort= postsort_srv),
DEEP_TYPE(soa, "SOA","822", soa, soa, 0, soa ),
DEEP_TYPE(rp, "RP", "822", strpair, rp, 0, rp ),