mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-12 22:19:59 -04:00
589. [bug] The server could deadlock if a zone was updated
while being transferred out.
This commit is contained in:
parent
5a6335a8bf
commit
4d5c668a91
2 changed files with 53 additions and 4 deletions
4
CHANGES
4
CHANGES
|
|
@ -1,3 +1,7 @@
|
|||
|
||||
589. [bug] The server could deadlock if a zone was updated
|
||||
while being transferred out.
|
||||
|
||||
588. [bug] ctx->in_use was not being correctly initalised when
|
||||
when pushing a file for $INCLUDE. [RT #523]
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: xfrout.c,v 1.82 2000/11/17 19:04:51 gson Exp $ */
|
||||
/* $Id: xfrout.c,v 1.83 2000/12/04 06:31:41 gson Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
|
|
@ -223,6 +223,11 @@ db_rr_iterator_next(db_rr_iterator_t *it) {
|
|||
return (it->result);
|
||||
}
|
||||
|
||||
static void
|
||||
db_rr_iterator_pause(db_rr_iterator_t *it) {
|
||||
dns_dbiterator_pause(it->dbit);
|
||||
}
|
||||
|
||||
static void
|
||||
db_rr_iterator_destroy(db_rr_iterator_t *it) {
|
||||
if (dns_rdataset_isassociated(&it->rdataset))
|
||||
|
|
@ -316,9 +321,15 @@ struct rrstream_methods {
|
|||
dns_name_t **,
|
||||
isc_uint32_t *,
|
||||
dns_rdata_t **);
|
||||
void (*pause)(rrstream_t *);
|
||||
void (*destroy)(rrstream_t **);
|
||||
};
|
||||
|
||||
static void
|
||||
rrstream_noop_pause(rrstream_t *rs) {
|
||||
UNUSED(rs);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
* An 'ixfr_rrstream_t' is an 'rrstream_t' that returns
|
||||
|
|
@ -410,12 +421,13 @@ static rrstream_methods_t ixfr_rrstream_methods = {
|
|||
ixfr_rrstream_first,
|
||||
ixfr_rrstream_next,
|
||||
ixfr_rrstream_current,
|
||||
rrstream_noop_pause,
|
||||
ixfr_rrstream_destroy
|
||||
};
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
* An 'ixfr_rrstream_t' is an 'rrstream_t' that returns
|
||||
* 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
|
||||
|
|
@ -425,7 +437,7 @@ static rrstream_methods_t ixfr_rrstream_methods = {
|
|||
typedef struct axfr_rrstream {
|
||||
rrstream_t common;
|
||||
int state;
|
||||
db_rr_iterator_t it;
|
||||
db_rr_iterator_t it;
|
||||
isc_boolean_t it_valid;
|
||||
} axfr_rrstream_t;
|
||||
|
||||
|
|
@ -516,6 +528,12 @@ axfr_rrstream_current(rrstream_t *rs, dns_name_t **name, isc_uint32_t *ttl,
|
|||
db_rr_iterator_current(&s->it, name, ttl, rdata);
|
||||
}
|
||||
|
||||
static void
|
||||
axfr_rrstream_pause(rrstream_t *rs) {
|
||||
axfr_rrstream_t *s = (axfr_rrstream_t *) rs;
|
||||
db_rr_iterator_pause(&s->it);
|
||||
}
|
||||
|
||||
static void
|
||||
axfr_rrstream_destroy(rrstream_t **rsp) {
|
||||
axfr_rrstream_t *s = (axfr_rrstream_t *) *rsp;
|
||||
|
|
@ -528,6 +546,7 @@ static rrstream_methods_t axfr_rrstream_methods = {
|
|||
axfr_rrstream_first,
|
||||
axfr_rrstream_next,
|
||||
axfr_rrstream_current,
|
||||
axfr_rrstream_pause,
|
||||
axfr_rrstream_destroy
|
||||
};
|
||||
|
||||
|
|
@ -611,6 +630,7 @@ static rrstream_methods_t soa_rrstream_methods = {
|
|||
soa_rrstream_first,
|
||||
soa_rrstream_next,
|
||||
soa_rrstream_current,
|
||||
rrstream_noop_pause,
|
||||
soa_rrstream_destroy
|
||||
};
|
||||
|
||||
|
|
@ -698,6 +718,11 @@ compound_rrstream_next(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++;
|
||||
|
|
@ -719,6 +744,16 @@ compound_rrstream_current(rrstream_t *rs, dns_name_t **name, isc_uint32_t *ttl,
|
|||
curstream->methods->current(curstream, name, ttl, rdata);
|
||||
}
|
||||
|
||||
static void
|
||||
compound_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 void
|
||||
compound_rrstream_destroy(rrstream_t **rsp) {
|
||||
compound_rrstream_t *s = (compound_rrstream_t *) *rsp;
|
||||
|
|
@ -732,6 +767,7 @@ static rrstream_methods_t compound_rrstream_methods = {
|
|||
compound_rrstream_first,
|
||||
compound_rrstream_next,
|
||||
compound_rrstream_current,
|
||||
compound_rrstream_pause,
|
||||
compound_rrstream_destroy
|
||||
};
|
||||
|
||||
|
|
@ -1411,7 +1447,8 @@ sendstream(xfrout_ctx_t *xfr) {
|
|||
msg = NULL;
|
||||
ns_client_send(xfr->client);
|
||||
xfrout_ctx_destroy(&xfr);
|
||||
return;
|
||||
result = ISC_R_SUCCESS;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Advance lasttsig to be the last TSIG generated */
|
||||
|
|
@ -1440,6 +1477,14 @@ sendstream(xfrout_ctx_t *xfr) {
|
|||
}
|
||||
dns_message_destroy(&msg);
|
||||
}
|
||||
|
||||
done:
|
||||
/*
|
||||
* Make sure to release any locks held by database
|
||||
* iterators before returning from the event handler.
|
||||
*/
|
||||
xfr->stream->methods->pause(xfr->stream);
|
||||
|
||||
if (result == ISC_R_SUCCESS)
|
||||
return;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue