From 09957b1ca58af52bbc90e88ec198f14b8a06c0f7 Mon Sep 17 00:00:00 2001 From: ian Date: Sat, 28 Nov 1998 17:37:56 +0000 Subject: [PATCH] sortlist; init supplying text of config file; env vars with config file text --- src/adns.h | 2 ++ src/general.c | 8 +++-- src/internal.h | 13 ++++--- src/query.c | 4 ++- src/setup.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++------ src/types.c | 54 ++++++++++++++++++++-------- 6 files changed, 158 insertions(+), 33 deletions(-) diff --git a/src/adns.h b/src/adns.h index da30694..d4ca0df 100644 --- a/src/adns.h +++ b/src/adns.h @@ -30,6 +30,8 @@ #include #include +/* All struct in_addr anywhere in adns are in NETWORK byte order. */ + typedef struct adns__state *adns_state; typedef struct adns__query *adns_query; diff --git a/src/general.c b/src/general.c index 45aec68..15025a4 100644 --- a/src/general.c +++ b/src/general.c @@ -254,13 +254,15 @@ const char *adns_strerror(adns_status st) { } void adns__isort(void *array, int nobjs, int sz, void *tempbuf, - int (*needswap)(const void *a, const void *b)) { + int (*needswap)(void *context, const void *a, const void *b), + void *context) { byte *data= array; int i, place; for (i=0; i0 && needswap(data + (place-1)*sz, data + i*sz); place--); - + for (place= i; + place>0 && needswap(context, data + (place-1)*sz, data + i*sz); + place--); if (place != i) { memcpy(tempbuf, data + i*sz, sz); memmove(data + (place+1)*sz, data + place*sz, (i-place)*sz); diff --git a/src/internal.h b/src/internal.h index 27d0258..92debfd 100644 --- a/src/internal.h +++ b/src/internal.h @@ -39,7 +39,8 @@ typedef unsigned char byte; /* Configuration and constants */ #define MAXSERVERS 5 -#define UDPMAXRETRIES /*15*/5 +#define MAXSORTLIST 15 +#define UDPMAXRETRIES /*15 fixme*/5 #define UDPRETRYMS 2000 #define TCPMS 30000 #define LOCALRESOURCEMS 20 @@ -115,7 +116,7 @@ typedef struct { * nsstart is the offset of the authority section. */ - int (*diff_needswap)(const void *datap_a, const void *datap_b); + int (*diff_needswap)(adns_state ads, const void *datap_a, const void *datap_b); /* Returns !0 if RR a should be strictly after RR b in the sort order, * 0 otherwise. Must not fail. */ @@ -243,12 +244,15 @@ struct adns__state { struct { adns_query head, tail; } timew, childw, output; int nextid, udpsocket, tcpsocket; vbuf tcpsend, tcprecv; - int nservers, tcpserver; + int nservers, nsortlist, tcpserver; enum adns__tcpstate { server_disconnected, server_connecting, server_ok } tcpstate; struct timeval tcptimeout; struct server { struct in_addr addr; } servers[MAXSERVERS]; + struct sortlist { + struct in_addr base, mask; + } sortlist[MAXSORTLIST]; }; /* From setup.c: */ @@ -289,7 +293,8 @@ const char *adns__diag_domain(adns_state ads, int serv, adns_query qu, */ void adns__isort(void *array, int nobjs, int sz, void *tempbuf, - int (*needswap)(const void *a, const void *b)); + int (*needswap)(void *context, const void *a, const void *b), + void *context); /* Does an insertion sort of array which must contain nobjs objects * each sz bytes long. tempbuf must point to a buffer at least * sz bytes long. needswap should return !0 if a>b (strictly, ie diff --git a/src/query.c b/src/query.c index f24dbd1..c8d312d 100644 --- a/src/query.c +++ b/src/query.c @@ -300,7 +300,9 @@ void adns__query_done(adns_query qu) { return; } adns__isort(ans->rrs.bytes, ans->nrrs, ans->rrsz, - qu->vb.buf, qu->typei->diff_needswap); + qu->vb.buf, + (int(*)(void*, const void*, const void*))qu->typei->diff_needswap, + qu->ads); } parent= qu->parent; diff --git a/src/setup.c b/src/setup.c index c0f584b..29587ce 100644 --- a/src/setup.c +++ b/src/setup.c @@ -90,8 +90,85 @@ static void ccf_search(adns_state ads, const char *fn, int lno, const char *buf) 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,0,"warning - `sortlist' ignored fixme"); +static void ccf_sortlist(adns_state ads, const char *fn, int lno, const char *bufp) { + const char *p, *q; + char tbuf[200], *slash, *ep; + struct in_addr base, mask; + int l; + unsigned long initial, baselocal; + + ads->nsortlist= 0; + if (!bufp) return; + + for (;;) { + while (ctype_whitespace(*bufp)) bufp++; + if (!*bufp) return; + + q= bufp; + while (*q && !ctype_whitespace(*q)) q++; + + p= bufp; + l= q-p; + bufp= q; + + if (ads->nsortlist >= MAXSORTLIST) { + adns__diag(ads,-1,0,"too many sortlist entries, ignoring %.*s onwards",l,p); + return; + } + + if (l >= sizeof(tbuf)) { + configparseerr(ads,fn,lno,"sortlist entry `%.*s' too long",l,p); + continue; + } + + memcpy(tbuf,p,l); + slash= strchr(tbuf,'/'); + if (slash) *slash++= 0; + + if (!inet_aton(tbuf,&base)) { + configparseerr(ads,fn,lno,"invalid address `%s' in sortlist",tbuf); + continue; + } + + if (slash) { + if (strchr(slash,'.')) { + if (!inet_aton(slash,&mask)) { + configparseerr(ads,fn,lno,"invalid mask `%s' in sortlist",slash); + continue; + } + if (base.s_addr & ~mask.s_addr) { + configparseerr(ads,fn,lno, + "mask `%s' in sortlist overlaps address `%s'",slash,tbuf); + continue; + } + } else { + initial= strtoul(slash,&ep,10); + if (*ep || initial>32) { + configparseerr(ads,fn,lno,"mask length `%s' invalid",slash); + continue; + } + mask.s_addr= htonl((0x0ffffffffUL) << (32-initial)); + } + } else { + baselocal= ntohl(base.s_addr); + if (!baselocal & 0x080000000UL) /* class A */ + mask.s_addr= htonl(0x0ff000000UL); + else if ((baselocal & 0x0c0000000UL) == 0x080000000UL) + mask.s_addr= htonl(0x0ffff0000UL); /* class B */ + else if ((baselocal & 0x0f0000000UL) == 0x0e0000000UL) + mask.s_addr= htonl(0x0ff000000UL); /* class C */ + else { + configparseerr(ads,fn,lno, + "network address `%s' in sortlist is not in classed ranges," + " must specify mask explicitly", tbuf); + continue; + } + } + + ads->sortlist[ads->nsortlist].base= base; + ads->sortlist[ads->nsortlist].mask= mask; + ads->nsortlist++; + } } static void ccf_options(adns_state ads, const char *fn, int lno, const char *buf) { @@ -176,15 +253,14 @@ static int gl_file(adns_state ads, getline_ctx *src_io, const char *filename, static int gl_text(adns_state ads, getline_ctx *src_io, const char *filename, int lno, char *buf, int buflen) { - const char *cp= src_io->text, *nn; + const char *cp= src_io->text; int l; - if (!cp) return -1; - - nn= strchr(cp,'\n'); + if (!cp || !*cp) return -1; - l= nn ? nn-cp : strlen(cp); - src_io->text= nn ? nn+1 : 0; + if (*cp == ';' || *cp == '\n') cp++; + l= strcspn(cp,";\n"); + src_io->text = cp+l; if (l >= buflen) { adns__diag(ads,-1,0,"%s:%d: line too long, ignored",filename,lno); @@ -282,6 +358,17 @@ static void readconfigenv(adns_state ads, const char *envvar) { if (filename) readconfig(ads,filename); } +static void readconfigenvtext(adns_state ads, const char *envvar) { + const char *textdata; + + if (ads->iflags & adns_if_noenv) { + adns__debug(ads,-1,0,"not checking environment variable `%s'",envvar); + return; + } + textdata= instrum_getenv(ads,envvar); + if (textdata) readconfigtext(ads,textdata,envvar); +} + int adns__setnonblock(adns_state ads, int fd) { int r; @@ -306,7 +393,7 @@ static int init_begin(adns_state *ads_r, adns_initflags flags, FILE *diagfile) { ads->udpsocket= ads->tcpsocket= -1; adns__vbuf_init(&ads->tcpsend); adns__vbuf_init(&ads->tcprecv); - ads->nservers= ads->tcpserver= 0; + ads->nservers= ads->nsortlist= ads->tcpserver= 0; ads->tcpstate= server_disconnected; timerclear(&ads->tcptimeout); @@ -322,7 +409,7 @@ static int init_finish(adns_state ads) { if (!ads->nservers) { if (ads->diagfile && ads->iflags & adns_if_debug) fprintf(ads->diagfile,"adns: no nameservers, using localhost\n"); - ia.s_addr= INADDR_LOOPBACK; + ia.s_addr= htonl(INADDR_LOOPBACK); addserver(ads,ia); } @@ -359,6 +446,9 @@ int adns_init(adns_state *ads_r, adns_initflags flags, FILE *diagfile) { readconfigenv(ads,"RES_CONF"); readconfigenv(ads,"ADNS_RES_CONF"); + readconfigenvtext(ads,"RES_CONF_TEXT"); + readconfigenvtext(ads,"ADNS_RES_CONF_TEXT"); + ccf_options(ads,"RES_OPTIONS",-1,res_options); ccf_options(ads,"ADNS_RES_OPTIONS",-1,adns_res_options); diff --git a/src/types.c b/src/types.c index e59da80..32db284 100644 --- a/src/types.c +++ b/src/types.c @@ -245,15 +245,30 @@ static adns_status pa_inaddr(const parseinfo *pai, int cbyte, int max, void *dat return adns_s_ok; } -static int dip_inaddr(struct in_addr a, struct in_addr b) { - /* fixme implement sortlist */ - return 0; +static int search_sortlist(adns_state ads, struct in_addr ad) { + const struct sortlist *slp; + int i; + + for (i=0, slp=ads->sortlist; + insortlist && !((ad.s_addr & slp->mask.s_addr) == slp->base.s_addr); + i++, slp++); + return i; } -static int di_inaddr(const void *datap_a, const void *datap_b) { +static int dip_inaddr(adns_state ads, struct in_addr a, struct in_addr b) { + int ai, bi; + + if (!ads->nsortlist) return 0; + + ai= search_sortlist(ads,a); + bi= search_sortlist(ads,b); + return biaddr.sa.sa_family == AF_INET); - return dip_inaddr(ap->addr.inet.sin_addr,bp->addr.inet.sin_addr); + return dip_inaddr(ads, ap->addr.inet.sin_addr, bp->addr.inet.sin_addr); } +static int div_addr(void *context, const void *datap_a, const void *datap_b) { + const adns_state ads= context; + + return di_addr(ads, datap_a, datap_b); +} + static adns_status csp_addr(vbuf *vb, const adns_rr_addr *rrp) { const char *ia; static char buf[30]; @@ -386,7 +407,8 @@ static adns_status pap_findaddrs(const parseinfo *pai, adns_rr_hostaddr *ha, ha->naddrs= naddrs; ha->astatus= adns_s_ok; - adns__isort(ha->addrs, naddrs, sizeof(adns_rr_addr), pai->qu->vb.buf, di_addr); + adns__isort(ha->addrs, naddrs, sizeof(adns_rr_addr), pai->qu->vb.buf, + div_addr, pai->ads); } return adns_s_ok; } @@ -461,19 +483,21 @@ static adns_status pa_hostaddr(const parseinfo *pai, int cbyte, int max, void *d return adns_s_ok; } -static int dip_hostaddr(const adns_rr_hostaddr *ap, const adns_rr_hostaddr *bp) { +static int dip_hostaddr(adns_state ads, const adns_rr_hostaddr *ap, const adns_rr_hostaddr *bp) { if (ap->astatus != bp->astatus) return ap->astatus; if (ap->astatus) return 0; assert(ap->addrs[0].addr.sa.sa_family == AF_INET); assert(bp->addrs[0].addr.sa.sa_family == AF_INET); - return dip_inaddr(ap->addrs[0].addr.inet.sin_addr, bp->addrs[0].addr.inet.sin_addr); + return dip_inaddr(ads, + ap->addrs[0].addr.inet.sin_addr, + bp->addrs[0].addr.inet.sin_addr); } -static int di_hostaddr(const void *datap_a, const void *datap_b) { +static int di_hostaddr(adns_state ads, const void *datap_a, const void *datap_b) { const adns_rr_hostaddr *ap= datap_a, *bp= datap_b; - return dip_hostaddr(ap,bp); + return dip_hostaddr(ads, ap,bp); } static void mfp_hostaddr(adns_query qu, adns_rr_hostaddr *rrp) { @@ -538,7 +562,7 @@ static adns_status pa_mx_raw(const parseinfo *pai, int cbyte, int max, void *dat return adns_s_ok; } -static int di_mx_raw(const void *datap_a, const void *datap_b) { +static int di_mx_raw(adns_state ads, const void *datap_a, const void *datap_b) { const adns_rr_intstr *ap= datap_a, *bp= datap_b; if (ap->i < bp->i) return 0; @@ -566,12 +590,12 @@ static adns_status pa_mx(const parseinfo *pai, int cbyte, int max, void *datap) return adns_s_ok; } -static int di_mx(const void *datap_a, const void *datap_b) { +static int di_mx(adns_state ads, const void *datap_a, const void *datap_b) { const adns_rr_inthostaddr *ap= datap_a, *bp= datap_b; if (ap->i < bp->i) return 0; if (ap->i > bp->i) return 1; - return dip_hostaddr(&ap->ha,&bp->ha); + return dip_hostaddr(ads, &ap->ha, &bp->ha); } /* -- 2.11.0