chiark
/
gitweb
/
~ianmdlvl
/
adns.git
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
|
inline
| side by side (parent:
f44558a
)
Include TTL (well, actually, expiry time) in answers.
author
ian
<ian>
Sun, 11 Apr 1999 17:21:15 +0000
(17:21 +0000)
committer
ian
<ian>
Sun, 11 Apr 1999 17:21:15 +0000
(17:21 +0000)
12 files changed:
client/adnstest.c
patch
|
blob
|
history
regress/Makefile.in
patch
|
blob
|
history
regress/case-manya.out
patch
|
blob
|
history
regress/case-norm.out
patch
|
blob
|
history
regress/case-timeout.out
patch
|
blob
|
history
regress/case-trunc.out
patch
|
blob
|
history
src/adns.h
patch
|
blob
|
history
src/internal.h
patch
|
blob
|
history
src/parse.c
patch
|
blob
|
history
src/query.c
patch
|
blob
|
history
src/reply.c
patch
|
blob
|
history
src/types.c
patch
|
blob
|
history
diff --git
a/client/adnstest.c
b/client/adnstest.c
index ea9ed2a35bd1e7c98ca41fa164d281f0356b1a3d..98caf2fd78de31db789a3b6e6e48cd6251703e24 100644
(file)
--- a/
client/adnstest.c
+++ b/
client/adnstest.c
@@
-21,6
+21,7
@@
*/
#include <stdio.h>
*/
#include <stdio.h>
+#include <sys/time.h>
#include <unistd.h>
#include <assert.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <stdlib.h>
@@
-76,6
+77,7
@@
int main(int argc, char *const *argv) {
int len, i, qc, qi, tc, ti, ch;
adns_status r, ri;
const adns_rrtype *types;
int len, i, qc, qi, tc, ti, ch;
adns_status r, ri;
const adns_rrtype *types;
+ struct timeval now;
adns_rrtype *types_a;
if (argv[0] && argv[1] && argv[1][0] == '/') {
adns_rrtype *types_a;
if (argv[0] && argv[1] && argv[1][0] == '/') {
@@
-146,12
+148,15
@@
int main(int argc, char *const *argv) {
r= adns_wait(ads,&qu,&ans,0);
if (r) failure("wait",r);
r= adns_wait(ads,&qu,&ans,0);
if (r) failure("wait",r);
+ if (gettimeofday(&now,0)) { perror("gettimeofday"); exit(3); }
+
ri= adns_rr_info(ans->type, &rrtn,&fmtn,&len, 0,0);
fprintf(stdout, "%s type ", domlist[qi]);
dumptype(ri,rrtn,fmtn);
ri= adns_rr_info(ans->type, &rrtn,&fmtn,&len, 0,0);
fprintf(stdout, "%s type ", domlist[qi]);
dumptype(ri,rrtn,fmtn);
- fprintf(stdout, ": %s; nrrs=%d; cname=%s\n",
+ fprintf(stdout, ": %s; nrrs=%d; cname=%s
; ttl=%ld
\n",
adns_strerror(ans->status),
adns_strerror(ans->status),
- ans->nrrs, ans->cname ? ans->cname : "$");
+ ans->nrrs, ans->cname ? ans->cname : "$",
+ (long)ans->expires - (long)now.tv_sec);
if (ans->nrrs) {
assert(!ri);
for (i=0; i<ans->nrrs; i++) {
if (ans->nrrs) {
assert(!ri);
for (i=0; i<ans->nrrs; i++) {
diff --git
a/regress/Makefile.in
b/regress/Makefile.in
index a356ccfd2d558c64accae381a76584899af42813..2055f08cb2c3de45b527da49b45f5ba709d40cc9 100644
(file)
--- a/
regress/Makefile.in
+++ b/
regress/Makefile.in
@@
-40,12
+40,15
@@
ALLOBJS= $(HARNLOBJS) dtest.o hrecord.o hplayback.o hcommon.o
check: $(TARGETS)
./checkall
check: $(TARGETS)
./checkall
-hrecord:
$(srcdir)/../client/adnstest
.o hrecord.o hcommon.o $(HARNLOBJS)
-hplayback:
$(srcdir)/../client/adnstest
.o hplayback.o hcommon.o $(HARNLOBJS)
+hrecord:
adnstest_c
.o hrecord.o hcommon.o $(HARNLOBJS)
+hplayback:
adnstest_c
.o hplayback.o hcommon.o $(HARNLOBJS)
%_d.o: $(srcdir)/../src/%.c
$(CC) $(HCPPFLAGS) -c -g -o $@ $<
%_d.o: $(srcdir)/../src/%.c
$(CC) $(HCPPFLAGS) -c -g -o $@ $<
+%_c.o: $(srcdir)/../client/%.c
+ $(CC) $(HCPPFLAGS) -I $(srcdir)/../src -c -g -o $@ $<
+
$(ALLOBJS): $(srcdir)/../src/adns.h $(srcdir)/../src/internal.h harness.h
%:: %.m4 hmacros.i4 hsyscalls.i4
$(ALLOBJS): $(srcdir)/../src/adns.h $(srcdir)/../src/internal.h harness.h
%:: %.m4 hmacros.i4 hsyscalls.i4
diff --git
a/regress/case-manya.out
b/regress/case-manya.out
index f21068c519c92c36ad3f2c04297331c338660086..6a352a0f9f9f18ee00706d965ed3578158d02f22 100644
(file)
--- a/
regress/case-manya.out
+++ b/
regress/case-manya.out
@@
-1,6
+1,6
@@
adns debug: using nameserver 172.18.45.6
manyaddrs.test.iwj.relativity.greenend.org.uk type 1 A(-) submitted
adns debug: using nameserver 172.18.45.6
manyaddrs.test.iwj.relativity.greenend.org.uk type 1 A(-) submitted
-manyaddrs.test.iwj.relativity.greenend.org.uk type A(-): OK; nrrs=4; cname=$
+manyaddrs.test.iwj.relativity.greenend.org.uk type A(-): OK; nrrs=4; cname=$
; ttl=60
127.0.0.1
172.18.45.6
172.18.45.1
127.0.0.1
172.18.45.6
172.18.45.1
diff --git
a/regress/case-norm.out
b/regress/case-norm.out
index 70648e527ac71ec4e2293df8771a116fe689d7e3..9be2769fa4fc25b9bb30360cfe547fd368008ee7 100644
(file)
--- a/
regress/case-norm.out
+++ b/
regress/case-norm.out
@@
-1,4
+1,4
@@
adns debug: using nameserver 172.18.45.6
chiark.greenend.org.uk type 1 A(-) submitted
adns debug: using nameserver 172.18.45.6
chiark.greenend.org.uk type 1 A(-) submitted
-chiark.greenend.org.uk type A(-): OK; nrrs=1; cname=$
+chiark.greenend.org.uk type A(-): OK; nrrs=1; cname=$
; ttl=86400
195.224.76.132
195.224.76.132
diff --git
a/regress/case-timeout.out
b/regress/case-timeout.out
index 1b71759c66410a9d97518bb96ebe9c5c4eec1acc..ccbbd398b7e6c3efbea123e6878a334c66f0fb1b 100644
(file)
--- a/
regress/case-timeout.out
+++ b/
regress/case-timeout.out
@@
-1,3
+1,3
@@
adns debug: using nameserver 172.18.45.36
chiark.greenend.org.uk type 1 A(-) submitted
adns debug: using nameserver 172.18.45.36
chiark.greenend.org.uk type 1 A(-) submitted
-chiark.greenend.org.uk type A(-): DNS query timed out; nrrs=0; cname=$
+chiark.greenend.org.uk type A(-): DNS query timed out; nrrs=0; cname=$
; ttl=604770
diff --git
a/regress/case-trunc.out
b/regress/case-trunc.out
index dbd0c4a5aba8ac548acda66c06c7ffdaec19dead..7943119240cb40df415db5680985c6551ca8bc30 100644
(file)
--- a/
regress/case-trunc.out
+++ b/
regress/case-trunc.out
@@
-1,3
+1,3
@@
adns debug: using nameserver 172.18.45.6
trunc.test.iwj.relativity.greenend.org.uk type 1 A(-) submitted
adns debug: using nameserver 172.18.45.6
trunc.test.iwj.relativity.greenend.org.uk type 1 A(-) submitted
-trunc.test.iwj.relativity.greenend.org.uk type A(-): No such data; nrrs=0; cname=$
+trunc.test.iwj.relativity.greenend.org.uk type A(-): No such data; nrrs=0; cname=$
; ttl=60
diff --git
a/src/adns.h
b/src/adns.h
index 82f29d4d6137eb38e1f60e3cab895f3d0a81d90c..a234cda45951c4770bb0355704939b1a0f6d0972 100644
(file)
--- a/
src/adns.h
+++ b/
src/adns.h
@@
-195,6
+195,7
@@
typedef struct {
adns_status status;
char *cname; /* always NULL if query was for CNAME records */
adns_rrtype type; /* guaranteed to be same as in query */
adns_status status;
char *cname; /* always NULL if query was for CNAME records */
adns_rrtype type; /* guaranteed to be same as in query */
+ time_t expires; /* expiry time, defined only if _s_ok, nxdomain or nodata. NOT TTL! */
int nrrs, rrsz;
union {
void *untyped;
int nrrs, rrsz;
union {
void *untyped;
@@
-268,8
+269,8
@@
int adns_wait(adns_state ads,
adns_query *query_io,
adns_answer **answer_r,
void **context_r);
adns_query *query_io,
adns_answer **answer_r,
void **context_r);
-/* fixme: include TTL in answer somehow */
/* fixme: easy way to get lists of fd's */
/* fixme: easy way to get lists of fd's */
+/* fixme: minor cache */
void adns_cancel(adns_query query);
void adns_cancel(adns_query query);
diff --git
a/src/internal.h
b/src/internal.h
index f0f9147f5cbf55e813691155871efd6047dc6539..5e59a12877b066eb47a199a2aae8f491bc52c7a3 100644
(file)
--- a/
src/internal.h
+++ b/
src/internal.h
@@
-44,6
+44,7
@@
typedef unsigned char byte;
#define UDPRETRYMS 2000
#define TCPMS 30000
#define LOCALRESOURCEMS 20
#define UDPRETRYMS 2000
#define TCPMS 30000
#define LOCALRESOURCEMS 20
+#define MAXTTLBELIEVE (7*86400) /* any TTL > 7 days is capped */
#define DNS_PORT 53
#define DNS_MAXUDP 512
#define DNS_PORT 53
#define DNS_MAXUDP 512
@@
-181,6
+182,7
@@
struct adns__query {
int udpnextserver;
unsigned long udpsent, tcpfailed; /* bitmap indexed by server */
struct timeval timeout;
int udpnextserver;
unsigned long udpsent, tcpfailed; /* bitmap indexed by server */
struct timeval timeout;
+ time_t expires; /* Earliest expiry time of any record we used. */
qcontext ctx;
qcontext ctx;
@@
-379,6
+381,10
@@
void adns__transfer_interim(adns_query from, adns_query to, void *block, size_t
*
* It is legal to call adns__transfer_interim with a null pointer; this
* has no effect.
*
* It is legal to call adns__transfer_interim with a null pointer; this
* has no effect.
+ *
+ * _transfer_interim also ensures that the expiry time of the `to' query
+ * is no later than that of the `from' query, so that child queries'
+ * TTLs get inherited by their parents.
*/
void *adns__alloc_mine(adns_query qu, size_t sz);
*/
void *adns__alloc_mine(adns_query qu, size_t sz);
@@
-478,16
+484,17
@@
adns_status adns__parse_domain(adns_state ads, int serv, adns_query qu,
adns_status adns__findrr(adns_query qu, int serv,
const byte *dgram, int dglen, int *cbyte_io,
adns_status adns__findrr(adns_query qu, int serv,
const byte *dgram, int dglen, int *cbyte_io,
- int *type_r, int *class_r, int *rdlen_r, int *rdstart_r,
+ int *type_r, int *class_r, unsigned long *ttl_r,
+ int *rdlen_r, int *rdstart_r,
int *ownermatchedquery_r);
/* Finds the extent and some of the contents of an RR in a datagram
* and does some checks. The datagram is *dgram, length dglen, and
* the RR starts at *cbyte_io (which is updated afterwards to point
* to the end of the RR).
*
int *ownermatchedquery_r);
/* Finds the extent and some of the contents of an RR in a datagram
* and does some checks. The datagram is *dgram, length dglen, and
* the RR starts at *cbyte_io (which is updated afterwards to point
* to the end of the RR).
*
- * The type, class and RRdata length and start are returned iff
- * the corresponding pointer variables are not null. type_r
and
- *
class_r may not be null
.
+ * The type, class
, TTL
and RRdata length and start are returned iff
+ * the corresponding pointer variables are not null. type_r
, class_r
+ *
and ttl_r may not be null. The TTL will be capped
.
*
* If ownermatchedquery_r != 0 then the owner domain of this
* RR will be compared with that in the query (or, if the query
*
* If ownermatchedquery_r != 0 then the owner domain of this
* RR will be compared with that in the query (or, if the query
@@
-506,7
+513,8
@@
adns_status adns__findrr(adns_query qu, int serv,
adns_status adns__findrr_anychk(adns_query qu, int serv,
const byte *dgram, int dglen, int *cbyte_io,
adns_status adns__findrr_anychk(adns_query qu, int serv,
const byte *dgram, int dglen, int *cbyte_io,
- int *type_r, int *class_r, int *rdlen_r, int *rdstart_r,
+ int *type_r, int *class_r, unsigned long *ttl_r,
+ int *rdlen_r, int *rdstart_r,
const byte *eo_dgram, int eo_dglen, int eo_cbyte,
int *eo_matched_r);
/* Like adns__findrr_checked, except that the datagram and
const byte *eo_dgram, int eo_dglen, int eo_cbyte,
int *eo_matched_r);
/* Like adns__findrr_checked, except that the datagram and
@@
-523,6
+531,11
@@
adns_status adns__findrr_anychk(adns_query qu, int serv,
* untruncated.
*/
* untruncated.
*/
+void adns__update_expires(adns_query qu, unsigned long ttl, struct timeval now);
+/* Updates the `expires' field in the query, so that it doesn't exceed
+ * now + ttl.
+ */
+
int vbuf__append_quoted1035(vbuf *vb, const byte *buf, int len);
/* From event.c: */
int vbuf__append_quoted1035(vbuf *vb, const byte *buf, int len);
/* From event.c: */
@@
-581,5
+594,11
@@
static inline int ctype_alpha(int c) {
#define GETIL_B(cb) (((dgram)[(cb)++]) & 0x0ff)
#define GET_B(cb,tv) ((tv)= GETIL_B((cb)))
#define GET_W(cb,tv) ((tv)=0, (tv)|=(GETIL_B((cb))<<8), (tv)|=GETIL_B(cb), (tv))
#define GETIL_B(cb) (((dgram)[(cb)++]) & 0x0ff)
#define GET_B(cb,tv) ((tv)= GETIL_B((cb)))
#define GET_W(cb,tv) ((tv)=0, (tv)|=(GETIL_B((cb))<<8), (tv)|=GETIL_B(cb), (tv))
+#define GET_L(cb,tv) ( (tv)=0, \
+ (tv)|=(GETIL_B((cb))<<24), \
+ (tv)|=(GETIL_B((cb))<<16), \
+ (tv)|=(GETIL_B((cb))<<8), \
+ (tv)|=GETIL_B(cb), \
+ (tv) )
#endif
#endif
diff --git
a/src/parse.c
b/src/parse.c
index 22d9d96cea3fb4269b5420955c8a3925abc321c3..842556a79ae55ff93a540597ecd4b7a70d4c3dc2 100644
(file)
--- a/
src/parse.c
+++ b/
src/parse.c
@@
-150,13
+150,15
@@
adns_status adns__parse_domain(adns_state ads, int serv, adns_query qu,
adns_status adns__findrr_anychk(adns_query qu, int serv,
const byte *dgram, int dglen, int *cbyte_io,
adns_status adns__findrr_anychk(adns_query qu, int serv,
const byte *dgram, int dglen, int *cbyte_io,
- int *type_r, int *class_r, int *rdlen_r, int *rdstart_r,
+ int *type_r, int *class_r, unsigned long *ttl_r,
+ int *rdlen_r, int *rdstart_r,
const byte *eo_dgram, int eo_dglen, int eo_cbyte,
int *eo_matched_r) {
findlabel_state fls, eo_fls;
int cbyte;
int tmp, rdlen, mismatch;
const byte *eo_dgram, int eo_dglen, int eo_cbyte,
int *eo_matched_r) {
findlabel_state fls, eo_fls;
int cbyte;
int tmp, rdlen, mismatch;
+ unsigned long ttl;
int lablen, labstart, ch;
int eo_lablen, eo_labstart, eo_ch;
adns_status st;
int lablen, labstart, ch;
int eo_lablen, eo_labstart, eo_ch;
adns_status st;
@@
-193,7
+195,11
@@
adns_status adns__findrr_anychk(adns_query qu, int serv,
if (cbyte+10>dglen) goto x_truncated;
GET_W(cbyte,tmp); *type_r= tmp;
GET_W(cbyte,tmp); *class_r= tmp;
if (cbyte+10>dglen) goto x_truncated;
GET_W(cbyte,tmp); *type_r= tmp;
GET_W(cbyte,tmp); *class_r= tmp;
- cbyte+= 4; /* we skip the TTL */
+
+ GET_L(cbyte,ttl);
+ if (ttl > MAXTTLBELIEVE) ttl= MAXTTLBELIEVE;
+ *ttl_r= ttl;
+
GET_W(cbyte,rdlen); if (rdlen_r) *rdlen_r= rdlen;
if (rdstart_r) *rdstart_r= cbyte;
cbyte+= rdlen;
GET_W(cbyte,rdlen); if (rdlen_r) *rdlen_r= rdlen;
if (rdstart_r) *rdstart_r= cbyte;
cbyte+= rdlen;
@@
-208,23
+214,24
@@
adns_status adns__findrr_anychk(adns_query qu, int serv,
adns_status adns__findrr(adns_query qu, int serv,
const byte *dgram, int dglen, int *cbyte_io,
adns_status adns__findrr(adns_query qu, int serv,
const byte *dgram, int dglen, int *cbyte_io,
- int *type_r, int *class_r, int *rdlen_r, int *rdstart_r,
+ int *type_r, int *class_r, unsigned long *ttl_r,
+ int *rdlen_r, int *rdstart_r,
int *ownermatchedquery_r) {
if (!ownermatchedquery_r) {
return adns__findrr_anychk(qu,serv,
dgram,dglen,cbyte_io,
int *ownermatchedquery_r) {
if (!ownermatchedquery_r) {
return adns__findrr_anychk(qu,serv,
dgram,dglen,cbyte_io,
- type_r,class_r,rdlen_r,rdstart_r,
+ type_r,class_r,
ttl_r,
rdlen_r,rdstart_r,
0,0,0, 0);
} else if (!qu->cname_dgram) {
return adns__findrr_anychk(qu,serv,
dgram,dglen,cbyte_io,
0,0,0, 0);
} else if (!qu->cname_dgram) {
return adns__findrr_anychk(qu,serv,
dgram,dglen,cbyte_io,
- type_r,class_r,rdlen_r,rdstart_r,
+ type_r,class_r,
ttl_r,
rdlen_r,rdstart_r,
qu->query_dgram,qu->query_dglen,DNS_HDRSIZE,
ownermatchedquery_r);
} else {
return adns__findrr_anychk(qu,serv,
dgram,dglen,cbyte_io,
qu->query_dgram,qu->query_dglen,DNS_HDRSIZE,
ownermatchedquery_r);
} else {
return adns__findrr_anychk(qu,serv,
dgram,dglen,cbyte_io,
- type_r,class_r,rdlen_r,rdstart_r,
+ type_r,class_r,
ttl_r,
rdlen_r,rdstart_r,
qu->cname_dgram,qu->cname_dglen,qu->cname_begin,
ownermatchedquery_r);
}
qu->cname_dgram,qu->cname_dglen,qu->cname_begin,
ownermatchedquery_r);
}
diff --git
a/src/query.c
b/src/query.c
index 545feec27414567527ef56cae967a72d6bffd568..666fdd705948c7714551bfb311734dc0932f0329 100644
(file)
--- a/
src/query.c
+++ b/
src/query.c
@@
-64,6
+64,7
@@
int adns__internal_submit(adns_state ads, adns_query *query_r,
qu->udpsent= qu->tcpfailed= 0;
timerclear(&qu->timeout);
memcpy(&qu->ctx,ctx,sizeof(qu->ctx));
qu->udpsent= qu->tcpfailed= 0;
timerclear(&qu->timeout);
memcpy(&qu->ctx,ctx,sizeof(qu->ctx));
+ qu->expires= now.tv_sec + MAXTTLBELIEVE;
qu->answer->status= adns_s_ok;
qu->answer->cname= 0;
qu->answer->status= adns_s_ok;
qu->answer->cname= 0;
@@
-192,6
+193,8
@@
void adns__transfer_interim(adns_query from, adns_query to, void *block, size_t
from->interim_allocd -= sz;
to->interim_allocd += sz;
from->interim_allocd -= sz;
to->interim_allocd += sz;
+
+ if (to->expires > from->expires) to->expires= from->expires;
}
void *adns__alloc_final(adns_query qu, size_t sz) {
}
void *adns__alloc_final(adns_query qu, size_t sz) {
@@
-255,6
+258,15
@@
void adns_cancel(adns_query qu) {
free(qu);
}
free(qu);
}
+void adns__update_expires(adns_query qu, unsigned long ttl, struct timeval now) {
+ time_t max;
+
+ assert(ttl <= MAXTTLBELIEVE);
+ max= now.tv_sec + ttl;
+ if (qu->expires < max) return;
+ qu->expires= max;
+}
+
static void makefinal_query(adns_query qu) {
adns_answer *ans;
int rrn;
static void makefinal_query(adns_query qu) {
adns_answer *ans;
int rrn;
@@
-276,7
+288,7
@@
static void makefinal_query(adns_query qu) {
for (rrn=0; rrn<ans->nrrs; rrn++)
qu->typei->makefinal(qu, ans->rrs.bytes + rrn*ans->rrsz);
}
for (rrn=0; rrn<ans->nrrs; rrn++)
qu->typei->makefinal(qu, ans->rrs.bytes + rrn*ans->rrsz);
}
-
+
free_query_allocs(qu);
return;
free_query_allocs(qu);
return;
@@
-305,6
+317,7
@@
void adns__query_done(adns_query qu) {
qu->ads);
}
qu->ads);
}
+ ans->expires= qu->expires;
parent= qu->parent;
if (parent) {
LIST_UNLINK_PART(parent->children,qu,siblings.);
parent= qu->parent;
if (parent) {
LIST_UNLINK_PART(parent->children,qu,siblings.);
diff --git
a/src/reply.c
b/src/reply.c
index c37bb4069683038b858fb99cd070f89f5c775472..452c5f69080ad4fe4822f7e82fafe4544322335b 100644
(file)
--- a/
src/reply.c
+++ b/
src/reply.c
@@
-33,6
+33,7
@@
void adns__procdgram(adns_state ads, const byte *dgram, int dglen,
int rrtype, rrclass, rdlength, rdstart;
int anstart, nsstart, arstart;
int ownermatched, l, nrrs;
int rrtype, rrclass, rdlength, rdstart;
int anstart, nsstart, arstart;
int ownermatched, l, nrrs;
+ unsigned long ttl, soattl;
const typeinfo *typei;
adns_query qu, nqu;
dns_rcode rcode;
const typeinfo *typei;
adns_query qu, nqu;
dns_rcode rcode;
@@
-138,7
+139,7
@@
void adns__procdgram(adns_state ads, const byte *dgram, int dglen,
for (rri= 0; rri<ancount; rri++) {
rrstart= cbyte;
st= adns__findrr(qu,serv, dgram,dglen,&cbyte,
for (rri= 0; rri<ancount; rri++) {
rrstart= cbyte;
st= adns__findrr(qu,serv, dgram,dglen,&cbyte,
- &rrtype,&rrclass,&rdlength,&rdstart,
+ &rrtype,&rrclass,&
ttl, &
rdlength,&rdstart,
&ownermatched);
if (st) { adns__query_fail(qu,st); return; }
if (rrtype == -1) goto x_truncated;
&ownermatched);
if (st) { adns__query_fail(qu,st); return; }
if (rrtype == -1) goto x_truncated;
@@
-177,6
+178,7
@@
void adns__procdgram(adns_state ads, const byte *dgram, int dglen,
memcpy(qu->answer->cname,qu->vb.buf,l);
cname_here= 1;
memcpy(qu->answer->cname,qu->vb.buf,l);
cname_here= 1;
+ adns__update_expires(qu,ttl,now);
/* If we find the answer section truncated after this point we restart
* the query at the CNAME; if beforehand then we obviously have to use
* TCP. If there is no truncation we can use the whole answer if
/* If we find the answer section truncated after this point we restart
* the query at the CNAME; if beforehand then we obviously have to use
* TCP. If there is no truncation we can use the whole answer if
@@
-203,18
+205,13
@@
void adns__procdgram(adns_state ads, const byte *dgram, int dglen,
if (!wantedrrs) {
/* Oops, NODATA or NXDOMAIN or perhaps a referral (which would be a problem) */
if (!wantedrrs) {
/* Oops, NODATA or NXDOMAIN or perhaps a referral (which would be a problem) */
-
- if (rcode == rcode_nxdomain) {
- adns__query_fail(qu,adns_s_nxdomain);
- return;
- }
/* RFC2308: NODATA has _either_ a SOA _or_ _no_ NS records in authority section */
/* RFC2308: NODATA has _either_ a SOA _or_ _no_ NS records in authority section */
- foundsoa= 0; foundns= 0;
+ foundsoa= 0;
soattl= 0;
foundns= 0;
for (rri= 0; rri<nscount; rri++) {
rrstart= cbyte;
st= adns__findrr(qu,serv, dgram,dglen,&cbyte,
for (rri= 0; rri<nscount; rri++) {
rrstart= cbyte;
st= adns__findrr(qu,serv, dgram,dglen,&cbyte,
- &rrtype,&rrclass,&rdlength,&rdstart, 0);
+ &rrtype,&rrclass,&
ttl, &
rdlength,&rdstart, 0);
if (st) { adns__query_fail(qu,st); return; }
if (rrtype==-1) goto x_truncated;
if (rrclass != DNS_CLASS_IN) {
if (st) { adns__query_fail(qu,st); return; }
if (rrtype==-1) goto x_truncated;
if (rrclass != DNS_CLASS_IN) {
@@
-223,12
+220,20
@@
void adns__procdgram(adns_state ads, const byte *dgram, int dglen,
rrclass,DNS_CLASS_IN);
continue;
}
rrclass,DNS_CLASS_IN);
continue;
}
- if (rrtype == adns_r_soa_raw) { foundsoa= 1; break; }
+ if (rrtype == adns_r_soa_raw) { foundsoa= 1;
soattl= ttl;
break; }
else if (rrtype == adns_r_ns_raw) { foundns= 1; }
}
else if (rrtype == adns_r_ns_raw) { foundns= 1; }
}
+
+ if (rcode == rcode_nxdomain) {
+ /* We still wanted to look for the SOA so we could find the TTL. */
+ adns__update_expires(qu,soattl,now);
+ adns__query_fail(qu,adns_s_nxdomain);
+ return;
+ }
if (foundsoa || !foundns) {
/* Aha ! A NODATA response, good. */
if (foundsoa || !foundns) {
/* Aha ! A NODATA response, good. */
+ adns__update_expires(qu,soattl,now);
adns__query_fail(qu,adns_s_nodata);
return;
}
adns__query_fail(qu,adns_s_nodata);
return;
}
@@
-275,13
+280,14
@@
void adns__procdgram(adns_state ads, const byte *dgram, int dglen,
for (rri=0, nrrs=0; rri<ancount; rri++) {
st= adns__findrr(qu,serv, dgram,dglen,&cbyte,
for (rri=0, nrrs=0; rri<ancount; rri++) {
st= adns__findrr(qu,serv, dgram,dglen,&cbyte,
- &rrtype,&rrclass,&rdlength,&rdstart,
+ &rrtype,&rrclass,&
ttl, &
rdlength,&rdstart,
&ownermatched);
assert(!st); assert(rrtype != -1);
if (rrclass != DNS_CLASS_IN ||
rrtype != (qu->typei->type & adns__rrt_typemask) ||
!ownermatched)
continue;
&ownermatched);
assert(!st); assert(rrtype != -1);
if (rrclass != DNS_CLASS_IN ||
rrtype != (qu->typei->type & adns__rrt_typemask) ||
!ownermatched)
continue;
+ adns__update_expires(qu,ttl,now);
st= typei->parse(&pai, rdstart,rdstart+rdlength, rrsdata+nrrs*typei->rrsz);
if (st) { adns__query_fail(qu,st); return; }
if (rdstart==-1) goto x_truncated;
st= typei->parse(&pai, rdstart,rdstart+rdlength, rrsdata+nrrs*typei->rrsz);
if (st) { adns__query_fail(qu,st); return; }
if (rdstart==-1) goto x_truncated;
diff --git
a/src/types.c
b/src/types.c
index bd87450a80349cddb2efec32b0927ae9b708f88e..deac6c4270498144e134e35bbea7d030b4c1a1d2 100644
(file)
--- a/
src/types.c
+++ b/
src/types.c
@@
-381,11
+381,12
@@
static adns_status pap_findaddrs(const parseinfo *pai, adns_rr_hostaddr *ha,
int *cbyte_io, int count, int dmstart) {
int rri, naddrs;
int type, class, rdlen, rdstart, ownermatched;
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,
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) {
pai->dgram, pai->dglen, dmstart, &ownermatched);
if (st) return st;
if (!ownermatched || class != DNS_CLASS_IN || type != adns_r_a) {
@@
-395,6
+396,7
@@
static adns_status pap_findaddrs(const parseinfo *pai, adns_rr_hostaddr *ha,
naddrs= 0;
}
if (!adns__vbuf_ensure(&pai->qu->vb, (naddrs+1)*sizeof(adns_rr_addr))) R_NOMEM;
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;
st= pa_addr(pai, rdstart,rdstart+rdlen,
pai->qu->vb.buf + naddrs*sizeof(adns_rr_addr));
if (st) return st;