diff options
Diffstat (limited to 'contrib/bind/bin/named/db_ixfr.c')
-rw-r--r-- | contrib/bind/bin/named/db_ixfr.c | 983 |
1 files changed, 0 insertions, 983 deletions
diff --git a/contrib/bind/bin/named/db_ixfr.c b/contrib/bind/bin/named/db_ixfr.c deleted file mode 100644 index 231db12aa08a..000000000000 --- a/contrib/bind/bin/named/db_ixfr.c +++ /dev/null @@ -1,983 +0,0 @@ -#if !defined(lint) && !defined(SABER) -static char rcsid[] = "$Id: db_ixfr.c,v 8.31 2002/01/02 04:47:10 marka Exp $"; -#endif - -/* - * Portions Copyright (c) 1999 by Check Point Software Technologies, Inc. - * - * 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, and that - * the name of Check Point Software Technologies Incorporated not be used - * in advertising or publicity pertaining to distribution of the document - * or software without specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND CHECK POINT SOFTWARE TECHNOLOGIES - * INCORPORATED DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. - * IN NO EVENT SHALL CHECK POINT SOFTWARE TECHNOLOGIES INCORPRATED - * 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. - */ - -/* - * Manage ixfr transaction log - */ - -#include "port_before.h" - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/stat.h> -#include <sys/socket.h> - -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <arpa/inet.h> - -#include <ctype.h> -#include <errno.h> -#include <netdb.h> -#include <resolv.h> -#include <res_update.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <time.h> - -#include <isc/eventlib.h> -#include <isc/logging.h> -#include <isc/memcluster.h> -#include <isc/misc.h> - -#include "port_after.h" - -#include "named.h" - -#define DBIXFR_ERROR (-1) -#define DBIXFR_FOUND_RR 2 -#define DBIXFR_END 3 - -static int ixfr_getdelta(struct zoneinfo *, FILE *, const char *, char *, - ns_updque *, u_int32_t *, u_int32_t *); - -ns_deltalist * -ixfr_get_change_list(struct zoneinfo *zp, - u_int32_t from_serial, u_int32_t to_serial) -{ - FILE * fp = NULL; - u_int32_t old_serial, new_serial; - char origin[MAXDNAME]; - ns_deltalist *dlhead = NULL; - int ret; - ns_updrec *uprec; - ns_delta *dl; - - if (SEQ_GT(from_serial, to_serial)) - return (NULL); - - dlhead = memget(sizeof(*dlhead)); - if (dlhead == NULL) - return (NULL); - INIT_LIST(*dlhead); - - if ((fp = fopen(zp->z_ixfr_base, "r")) == NULL) { - ns_warning(ns_log_db, "%s: %s", - zp->z_ixfr_base, strerror(errno)); - goto cleanup; - } - strcpy(origin, zp->z_origin); - lineno = 1; - old_serial = new_serial = 0; - - for (;;) { - dl = memget(sizeof *dl); - if (dl == NULL) { - ns_warning(ns_log_db, - "ixfr_get_change_list: out of memory"); - goto cleanup; - } - INIT_LINK(dl, d_link); - INIT_LIST(dl->d_changes); - ret = ixfr_getdelta(zp, fp, zp->z_ixfr_base, origin, - &dl->d_changes, &old_serial, &new_serial); - switch (ret) { - case DBIXFR_ERROR: - ns_warning(ns_log_db, "Logical error in %s: unlinking", - zp->z_ixfr_base); - if (fp != NULL) { - (void) my_fclose(fp); - fp = NULL; - } - unlink(zp->z_ixfr_base); - goto cleanup; - - case DBIXFR_FOUND_RR: - ns_debug(ns_log_default, 4, - "ixfr_getdelta DBIXFR_FOUND_RR (%s)", - zp->z_origin); - if (EMPTY(*dlhead)) { - /* skip updates prior to the one we want */ - uprec = HEAD(dl->d_changes); - INSIST(uprec != NULL); - if (SEQ_LT(uprec->r_zone, from_serial) || - SEQ_GT(uprec->r_zone, to_serial)) - { - while ((uprec = HEAD(dl->d_changes)) != NULL) { - UNLINK(dl->d_changes, uprec, r_link); - - if (uprec->r_dp != NULL) - db_detach(&uprec->r_dp); - res_freeupdrec(uprec); - } - memput(dl, sizeof *dl); - break; - } - else if (uprec->r_zone > from_serial) { - /* missed the boat */ - ns_debug(ns_log_default, 3, - "ixfr_getdelta first SOA is %d, asked for %d (%s)", - uprec->r_zone, - from_serial, - zp->z_origin); - goto cleanup; - } - } - ns_debug(ns_log_default, 4, - "adding to change list (%s)", - zp->z_origin); - APPEND(*dlhead, dl, d_link); - break; - - case DBIXFR_END: - ns_debug(ns_log_default, 4, - "ixfr_getdelta DBIXFR_END (%s)", - zp->z_origin); - (void) my_fclose(fp); - memput(dl, sizeof *dl); - return (dlhead); - - default: - (void) my_fclose(fp); - if (dl != NULL) - memput(dl, sizeof *dl); - return (NULL); - } - } - - cleanup: - if (fp != NULL) - (void) my_fclose(fp); - - while ((dl = HEAD(*dlhead)) != NULL) { - UNLINK(*dlhead, dl, d_link); - while ((uprec = HEAD(dl->d_changes)) != NULL) { - UNLINK(dl->d_changes, uprec, r_link); - - if (uprec->r_dp != NULL) - db_detach(&uprec->r_dp); - uprec->r_dp = NULL; - res_freeupdrec(uprec); - } - memput(dl, sizeof *dl); - } - memput(dlhead, sizeof *dlhead); - return (NULL); -} - -/* - * int ixfr_have_log(struct zoneinfo *zp,u_int32_t from_serial, - * u_int32_t to_serial) - * - * verify that ixfr transaction log contains changes - * from from_serial to to_serial - * - * returns: - * 0 = serial number is up to date - * 1 = transmission is possible - * -1 = error while opening the ixfr transaction log - * -2 = error in parameters - * -3 = logical error in the history file - */ -int -ixfr_have_log(struct zoneinfo *zp, u_int32_t from_serial, u_int32_t to_serial) -{ - FILE *fp; - u_int32_t old_serial = 0, new_serial = 0; - u_int32_t last_serial = 0; - u_int32_t first_serial = 0; - char buf[BUFSIZ]; - char *cp; - struct stat st; - int nonempty_lineno = -1, prev_pktdone = 0, cont = 0, - inside_next = 0; - int err; - int first = 0; - int rval = 0; - int id, rcode = NOERROR; - if (SEQ_GT(from_serial, to_serial)) - return (-2); - if (from_serial == to_serial) - return (0); - /* If there is no log file, just return. */ - if (zp->z_ixfr_base == NULL || zp->z_updatelog == NULL) - return (-1); - if (zp->z_serial_ixfr_start > 0) { - if (from_serial >= zp->z_serial_ixfr_start) - return (1); - } - if (stat(zp->z_ixfr_base, &st) < 0) { - if (errno != ENOENT) - ns_error(ns_log_db, - "unexpected stat(%s) failure: %s", - zp->z_ixfr_base, strerror(errno)); - return (-1); - } - if ((fp = fopen(zp->z_ixfr_base, "r")) == NULL) { - ns_warning(ns_log_db, "%s: %s", - zp->z_ixfr_base, strerror(errno)); - return (-1); - } - if (fgets(buf, sizeof(buf), fp) == NULL) { - ns_error(ns_log_update, "fgets() from %s failed: %s", - zp->z_ixfr_base, strerror(errno)); - fclose(fp); - return (-1); - } - if (strcmp(buf, LogSignature) != 0) { - ns_error(ns_log_update, "invalid log file %s", - zp->z_ixfr_base); - fclose(fp); - return (-3); - } - lineno = 1; - first = 1; - for (;;) { - if (getword(buf, sizeof buf, fp, 0)) { - nonempty_lineno = lineno; - } else { - if (lineno == (nonempty_lineno + 1)) - continue; - inside_next = 0; - prev_pktdone = 1; - cont = 1; - } - if (!strcasecmp(buf, "[DYNAMIC_UPDATE]") || - !strcasecmp(buf, "[IXFR_UPDATE]")) { - err = 0; - rcode = NOERROR; - cp = fgets(buf, sizeof buf, fp); - if (cp != NULL) - lineno++; - if (cp == NULL || !sscanf((char *) cp, "id %d", &id)) - id = -1; - inside_next = 1; - prev_pktdone = 1; - cont = 1; - } else if (!strcasecmp(buf, "serial")) { - cp = fgets(buf, sizeof buf, fp); - if (cp != NULL) - lineno++; - if (sscanf((char *) cp, "%u", &old_serial)) { - if (first == 1) { - first = 0; - first_serial = old_serial; - } - last_serial = old_serial; - if (from_serial >= old_serial) { - rval = 1; - } - } - prev_pktdone = 1; - cont = 1; - } else if (!strcasecmp(buf, "[INCR_SERIAL]")) { - /* XXXRTH not enough error checking here */ - cp = fgets(buf, sizeof buf, fp); - if (cp != NULL) - lineno++; - if (cp == NULL || - sscanf((char *) cp, "from %u to %u", - &old_serial, &new_serial) != 2) { - rval = -3; - break; - } else if (from_serial >= old_serial) { - if (first == 1) { - first = 0; - first_serial = old_serial; - } - last_serial = old_serial; - rval = 1; - } - } - if (prev_pktdone) { - prev_pktdone = 0; - if (feof(fp)) - break; - } - } - fclose(fp); - if (last_serial +1 < zp->z_serial) { - ns_warning(ns_log_db, - "%s: File Deleted. Found gap between serial:" - " %d and current serial: %d", - zp->z_ixfr_base, last_serial, zp->z_serial); - (void) unlink(zp->z_ixfr_base); - rval = -3; - } - if (from_serial < first_serial || from_serial > last_serial) - rval = -3; - if (rval == 1) - zp->z_serial_ixfr_start = first_serial; - return (rval); -} - -/* from db_load.c */ - -static struct map m_section[] = { - {"zone", S_ZONE}, - {"prereq", S_PREREQ}, - {"update", S_UPDATE}, - {"reserved", S_ADDT}, -}; -#define M_SECTION_CNT (sizeof(m_section) / sizeof(struct map)) - -/* from ns_req.c */ - -static struct map m_opcode[] = { - {"nxdomain", NXDOMAIN}, - {"yxdomain", YXDOMAIN}, - {"nxrrset", NXRRSET}, - {"yxrrset", YXRRSET}, - {"delete", DELETE}, - {"add", ADD}, -}; -#define M_OPCODE_CNT (sizeof(m_opcode) / sizeof(struct map)) - -/* XXXRTH workaround map difficulties */ -#define M_CLASS_CNT m_class_cnt -#define M_TYPE_CNT m_type_cnt - -/* - * read a line from the history of a zone. - * - * returns: - * - * DBIXFR_ERROR = an error occured - * DBIXFR_FOUND_RR = a rr encountered - * DBIXFR_END = end of file - */ -static int -ixfr_getdelta(struct zoneinfo *zp, FILE *fp, const char *filename, char *origin, - ns_updque *listuprec, u_int32_t *old_serial, - u_int32_t *new_serial) -{ - char data[MAXDATA], dnbuf[MAXDNAME], sclass[3]; - char *dname, *cp, *cp1; - char buf[MAXDATA]; - long unsigned lutmp; - u_int32_t serial = 0, ttl; - u_int32_t current_serial = 0; - int nonempty_lineno = -1, prev_pktdone = 0, cont = 0, - inside_next = 0; - int id; - int i, c, section, opcode, matches, zonenum, err, multiline; - int type, class; - u_int32_t n; - enum transport transport; - struct map *mp; - int zonelist[MAXDNAME]; - struct in_addr ina; - int datasize; - ns_updrec * rrecp; - u_long l; - -#define ERRTO(msg) if (1) { errtype = msg; goto err; } else (void)NULL - - err = 0; - transport = primary_trans; - lineno = 1; - zonenum = 0; - - /* - * Look for serial if "first" call othewise use new_serial to - * for current_serial. - */ - if (*old_serial == *new_serial && *old_serial == 0) - current_serial = 0; - else - current_serial = *new_serial; - - for (;;) { - dname = NULL; - if (!getword(buf, sizeof buf, fp, 0)) { - if (lineno == (nonempty_lineno + 1) && !(feof(fp))) { - /* - * End of a nonempty line inside an update - * packet or not inside an update packet. - */ - continue; - } - /* - * Empty line or EOF. - */ - if (feof(fp)) - break; - inside_next = 0; - cont = 1; - } else { - nonempty_lineno = lineno; - } - - if (!strcasecmp(buf, "[DYNAMIC_UPDATE]") || - !strcasecmp(buf, "[IXFR_UPDATE]")) { - cp = fgets(buf, sizeof buf, fp); - if (cp != NULL) - lineno++; - if (cp == NULL || !sscanf((char *) cp, "id %d", &id)) - id = -1; - inside_next = 1; - cont = 1; - } else if (!strcasecmp(buf, "[INCR_SERIAL]")) { - /* XXXRTH not enough error checking here */ - cp = fgets(buf, sizeof buf, fp); - if (cp != NULL) - lineno++; - if (cp == NULL || - sscanf((char *) cp, "from %u to %u", - old_serial, new_serial) != 2) { - ns_error(ns_log_update, - "incr_serial problem with %s", - zp->z_updatelog); - } else { - serial = get_serial(zp); - } - cont = 1; - } else if (!strcasecmp(buf, "[END_DELTA]")) { - prev_pktdone = 1; - cont = 1; - lineno++; - } - if (prev_pktdone) { - if (!EMPTY(*listuprec)) { - n++; - return (DBIXFR_FOUND_RR); - } - prev_pktdone = 0; - } - if (cont) { - cont = 0; - continue; - } - if (!inside_next) - continue; - /* - * inside the same update packet, continue accumulating - * records. - */ - section = -1; - n = strlen(buf); - if (buf[n - 1] == ':') - buf[--n] = '\0'; - for (mp = m_section; mp < m_section + M_SECTION_CNT; mp++) - if (!strcasecmp(buf, mp->token)) { - section = mp->val; - break; - } - ttl = 0; - type = -1; - class = zp->z_class; - n = 0; - data[0] = '\0'; - opcode = -1; - switch (section) { - case S_ZONE: - cp = fgets(buf, sizeof buf, fp); - if (!cp) - *buf = '\0'; - n = sscanf(cp, "origin %s class %s serial %lu", - origin, sclass, &lutmp); - serial = lutmp; - if (current_serial == 0) - current_serial = serial; - else if (current_serial != serial) { - ns_debug(ns_log_update, 1, - "%s:line %d serial # askew %d %d", - filename, lineno, serial, - current_serial); - current_serial = serial; - err++; - } - if (n != 3 || ns_samename(origin, zp->z_origin) != 1) - err++; - if (cp) - lineno++; - if (!err && inside_next) { - int success; - - dname = origin; - type = T_SOA; - class = res_nametoclass(sclass, &success); - if (!success) { - err++; - break; - } - matches = findzone(dname, class, 0, - zonelist, MAXDNAME); - if (matches) - zonenum = zonelist[0]; - else - err++; - } - break; - case S_PREREQ: - case S_UPDATE: - /* Operation code. */ - if (!getword(buf, sizeof buf, fp, 0)) { - err++; - break; - } - if (buf[0] == '{') { - n = strlen(buf); - for (i = 0; (u_int32_t) i < n; i++) - buf[i] = buf[i + 1]; - if (buf[n - 2] == '}') - buf[n - 2] = '\0'; - } - for (mp = m_opcode; mp < m_opcode + M_OPCODE_CNT; mp++) - if (!strcasecmp(buf, mp->token)) { - opcode = mp->val; - break; - } - if (opcode == -1) { - err++; - break; - } - /* Owner's domain name. */ - if (!getword((char *) dnbuf, sizeof dnbuf, fp, 0)) { - err++; - break; - } - n = strlen((char *) dnbuf) - 1; - if (dnbuf[n] == '.') - dnbuf[n] = '\0'; - dname = dnbuf; - ttl = 0; - type = -1; - class = zp->z_class; - n = 0; - data[0] = '\0'; - (void) getword(buf, sizeof buf, fp, 1); - if (isdigit(buf[0])) { /* ttl */ - if (ns_parse_ttl(buf, &l) < 0) { - err++; - break; - } - ttl = l; - (void) getword(buf, sizeof buf, fp, 1); - } - /* possibly class */ - if (buf[0] != '\0') { - int success; - int maybe_class; - - maybe_class = res_nametoclass(buf, &success); - if (success) { - class = maybe_class; - (void) getword(buf, sizeof buf, fp, 1); - } - } - /* possibly type */ - if (buf[0] != '\0') { - int success; - int maybe_type; - - maybe_type = res_nametotype(buf, &success); - - if (success) { - type = maybe_type; - (void) getword(buf, sizeof buf, fp, 1); - } - } - if (buf[0] != '\0') /* possibly rdata */ - /* - * Convert the ascii data 'buf' to the proper - * format based on the type and pack into - * 'data'. - * - * XXX - same as in db_load(), consolidation - * needed - */ - switch (type) { - case T_A: - if (!inet_aton(buf, &ina)) { - err++; - break; - } - n = ntohl(ina.s_addr); - cp = data; - PUTLONG(n, cp); - n = INT32SZ; - break; - case T_HINFO: - case T_ISDN: - n = strlen(buf); - data[0] = n; - memcpy(data + 1, buf, n); - n++; - if (!getword(buf, sizeof buf, fp, 0)) { - i = 0; - } else { - endline(fp); - i = strlen(buf); - } - data[n] = i; - n++; - memcpy(data + n + 1, buf, i); - n += i; - break; - case T_SOA: - case T_MINFO: - case T_RP: - (void) strcpy(data, buf); - cp = data + strlen(data) + 1; - if (!getword((char *) cp, - sizeof data - (cp - data), - fp, 1)) { - err++; - break; - } - cp += strlen((char *) cp) + 1; - if (type != T_SOA) { - n = cp - data; - break; - } - if (class != zp->z_class || - ns_samename(dname, zp->z_origin) != 1) { - err++; - break; - } - c = getnonblank(fp, zp->z_updatelog, 0); - if (c == '(') { - multiline = 1; - } else { - multiline = 0; - ungetc(c, fp); - } - n = getnum(fp, zp->z_updatelog, GETNUM_SERIAL, - &multiline); - if (getnum_error) { - err++; - break; - } - if (opcode == ADD) - *new_serial = n; - current_serial = n; - PUTLONG(n, cp); - for (i = 0; i < 4; i++) { - if (!getword(buf, sizeof buf, fp, 1)) { - err++; - break; - } - if (ns_parse_ttl(buf, &l) < 0) { - err++; - break; - } - n = l; - PUTLONG(n, cp); - } - if (multiline) { - c = getnonblank(fp, zp->z_updatelog, 1); - if (c != ')') { - ungetc(c, fp); - err++; - break; - } - } - endline(fp); - n = cp - data; - break; - case T_WKS: - if (!inet_aton(buf, &ina)) { - err++; - break; - } - n = ntohl(ina.s_addr); - cp = data; - PUTLONG(n, cp); - *cp = (char) getprotocol(fp, zp->z_updatelog); - n = INT32SZ + sizeof(char); - n = getservices((int) n, data, - fp, zp->z_updatelog); - break; - case T_NS: - case T_CNAME: - case T_MB: - case T_MG: - case T_MR: - case T_PTR: - (void) strcpy(data, buf); - if (makename(data, origin, - sizeof(data)) == -1) { - err++; - break; - } - n = strlen(data) + 1; - break; - case T_MX: - case T_AFSDB: - case T_RT: - n = 0; - cp = buf; - while (isdigit(*cp)) - n = n * 10 + (*cp++ - '0'); - /* catch bad values */ - cp = data; - PUTSHORT((u_int16_t) n, cp); - if (!getword(buf, sizeof(buf), fp, 1)) { - err++; - break; - } - (void) strcpy((char *) cp, buf); - if (makename((char *) cp, origin, - sizeof(data) - (cp - data)) == -1) - { - err++; - break; - } - /* advance pointer to end of data */ - cp += strlen((char *) cp) + 1; - /* now save length */ - n = (cp - data); - break; - case T_PX: - n = 0; - data[0] = '\0'; - cp = buf; - while (isdigit(*cp)) - n = n * 10 + (*cp++ - '0'); - cp = data; - PUTSHORT((u_int16_t) n, cp); - for (i = 0; i < 2; i++) { - if (!getword(buf, sizeof(buf), fp, 0)) - { - err++; - break; - } - (void) strcpy((char *) cp, buf); - cp += strlen((char *) cp) + 1; - } - n = cp - data; - break; - case T_TXT: - case T_X25: - i = strlen(buf); - cp = data; - datasize = sizeof data; - cp1 = buf; - while (i > MAXCHARSTRING) { - if (datasize <= MAXCHARSTRING) { - ns_error(ns_log_update, - "record too big"); - return (-1); - } - datasize -= MAXCHARSTRING; - *cp++ = (char)MAXCHARSTRING; - memcpy(cp, cp1, MAXCHARSTRING); - cp += MAXCHARSTRING; - cp1 += MAXCHARSTRING; - i -= MAXCHARSTRING; - } - if (datasize < i + 1) { - ns_error(ns_log_update, - "record too big"); - return (-1); - } - *cp++ = i; - memcpy(cp, cp1, i); - cp += i; - n = cp - data; - endline(fp); - /* XXXVIX: segmented texts 4.9.5 */ - break; - case T_NSAP: - n = inet_nsap_addr(buf, (u_char *) data, - sizeof data); - endline(fp); - break; - case T_LOC: - cp = buf + (n = strlen(buf)); - *cp = ' '; - cp++; - while ((i = getc(fp), *cp = i, i != EOF) - && *cp != '\n' && (n < MAXDATA)) - { - cp++; - n++; - } - if (*cp == '\n') - ungetc(*cp, fp); - *cp = '\0'; - n = loc_aton(buf, (u_char *) data); - if (n == 0) { - err++; - break; - } - endline(fp); - break; - case ns_t_sig: - case ns_t_nxt: - case ns_t_key: - case ns_t_cert:{ - const char *errmsg = NULL; - - n = parse_sec_rdata(buf, sizeof(buf), 1, - (u_char *) data, - sizeof(data), - fp, zp, dname, ttl, - type, domain_ctx, - transport, &errmsg); - if (errmsg) { - err++; - endline(fp); - n = 0; - } - break; - } - default: - if (strcmp(buf, "\\#") != 0) { - err++; - break; - } - if (!getword(buf, sizeof buf, fp, 0) || - !isdigit((unsigned char)buf[0])) { - err++; - break; - } - n = strtoul(buf, &cp, 10); - if (n > 0xffff || *cp != '\0') { - err++; - break; - } - multiline = 0; - i = isc_gethexstring((u_char *)data, - sizeof(data), n, fp, - &multiline); - if (i == -1) { - err++; - break; - } - if (multiline) { - c = getnonblank(fp, zp->z_updatelog, 1); - if (c != ')') { - ungetc(c, fp); - err++; - break; - } - multiline = 0; - } - endline(fp); - } - if (section == S_PREREQ) { - ttl = 0; - if (opcode == NXDOMAIN) { - class = C_NONE; - type = T_ANY; - n = 0; - } else if (opcode == YXDOMAIN) { - class = C_ANY; - type = T_ANY; - n = 0; - } else if (opcode == NXRRSET) { - class = C_NONE; - n = 0; - } else if (opcode == YXRRSET) { - if (n == 0) - class = C_ANY; - } - } else {/* section == S_UPDATE */ - if (opcode == DELETE) { - if (n == 0) { - class = C_ANY; - if (type == -1) - type = T_ANY; - } else { - class = zp->z_class; - } - } - } - break; - case S_ADDT: - default: - ns_debug(ns_log_update, 1, - "cannot interpret section: %d", section); - inside_next = 0; - err++; - } - if (err) { - inside_next = 0; - ns_debug(ns_log_update, 1, - "merge of update id %d failed due to error at line %d", - id, lineno); - return (DBIXFR_ERROR); - } - rrecp = res_mkupdrec(section, dname, class, type, ttl); - if (section != S_ZONE) { - struct databuf *dp; - dp = savedata(class, type, ttl, (u_char *) data, n); - dp->d_zone = zonenum; - dp->d_cred = DB_C_ZONE; - dp->d_clev = nlabels(zp->z_origin); - rrecp->r_dp = dp; - rrecp->r_opcode = opcode; - } else { - rrecp->r_zone = zonenum; - rrecp->r_opcode = opcode; - } - - /* remove add/delete pairs */ - if (section == S_UPDATE) { - ns_updrec *arp; - int foundmatch; - - arp = TAIL(*listuprec); - foundmatch = 0; - while (arp) { - if (arp->r_section == S_UPDATE && - ((arp->r_opcode == DELETE && - opcode == ADD) || - (opcode == DELETE && - arp->r_opcode == ADD)) && - arp->r_dp->d_type == rrecp->r_dp->d_type && - arp->r_dp->d_class == rrecp->r_dp->d_class && - arp->r_dp->d_ttl == rrecp->r_dp->d_ttl && - ns_samename(arp->r_dname, dname) == 1 && - db_cmp(arp->r_dp, rrecp->r_dp) == 0) { - db_detach(&rrecp->r_dp); - db_detach(&arp->r_dp); - UNLINK(*listuprec, arp, r_link); - res_freeupdrec(arp); - res_freeupdrec(rrecp); - foundmatch = 1; - break; - } - arp = PREV(arp, r_link); - } - if (foundmatch) - continue; - } - - APPEND(*listuprec, rrecp, r_link); - /* Override zone number with current zone serial number */ - rrecp->r_zone = serial; - } - - if (err) - return (DBIXFR_ERROR); - - return (DBIXFR_END); -} - |