isc_mem_free(mctx, ptr);
}
if (lookup->sendmsg != NULL)
- dns_message_destroy(&lookup->sendmsg);
+ dns_message_detach(&lookup->sendmsg);
if (lookup->querysig != NULL) {
debug("freeing buffer %p", lookup->querysig);
isc_buffer_free(&lookup->querysig);
printf(";; Got bad packet: %s\n", isc_result_totext(result));
hex_dump(b);
query->waiting_connect = false;
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
isc_event_free(&event);
clear_query(query);
cancel_lookup(l);
printf(";; Warning: Opcode mismatch: expected %s, got %s",
expect, got);
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
if (l->tcp_mode) {
isc_event_free(&event);
clear_query(query);
}
}
if (!match) {
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
if (l->tcp_mode) {
isc_event_free(&event);
clear_query(query);
n = requeue_lookup(l, true);
if (l->trace && l->trace_root)
n->rdtype = l->qrdtype;
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
isc_event_free(&event);
clear_query(query);
cancel_lookup(l);
n->tcp_mode = true;
if (l->trace && l->trace_root)
n->rdtype = l->qrdtype;
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
isc_event_free(&event);
clear_query(query);
cancel_lookup(l);
n->seenbadcookie = true;
if (l->trace && l->trace_root)
n->rdtype = l->qrdtype;
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
isc_event_free(&event);
clear_query(query);
cancel_lookup(l);
query->servname);
clear_query(query);
check_next_lookup(l);
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
isc_event_free(&event);
UNLOCK_LOOKUP;
return;
debug("still pending.");
if (l->doing_xfr) {
if (query != l->xfr_q) {
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
isc_event_free(&event);
query->waiting_connect = false;
UNLOCK_LOOKUP;
if (!docancel)
docancel = check_for_more_data(query, msg, sevent);
if (docancel) {
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
clear_query(query);
cancel_lookup(l);
check_next_lookup(l);
#ifdef DIG_SIGCHASE
if (!do_sigchase)
#endif
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
cancel_lookup(l);
}
msg = NULL;
else
#endif
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
}
isc_event_free(&event);
UNLOCK_LOOKUP;
while (chase_msg != NULL) {
INSIST(chase_msg->msg != NULL);
- dns_message_destroy(&(chase_msg->msg));
+ dns_message_detach(&(chase_msg->msg));
ptr = chase_msg;
chase_msg = ISC_LIST_NEXT(chase_msg, link);
isc_mem_free(mctx, ptr);
while (chase_msg != NULL) {
INSIST(chase_msg->msg != NULL);
- dns_message_destroy(&(chase_msg->msg));
+ dns_message_detach(&(chase_msg->msg));
ptr = chase_msg;
chase_msg = ISC_LIST_NEXT(chase_msg, link);
isc_mem_free(mctx, ptr);
}
if (l->sendmsg != NULL)
- dns_message_destroy(&l->sendmsg);
+ dns_message_detach(&l->sendmsg);
lp = l;
l = ISC_LIST_NEXT(l, link);
ISC_LIST_DEQUEUE(lookup_list, lp, link);
client->keytag_len = 0;
}
- dns_message_destroy(&client->message);
+ dns_message_detach(&client->message);
/*
* Detaching the task must be done after unlinking from
client->magic = 0;
cleanup_message:
- dns_message_destroy(&client->message);
+ dns_message_detach(&client->message);
cleanup_timer:
isc_timer_detach(&client->timer);
INSIST(client->nupdates > 0);
client->nupdates--;
ns_client_sendraw(client, uev->answer);
- dns_message_destroy(&uev->answer);
+ dns_message_detach(&uev->answer);
isc_event_free(&event);
ns_client_detach(&client);
}
}
if (tcpmsg != NULL)
- dns_message_destroy(&tcpmsg);
+ dns_message_detach(&tcpmsg);
if (cleanup_cctx)
dns_compress_invalidate(&cctx);
}
if (updatemsg != NULL)
- dns_message_destroy(&updatemsg);
+ dns_message_detach(&updatemsg);
if (is_dst_up) {
ddebug("Destroy DST lib");
if (shuttingdown) {
dns_request_destroy(&request);
- dns_message_destroy(&soaquery);
+ dns_message_detach(&soaquery);
isc_mem_put(gmctx, reqinfo, sizeof(nsu_requestinfo_t));
isc_event_free(&event);
maybeshutdown();
result = dns_request_getresponse(request, rcvmsg,
DNS_MESSAGEPARSE_PRESERVEORDER);
if (result == DNS_R_TSIGERRORSET && servers != NULL) {
- dns_message_destroy(&rcvmsg);
+ dns_message_detach(&rcvmsg);
ddebug("Destroying request [%p]", request);
dns_request_destroy(&request);
reqinfo = isc_mem_get(gmctx, sizeof(nsu_requestinfo_t));
dns_name_format(userzone, namebuf, sizeof(namebuf));
error("specified zone '%s' does not exist (NXDOMAIN)",
namebuf);
- dns_message_destroy(&rcvmsg);
+ dns_message_detach(&rcvmsg);
dns_request_destroy(&request);
- dns_message_destroy(&soaquery);
+ dns_message_detach(&soaquery);
ddebug("Out of recvsoa");
done_update();
seenerror = true;
setzoneclass(dns_rdataclass_none);
#endif
- dns_message_destroy(&soaquery);
+ dns_message_detach(&soaquery);
dns_request_destroy(&request);
out:
- dns_message_destroy(&rcvmsg);
+ dns_message_detach(&rcvmsg);
ddebug("Out of recvsoa");
return;
failure:
if (rmsg != NULL)
- dns_message_destroy(&rmsg);
+ dns_message_detach(&rmsg);
if (err_message != NULL)
isc_mem_free(gmctx, err_message);
failed_gssrequest();
if (shuttingdown) {
dns_request_destroy(&request);
- dns_message_destroy(&tsigquery);
+ dns_message_detach(&tsigquery);
isc_mem_put(gmctx, reqinfo, sizeof(nsu_gssinfo_t));
isc_event_free(&event);
maybeshutdown();
ddebug("Destroying request [%p]", request);
dns_request_destroy(&request);
if (!next_master("recvgss", addr, eresult)) {
- dns_message_destroy(&tsigquery);
+ dns_message_detach(&tsigquery);
failed_gssrequest();
} else {
dns_message_renderreset(tsigquery);
switch (result) {
case DNS_R_CONTINUE:
- dns_message_destroy(&rcvmsg);
+ dns_message_detach(&rcvmsg);
dns_request_destroy(&request);
send_gssrequest(kserver, tsigquery, &request, context);
ddebug("Out of recvgss");
done:
dns_request_destroy(&request);
- dns_message_destroy(&tsigquery);
+ dns_message_detach(&tsigquery);
- dns_message_destroy(&rcvmsg);
+ dns_message_detach(&rcvmsg);
ddebug("Out of recvgss");
}
#endif
LOCK(&answer_lock);
if (answer != NULL) {
- dns_message_destroy(&answer);
+ dns_message_detach(&answer);
}
UNLOCK(&answer_lock);
dns_message_puttempname(soaquery, &name);
dns_rdataset_disassociate(rdataset);
dns_message_puttemprdataset(soaquery, &rdataset);
- dns_message_destroy(&soaquery);
+ dns_message_detach(&soaquery);
done_update();
return;
}
LOCK(&answer_lock);
if (answer != NULL) {
- dns_message_destroy(&answer);
+ dns_message_detach(&answer);
}
UNLOCK(&answer_lock);
CHECK("dns_request_getresponse", result2);
if (response != NULL)
- dns_message_destroy(&response);
+ dns_message_detach(&response);
end:
if (query != NULL)
- dns_message_destroy(&query);
+ dns_message_detach(&query);
if (reqev->request != NULL)
dns_request_destroy(&reqev->request);
if (qrdataset != NULL)
dns_message_puttemprdataset(message, &qrdataset);
if (message != NULL)
- dns_message_destroy(&message);
+ dns_message_detach(&message);
}
static void
tsigkey = NULL;
}
- dns_message_destroy(&response);
+ dns_message_detach(&response);
end:
if (query != NULL)
- dns_message_destroy(&query);
+ dns_message_detach(&query);
if (reqev->request != NULL)
dns_request_destroy(&reqev->request);
printf("%.*s\n", (int)isc_buffer_usedlength(&outbuf),
(char *)isc_buffer_base(&outbuf));
- dns_message_destroy(&response);
+ dns_message_detach(&response);
isc_event_free(&event);
isc_app_shutdown();
inr.length = sizeof(rdata);
result = isc_socket_recv(s, &inr, 1, task1, recvdone, NULL);
CHECK("isc_socket_recv", result);
- dns_message_destroy(&query);
+ dns_message_detach(&query);
}
int
(char *)isc_buffer_base(&outbuf));
fflush(stdout);
- dns_message_destroy(&query);
- dns_message_destroy(&response);
+ dns_message_detach(&query);
+ dns_message_detach(&response);
dns_request_destroy(&reqev->request);
isc_event_free(&event);
result = dst_key_tofile(tsigkey->key, type, "");
CHECK("dst_key_tofile", result);
- dns_message_destroy(&query);
- dns_message_destroy(&response);
+ dns_message_detach(&query);
+ dns_message_detach(&response);
dns_request_destroy(&reqev->request);
isc_event_free(&event);
isc_app_shutdown();
result = dns_tkey_processdeleteresponse(query, response, ring);
CHECK("dns_tkey_processdhresponse", result);
- dns_message_destroy(&query);
- dns_message_destroy(&response);
+ dns_message_detach(&query);
+ dns_message_detach(&response);
dns_request_destroy(&reqev->request);
isc_event_free(&event);
isc_app_shutdown();
dns_compress_invalidate(&cctx);
message->from_to_wire = DNS_MESSAGE_INTENTPARSE;
- dns_message_destroy(&message);
+ dns_message_detach(&message);
printf("Message rendered.\n");
if (printmemstats)
result = printmessage(message);
CHECKRESULT(result, "printmessage() failed");
}
- dns_message_destroy(&message);
+ dns_message_detach(&message);
}
if (handle != NULL)
dns_dt_close(&handle);
if (message != NULL)
- dns_message_destroy(&message);
+ dns_message_detach(&message);
if (b != NULL)
isc_buffer_free(&b);
isc_mem_destroy(&mctx);
if (style != NULL)
dns_master_styledestroy(&style, mctx);
if (query != NULL)
- dns_message_destroy(&query);
+ dns_message_detach(&query);
if (response != NULL)
- dns_message_destroy(&response);
+ dns_message_detach(&response);
dns_request_destroy(&reqev->request);
isc_event_free(&event);
update_sendevent(updatectx_t *uctx, isc_result_t result) {
isc_task_t *task;
- dns_message_destroy(&uctx->updatemsg);
+ dns_message_detach(&uctx->updatemsg);
if (uctx->tsigkey != NULL)
dns_tsigkey_detach(&uctx->tsigkey);
if (uctx->sig0key != NULL)
out:
if (answer != NULL)
- dns_message_destroy(&answer);
+ dns_message_detach(&answer);
isc_event_free(&event);
LOCK(&uctx->lock);
dns_request_t *newrequest = NULL;
/* Retry SOA request without TSIG */
- dns_message_destroy(&rcvmsg);
+ dns_message_detach(&rcvmsg);
dns_message_renderreset(uctx->soaquery);
reqoptions = 0;
if (uctx->want_tcp)
}
if (!droplabel || result != ISC_R_SUCCESS) {
- dns_message_destroy(&uctx->soaquery);
+ dns_message_detach(&uctx->soaquery);
LOCK(&uctx->lock);
dns_request_destroy(&uctx->soareq);
UNLOCK(&uctx->lock);
}
if (rcvmsg != NULL)
- dns_message_destroy(&rcvmsg);
+ dns_message_detach(&rcvmsg);
if (result != ISC_R_SUCCESS)
update_sendevent(uctx, result);
}
if (name != NULL)
dns_message_puttempname(soaquery, &name);
- dns_message_destroy(&soaquery);
+ dns_message_detach(&soaquery);
return (result);
}
UNLOCK(&client->lock);
}
if (uctx->updatemsg != NULL)
- dns_message_destroy(&uctx->updatemsg);
+ dns_message_detach(&uctx->updatemsg);
while ((sa = ISC_LIST_HEAD(uctx->servers)) != NULL) {
ISC_LIST_UNLINK(uctx->servers, sa, link);
isc_mem_put(client->mctx, sa, sizeof(*sa));
result = dns_message_parse(d->msg, &b, 0);
if (result != ISC_R_SUCCESS) {
if (result != DNS_R_RECOVERABLE)
- dns_message_destroy(&d->msg);
+ dns_message_detach(&d->msg);
result = ISC_R_SUCCESS;
}
d = *dp;
if (d->msg != NULL)
- dns_message_destroy(&d->msg);
+ dns_message_detach(&d->msg);
if (d->frame != NULL)
dnstap__dnstap__free_unpacked(d->frame, NULL);
#include <isc/lang.h>
#include <isc/magic.h>
+#include <isc/refcount.h>
#include <dns/compress.h>
#include <dns/masterdump.h>
struct dns_message {
/* public from here down */
unsigned int magic;
+ isc_refcount_t refcount;
dns_messageid_t id;
unsigned int flags;
/*%<
* Reset a message structure to default state. All internal lists are freed
* or reset to a default state as well. This is simply a more efficient
- * way to call dns_message_destroy() followed by dns_message_allocate(),
- * since it avoid many memory allocations.
+ * way to call dns_message_detach() (assuming last reference is hold),
+ * followed by dns_message_create(), since it avoid many memory allocations.
*
* If any data loanouts (buffers, names, rdatas, etc) were requested,
* the caller must no longer use them after this call.
*/
void
-dns_message_destroy(dns_message_t **msgp);
+dns_message_attach(dns_message_t *source, dns_message_t **target);
/*%<
- * Destroy all state in the message.
+ * Attach to message 'source'.
*
* Requires:
+ *\li 'source' to be a valid message.
+ *\li 'target' to be non NULL and '*target' to be NULL.
+ */
+
+void
+dns_message_detach(dns_message_t **messagep);
+/*%<
+ * Detach *messagep from its message.
+ * list.
*
- *\li 'msgp' be valid.
- *
- * Ensures:
- *\li '*msgp' == NULL
+ * Requires:
+ *\li '*messagep' to be a valid message.
*/
isc_result_t
#include <isc/buffer.h>
#include <isc/mem.h>
#include <isc/print.h>
+#include <isc/refcount.h>
#include <isc/string.h> /* Required for HP/UX (and others?) */
#include <isc/utf8.h>
#include <isc/util.h>
/*
* Free all but one (or everything) for this message. This is used by
- * both dns_message_reset() and dns_message_destroy().
+ * both dns_message_reset() and dns__message_destroy().
*/
static void
msgreset(dns_message_t *msg, bool everything) {
m->cctx = NULL;
+ isc_refcount_init(&m->refcount, 1);
+
*msgp = m;
return (ISC_R_SUCCESS);
msg->from_to_wire = intent;
}
-void
-dns_message_destroy(dns_message_t **msgp) {
- dns_message_t *msg;
-
- REQUIRE(msgp != NULL);
- REQUIRE(DNS_MESSAGE_VALID(*msgp));
-
- msg = *msgp;
- *msgp = NULL;
+static void
+dns__message_destroy(dns_message_t *msg) {
+ REQUIRE(msg != NULL);
+ REQUIRE(DNS_MESSAGE_VALID(msg));
msgreset(msg, true);
isc_mempool_destroy(&msg->namepool);
isc_mempool_destroy(&msg->rdspool);
+ isc_refcount_destroy(&msg->refcount);
msg->magic = 0;
isc_mem_putanddetach(&msg->mctx, msg, sizeof(dns_message_t));
}
+void
+dns_message_attach(dns_message_t *source, dns_message_t **target) {
+ REQUIRE(DNS_MESSAGE_VALID(source));
+
+ isc_refcount_increment(&source->refcount, NULL);
+ *target = source;
+}
+
+void
+dns_message_detach(dns_message_t **messagep) {
+ REQUIRE(messagep != NULL && DNS_MESSAGE_VALID(*messagep));
+ dns_message_t *msg = *messagep;
+ *messagep = NULL;
+ int32_t refs;
+
+ isc_refcount_decrement(&msg->refcount, &refs);
+ if (refs == 0) {
+ dns__message_destroy(msg);
+ }
+}
+
static isc_result_t
findname(dns_name_t **foundname, dns_name_t *target,
dns_namelist_t *section)
isc_counter_detach(&fctx->qc);
fcount_decr(fctx);
isc_timer_detach(&fctx->timer);
- dns_message_destroy(&fctx->rmessage);
- dns_message_destroy(&fctx->qmessage);
+ dns_message_detach(&fctx->rmessage);
+ dns_message_detach(&fctx->qmessage);
if (dns_name_countlabels(&fctx->domain) > 0)
dns_name_free(&fctx->domain, fctx->mctx);
if (dns_rdataset_isassociated(&fctx->nameservers))
return (ISC_R_SUCCESS);
cleanup_rmessage:
- dns_message_destroy(&fctx->rmessage);
+ dns_message_detach(&fctx->rmessage);
cleanup_qmessage:
- dns_message_destroy(&fctx->qmessage);
+ dns_message_detach(&fctx->qmessage);
cleanup_fcount:
fcount_decr(fctx);
}
dns_compress_invalidate(&cctx);
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
}
/*
tsigctx = msg->tsigctx;
msg->tsigctx = NULL;
isc_buffer_free(&buf);
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
result = dst_context_create3(key->key, mctx, DNS_LOGCATEGORY_DNSSEC,
false, &outctx);
tsigctx = msg->tsigctx;
msg->tsigctx = NULL;
isc_buffer_free(&buf);
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
/*
* Create response message 3.
assert_int_equal(result, ISC_R_SUCCESS);
isc_buffer_free(&buf);
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
if (outctx != NULL) {
dst_context_destroy(&outctx);
dns_master_styledestroy
dns_master_styleflags
dns_message_addname
+dns_message_attach
dns_message_buildopt
dns_message_checksig
dns_message_create
dns_message_currentname
-dns_message_destroy
+dns_message_detach
dns_message_find
dns_message_findname
dns_message_findtype
if (qrdataset != NULL)
dns_message_puttemprdataset(msg, &qrdataset);
if (msg != NULL)
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
if (soatuple != NULL)
dns_difftuple_free(&soatuple);
if (ver != NULL)
xfrin_log(xfr, ISC_LOG_DEBUG(3), "got %s, retrying with AXFR",
isc_result_totext(result));
try_axfr:
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
xfrin_reset(xfr);
xfr->reqtype = dns_rdatatype_soa;
xfr->state = XFRST_SOAQUERY;
xfr->tsigctx = msg->tsigctx;
msg->tsigctx = NULL;
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
switch (xfr->state) {
case XFRST_GOTSOA:
failure:
if (msg != NULL)
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
if (result != ISC_R_SUCCESS)
xfrin_fail(xfr, result, "failed while receiving responses");
}
if (key != NULL)
dns_tsigkey_detach(&key);
cleanup_message:
- dns_message_destroy(&message);
+ dns_message_detach(&message);
cleanup:
UNLOCK_ZONE(notify->zone);
isc_event_free(&event);
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
dns_db_detach(&stub->db);
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
isc_event_free(&event);
dns_request_destroy(&zone->request);
if (stub->db != NULL)
dns_db_detach(&stub->db);
if (msg != NULL)
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
isc_event_free(&event);
dns_request_destroy(&zone->request);
/*
same_master:
if (msg != NULL)
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
isc_event_free(&event);
dns_request_destroy(&zone->request);
ns_query(zone, NULL, stub);
ns_query(zone, rdataset, NULL);
}
if (msg != NULL)
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
} else if (isc_serial_eq(soa.serial, oldserial)) {
isc_time_t expiretime;
uint32_t expire;
goto next_master;
}
if (msg != NULL)
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
goto detach;
next_master:
if (msg != NULL)
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
isc_event_free(&event);
dns_request_destroy(&zone->request);
/*
same_master:
if (msg != NULL)
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
isc_event_free(&event);
dns_request_destroy(&zone->request);
queue_soa_query(zone);
if (qrdataset != NULL)
dns_message_puttemprdataset(message, &qrdataset);
if (message != NULL)
- dns_message_destroy(&message);
+ dns_message_detach(&message);
return (result);
}
if (result != ISC_R_SUCCESS)
DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
if (message != NULL)
- dns_message_destroy(&message);
+ dns_message_detach(&message);
if (cancel)
cancel_refresh(zone);
isc_event_free(&event);
skip_master:
if (key != NULL)
dns_tsigkey_detach(&key);
- dns_message_destroy(&message);
+ dns_message_detach(&message);
/*
* Skip to next failed / untried master.
*/
dns_result_totext(result));
goto cleanup;
}
- dns_message_destroy(&message);
+ dns_message_detach(&message);
goto unlock;
cleanup:
isc_mem_put(stub->mctx, stub, sizeof(*stub));
}
if (message != NULL)
- dns_message_destroy(&message);
+ dns_message_detach(&message);
unlock:
if (key != NULL)
dns_tsigkey_detach(&key);
dns_message_puttempname(message, &tempname);
if (temprdataset != NULL)
dns_message_puttemprdataset(message, &temprdataset);
- dns_message_destroy(&message);
+ dns_message_detach(&message);
return (result);
}
notify_destroy(notify, false);
}
if (message != NULL)
- dns_message_destroy(&message);
+ dns_message_detach(&message);
}
struct secure_event {
next_master:
if (msg != NULL)
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
isc_event_free(&event);
forward->which++;
dns_request_destroy(&forward->request);
/* Cleanup */
for (i = 0; i < MAX_PROBES; i++) {
- dns_message_destroy(&probes[i].qmessage);
- dns_message_destroy(&probes[i].rmessage);
+ dns_message_detach(&probes[i].qmessage);
+ dns_message_detach(&probes[i].rmessage);
}
isc_task_detach(&probe_task);
dns_client_destroy(&client);
dns_message_puttempname(message, &qname);
if (qrdataset != NULL)
dns_message_puttemprdataset(message, &qrdataset);
- dns_message_destroy(&message);
+ dns_message_detach(&message);
return (result);
}
isc_buffer_free(&outputbuf);
/* Cleanup */
- dns_message_destroy(&qmessage);
- dns_message_destroy(&rmessage);
+ dns_message_detach(&qmessage);
+ dns_message_detach(&rmessage);
isc_mem_destroy(&mctx);
dns_client_destroy(&client);
dns_lib_shutdown();