static PyObject * _cdbo_keyiter(CdbObject *self) { PyObject *key; char buf[8]; uint32 klen, dlen; if (! self->eod) _cdbo_init_eod(self); while (self->iter_pos < self->eod) { if (cdb_read(&self->c, buf, 8, self->iter_pos) == -1) return CDBerr; uint32_unpack(buf, &klen); uint32_unpack(buf+4, &dlen); key = cdb_pyread(self, klen, self->iter_pos + 8); if (key == NULL) return NULL; switch(cdb_find(&self->c,PyString_AsString(key),PyString_Size(key))) { case -1: Py_DECREF(key); key = NULL; return CDBerr; case 0: /* bizarre, impossible? PyExc_RuntimeError? */ PyErr_SetString(PyExc_KeyError, PyString_AS_STRING((PyStringObject *) key)); Py_DECREF(key); key = NULL; default: if (key == NULL) /* already raised error */ return NULL; if (cdb_datapos(&self->c) == self->iter_pos + klen + 8) { /** first occurrence of key in the cdb **/ self->iter_pos += 8 + klen + dlen; return key; } Py_DECREF(key); /* better luck next time around */ self->iter_pos += 8 + klen + dlen; } } return Py_BuildValue(""); /* iter_pos >= eod; we're done */ }
static int doit(struct cdb *c,uint32 *kpos) { char buf[8]; uint32 eod,klen; if (cdb_read(c,buf,4,0)) return -1; uint32_unpack(buf,&eod); if (eod<8 || eod-8<*kpos) return 0; c->kpos=*kpos+8; if (c->kpos<*kpos) return -1; /* wraparound */ cdb_findstart(c); c->hslots=1; if (cdb_read(c,buf,8,*kpos) == -1) return -1; uint32_unpack(buf,&klen); uint32_unpack(buf+4,&c->dlen); c->dpos=c->kpos+klen; *kpos+=8+klen+c->dlen; return 1; }
int cdb_findnext(struct cdb *c,char *key,unsigned int len) { char buf[8]; uint32 pos; uint32 u; if (!c->loop) { u = cdb_hash(key,len); if (cdb_read(c,buf,8,(u << 3) & 2047) == -1) return -1; uint32_unpack(buf + 4,&c->hslots); if (!c->hslots) return 0; uint32_unpack(buf,&c->hpos); c->khash = u; u >>= 8; u %= c->hslots; u <<= 3; c->kpos = c->hpos + u; }
int aa_service_status_read (aa_service_status *svst, const char *dir) { size_t len = strlen (dir); char file[len + 1 + sizeof (AA_SVST_FILENAME)]; uint32_t u; /* most cases should be w/out a message, so we'll only need FIXED_SIZE and * one extra byte to NUL-terminate the (empty) message */ if (!stralloc_ready_tuned (&svst->sa, AA_SVST_FIXED_SIZE + 1, 0, 0, 1)) return -1; byte_copy (file, len, dir); byte_copy (file + len, 1 + sizeof (AA_SVST_FILENAME), "/" AA_SVST_FILENAME); if (!openreadfileclose (file, &svst->sa, AA_SVST_FIXED_SIZE + AA_SVST_MAX_MSG_SIZE) || svst->sa.len < AA_SVST_FIXED_SIZE) { int e = errno; tain_now_g (); errno = e; return -1; } tain_now_g (); if (svst->sa.len >= svst->sa.a && !stralloc_ready_tuned (&svst->sa, svst->sa.len + 1, 0, 0, 1)) return -1; svst->sa.s[svst->sa.len] = '\0'; svst->sa.len++; tain_unpack (svst->sa.s, &svst->stamp); uint32_unpack (svst->sa.s + 12, &u); svst->event = (unsigned int) u; uint32_unpack (svst->sa.s + 16, &u); svst->code = (int) u; return 0; }
static int cdbo_length(CdbObject *self) { if (! self->numrecords) { char buf[8]; uint32 pos, klen, dlen; pos = 2048; if (! self->eod) (void) _cdbo_init_eod(self); while (pos < self->eod) { if (cdb_read(&self->c, buf, 8, pos) == -1) return -1; uint32_unpack(buf, &klen); uint32_unpack(buf + 4, &dlen); pos += 8 + klen + dlen; self->numrecords++; } } return (int) self->numrecords; }
unsigned int freelist_get (char const *s, unsigned int max, unsigned int i) { char pack[4] ; uint32 n ; register unsigned int esize = freelist_size(max) ; byte_copy(pack, esize, s + esize * i) ; byte_zero(pack + esize, 4 - esize) ; uint32_unpack(pack, &n) ; #ifdef DEBUG lolprintf("freelist_get: got freecell number %u\n", n) ; buffer_flush(buffer_1) ; #endif return (unsigned int)n ; }
int cdb_findnext(struct cdb *c,char *key,unsigned int len) { char buf[8]; uint32 pos; uint32 u; U_INTERNAL_TRACE("cdb_findnext(%p,%.*s,%u)",c,len,key,len) if (!c->loop) { u = cdb_hash(key,len); if (cdb_read(c,buf,8,(u % CDB_NUM_HASH_TABLE_POINTER) * 8) == -1) return -1; uint32_unpack(buf + 4,&c->hslots); if (!c->hslots) return 0; uint32_unpack(buf,&c->hpos); c->khash = u; u /= CDB_NUM_HASH_TABLE_POINTER; u %= c->hslots; u <<= 3; c->kpos = c->hpos + u; } while (c->loop < c->hslots) { if (cdb_read(c,buf,8,c->kpos) == -1) return -1; uint32_unpack(buf + 4,&pos); if (!pos) return 0; c->loop += 1; c->kpos += 8; if (c->kpos == c->hpos + (c->hslots << 3)) c->kpos = c->hpos; uint32_unpack(buf,&u); if (u == c->khash) { if (cdb_read(c,buf,8,pos) == -1) return -1; uint32_unpack(buf,&u); if (u == len) switch(match(c,key,len,pos + 8)) { case -1: return -1; case 1: uint32_unpack(buf + 4,&c->dlen); c->dpos = pos + 8 + len; return 1; } } } U_INTERNAL_TRACE("not found",0) return 0; }
int main(int argc,char **argv) { long long pos; long long len; long long u; long long r; long long i; long long k; long long recent; long long nextaction; long long timeout; struct pollfd *q; struct pollfd *watch8; struct pollfd *watchtochild; struct pollfd *watchfromchild; signal(SIGPIPE,SIG_IGN); if (!argv[0]) die_usage(0); for (;;) { char *x; if (!argv[1]) break; if (argv[1][0] != '-') break; x = *++argv; if (x[0] == '-' && x[1] == 0) break; if (x[0] == '-' && x[1] == '-' && x[2] == 0) break; while (*++x) { if (*x == 'q') { flagverbose = 0; continue; } if (*x == 'Q') { flagverbose = 1; continue; } if (*x == 'v') { if (flagverbose == 2) flagverbose = 3; else flagverbose = 2; continue; } if (*x == 'c') { flagserver = 0; wantping = 2; continue; } if (*x == 'C') { flagserver = 0; wantping = 1; continue; } if (*x == 's') { flagserver = 1; wantping = 0; continue; } die_usage(0); } } if (!*++argv) die_usage("missing prog"); for (;;) { r = open_read("/dev/null"); if (r == -1) die_fatal("unable to open /dev/null",0,0); if (r > 9) { close(r); break; } } if (open_pipe(tochild) == -1) die_fatal("unable to create pipe",0,0); if (open_pipe(fromchild) == -1) die_fatal("unable to create pipe",0,0); blocking_enable(tochild[0]); blocking_enable(fromchild[1]); child = fork(); if (child == -1) die_fatal("unable to fork",0,0); if (child == 0) { close(8); close(9); if (flagserver) { close(0); if (dup(tochild[0]) != 0) die_fatal("unable to dup",0,0); close(1); if (dup(fromchild[1]) != 1) die_fatal("unable to dup",0,0); } else { close(6); if (dup(tochild[0]) != 6) die_fatal("unable to dup",0,0); close(7); if (dup(fromchild[1]) != 7) die_fatal("unable to dup",0,0); } signal(SIGPIPE,SIG_DFL); execvp(*argv,argv); die_fatal("unable to run",*argv,0); } close(tochild[0]); close(fromchild[1]); recent = nanoseconds(); lastspeedadjustment = recent; if (flagserver) maxblocklen = 1024; for (;;) { if (sendeofacked) if (receivewritten == receivetotalbytes) if (receiveeof) if (tochild[1] < 0) break; /* XXX: to re-ack should enter a TIME-WAIT state here */ q = p; watch8 = q; if (watch8) { q->fd = 8; q->events = POLLIN; ++q; } watchtochild = q; if (tochild[1] < 0) watchtochild = 0; if (receivewritten >= receivebytes) watchtochild = 0; if (watchtochild) { q->fd = tochild[1]; q->events = POLLOUT; ++q; } watchfromchild = q; if (sendeof) watchfromchild = 0; if (sendbytes + 4096 > sizeof sendbuf) watchfromchild = 0; if (watchfromchild) { q->fd = fromchild[0]; q->events = POLLIN; ++q; } nextaction = recent + 60000000000LL; if (wantping == 1) nextaction = recent + 1000000000; if (wantping == 2) nextaction = 0; if (blocknum < OUTGOING) if (!(sendeof ? sendeofprocessed : sendprocessed >= sendbytes)) if (nextaction > lastblocktime + nsecperblock) nextaction = lastblocktime + nsecperblock; if (earliestblocktime) { long long nextretry = earliestblocktime + rtt_timeout; if (nextretry < lastblocktime + nsecperblock) nextretry = lastblocktime + nsecperblock; if (nextretry < nextaction) nextaction = nextretry; } if (messagenum) if (!watchtochild) nextaction = 0; if (nextaction <= recent) timeout = 0; else timeout = (nextaction - recent) / 1000000 + 1; /* XXX */ if (childdied) timeout = 10; pollret = poll(p,q - p,timeout); if (pollret < 0) { watch8 = 0; watchtochild = 0; watchfromchild = 0; } else { if (watch8) if (!watch8->revents) watch8 = 0; if (watchtochild) if (!watchtochild->revents) watchtochild = 0; if (watchfromchild) if (!watchfromchild->revents) watchfromchild = 0; } /* XXX */ if (childdied && !pollret) { if (childdied++ > 999) goto finish; } /* XXX: keepalives */ do { /* try receiving data from child: */ if (!watchfromchild) break; if (sendeof) break; if (sendbytes + 4096 > sizeof sendbuf) break; pos = (sendacked & (sizeof sendbuf - 1)) + sendbytes; if (pos < sizeof sendbuf) { r = read(fromchild[0],sendbuf + pos,sizeof sendbuf - pos); } else { r = read(fromchild[0],sendbuf + pos - sizeof sendbuf,sizeof sendbuf - sendbytes); } if (r == -1) if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN) break; if (r < 0) { sendeof = 4096; break; } if (r == 0) { sendeof = 2048; break; } sendbytes += r; if (sendbytes >= 1152921504606846976LL) die_internalerror(); } while(0); recent = nanoseconds(); do { /* try re-sending an old block: */ if (recent < lastblocktime + nsecperblock) break; if (earliestblocktime == 0) break; if (recent < earliestblocktime + rtt_timeout) break; for (i = 0;i < blocknum;++i) { pos = (blockfirst + i) & (OUTGOING - 1); if (blocktime[pos] == earliestblocktime) { if (recent > lastpanic + 4 * rtt_timeout) { nsecperblock *= 2; lastpanic = recent; lastedge = recent; } goto sendblock; } } } while(0); do { /* try sending a new block: */ if (recent < lastblocktime + nsecperblock) break; if (blocknum >= OUTGOING) break; if (!wantping) if (sendeof ? sendeofprocessed : sendprocessed >= sendbytes) break; /* XXX: if any Nagle-type processing is desired, do it here */ pos = (blockfirst + blocknum) & (OUTGOING - 1); ++blocknum; blockpos[pos] = sendacked + sendprocessed; blocklen[pos] = sendbytes - sendprocessed; if (blocklen[pos] > maxblocklen) blocklen[pos] = maxblocklen; if ((blockpos[pos] & (sizeof sendbuf - 1)) + blocklen[pos] > sizeof sendbuf) blocklen[pos] = sizeof sendbuf - (blockpos[pos] & (sizeof sendbuf - 1)); /* XXX: or could have the full block in post-buffer space */ sendprocessed += blocklen[pos]; blockeof[pos] = 0; if (sendprocessed == sendbytes) { blockeof[pos] = sendeof; if (sendeof) sendeofprocessed = 1; } blocktransmissions[pos] = 0; sendblock: blocktransmissions[pos] += 1; blocktime[pos] = recent; blockid[pos] = nextmessageid; if (!++nextmessageid) ++nextmessageid; /* constraints: u multiple of 16; u >= 16; u <= 1088; u >= 48 + blocklen[pos] */ u = 64 + blocklen[pos]; if (u <= 192) u = 192; else if (u <= 320) u = 320; else if (u <= 576) u = 576; else if (u <= 1088) u = 1088; else die_internalerror(); if (blocklen[pos] < 0 || blocklen[pos] > 1024) die_internalerror(); byte_zero(buf + 8,u); buf[7] = u / 16; uint32_pack(buf + 8,blockid[pos]); /* XXX: include any acknowledgments that have piled up */ uint16_pack(buf + 46,blockeof[pos] | (crypto_uint16) blocklen[pos]); uint64_pack(buf + 48,blockpos[pos]); byte_copy(buf + 8 + u - blocklen[pos],blocklen[pos],sendbuf + (blockpos[pos] & (sizeof sendbuf - 1))); if (writeall(9,buf + 7,u + 1) == -1) die_fatal("unable to write descriptor 9",0,0); lastblocktime = recent; wantping = 0; earliestblocktime_compute(); } while(0); do { /* try receiving messages: */ if (!watch8) break; r = read(8,buf,sizeof buf); if (r == -1) if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN) break; if (r == 0) die_badmessage(); if (r < 0) die_fatal("unable to read from file descriptor 8",0,0); for (k = 0;k < r;++k) { messagetodo[messagetodolen++] = buf[k]; u = 16 * (unsigned long long) messagetodo[0]; if (u < 16) die_badmessage(); if (u > 1088) die_badmessage(); if (messagetodolen == 1 + u) { if (messagenum < INCOMING) { pos = (messagefirst + messagenum) & (INCOMING - 1); messagelen[pos] = messagetodo[0]; byte_copy(message[pos],u,messagetodo + 1); ++messagenum; } else { ; /* drop tail */ } messagetodolen = 0; } } } while(0); do { /* try processing a message: */ if (!messagenum) break; if (tochild[1] >= 0 && receivewritten < receivebytes) break; maxblocklen = 1024; pos = messagefirst & (INCOMING - 1); len = 16 * (unsigned long long) messagelen[pos]; do { /* handle this message if it's comprehensible: */ unsigned long long D; unsigned long long SF; unsigned long long startbyte; unsigned long long stopbyte; crypto_uint32 id; long long i; if (len < 48) break; if (len > 1088) break; id = uint32_unpack(message[pos] + 4); for (i = 0;i < blocknum;++i) { k = (blockfirst + i) & (OUTGOING - 1); if (blockid[k] == id) { rtt = recent - blocktime[k]; if (!rtt_average) { nsecperblock = rtt; rtt_average = rtt; rtt_deviation = rtt / 2; rtt_highwater = rtt; rtt_lowwater = rtt; } /* Jacobson's retransmission timeout calculation: */ rtt_delta = rtt - rtt_average; rtt_average += rtt_delta / 8; if (rtt_delta < 0) rtt_delta = -rtt_delta; rtt_delta -= rtt_deviation; rtt_deviation += rtt_delta / 4; rtt_timeout = rtt_average + 4 * rtt_deviation; /* adjust for delayed acks with anti-spiking: */ rtt_timeout += 8 * nsecperblock; /* recognizing top and bottom of congestion cycle: */ rtt_delta = rtt - rtt_highwater; rtt_highwater += rtt_delta / 1024; rtt_delta = rtt - rtt_lowwater; if (rtt_delta > 0) rtt_lowwater += rtt_delta / 8192; else rtt_lowwater += rtt_delta / 256; if (rtt_average > rtt_highwater + 5000000) rtt_seenrecenthigh = 1; else if (rtt_average < rtt_lowwater) rtt_seenrecentlow = 1; if (recent >= lastspeedadjustment + 16 * nsecperblock) { if (recent - lastspeedadjustment > 10000000000LL) { nsecperblock = 1000000000; /* slow restart */ nsecperblock += randommod(nsecperblock / 8); } lastspeedadjustment = recent; if (nsecperblock >= 131072) { /* additive increase: adjust 1/N by a constant c */ /* rtt-fair additive increase: adjust 1/N by a constant c every nanosecond */ /* approximation: adjust 1/N by cN every N nanoseconds */ /* i.e., N <- 1/(1/N + cN) = N/(1 + cN^2) every N nanoseconds */ if (nsecperblock < 16777216) { /* N/(1+cN^2) approx N - cN^3 */ u = nsecperblock / 131072; nsecperblock -= u * u * u; } else { double d = nsecperblock; nsecperblock = d/(1 + d*d / 2251799813685248.0); } } if (rtt_phase == 0) { if (rtt_seenolderhigh) { rtt_phase = 1; lastedge = recent; nsecperblock += randommod(nsecperblock / 4); } } else { if (rtt_seenolderlow) { rtt_phase = 0; } } rtt_seenolderhigh = rtt_seenrecenthigh; rtt_seenolderlow = rtt_seenrecentlow; rtt_seenrecenthigh = 0; rtt_seenrecentlow = 0; } do { if (recent - lastedge < 60000000000LL) { if (recent < lastdoubling + 4 * nsecperblock + 64 * rtt_timeout + 5000000000LL) break; } else { if (recent < lastdoubling + 4 * nsecperblock + 2 * rtt_timeout) break; } if (nsecperblock <= 65535) break; nsecperblock /= 2; lastdoubling = recent; if (lastedge) lastedge = recent; } while(0); } } stopbyte = uint64_unpack(message[pos] + 8); acknowledged(0,stopbyte); startbyte = stopbyte + (unsigned long long) uint32_unpack(message[pos] + 16); stopbyte = startbyte + (unsigned long long) uint16_unpack(message[pos] + 20); acknowledged(startbyte,stopbyte); startbyte = stopbyte + (unsigned long long) uint16_unpack(message[pos] + 22); stopbyte = startbyte + (unsigned long long) uint16_unpack(message[pos] + 24); acknowledged(startbyte,stopbyte); startbyte = stopbyte + (unsigned long long) uint16_unpack(message[pos] + 26); stopbyte = startbyte + (unsigned long long) uint16_unpack(message[pos] + 28); acknowledged(startbyte,stopbyte); startbyte = stopbyte + (unsigned long long) uint16_unpack(message[pos] + 30); stopbyte = startbyte + (unsigned long long) uint16_unpack(message[pos] + 32); acknowledged(startbyte,stopbyte); startbyte = stopbyte + (unsigned long long) uint16_unpack(message[pos] + 34); stopbyte = startbyte + (unsigned long long) uint16_unpack(message[pos] + 36); acknowledged(startbyte,stopbyte); D = uint16_unpack(message[pos] + 38); SF = D & (2048 + 4096); D -= SF; if (D > 1024) break; if (48 + D > len) break; startbyte = uint64_unpack(message[pos] + 40); stopbyte = startbyte + D; if (stopbyte > receivewritten + sizeof receivebuf) { break; /* of course, flow control would avoid this case */ } if (SF) { receiveeof = SF; receivetotalbytes = stopbyte; } for (k = 0;k < D;++k) { unsigned char ch = message[pos][len - D + k]; unsigned long long where = startbyte + k; if (where >= receivewritten && where < receivewritten + sizeof receivebuf) { receivevalid[where & (sizeof receivebuf - 1)] = 1; receivebuf[where & (sizeof receivebuf - 1)] = ch; } } for (;;) { if (receivebytes >= receivewritten + sizeof receivebuf) break; if (!receivevalid[receivebytes & (sizeof receivebuf - 1)]) break; ++receivebytes; } if (!uint32_unpack(message[pos])) break; /* never acknowledge a pure acknowledgment */ /* XXX: delay acknowledgments */ u = 192; byte_zero(buf + 8,u); buf[7] = u / 16; byte_copy(buf + 12,4,message[pos]); if (receiveeof && receivebytes == receivetotalbytes) { uint64_pack(buf + 16,receivebytes + 1); } else uint64_pack(buf + 16,receivebytes); /* XXX: incorporate selective acknowledgments */ if (writeall(9,buf + 7,u + 1) == -1) die_fatal("unable to write descriptor 9",0,0); } while(0); ++messagefirst; --messagenum; } while(0); do { /* try sending data to child: */ if (!watchtochild) break; if (tochild[1] < 0) { receivewritten = receivebytes; break; } if (receivewritten >= receivebytes) break; pos = receivewritten & (sizeof receivebuf - 1); len = receivebytes - receivewritten; if (pos + len > sizeof receivebuf) len = sizeof receivebuf - pos; r = write(tochild[1],receivebuf + pos,len); if (r == -1) if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN) break; if (r <= 0) { close(tochild[1]); tochild[1] = -1; break; } byte_zero(receivevalid + pos,r); receivewritten += r; } while(0); do { /* try closing pipe to child: */ if (!receiveeof) break; if (receivewritten < receivetotalbytes) break; if (tochild[1] < 0) break; if (receiveeof == 4096) ; /* XXX: UNIX doesn't provide a way to signal an error through a pipe */ close(tochild[1]); tochild[1] = -1; } while(0); /* XXX */ if (!childdied){ if (waitpid(child,&childstatus, WNOHANG) > 0) { close(tochild[1]); tochild[1] = -1; childdied = 1; } } } if (!childdied) { do { r = waitpid(child,&childstatus,0); } while (r == -1 && errno == EINTR); } finish: if (!WIFEXITED(childstatus)) { errno = 0; die_fatal("process killed by signal",0,0); } return WEXITSTATUS(childstatus); }
void getnum(uint32 *num) { char buf[4]; get(buf,4); uint32_unpack(buf,num); }
void doaxfr (char id[2]) { int r = 0; char num[4]; char key[512]; uint32 klen = 0; uint32 eod = 0, pos = 0; axfrcheck (zone); tai_now (&now); cdb_init (&c, fdcdb); byte_zero (clientloc, 2); key[0] = 0; key[1] = '%'; byte_copy (key + 2, 4, ip); r = cdb_find (&c, key, 6); if (!r) r = cdb_find (&c, key, 5); if (!r) r = cdb_find (&c, key, 4); if (!r) r = cdb_find (&c, key, 3); if (!r) r = cdb_find (&c, key, 2); if (r == -1) errx (-1, "could not read from file `data.cdb'"); if (r && (cdb_datalen (&c) == 2)) if (cdb_read (&c, clientloc, 2, cdb_datapos (&c)) == -1) err (-1, "could not read from file `data.cdb'"); cdb_findstart (&c); for (;;) { r = cdb_findnext (&c, zone, zonelen); if (r == -1) errx (-1, "could not read from file `data.cdb'"); if (!r) errx (-1, "could not find information in `data.cdb'"); dlen = cdb_datalen (&c); if (dlen > sizeof data) errx (-1, "could not read from file `data.cdb': format error"); if (cdb_read (&c, data, dlen, cdb_datapos (&c)) == -1) errx (-1, "could not read from file `data.cdb': format error"); if (build (&soa, zone, 1, id)) break; } cdb_free (&c); print (soa.s, soa.len); seek_begin (fdcdb); buffer_init (&bcdb, buffer_unixread, fdcdb, bcdbspace, sizeof (bcdbspace)); pos = 0; get (num, 4); pos += 4; uint32_unpack (num, &eod); while (pos < 2048) { get (num, 4); pos += 4; } while (pos < eod) { if (eod - pos < 8) errx (-1, "could not read from file `data.cdb': format error"); get (num, 4); pos += 4; uint32_unpack (num, &klen); get (num,4); pos += 4; uint32_unpack (num, &dlen); if (eod - pos < klen) errx (-1, "could not read from file `data.cdb': format error"); pos += klen; if (eod - pos < dlen) errx (-1, "could not read from file `data.cdb': format error"); pos += dlen; if (klen > sizeof key) errx (-1, "could not read from file `data.cdb': format error"); get (key, klen); if (dlen > sizeof data) errx (-1, "could not read from file `data.cdb': format error"); get (data, dlen); if ((klen > 1) && (key[0] == 0)) continue; /* location */ if (klen < 1) errx (-1, "could not read from file `data.cdb': format error"); if (dns_packet_getname (key, klen, 0, &q) != klen) errx (-1, "could not read from file `data.cdb': format error"); if (!dns_domain_suffix (q, zone)) continue; if (!build (&message, q, 0, id)) continue; print (message.s, message.len); } print (soa.s, soa.len); }
void doaxfr(char id[2]) { char key[512]; uint32 klen; char num[4]; uint32 eod; uint32 pos; int r; axfrcheck(zone); find_client_loc(clientloc, ip); tai_now(&now); cdb_init(&c,fdcdb); cdb_findstart(&c); for (;;) { r = cdb_findnext(&c,zone,zonelen); if (r == -1) die_cdbread(); if (!r) die_outside(); dlen = cdb_datalen(&c); if (dlen > sizeof data) die_cdbformat(); if (cdb_read(&c,data,dlen,cdb_datapos(&c)) == -1) die_cdbformat(); if (build(&soa,zone,1,id)) break; } cdb_free(&c); print(soa.s,soa.len); seek_begin(fdcdb); buffer_init(&bcdb,buffer_unixread,fdcdb,bcdbspace,sizeof bcdbspace); pos = 0; get(num,4); pos += 4; uint32_unpack(num,&eod); while (pos < 2048) { get(num,4); pos += 4; } while (pos < eod) { if (eod - pos < 8) die_cdbformat(); get(num,4); pos += 4; uint32_unpack(num,&klen); get(num,4); pos += 4; uint32_unpack(num,&dlen); if (eod - pos < klen) die_cdbformat(); pos += klen; if (eod - pos < dlen) die_cdbformat(); pos += dlen; if (klen > sizeof key) die_cdbformat(); get(key,klen); if (dlen > sizeof data) die_cdbformat(); get(data,dlen); if ((klen > 1) && (key[0] == 0)) continue; /* location */ if (klen < 1) die_cdbformat(); if (dns_packet_getname(key,klen,0,&q) != klen) die_cdbformat(); if (!dns_domain_suffix(q,zone)) continue; if (!build(&message,q,0,id)) continue; print(message.s,message.len); } print(soa.s,soa.len); }