void connection_destroy(struct relay_connection *conn)
{
- struct relay_stream *stream, *tmp_stream;
-
assert(conn);
- /* Clean up recv list of this connection if any. */
- cds_list_for_each_entry_safe(stream, tmp_stream, &conn->recv_head,
- recv_list) {
- cds_list_del(&stream->recv_list);
- }
-
call_rcu(&conn->rcu_node, rcu_free_connection);
}
session->stream_count--;
assert(session->stream_count >= 0);
- /*
- * Remove the stream from the connection recv list since we are about to
- * flag it invalid and thus might be freed. This has to be done here since
- * only the control thread can do actions on that list.
- *
- * Note that this stream might NOT be in the list but we have to try to
- * remove it here else this can race with the stream destruction freeing
- * the object and the connection destroy doing a use after free when
- * deleting the remaining nodes in this list.
- */
- cds_list_del(&stream->recv_list);
-
/* Check if we can close it or else the data will do it. */
try_close_stream(session, stream);