Added calls to close links when a close frame is sent without being proceeded by a detach and end frames
@@ -260,6 +260,22 @@ static void notify_closed(qd_container_t *container, qd_connection_t *conn, void
}
}
+static void close_links(qd_container_t *container, pn_connection_t *conn)
+{
+ pn_link_t *pn_link = pn_link_head(conn, 0);
+ while (pn_link) {
+ qd_link_t *qd_link = (qd_link_t*) pn_link_get_context(pn_link);
+ if (qd_link && qd_link->node) {
+ qd_node_t *node = qd_link->node;
+ qd_log(container->log_source, QD_LOG_NOTICE,
+ "Aborting link '%s' due to parent connection end",
+ pn_link_name(pn_link));
+ node->ntype->link_detach_handler(node->context, qd_link, QD_LOST);
+ }
+ pn_link = pn_link_next(pn_link, 0);
+ }
+}
+
static int close_handler(qd_container_t *container, void* conn_context, pn_connection_t *conn, qd_connection_t* qd_conn)
{
@@ -267,18 +283,7 @@ static int close_handler(qd_container_t *container, void* conn_context, pn_conne
// Close all links, passing QD_LOST as the reason. These links are not
// being properly 'detached'. They are being orphaned.
//
- pn_link_t *pn_link = pn_link_head(conn, 0);
- while (pn_link) {
- qd_link_t *link = (qd_link_t*) pn_link_get_context(pn_link);
- pn_link_t *next = pn_link_next(pn_link, 0);
- if (link) {
- qd_node_t *node = link->node;
- if (node) {
- node->ntype->link_detach_handler(node->context, link, QD_LOST);
- }
- }
- pn_link = next;
- }
+ close_links(container, conn);
// close the connection
pn_connection_close(conn);
@@ -414,8 +419,10 @@ int pn_event_handler(void *handler_context, void *conn_context, pn_event_t *even
break;
case PN_CONNECTION_REMOTE_CLOSE :
- if (pn_connection_state(conn) == (PN_LOCAL_ACTIVE | PN_REMOTE_CLOSED))
+ if (pn_connection_state(conn) == (PN_LOCAL_ACTIVE | PN_REMOTE_CLOSED)) {
+ close_links(container, conn);
pn_connection_close(conn);
+ }
break;
case PN_SESSION_REMOTE_OPEN :
