Skip to content

Commit

Permalink
Fixes #1606: Prevent connection activation if the listener or connect…
Browse files Browse the repository at this point in the history
…or is closed
  • Loading branch information
ganeshmurthy committed Sep 4, 2024
1 parent 31c72f6 commit 5ae35c4
Showing 1 changed file with 36 additions and 23 deletions.
59 changes: 36 additions & 23 deletions src/adaptors/tcp/tcp_adaptor.c
Original file line number Diff line number Diff line change
Expand Up @@ -279,14 +279,6 @@ static void on_activate(void *context)

qd_log(LOG_TCP_ADAPTOR, QD_LOG_DEBUG, "[C%" PRIu64 "] on_activate", conn->conn_id);
while (qdr_connection_process(conn->qdr_conn)) {}
if (conn->is_egress_dispatcher_conn && conn->connector_closed) {
detach_links(conn);
qdr_connection_set_context(conn->qdr_conn, 0);
qdr_connection_closed(conn->qdr_conn);
qd_connection_counter_dec(QD_PROTOCOL_TCP);
conn->qdr_conn = 0;
free_qdr_tcp_connection(conn);
}
}

/**
Expand Down Expand Up @@ -1859,40 +1851,50 @@ qd_tcp_connector_t *qd_dispatch_configure_tcp_connector_legacy(qd_dispatch_t *qd
return c;
}

void qd_dispatch_delete_tcp_connector_legacy(qd_dispatch_t *qd, qd_tcp_connector_t *ct)
void qd_dispatch_delete_tcp_connector_legacy(qd_dispatch_t *qd, qd_tcp_connector_t *connector)
{
if (ct) {
if (connector) {
qd_log(LOG_TCP_ADAPTOR, QD_LOG_INFO, "Deleted TcpConnector for %s, %s:%s",
ct->config->adaptor_config->address, ct->config->adaptor_config->host, ct->config->adaptor_config->port);
connector->config->adaptor_config->address, connector->config->adaptor_config->host, connector->config->adaptor_config->port);

// need to close the pseudo-connection used for dispatching
// deliveries out to live connections:
handle_disconnected((qdr_tcp_connection_t*) ct->dispatcher_conn);
ct->dispatcher_conn = 0;
DEQ_REMOVE(tcp_adaptor->connectors, ct);
DEQ_REMOVE(tcp_adaptor->connectors, connector);

//
// Initiate termination of existing connections
//
qd_timer_t *temp_timer = 0;
if (qd->terminate_tcp_conns) {
// Note: PN_RAW_CONNECTION_CONNECTED event or PN_RAW_CONNECTION_DISCONNECTED event
// could come upon any of the connections. We need to hold the connector->lock
// to prevent any modification of the connections list while it is being traversed.
sys_mutex_lock(&ct->lock);
SET_ATOMIC_FLAG(&ct->closing);
sys_mutex_lock(&connector->lock);
qdr_tcp_connection_t* dispatcher_conn = connector->dispatcher_conn;
qd_timer_cancel(dispatcher_conn->activate_timer);
temp_timer = dispatcher_conn->activate_timer;
dispatcher_conn->activate_timer = 0;
SET_ATOMIC_FLAG(&connector->closing);
//
// Only the head connection is woken when holding the lock.
// This is an optimization. The next connection in the list is woken up in the handler of the PN_RAW_DISCONNECTED
// event of this connection (See close_connection_XSIDE_IO() to see where the next connection in the list is woken up).
// That way, we don't have to wake all the connections when holding the lock.
//
qdr_tcp_connection_t *conn = DEQ_HEAD(ct->connections);
if (conn)
qdr_tcp_connection_t *conn = DEQ_HEAD(connector->connections);
if (conn && conn->pn_raw_conn)
pn_raw_connection_wake(conn->pn_raw_conn);
sys_mutex_unlock(&ct->lock);
sys_mutex_unlock(&connector->lock);
}

qd_tcp_connector_decref(ct);
if (temp_timer) {
qd_timer_free(temp_timer);
}

// need to close the pseudo-connection used for dispatching
// deliveries out to live connections:
handle_disconnected((qdr_tcp_connection_t*) connector->dispatcher_conn);
connector->dispatcher_conn = 0;

qd_tcp_connector_decref(connector);
}
}

Expand Down Expand Up @@ -2428,7 +2430,18 @@ static void qdr_tcp_activate_CT(void *notused, qdr_connection_t *c)
// fake wakeup by using a timer.
qd_log(LOG_TCP_ADAPTOR, QD_LOG_DEBUG,
"[C%" PRIu64 "] qdr_tcp_activate_CT: schedule activate_timer", conn->conn_id);
qd_timer_schedule(conn->activate_timer, 0);

//
// https://github.com/skupperproject/skupper-router/issues/1606
// Do not schedule a zero length activate_timer if the connector is closing.
//
assert(conn->is_egress_dispatcher_conn);
qd_tcp_connector_t *connector = conn->connector;
sys_mutex_lock(&connector->lock);
if (!IS_ATOMIC_FLAG_SET(&connector->closing) && conn->activate_timer) {
qd_timer_schedule(conn->activate_timer, 0);
}
sys_mutex_unlock(&connector->lock);
} else {
UNLOCK(&conn->activation_lock);
qd_log(LOG_TCP_ADAPTOR, QD_LOG_DEBUG, "[C%" PRIu64 "] qdr_tcp_activate_CT: Cannot activate",
Expand Down

0 comments on commit 5ae35c4

Please sign in to comment.