You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by kg...@apache.org on 2021/04/15 02:10:33 UTC
[qpid-dispatch] branch main updated: DISPATCH-2019: prevent early
free of qdr_address_t on link detach
This is an automated email from the ASF dual-hosted git repository.
kgiusti pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/qpid-dispatch.git
The following commit(s) were added to refs/heads/main by this push:
new f67e135 DISPATCH-2019: prevent early free of qdr_address_t on link detach
f67e135 is described below
commit f67e135c0cfd579272d191b0e14342c0f4cd8cc6
Author: Kenneth Giusti <kg...@apache.org>
AuthorDate: Wed Apr 14 12:45:55 2021 -0400
DISPATCH-2019: prevent early free of qdr_address_t on link detach
This closes #1121
---
src/router_core/connections.c | 194 +++++++++++++++++++++---------------------
1 file changed, 97 insertions(+), 97 deletions(-)
diff --git a/src/router_core/connections.c b/src/router_core/connections.c
index 2e80769..27ceb81 100644
--- a/src/router_core/connections.c
+++ b/src/router_core/connections.c
@@ -1949,8 +1949,6 @@ static void qdr_link_inbound_detach_CT(qdr_core_t *core, qdr_action_t *action, b
return;
}
- qdr_address_t *addr = link->owning_addr;
-
if (link->detach_received)
return;
@@ -1960,123 +1958,123 @@ static void qdr_link_inbound_detach_CT(qdr_core_t *core, qdr_action_t *action, b
if (link->core_endpoint) {
qdrc_endpoint_do_detach_CT(core, link->core_endpoint, error, dt);
return;
+ }
- } else {
+ //
+ // ensure a pooled link is no longer available for use
+ //
+ if (link->streaming) {
+ if (link->in_streaming_pool) {
+ DEQ_REMOVE_N(STREAMING_POOL, conn->streaming_link_pool, link);
+ link->in_streaming_pool = false;
+ }
+ }
+ //
+ // For routed links, propagate the detach
+ //
+ if (link->connected_link) {
//
- // ensure a pooled link is no longer available for use
+ // If the connected link is outgoing and there is a delivery on the connected link's undelivered
+ // list that is not receive-complete, we must flag that delivery as aborted or it will forever
+ // block the propagation of the detach.
//
- if (link->streaming) {
- if (link->in_streaming_pool) {
- DEQ_REMOVE_N(STREAMING_POOL, conn->streaming_link_pool, link);
- link->in_streaming_pool = false;
- }
+ if (link->connected_link->link_direction == QD_OUTGOING)
+ qdr_link_abort_undelivered_CT(core, link->connected_link);
+
+ if (dt != QD_LOST)
+ qdr_link_outbound_detach_CT(core, link->connected_link, error, QDR_CONDITION_NONE, dt == QD_CLOSED);
+ else {
+ qdr_link_outbound_detach_CT(core, link->connected_link, 0, QDR_CONDITION_ROUTED_LINK_LOST, !link->terminus_survives_disconnect);
+ qdr_error_free(error);
}
//
- // For routed links, propagate the detach
+ // If the link is completely detached, release its resources
//
- if (link->connected_link) {
- //
- // If the connected link is outgoing and there is a delivery on the connected link's undelivered
- // list that is not receive-complete, we must flag that delivery as aborted or it will forever
- // block the propagation of the detach.
- //
- if (link->connected_link->link_direction == QD_OUTGOING)
- qdr_link_abort_undelivered_CT(core, link->connected_link);
+ if (link->detach_send_done)
+ qdr_link_cleanup_protected_CT(core, conn, link, "Link detached");
- if (dt != QD_LOST)
- qdr_link_outbound_detach_CT(core, link->connected_link, error, QDR_CONDITION_NONE, dt == QD_CLOSED);
- else {
- qdr_link_outbound_detach_CT(core, link->connected_link, 0, QDR_CONDITION_ROUTED_LINK_LOST, !link->terminus_survives_disconnect);
- qdr_error_free(error);
- }
-
- //
- // If the link is completely detached, release its resources
- //
- if (link->detach_send_done)
- qdr_link_cleanup_protected_CT(core, conn, link, "Link detached");
+ return;
+ }
- return;
- }
+ //
+ // For auto links, switch the auto link to failed state and record the error
+ //
+ if (link->auto_link) {
+ link->auto_link->link = 0;
+ link->auto_link->state = QDR_AUTO_LINK_STATE_FAILED;
+ free(link->auto_link->last_error);
+ link->auto_link->last_error = qdr_error_description(error);
//
- // For auto links, switch the auto link to failed state and record the error
+ // The auto link has failed. Periodically retry setting up the auto link until
+ // it succeeds.
//
- if (link->auto_link) {
- link->auto_link->link = 0;
- link->auto_link->state = QDR_AUTO_LINK_STATE_FAILED;
- free(link->auto_link->last_error);
- link->auto_link->last_error = qdr_error_description(error);
+ qdr_route_auto_link_detached_CT(core, link);
+ }
- //
- // The auto link has failed. Periodically retry setting up the auto link until
- // it succeeds.
- //
- qdr_route_auto_link_detached_CT(core, link);
- }
- if (link->link_direction == QD_INCOMING) {
- qdrc_event_link_raise(core, QDRC_EVENT_LINK_IN_DETACHED, link);
- //
- // Handle incoming link cases
- //
- switch (link->link_type) {
- case QD_LINK_ENDPOINT:
- if (addr) {
- //
- // Drain the undelivered list to ensure deliveries don't get dropped by a detach.
- //
- qdr_drain_inbound_undelivered_CT(core, link, addr);
- //
- // Unbind the address and the link.
- //
- addr->ref_count++;
- qdr_core_unbind_address_link_CT(core, addr, link);
- addr->ref_count--;
-
- //
- // If this is an edge data link, raise a link event to indicate its detachment.
- //
- if (link->conn->role == QDR_ROLE_EDGE_CONNECTION)
- qdrc_event_link_raise(core, QDRC_EVENT_LINK_EDGE_DATA_DETACHED, link);
- }
- break;
+ qdr_address_t *addr = link->owning_addr;
+ if (addr)
+ addr->ref_count++;
- case QD_LINK_CONTROL:
- break;
+ if (link->link_direction == QD_INCOMING) {
+ qdrc_event_link_raise(core, QDRC_EVENT_LINK_IN_DETACHED, link);
+ //
+ // Handle incoming link cases
+ //
+ switch (link->link_type) {
+ case QD_LINK_ENDPOINT:
+ if (addr) {
+ //
+ // Drain the undelivered list to ensure deliveries don't get dropped by a detach.
+ //
+ qdr_drain_inbound_undelivered_CT(core, link, addr);
- case QD_LINK_ROUTER:
- break;
+ //
+ // Unbind the address and the link.
+ //
+ qdr_core_unbind_address_link_CT(core, addr, link);
- case QD_LINK_EDGE_DOWNLINK:
- break;
+ //
+ // If this is an edge data link, raise a link event to indicate its detachment.
+ //
+ if (link->conn->role == QDR_ROLE_EDGE_CONNECTION)
+ qdrc_event_link_raise(core, QDRC_EVENT_LINK_EDGE_DATA_DETACHED, link);
}
- } else {
- //
- // Handle outgoing link cases
- //
- qdrc_event_link_raise(core, QDRC_EVENT_LINK_OUT_DETACHED, link);
- switch (link->link_type) {
- case QD_LINK_ENDPOINT:
- case QD_LINK_EDGE_DOWNLINK:
- if (addr) {
- addr->ref_count++;
- qdr_core_unbind_address_link_CT(core, addr, link);
- addr->ref_count--;
- }
- break;
+ break;
- case QD_LINK_CONTROL:
- qdr_detach_link_control_CT(core, conn, link);
- break;
+ case QD_LINK_CONTROL:
+ break;
- case QD_LINK_ROUTER:
- qdr_detach_link_data_CT(core, conn, link);
- break;
+ case QD_LINK_ROUTER:
+ break;
+
+ case QD_LINK_EDGE_DOWNLINK:
+ break;
+ }
+ } else {
+ //
+ // Handle outgoing link cases
+ //
+ qdrc_event_link_raise(core, QDRC_EVENT_LINK_OUT_DETACHED, link);
+ switch (link->link_type) {
+ case QD_LINK_ENDPOINT:
+ case QD_LINK_EDGE_DOWNLINK:
+ if (addr) {
+ qdr_core_unbind_address_link_CT(core, addr, link);
}
+ break;
+
+ case QD_LINK_CONTROL:
+ qdr_detach_link_control_CT(core, conn, link);
+ break;
+
+ case QD_LINK_ROUTER:
+ qdr_detach_link_data_CT(core, conn, link);
+ break;
}
}
@@ -2107,8 +2105,10 @@ static void qdr_link_inbound_detach_CT(qdr_core_t *core, qdr_action_t *action, b
// If there was an address associated with this link, check to see if any address-related
// cleanup has to be done.
//
- if (addr)
+ if (addr) {
+ addr->ref_count--;
qdr_check_addr_CT(core, addr);
+ }
if (error)
qdr_error_free(error);
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org