DDNS Update Error not really fixed?

John Hascall john at iastate.edu
Fri Oct 26 15:57:10 UTC 2007


In the Release notes file (for 3.1.0) I see this entry:

                        Changes since 3.0.3

- A DDNS update handling function was misusing the DNS error codes, rather
  than the internal generic result enumeration.  The result is a confusing
  syslog line, logging the wrong condition.

but in my syslog I am seeing:

Oct 26 09:38:04 netreg-1 dhcpd: \
Unable to add forward map from d810laptop.iastate.edu to 10.32.106.1: timed out

but the actual error was not a timeout -- it was a refused (dhcpd is not
permitted to update that zone).


I think this is triggering a bug which prevents DDNS updates from
working properly.

In the function res_nupdate() in the file minires/res_update.c
starting at line 163 we see the code below.

163     rcode = find_tsig_key (&key, zptr->z_origin, zcookie);
164     if (rcode == ISC_R_SUCCESS) {
165             rcode = res_nsendsigned(statp, packet, n, key,
166                                     answer, sizeof answer, &rval);
167             tkey_free (&key);
168     } else if (rcode == ISC_R_NOTFOUND || rcode == ISC_R_KEY_UNKNOWN) {
169             rcode = res_nsend(statp, packet, n,
170                               answer, sizeof answer, &rval);
171     }
172     if (rcode != ISC_R_SUCCESS)
173             goto undone;
174
175     rcode = ns_rcode_to_isc (((HEADER *)answer)->rcode);
176     if (zcookie && rcode == ISC_R_BADSIG) {
177             repudiate_zone (&zcookie);
178     }
179
undone:
181     /* Restore resolver's nameserver set. */
182     statp->nscount = nscopy(statp->nsaddr_list, nsaddrs, nscount);
183     nscount = 0;
done:
185     if (zptr) {
186             if ((zptr->z_flags & ZG_F_ZONESECTADDED) != 0)
187                     res_freeupdrec(ISC_LIST_HEAD(zptr->z_rrlist));
188             free(zptr);
189     }
190
191     /* If the update failed because we used a cached zone and it
192        didn't work, try it again without the cached zone. */
193     if (zcookp && (rcode == ISC_R_NOTZONE || rcode == ISC_R_BADSIG)) {
194             zcookp = 0;
195             goto again;
196     }

If res_nsend (169) fails because the update is refused
for that zone, then it (curiously) returns ISC_R_TIMEOUT
which becomes rcode.

Then the if-statement (172/173) jumps to line 180.

Then the if-statement on line 193 fails because the rcode is
not ISC_R_NOTZONE thus causing the update to incorrectly
NOT be tried again w/o the cached zone.

If you have explicit zone statements for all your zones in your
config file you probably avoid this problem because you won't have
speculative-but-incorrect zones cached.  See my message dated 10-Oct-2007
titled "DDNS update to wrong zone" for background.

John


More information about the dhcp-users mailing list