* - RR-type-specific code, and the machinery to call it
*/
/*
- * This file is part of adns, which is Copyright (C) 1997, 1998 Ian Jackson
+ * This file is part of adns, which is Copyright (C) 1997-1999 Ian Jackson
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
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;
+ i<ads->nsortlist && !((ad.s_addr & slp->mask.s_addr) == slp->base.s_addr);
+ i++, slp++);
+ return i;
+}
+
+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 bi<ai;
}
-static int di_inaddr(const void *datap_a, const void *datap_b) {
+static int di_inaddr(adns_state ads, const void *datap_a, const void *datap_b) {
const struct in_addr *ap= datap_a, *bp= datap_b;
- return dip_inaddr(*ap,*bp);
+ return dip_inaddr(ads,*ap,*bp);
}
static adns_status cs_inaddr(vbuf *vb, const void *datap) {
return adns_s_ok;
}
-static int di_addr(const void *datap_a, const void *datap_b) {
+static int di_addr(adns_state ads, const void *datap_a, const void *datap_b) {
const adns_rr_addr *ap= datap_a, *bp= datap_b;
assert(ap->addr.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];
int *cbyte_io, int count, int dmstart) {
int rri, naddrs;
int type, class, rdlen, rdstart, ownermatched;
+ unsigned long ttl;
adns_status st;
for (rri=0, naddrs=-1; rri<count; rri++) {
st= adns__findrr_anychk(pai->qu, pai->serv, pai->dgram, pai->dglen, cbyte_io,
- &type, &class, &rdlen, &rdstart,
+ &type, &class, &ttl, &rdlen, &rdstart,
pai->dgram, pai->dglen, dmstart, &ownermatched);
if (st) return st;
if (!ownermatched || class != DNS_CLASS_IN || type != adns_r_a) {
naddrs= 0;
}
if (!adns__vbuf_ensure(&pai->qu->vb, (naddrs+1)*sizeof(adns_rr_addr))) R_NOMEM;
+ adns__update_expires(pai->qu,ttl,pai->now);
st= pa_addr(pai, rdstart,rdstart+rdlen,
pai->qu->vb.buf + naddrs*sizeof(adns_rr_addr));
if (st) return st;
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;
}
qcontext ctx;
int id;
adns_query nqu;
+ adns_queryflags nflags;
dmstart= cbyte= *cbyte_io;
st= pap_domain(pai, &cbyte, max, &rrp->host,
ctx.ext= 0;
ctx.callback= icb_hostaddr;
ctx.info.hostaddr= rrp;
+
+ nflags= adns_qf_quoteok_query;
+ if (!(pai->qu->flags & adns_qf_cname_loose)) nflags |= adns_qf_cname_forbid;
+
st= adns__internal_submit(pai->ads, &nqu, adns__findtype(adns_r_addr),
- &pai->qu->vb, id,
- adns_qf_quoteok_query, pai->now, 0, &ctx);
+ &pai->qu->vb, id, nflags, pai->now, 0, &ctx);
if (st) return st;
nqu->parent= pai->qu;
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) {
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;
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);
}
/*