📄 xfrout.c
字号:
ixfr_rrstream_next(rrstream_t *rs) { ixfr_rrstream_t *s = (ixfr_rrstream_t *) rs; return (dns_journal_next_rr(s->journal));}static voidixfr_rrstream_current(rrstream_t *rs, dns_name_t **name, isc_uint32_t *ttl, dns_rdata_t **rdata){ ixfr_rrstream_t *s = (ixfr_rrstream_t *) rs; dns_journal_current_rr(s->journal, name, ttl, rdata);}static voidixfr_rrstream_destroy(rrstream_t **rsp) { ixfr_rrstream_t *s = (ixfr_rrstream_t *) *rsp; if (s->journal != 0) dns_journal_destroy(&s->journal); isc_mem_put(s->common.mctx, s, sizeof(*s));}static rrstream_methods_t ixfr_rrstream_methods = { ixfr_rrstream_first, ixfr_rrstream_next, ixfr_rrstream_current, rrstream_noop_pause, ixfr_rrstream_destroy};/**************************************************************************//* * An 'axfr_rrstream_t' is an 'rrstream_t' that returns * an AXFR-like RR stream from a database. * * The SOAs at the beginning and end of the transfer are * not included in the stream. */typedef struct axfr_rrstream { rrstream_t common; db_rr_iterator_t it; isc_boolean_t it_valid;} axfr_rrstream_t;/* * Forward declarations. */static voidaxfr_rrstream_destroy(rrstream_t **rsp);static rrstream_methods_t axfr_rrstream_methods;static isc_result_taxfr_rrstream_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *ver, rrstream_t **sp){ axfr_rrstream_t *s; isc_result_t result; INSIST(sp != NULL && *sp == NULL); s = isc_mem_get(mctx, sizeof(*s)); if (s == NULL) return (ISC_R_NOMEMORY); s->common.mctx = mctx; s->common.methods = &axfr_rrstream_methods; s->it_valid = ISC_FALSE; CHECK(db_rr_iterator_init(&s->it, db, ver, 0)); s->it_valid = ISC_TRUE; *sp = (rrstream_t *) s; return (ISC_R_SUCCESS); failure: axfr_rrstream_destroy((rrstream_t **) &s); return (result);}static isc_result_taxfr_rrstream_first(rrstream_t *rs) { axfr_rrstream_t *s = (axfr_rrstream_t *) rs; isc_result_t result; result = db_rr_iterator_first(&s->it); if (result != ISC_R_SUCCESS) return (result); /* Skip SOA records. */ for (;;) { dns_name_t *name_dummy = NULL; isc_uint32_t ttl_dummy; dns_rdata_t *rdata = NULL; db_rr_iterator_current(&s->it, &name_dummy, &ttl_dummy, &rdata); if (rdata->type != dns_rdatatype_soa) break; result = db_rr_iterator_next(&s->it); if (result != ISC_R_SUCCESS) break; } return (result);}static isc_result_taxfr_rrstream_next(rrstream_t *rs) { axfr_rrstream_t *s = (axfr_rrstream_t *) rs; isc_result_t result; /* Skip SOA records. */ for (;;) { dns_name_t *name_dummy = NULL; isc_uint32_t ttl_dummy; dns_rdata_t *rdata = NULL; result = db_rr_iterator_next(&s->it); if (result != ISC_R_SUCCESS) break; db_rr_iterator_current(&s->it, &name_dummy, &ttl_dummy, &rdata); if (rdata->type != dns_rdatatype_soa) break; } return (result);}static voidaxfr_rrstream_current(rrstream_t *rs, dns_name_t **name, isc_uint32_t *ttl, dns_rdata_t **rdata){ axfr_rrstream_t *s = (axfr_rrstream_t *) rs; db_rr_iterator_current(&s->it, name, ttl, rdata);}static voidaxfr_rrstream_pause(rrstream_t *rs) { axfr_rrstream_t *s = (axfr_rrstream_t *) rs; db_rr_iterator_pause(&s->it);}static voidaxfr_rrstream_destroy(rrstream_t **rsp) { axfr_rrstream_t *s = (axfr_rrstream_t *) *rsp; if (s->it_valid) db_rr_iterator_destroy(&s->it); isc_mem_put(s->common.mctx, s, sizeof(*s));}static rrstream_methods_t axfr_rrstream_methods = { axfr_rrstream_first, axfr_rrstream_next, axfr_rrstream_current, axfr_rrstream_pause, axfr_rrstream_destroy};/**************************************************************************//* * An 'soa_rrstream_t' is a degenerate 'rrstream_t' that returns * a single SOA record. */typedef struct soa_rrstream { rrstream_t common; dns_difftuple_t *soa_tuple;} soa_rrstream_t;/* * Forward declarations. */static voidsoa_rrstream_destroy(rrstream_t **rsp);static rrstream_methods_t soa_rrstream_methods;static isc_result_tsoa_rrstream_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *ver, rrstream_t **sp){ soa_rrstream_t *s; isc_result_t result; INSIST(sp != NULL && *sp == NULL); s = isc_mem_get(mctx, sizeof(*s)); if (s == NULL) return (ISC_R_NOMEMORY); s->common.mctx = mctx; s->common.methods = &soa_rrstream_methods; s->soa_tuple = NULL; CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_EXISTS, &s->soa_tuple)); *sp = (rrstream_t *) s; return (ISC_R_SUCCESS); failure: soa_rrstream_destroy((rrstream_t **) &s); return (result);}static isc_result_tsoa_rrstream_first(rrstream_t *rs) { UNUSED(rs); return (ISC_R_SUCCESS);}static isc_result_tsoa_rrstream_next(rrstream_t *rs) { UNUSED(rs); return (ISC_R_NOMORE);}static voidsoa_rrstream_current(rrstream_t *rs, dns_name_t **name, isc_uint32_t *ttl, dns_rdata_t **rdata){ soa_rrstream_t *s = (soa_rrstream_t *) rs; *name = &s->soa_tuple->name; *ttl = s->soa_tuple->ttl; *rdata = &s->soa_tuple->rdata;}static voidsoa_rrstream_destroy(rrstream_t **rsp) { soa_rrstream_t *s = (soa_rrstream_t *) *rsp; if (s->soa_tuple != NULL) dns_difftuple_free(&s->soa_tuple); isc_mem_put(s->common.mctx, s, sizeof(*s));}static rrstream_methods_t soa_rrstream_methods = { soa_rrstream_first, soa_rrstream_next, soa_rrstream_current, rrstream_noop_pause, soa_rrstream_destroy};/**************************************************************************//* * A 'compound_rrstream_t' objects owns a soa_rrstream * and another rrstream, the "data stream". It returns * a concatenated stream consisting of the soa_rrstream, then * the data stream, then the soa_rrstream again. * * The component streams are owned by the compound_rrstream_t * and are destroyed with it. */typedef struct compound_rrstream { rrstream_t common; rrstream_t *components[3]; int state; isc_result_t result;} compound_rrstream_t;/* * Forward declarations. */static voidcompound_rrstream_destroy(rrstream_t **rsp);static isc_result_tcompound_rrstream_next(rrstream_t *rs);static rrstream_methods_t compound_rrstream_methods;/* * Requires: * soa_stream != NULL && *soa_stream != NULL * data_stream != NULL && *data_stream != NULL * sp != NULL && *sp == NULL * * Ensures: * *soa_stream == NULL * *data_stream == NULL * *sp points to a valid compound_rrstream_t * The soa and data streams will be destroyed * when the compound_rrstream_t is destroyed. */static isc_result_tcompound_rrstream_create(isc_mem_t *mctx, rrstream_t **soa_stream, rrstream_t **data_stream, rrstream_t **sp){ compound_rrstream_t *s; INSIST(sp != NULL && *sp == NULL); s = isc_mem_get(mctx, sizeof(*s)); if (s == NULL) return (ISC_R_NOMEMORY); s->common.mctx = mctx; s->common.methods = &compound_rrstream_methods; s->components[0] = *soa_stream; s->components[1] = *data_stream; s->components[2] = *soa_stream; s->state = -1; s->result = ISC_R_FAILURE; *soa_stream = NULL; *data_stream = NULL; *sp = (rrstream_t *) s; return (ISC_R_SUCCESS);}static isc_result_tcompound_rrstream_first(rrstream_t *rs) { compound_rrstream_t *s = (compound_rrstream_t *) rs; s->state = 0; do { rrstream_t *curstream = s->components[s->state]; s->result = curstream->methods->first(curstream); } while (s->result == ISC_R_NOMORE && s->state < 2) ; return (s->result);}static isc_result_tcompound_rrstream_next(rrstream_t *rs) { compound_rrstream_t *s = (compound_rrstream_t *) rs; rrstream_t *curstream = s->components[s->state]; s->result = curstream->methods->next(curstream); while (s->result == ISC_R_NOMORE) { /* * Make sure locks held by the current stream * are released before we switch streams. */ curstream->methods->pause(curstream); if (s->state == 2) return (ISC_R_NOMORE); s->state++; curstream = s->components[s->state]; s->result = curstream->methods->first(curstream); } return (s->result);}static voidcompound_rrstream_current(rrstream_t *rs, dns_name_t **name, isc_uint32_t *ttl, dns_rdata_t **rdata){ compound_rrstream_t *s = (compound_rrstream_t *) rs; rrstream_t *curstream; INSIST(0 <= s->state && s->state < 3); INSIST(s->result == ISC_R_SUCCESS); curstream = s->components[s->state]; curstream->methods->current(curstream, name, ttl, rdata);}static voidcompound_rrstream_pause(rrstream_t *rs){ compound_rrstream_t *s = (compound_rrstream_t *) rs; rrstream_t *curstream; INSIST(0 <= s->state && s->state < 3); curstream = s->components[s->state]; curstream->methods->pause(curstream);}static voidcompound_rrstream_destroy(rrstream_t **rsp) { compound_rrstream_t *s = (compound_rrstream_t *) *rsp; s->components[0]->methods->destroy(&s->components[0]); s->components[1]->methods->destroy(&s->components[1]); s->components[2] = NULL; /* Copy of components[0]. */ isc_mem_put(s->common.mctx, s, sizeof(*s));}static rrstream_methods_t compound_rrstream_methods = { compound_rrstream_first, compound_rrstream_next, compound_rrstream_current, compound_rrstream_pause, compound_rrstream_destroy};/**************************************************************************//* * An 'xfrout_ctx_t' contains the state of an outgoing AXFR or IXFR * in progress. */typedef struct { isc_mem_t *mctx; ns_client_t *client; unsigned int id; /* ID of request */ dns_name_t *qname; /* Question name of request */ dns_rdatatype_t qtype; /* dns_rdatatype_{a,i}xfr */ dns_rdataclass_t qclass; dns_db_t *db; dns_dbversion_t *ver; isc_quota_t *quota; rrstream_t *stream; /* The XFR RR stream */ isc_boolean_t end_of_stream; /* EOS has been reached */ isc_buffer_t buf; /* Buffer for message owner names and rdatas */ isc_buffer_t txlenbuf; /* Transmit length buffer */ isc_buffer_t txbuf; /* Transmit message buffer */ void *txmem; unsigned int txmemlen; unsigned int nmsg; /* Number of messages sent */ dns_tsigkey_t *tsigkey; /* Key used to create TSIG */ isc_buffer_t *lasttsig; /* the last TSIG */ isc_boolean_t many_answers; int sends; /* Send in progress */ isc_boolean_t shuttingdown;} xfrout_ctx_t;static isc_result_txfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client, unsigned int id, dns_name_t *qname, dns_rdatatype_t qtype, dns_rdataclass_t qclass, dns_db_t *db, dns_dbversion_t *ver, isc_quota_t *quota, rrstream_t *stream, dns_tsigkey_t *tsigkey, isc_buffer_t *lasttsig, unsigned int maxtime, unsigned int idletime, isc_boolean_t many_answers, xfrout_ctx_t **xfrp);static voidsendstream(xfrout_ctx_t *xfr);static voidxfrout_senddone(isc_task_t *task, isc_event_t *event);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -