From: ian Date: Sat, 14 Nov 1998 14:21:50 +0000 (+0000) Subject: Use struct sockaddr in several places; distinguish various places where X-Git-Tag: abandon.1999-04-10.multithread~38 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=adns.git;a=commitdiff_plain;h=828d89bd4196ad8ef825cdf2db26afe2eb797b69 Use struct sockaddr in several places; distinguish various places where quoted-names are allowed or not. --- diff --git a/client/adnstest.c b/client/adnstest.c index a7a247a..95955cb 100644 --- a/client/adnstest.c +++ b/client/adnstest.c @@ -42,6 +42,7 @@ static const adns_rrtype defaulttypes[]= { adns_r_mx_raw, adns_r_rp_raw, adns_r_txt, + adns_r_addr, adns_r_none }; diff --git a/src/adns.h b/src/adns.h index d5cddec..afcb6b4 100644 --- a/src/adns.h +++ b/src/adns.h @@ -42,11 +42,14 @@ typedef enum { } adns_initflags; typedef enum { - adns_qf_search= 0x0001, /* use the searchlist */ - adns_qf_usevc= 0x0002, /* use a virtual circuit (TCP connection) */ - adns_qf_anyquote= 0x0004, - adns_qf_loosecname= 0x0008, /* allow refs to CNAMEs - without, get _s_cname */ - adns_qf_nocname= 0x0010, /* don't follow CNAMEs, instead give _s_cname */ + adns_qf_search= 0x000001, /* use the searchlist */ + adns_qf_usevc= 0x000002, /* use a virtual circuit (TCP connection) */ + adns_qf_quoteok_query= 0x000010, /* allow quote-requiring chars in query domain */ + adns_qf_quoteok_cname= 0x000020, /* allow ... in CNAME we go via */ + adns_qf_quoteok_anshost= 0x000040, /* allow ... in answers expected to be hostnames */ + adns_qf_cname_loose= 0x000100, /* allow refs to CNAMEs - without, get _s_cname */ + adns_qf_cname_forbid= 0x000200, /* don't follow CNAMEs, instead give _s_cname */ + adns__qf_internalmask= 0x0ff000 } adns_queryflags; typedef enum { @@ -78,6 +81,8 @@ typedef enum { adns_r_rp_raw= 17, adns_r_rp= adns_r_rp_raw|adns__qtf_mail822, + + adns_r_addr= adns_r_a|adns__qtf_deref } adns_rrtype; @@ -121,11 +126,19 @@ typedef enum { adns_s_domaintoolong, } adns_status; +typedef struct { + int len; + union { + struct sockaddr sa; + struct sockaddr_in inet; + } addr; +} adns_addr; + typedef struct { char *dm; adns_status astatus; int naddrs; /* temp fail => -1, perm fail => 0, s_ok => >0 */ - struct in_addr *addrs; + adns_addr *addrs; } adns_rr_dmaddr; typedef struct { @@ -162,6 +175,7 @@ typedef struct { unsigned char *bytes; char *(*str); /* ns_raw, cname, ptr, ptr_raw */ adns_rr_intstr *(*manyistr); /* txt (list of strings ends with i=-1, str=0) */ + adns_addr *addr; /* addr */ struct in_addr *inaddr; /* a */ adns_rr_dmaddr *dmaddr; /* ns */ adns_rr_strpair *strpair; /* hinfo ??fixme, rp, rp_raw */ diff --git a/src/general.c b/src/general.c index 3f4c8c8..8311dd7 100644 --- a/src/general.c +++ b/src/general.c @@ -46,7 +46,7 @@ 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(qu->ads,-1,0, &vb,qu->flags, + adns__diag_domain(qu->ads,-1,0, &vb, qu->query_dgram,qu->query_dglen,DNS_HDRSIZE), qu->typei ? qu->typei->rrtname : ""); if (qu->typei && qu->typei->fmtname) @@ -138,11 +138,11 @@ void adns__vbuf_free(vbuf *vb) { /* Additional diagnostic functions */ -const char *adns__diag_domain(adns_state ads, int serv, adns_query qu, vbuf *vb, - int flags, const byte *dgram, int dglen, int cbyte) { +const char *adns__diag_domain(adns_state ads, int serv, adns_query qu, + vbuf *vb, const byte *dgram, int dglen, int cbyte) { adns_status st; - st= adns__parse_domain(ads,serv,qu,vb, flags,dgram,dglen,&cbyte,dglen); + st= adns__parse_domain(ads,serv,qu,vb, pdf_quoteok, dgram,dglen,&cbyte,dglen); if (st == adns_s_nolocalmem) { return ""; } diff --git a/src/internal.h b/src/internal.h index 69eb827..19adb4f 100644 --- a/src/internal.h +++ b/src/internal.h @@ -258,8 +258,8 @@ void adns__vbuf_appendq(vbuf *vb, const byte *data, int len); void adns__vbuf_init(vbuf *vb); void adns__vbuf_free(vbuf *vb); -const char *adns__diag_domain(adns_state ads, int serv, adns_query qu, vbuf *vb, - int flags, const byte *dgram, int dglen, int cbyte); +const char *adns__diag_domain(adns_state ads, int serv, adns_query qu, + vbuf *vb, 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. @@ -421,8 +421,12 @@ adns_status adns__findlabel_next(findlabel_state *fls, int *lablen_r, int *labst * Do not then call findlabel_next again. */ +typedef enum { + pdf_quoteok= 0x001 +} parsedomain_flags; + adns_status adns__parse_domain(adns_state ads, int serv, adns_query qu, - vbuf *vb, int flags, + vbuf *vb, parsedomain_flags 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 diff --git a/src/parse.c b/src/parse.c index d516d24..722d9e4 100644 --- a/src/parse.c +++ b/src/parse.c @@ -111,7 +111,7 @@ adns_status adns__findlabel_next(findlabel_state *fls, } adns_status adns__parse_domain(adns_state ads, int serv, adns_query qu, - vbuf *vb, int flags, + vbuf *vb, adns_queryflags flags, const byte *dgram, int dglen, int *cbyte_io, int max) { findlabel_state fls; @@ -127,7 +127,7 @@ adns_status adns__parse_domain(adns_state ads, int serv, adns_query qu, if (!lablen) break; if (vb->used) if (!adns__vbuf_append(vb,".",1)) return adns_s_nolocalmem; - if (flags & adns_qf_anyquote) { + if (flags & pdf_quoteok) { if (!vbuf__append_quoted1035(vb,dgram+labstart,lablen)) return adns_s_nolocalmem; } else { diff --git a/src/reply.c b/src/reply.c index 87ee361..3b46e21 100644 --- a/src/reply.c +++ b/src/reply.c @@ -93,8 +93,7 @@ void adns__procdgram(adns_state ads, const byte *dgram, int dglen, if (ads->iflags & adns_if_debug) { adns__vbuf_init(&tempvb); adns__debug(ads,serv,0,"reply not found, id %02x, query owner %s", - id, adns__diag_domain(ads,serv,0,&tempvb,adns_qf_anyquote, - dgram,dglen,DNS_HDRSIZE)); + id, adns__diag_domain(ads,serv,0,&tempvb,dgram,dglen,DNS_HDRSIZE)); adns__vbuf_free(&tempvb); } return; @@ -150,8 +149,7 @@ 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, &qu->vb,qu->flags, - dgram,dglen,rrstart)); + adns__diag_domain(ads,serv,qu, &qu->vb, dgram,dglen,rrstart)); } continue; } @@ -160,7 +158,8 @@ void adns__procdgram(adns_state ads, const byte *dgram, int dglen, if (!qu->cname_dgram) { /* Ignore second and subsequent CNAMEs */ qu->cname_begin= rdstart; qu->cname_dglen= dglen; - st= adns__parse_domain(ads,serv,qu, &qu->vb,qu->flags, + st= adns__parse_domain(ads,serv,qu, &qu->vb, + qu->flags & adns_qf_quoteok_cname ? pdf_quoteok : 0, dgram,dglen, &rdstart,rdstart+rdlength); if (!qu->vb.used) goto x_truncated; if (st) { adns__query_fail(qu,st); return; } @@ -180,8 +179,7 @@ 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, &qu->vb,qu->flags, - dgram,dglen,rdstart), + adns__diag_domain(ads,serv,qu, &qu->vb, dgram,dglen,rdstart), qu->answer->cname); } } else if (rrtype == (qu->typei->type & adns__rrt_typemask)) { diff --git a/src/transmit.c b/src/transmit.c index 46d2cbf..3b869fc 100644 --- a/src/transmit.c +++ b/src/transmit.c @@ -88,7 +88,7 @@ adns_status adns__mkquery(adns_state ads, vbuf *vb, int *id_r, ll= 0; while (p!=pe && (c= *p++)!='.') { if (c=='\\') { - if (!(flags & adns_qf_anyquote)) return adns_s_invalidquerydomain; + if (!(flags & adns_qf_quoteok_query)) 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'); @@ -100,7 +100,7 @@ adns_status adns__mkquery(adns_state ads, vbuf *vb, int *id_r, return adns_s_invalidquerydomain; } } - if (!(flags & adns_qf_anyquote)) { + if (!(flags & adns_qf_quoteok_query)) { if (c == '-') { if (!ll) return adns_s_invalidquerydomain; } else if (!ctype_alpha(c) && !ctype_digit(c)) { diff --git a/src/types.c b/src/types.c index 4b5e752..94b79d2 100644 --- a/src/types.c +++ b/src/types.c @@ -21,11 +21,17 @@ */ #include +#include #include #include "internal.h" +static int dip_inaddr(struct in_addr a, struct in_addr b) { + /* fixme implement sortlist */ + return 0; +} + static adns_status pa_inaddr(adns_query qu, int serv, const byte *dgram, int dglen, int cbyte, int max, void *datap) { @@ -36,11 +42,6 @@ static adns_status pa_inaddr(adns_query qu, int serv, return adns_s_ok; } -static int dip_inaddr(struct in_addr a, struct in_addr b) { - /* fixme implement sortlist */ - return 0; -} - static int di_inaddr(const void *datap_a, const void *datap_b) { const struct in_addr *ap= datap_a, *bp= datap_b; @@ -55,14 +56,52 @@ static adns_status cs_inaddr(vbuf *vb, const void *datap) { return adns__vbuf_appendstr(vb,ia) ? adns_s_ok : adns_s_nolocalmem; } -static adns_status pap_domain(adns_query qu, int serv, +static adns_status pa_addr(adns_query qu, int serv, + const byte *dgram, int dglen, int cbyte, int max, + void *datap) { + adns_addr *storeto= datap; + + if (max-cbyte != 4) return adns_s_invaliddata; + storeto->len= sizeof(storeto->addr.inet); + memset(&storeto->addr,0,sizeof(storeto->addr.inet)); + storeto->addr.inet.sin_family= AF_INET; + storeto->addr.inet.sin_port= 0; + memcpy(&storeto->addr.inet.sin_addr,dgram+cbyte,4); + return adns_s_ok; +} + +static int di_addr(const void *datap_a, const void *datap_b) { + const adns_addr *ap= datap_a, *bp= datap_b; + + return dip_inaddr(ap->addr.inet.sin_addr,bp->addr.inet.sin_addr); +} + +static adns_status cs_addr(vbuf *vb, const void *datap) { + const adns_addr *rrp= datap; + const char *ia; + static char buf[30]; + + switch (rrp->addr.inet.sin_family) { + case AF_INET: + if (!adns__vbuf_appendstr(vb,"AF_INET ")) return adns_s_nolocalmem; + ia= inet_ntoa(rrp->addr.inet.sin_addr); assert(ia); + if (!adns__vbuf_appendstr(vb,ia)) return adns_s_nolocalmem; + break; + default: + sprintf(buf,"AF=%u",rrp->addr.sa.sa_family); + if (!adns__vbuf_appendstr(vb,buf)) return adns_s_nolocalmem; + break; + } + return adns_s_ok; +} + +static adns_status pap_domain(adns_query qu, int serv, parsedomain_flags flags, const byte *dgram, int dglen, int *cbyte_io, int max, char **domain_r) { adns_status st; char *dm; - st= adns__parse_domain(qu->ads,serv,qu,&qu->vb,qu->flags, - dgram,dglen, cbyte_io,max); + st= adns__parse_domain(qu->ads,serv,qu,&qu->vb,flags, dgram,dglen, cbyte_io,max); if (st) return st; if (!qu->vb.used) return adns_s_invaliddata; @@ -76,13 +115,15 @@ static adns_status pap_domain(adns_query qu, int serv, return adns_s_ok; } -static adns_status pa_domain_raw(adns_query qu, int serv, - const byte *dgram, int dglen, int cbyte, int max, - void *datap) { +static adns_status pa_host_raw(adns_query qu, int serv, + const byte *dgram, int dglen, int cbyte, int max, + void *datap) { char **rrp= datap; adns_status st; - st= pap_domain(qu,serv,dgram,dglen,&cbyte,max,rrp); + st= pap_domain(qu,serv, + qu->flags & adns_qf_quoteok_anshost ? pdf_quoteok : 0, + dgram,dglen,&cbyte,max,rrp); if (st) return st; if (cbyte != max) return adns_s_invaliddata; @@ -99,7 +140,9 @@ static adns_status pa_mx_raw(adns_query qu, int serv, if (cbyte+2 > max) return adns_s_invaliddata; GET_W(cbyte,pref); rrp->i= pref; - st= pap_domain(qu,serv,dgram,dglen,&cbyte,max,&rrp->str); + st= pap_domain(qu,serv, + qu->flags & adns_qf_quoteok_anshost ? pdf_quoteok : 0, + dgram,dglen,&cbyte,max,&rrp->str); if (st) return st; if (cbyte != max) return adns_s_invaliddata; @@ -254,12 +297,12 @@ static const typeinfo typeinfos[] = { /* rr type code rrt fmt mem.mgmt member parser comparer */ { adns_r_a, "A", 0, FLAT_MEMB(inaddr), pa_inaddr, di_inaddr }, - { adns_r_ns_raw, "NS", "raw", DEEP_MEMB(str), pa_domain_raw, 0 }, - { adns_r_cname, "CNAME", 0, DEEP_MEMB(str), pa_domain_raw, 0 }, + { adns_r_ns_raw, "NS", "raw", DEEP_MEMB(str), pa_host_raw, 0 }, + { adns_r_cname, "CNAME", 0, DEEP_MEMB(str), pa_host_raw, 0 }, #if 0 /*fixme*/ { adns_r_soa_raw, "SOA", "raw", DEEP_MEMB(soa), pa_soa, 0 }, #endif - { adns_r_ptr_raw, "PTR", "raw", DEEP_MEMB(str), pa_domain_raw, 0 }, + { adns_r_ptr_raw, "PTR", "raw", DEEP_MEMB(str), pa_host_raw, 0 }, #if 0 /*fixme*/ { adns_r_hinfo, "HINFO", 0, DEEP_MEMB(strpair), pa_hinfo, 0 }, #endif @@ -268,8 +311,9 @@ static const typeinfo typeinfos[] = { #if 0 /*fixme*/ { adns_r_rp_raw, "RP", "raw", DEEP_MEMB(strpair), pa_rp, 0 }, #endif -#if 0 /*fixme*/ + { adns_r_addr, "A", "addr", FLAT_MEMB(addr), pa_addr, di_addr }, +#if 0 /*fixme*/ { adns_r_ns, "NS", "+addr", DEEP_MEMB(dmaddr), pa_dmaddr, di_dmaddr }, { adns_r_ptr, "PTR","checked", DEEP_MEMB(str), pa_ptr, 0 }, { adns_r_mx, "MX", "+addr", DEEP_MEMB(intdmaddr), pa_mx, di_mx },