diff options
author | peter <peter@FreeBSD.org> | 1998-05-03 04:11:49 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 1998-05-03 04:11:49 +0000 |
commit | 0666320b4eda500556d2c671c9527c9000057492 (patch) | |
tree | 759849259eae9f7cb0d3ddbd7a131081c6688068 /contrib/bind/bin/named/ns_ncache.c | |
parent | 58ca52f41726d17758909ddafba7b6b6766c789c (diff) | |
download | FreeBSD-src-0666320b4eda500556d2c671c9527c9000057492.zip FreeBSD-src-0666320b4eda500556d2c671c9527c9000057492.tar.gz |
Import (trimmed) ISC bind-8.1.2-t3b. This will be updated to 8.1.2 on
final release.
Obtained from: ftp.isc.org
Diffstat (limited to 'contrib/bind/bin/named/ns_ncache.c')
-rw-r--r-- | contrib/bind/bin/named/ns_ncache.c | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/contrib/bind/bin/named/ns_ncache.c b/contrib/bind/bin/named/ns_ncache.c new file mode 100644 index 0000000..413ccc6 --- /dev/null +++ b/contrib/bind/bin/named/ns_ncache.c @@ -0,0 +1,226 @@ +#if !defined(lint) && !defined(SABER) +static char rcsid[] = "$Id: ns_ncache.c,v 8.17 1998/03/20 01:12:01 halley Exp $"; +#endif /* not lint */ + +/* + * Copyright (c) 1996, 1997 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#include "port_before.h" + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/socket.h> +#include <sys/file.h> + +#include <netinet/in.h> +#include <arpa/nameser.h> + +#include <errno.h> +#include <resolv.h> +#include <stdio.h> +#include <string.h> +#include <syslog.h> +#include <time.h> + +#include <isc/eventlib.h> +#include <isc/logging.h> + +#include "port_after.h" + +#include "named.h" + +#define BOUNDS_CHECK(ptr, count) \ + do { \ + if ((ptr) + (count) > eom) { \ + return; \ + } \ + } while (0) + +void +cache_n_resp(u_char *msg, int msglen, struct sockaddr_in from) { + struct databuf *dp; + HEADER *hp; + u_char *cp, *eom, *rdatap; + char dname[MAXDNAME]; + int n; + int type, class; + int Vcode; + int flags; + u_int16_t ancount; + u_int dlen; + + nameserIncr(from.sin_addr, nssRcvdNXD); + + hp = (HEADER *)msg; + cp = msg+HFIXEDSZ; + eom = msg + msglen; + + n = dn_expand(msg, eom, cp, dname, sizeof dname); + if (n < 0) { + ns_debug(ns_log_ncache, 1, + "Query expand name failed: cache_n_resp"); + hp->rcode = FORMERR; + return; + } + cp += n; + BOUNDS_CHECK(cp, 2 * INT16SZ); + GETSHORT(type, cp); + GETSHORT(class, cp); + ns_debug(ns_log_ncache, 1, "ncache: dname %s, type %d, class %d", + dname, type, class); + + ancount = ntohs(hp->ancount); + + while (ancount--) { + u_int32_t ttl; + u_int16_t atype; + u_int16_t aclass; + n = dn_skipname(cp, eom); + if (n < 0) { + ns_debug(ns_log_ncache, 3, "ncache: form error"); + return; + } + cp += n; + BOUNDS_CHECK(cp, 3 * INT16SZ + INT32SZ); + GETSHORT(atype, cp); + GETSHORT(aclass, cp); + if (atype != T_CNAME || aclass != class) { + ns_debug(ns_log_ncache, 3, "ncache: form error"); + return; + } + GETLONG(ttl, cp); + GETSHORT(dlen, cp); + BOUNDS_CHECK(cp, dlen); + rdatap = cp; + n = dn_expand(msg, msg + msglen, cp, dname, sizeof dname); + if (n < 0) { + ns_debug(ns_log_ncache, 3, "ncache: form error"); + return; + } + cp += n; + if (cp != rdatap + dlen) { + ns_debug(ns_log_ncache, 3, "ncache: form error"); + return; + } + } + +#ifdef RETURNSOA + if (hp->nscount) { + u_int32_t ttl; + u_int16_t atype; + u_char *tp = cp; + u_char *cp1; + u_char data[MAXDATA]; + size_t len = sizeof data; + + /* we store NXDOMAIN as T_SOA regardless of the query type */ + if (hp->rcode == NXDOMAIN) + type = T_SOA; + + /* store ther SOA record */ + n = dn_skipname(tp, msg + msglen); + if (n < 0) { + ns_debug(ns_log_ncache, 3, "ncache: form error"); + return; + } + tp += n; + + BOUNDS_CHECK(tp, 3 * INT16SZ + INT32SZ); + GETSHORT(atype, tp); /* type */ + if (atype != T_SOA) { + ns_debug(ns_log_ncache, 3, + "ncache: type (%d) != T_SOA", atype); + goto no_soa; + } + tp += INT16SZ; /* class */ + GETLONG(ttl, tp); /* ttl */ + GETSHORT(dlen, tp); /* dlen */ + BOUNDS_CHECK(tp, dlen); + rdatap = tp; + + /* origin */ + n = dn_expand(msg, msg + msglen, tp, (char*)data, len); + if (n < 0) { + ns_debug(ns_log_ncache, 3, + "ncache: origin form error"); + return; + } + tp += n; + n = strlen((char*)data) + 1; + cp1 = data + n; + len -= n; + /* mail */ + n = dn_expand(msg, msg + msglen, tp, (char*)cp1, len); + if (n < 0) { + ns_debug(ns_log_ncache, 3, "ncache: mail form error"); + return; + } + tp += n; + n = strlen((char*)cp1) + 1; + cp1 += n; + len -= n; + n = 5 * INT32SZ; + BOUNDS_CHECK(tp, n); + memcpy(cp1, tp, n); + /* serial, refresh, retry, expire, min */ + cp1 += n; + len -= n; + tp += n; + if (tp != rdatap + dlen) { + ns_debug(ns_log_ncache, 3, "ncache: form error"); + return; + } + /* store the zone of the soa record */ + n = dn_expand(msg, msg + msglen, cp, (char*)cp1, len); + if (n < 0) { + ns_debug(ns_log_ncache, 3, "ncache: form error 2"); + return; + } + n = strlen((char*)cp1) + 1; + cp1 += n; + + dp = savedata(class, type, MIN(ttl, NTTL) + tt.tv_sec, data, + cp1 - data); + } else { + no_soa: +#endif + dp = savedata(class, type, NTTL + tt.tv_sec, NULL, 0); +#ifdef RETURNSOA + } +#endif + dp->d_zone = DB_Z_CACHE; + dp->d_cred = hp->aa ? DB_C_AUTH : DB_C_ANSWER; + dp->d_clev = 0; + if(hp->rcode == NXDOMAIN) { + dp->d_rcode = NXDOMAIN; + flags = DB_NODATA|DB_NOTAUTH|DB_NOHINTS; + } else { + dp->d_rcode = NOERROR_NODATA; + flags = DB_NOTAUTH|DB_NOHINTS; + } + + if ((n = db_update(dname, dp, dp, NULL, flags, hashtab, from)) != OK) { + ns_debug(ns_log_ncache, 1, + "db_update failed (%d), cache_n_resp()", n); + db_freedata(dp); + return; + } + ns_debug(ns_log_ncache, 4, + "ncache succeeded: [%s %s %s] rcode:%d ttl:%ld", + dname, p_type(type), p_class(class), + dp->d_rcode, (long)(dp->d_ttl - tt.tv_sec)); +} |