ClusterNode::identity() returns const bmqp_ctrlmsg::ClientIdentity& to d_identity, which is modified without synchronization in setChannel() at mqbnet_clusterimp.cpp:77 and resetChannel() at mqbnet_clusterimp.cpp:132. Both are called from IO threads. ClusterNodeImp has no mutex, and d_identity has no guard of any kind. Current callers happen to copy by value, so this may not manifest today, but the unprotected reference means any future const auto& binding would be a live data race.
Also worth noting that setChannel() and resetChannel() also write other members like d_description without synchronization. I suppose we should consider whether a fix should cover identity() alone or the broader class.
ClusterNode::identity() returns const bmqp_ctrlmsg::ClientIdentity& to d_identity, which is modified without synchronization in setChannel() at mqbnet_clusterimp.cpp:77 and resetChannel() at mqbnet_clusterimp.cpp:132. Both are called from IO threads. ClusterNodeImp has no mutex, and d_identity has no guard of any kind. Current callers happen to copy by value, so this may not manifest today, but the unprotected reference means any future const auto& binding would be a live data race.
Also worth noting that setChannel() and resetChannel() also write other members like d_description without synchronization. I suppose we should consider whether a fix should cover identity() alone or the broader class.