#if !defined(lint) && !defined(SABER)
-static const char rcsid[] = "$Id: res_update.c,v 1.5 2000/04/06 23:02:59 mellon Exp $";
+static const char rcsid[] = "$Id: res_update.c,v 1.6 2000/05/01 23:46:39 mellon Exp $";
#endif /* not lint */
/*
static void dprintf(const char *, ...);
void tkey_free (ns_tsig_key **);
-int find_tsig_key (ns_tsig_key **, const char *);
ns_rcode
res_nupdate(res_state statp, ns_updrec *rrecp_in) {
struct sockaddr_in nsaddrs[MAXNS];
ns_rcode rcode;
ns_tsig_key *key;
+ void *zcookie = 0;
+ void *zcookp = &zcookie;
+ again:
/* Make sure all the updates are in the same zone, and find out
what zone they are in. */
zptr = NULL;
RES_EXHAUSTIVE,
tgrp.z_origin,
sizeof tgrp.z_origin,
- tgrp.z_nsaddrs, MAXNS);
+ tgrp.z_nsaddrs, MAXNS, zcookp);
if (tgrp.z_nscount <= 0) {
rcode = ns_r_notzone;
goto done;
/* Send the update and remember the result. */
key = (ns_tsig_key *)0;
- if (!find_tsig_key (&key, zptr->z_origin)) {
+ if (!find_tsig_key (&key, zptr->z_origin, zcookie)) {
rval = res_nsendsigned(statp, packet, n, key,
answer, sizeof answer);
tkey_free (&key);
goto undone;
}
rcode = ((HEADER *)answer)->rcode;
+ if (zcookie && rcode == ns_r_badsig) {
+ repudiate_zone (&zcookie);
+ }
undone:
/* Restore resolver's nameserver set. */
free(zptr);
}
+ /* If the update failed because we used a cached zone and it
+ didn't work, try it again without the cached zone. */
+ if (zcookp && (rcode == ns_r_notzone || rcode == ns_r_badsig)) {
+ zcookp = 0;
+ goto again;
+ }
+
+ if (zcookie)
+ forget_zone (&zcookie);
return rcode;
}