Thread checks for the Connection class.
Following [1], add many more checks for safe access to member variables.
This change is effectively a no-op, but landed separately from the
earlier change that's smaller but contains a fundamental assumption
gleaned from the implementation (and its use).
[1]: https://webrtc-review.googlesource.com/c/src/+/249942
Bug: webrtc:11988
Change-Id: I1568e2160c9faa6993c5b68044312f83d00e4815
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/249943
Auto-Submit: Tomas Gunnarsson <tommi@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Commit-Queue: Tomas Gunnarsson <tommi@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#35850}
diff --git a/p2p/base/connection.cc b/p2p/base/connection.cc
index e0dcf7f..8575d65 100644
--- a/p2p/base/connection.cc
+++ b/p2p/base/connection.cc
@@ -167,6 +167,7 @@
: StunRequest(new IceMessage()), connection_(connection) {}
void ConnectionRequest::Prepare(StunMessage* request) {
+ RTC_DCHECK_RUN_ON(connection_->network_thread_);
request->SetType(STUN_BINDING_REQUEST);
std::string username;
connection_->port()->CreateStunUsername(
@@ -207,10 +208,10 @@
request->AddAttribute(
std::make_unique<StunByteStringAttribute>(STUN_ATTR_USE_CANDIDATE));
}
- if (connection_->nomination() &&
- connection_->nomination() != connection_->acked_nomination()) {
+ if (connection_->nomination_ &&
+ connection_->nomination_ != connection_->acked_nomination()) {
request->AddAttribute(std::make_unique<StunUInt32Attribute>(
- STUN_ATTR_NOMINATION, connection_->nomination()));
+ STUN_ATTR_NOMINATION, connection_->nomination_));
}
} else if (connection_->port()->GetIceRole() == ICEROLE_CONTROLLED) {
request->AddAttribute(std::make_unique<StunUInt64Attribute>(
@@ -257,18 +258,22 @@
}
void ConnectionRequest::OnResponse(StunMessage* response) {
+ RTC_DCHECK_RUN_ON(connection_->network_thread_);
connection_->OnConnectionRequestResponse(this, response);
}
void ConnectionRequest::OnErrorResponse(StunMessage* response) {
+ RTC_DCHECK_RUN_ON(connection_->network_thread_);
connection_->OnConnectionRequestErrorResponse(this, response);
}
void ConnectionRequest::OnTimeout() {
+ RTC_DCHECK_RUN_ON(connection_->network_thread_);
connection_->OnConnectionRequestTimeout(this);
}
void ConnectionRequest::OnSent() {
+ RTC_DCHECK_RUN_ON(connection_->network_thread_);
connection_->OnConnectionRequestSent(this);
// Each request is sent only once. After a single delay , the request will
// time out.
@@ -305,7 +310,7 @@
time_created_ms_(rtc::TimeMillis()),
field_trials_(&kDefaultFieldTrials),
rtt_estimate_(DEFAULT_RTT_ESTIMATE_HALF_TIME_MS) {
- RTC_DCHECK_RUN_ON(network_thread());
+ RTC_DCHECK_RUN_ON(network_thread_);
// All of our connections start in WAITING state.
// TODO(mallinath) - Start connections from STATE_FROZEN.
// Wire up to send stun packets
@@ -314,7 +319,7 @@
}
Connection::~Connection() {
- RTC_DCHECK_RUN_ON(network_thread());
+ RTC_DCHECK_RUN_ON(network_thread_);
}
webrtc::TaskQueueBase* Connection::network_thread() const {
@@ -322,6 +327,7 @@
}
const Candidate& Connection::local_candidate() const {
+ RTC_DCHECK_RUN_ON(network_thread_);
RTC_DCHECK(local_candidate_index_ < port_->Candidates().size());
return port_->Candidates()[local_candidate_index_];
}
@@ -364,6 +370,7 @@
}
void Connection::set_write_state(WriteState value) {
+ RTC_DCHECK_RUN_ON(network_thread_);
WriteState old_value = write_state_;
write_state_ = value;
if (value != old_value) {
@@ -374,6 +381,7 @@
}
void Connection::UpdateReceiving(int64_t now) {
+ RTC_DCHECK_RUN_ON(network_thread_);
bool receiving;
if (last_ping_sent() < last_ping_response_received()) {
// We consider any candidate pair that has its last connectivity check
@@ -399,6 +407,7 @@
}
void Connection::set_state(IceCandidatePairState state) {
+ RTC_DCHECK_RUN_ON(network_thread_);
IceCandidatePairState old_state = state_;
state_ = state;
if (state != old_state) {
@@ -407,6 +416,7 @@
}
void Connection::set_connected(bool value) {
+ RTC_DCHECK_RUN_ON(network_thread_);
bool old_value = connected_;
connected_ = value;
if (value != old_value) {
@@ -415,27 +425,74 @@
}
}
+bool Connection::use_candidate_attr() const {
+ RTC_DCHECK_RUN_ON(network_thread_);
+ return use_candidate_attr_;
+}
+
void Connection::set_use_candidate_attr(bool enable) {
+ RTC_DCHECK_RUN_ON(network_thread_);
use_candidate_attr_ = enable;
}
+void Connection::set_nomination(uint32_t value) {
+ RTC_DCHECK_RUN_ON(network_thread_);
+ nomination_ = value;
+}
+
+uint32_t Connection::remote_nomination() const {
+ RTC_DCHECK_RUN_ON(network_thread_);
+ return remote_nomination_;
+}
+
+bool Connection::nominated() const {
+ RTC_DCHECK_RUN_ON(network_thread_);
+ return acked_nomination_ || remote_nomination_;
+}
+
int Connection::unwritable_timeout() const {
+ RTC_DCHECK_RUN_ON(network_thread_);
return unwritable_timeout_.value_or(CONNECTION_WRITE_CONNECT_TIMEOUT);
}
+void Connection::set_unwritable_timeout(const absl::optional<int>& value_ms) {
+ RTC_DCHECK_RUN_ON(network_thread_);
+ unwritable_timeout_ = value_ms;
+}
+
int Connection::unwritable_min_checks() const {
+ RTC_DCHECK_RUN_ON(network_thread_);
return unwritable_min_checks_.value_or(CONNECTION_WRITE_CONNECT_FAILURES);
}
+void Connection::set_unwritable_min_checks(const absl::optional<int>& value) {
+ RTC_DCHECK_RUN_ON(network_thread_);
+ unwritable_min_checks_ = value;
+}
+
int Connection::inactive_timeout() const {
+ RTC_DCHECK_RUN_ON(network_thread_);
return inactive_timeout_.value_or(CONNECTION_WRITE_TIMEOUT);
}
+void Connection::set_inactive_timeout(const absl::optional<int>& value) {
+ RTC_DCHECK_RUN_ON(network_thread_);
+ inactive_timeout_ = value;
+}
+
int Connection::receiving_timeout() const {
+ RTC_DCHECK_RUN_ON(network_thread_);
return receiving_timeout_.value_or(WEAK_CONNECTION_RECEIVE_TIMEOUT);
}
+void Connection::set_receiving_timeout(
+ absl::optional<int> receiving_timeout_ms) {
+ RTC_DCHECK_RUN_ON(network_thread_);
+ receiving_timeout_ = receiving_timeout_ms;
+}
+
void Connection::SetIceFieldTrials(const IceFieldTrials* field_trials) {
+ RTC_DCHECK_RUN_ON(network_thread_);
field_trials_ = field_trials;
rtt_estimate_.SetHalfTime(field_trials->rtt_estimate_halftime_ms);
}
@@ -443,6 +500,7 @@
void Connection::OnSendStunPacket(const void* data,
size_t size,
StunRequest* req) {
+ RTC_DCHECK_RUN_ON(network_thread_);
rtc::PacketOptions options(port_->StunDscpValue());
options.info_signaled_after_sent.packet_type =
rtc::PacketType::kIceConnectivityCheck;
@@ -459,6 +517,7 @@
void Connection::OnReadPacket(const char* data,
size_t size,
int64_t packet_time_us) {
+ RTC_DCHECK_RUN_ON(network_thread_);
std::unique_ptr<IceMessage> msg;
std::string remote_ufrag;
const rtc::SocketAddress& addr(remote_candidate_.address());
@@ -542,6 +601,7 @@
}
void Connection::HandleStunBindingOrGoogPingRequest(IceMessage* msg) {
+ RTC_DCHECK_RUN_ON(network_thread_);
// This connection should now be receiving.
ReceivedPing(msg->transaction_id());
if (webrtc::field_trial::IsEnabled("WebRTC-ExtraICEPing") &&
@@ -641,6 +701,7 @@
}
void Connection::SendStunBindingResponse(const StunMessage* request) {
+ RTC_DCHECK_RUN_ON(network_thread_);
RTC_DCHECK(request->type() == STUN_BINDING_REQUEST);
// Retrieve the username from the request.
@@ -697,6 +758,7 @@
}
void Connection::SendGoogPingResponse(const StunMessage* request) {
+ RTC_DCHECK_RUN_ON(network_thread_);
RTC_DCHECK(request->type() == GOOG_PING_REQUEST);
// Fill in the response message.
@@ -708,6 +770,7 @@
}
void Connection::SendResponseMessage(const StunMessage& response) {
+ RTC_DCHECK_RUN_ON(network_thread_);
// Where I send the response.
const rtc::SocketAddress& addr = remote_candidate_.address();
@@ -738,11 +801,28 @@
}
}
+uint32_t Connection::acked_nomination() const {
+ RTC_DCHECK_RUN_ON(network_thread_);
+ return acked_nomination_;
+}
+
+void Connection::set_remote_nomination(uint32_t remote_nomination) {
+ RTC_DCHECK_RUN_ON(network_thread_);
+ remote_nomination_ = remote_nomination;
+}
+
void Connection::OnReadyToSend() {
+ RTC_DCHECK_RUN_ON(network_thread_);
SignalReadyToSend(this);
}
+bool Connection::pruned() const {
+ RTC_DCHECK_RUN_ON(network_thread_);
+ return pruned_;
+}
+
void Connection::Prune() {
+ RTC_DCHECK_RUN_ON(network_thread_);
if (!pruned_ || active()) {
RTC_LOG(LS_INFO) << ToString() << ": Connection pruned";
pruned_ = true;
@@ -752,6 +832,7 @@
}
void Connection::Destroy() {
+ RTC_DCHECK_RUN_ON(network_thread_);
// TODO(deadbeef, nisse): This may leak if an application closes a
// PeerConnection and then quickly destroys the PeerConnectionFactory (along
// with the networking thread on which this message is posted). Also affects
@@ -764,16 +845,19 @@
}
void Connection::FailAndDestroy() {
+ RTC_DCHECK_RUN_ON(network_thread_);
set_state(IceCandidatePairState::FAILED);
Destroy();
}
void Connection::FailAndPrune() {
+ RTC_DCHECK_RUN_ON(network_thread_);
set_state(IceCandidatePairState::FAILED);
Prune();
}
void Connection::PrintPingsSinceLastResponse(std::string* s, size_t max) {
+ RTC_DCHECK_RUN_ON(network_thread_);
rtc::StringBuilder oss;
if (pings_since_last_response_.size() > max) {
for (size_t i = 0; i < max; i++) {
@@ -789,7 +873,28 @@
*s = oss.str();
}
+bool Connection::reported() const {
+ RTC_DCHECK_RUN_ON(network_thread_);
+ return reported_;
+}
+
+void Connection::set_reported(bool reported) {
+ RTC_DCHECK_RUN_ON(network_thread_);
+ reported_ = reported;
+}
+
+bool Connection::selected() const {
+ RTC_DCHECK_RUN_ON(network_thread_);
+ return selected_;
+}
+
+void Connection::set_selected(bool selected) {
+ RTC_DCHECK_RUN_ON(network_thread_);
+ selected_ = selected;
+}
+
void Connection::UpdateState(int64_t now) {
+ RTC_DCHECK_RUN_ON(network_thread_);
int rtt = ConservativeRTTEstimate(rtt_);
if (RTC_LOG_CHECK_LEVEL(LS_VERBOSE)) {
@@ -846,7 +951,13 @@
}
}
+int64_t Connection::last_ping_sent() const {
+ RTC_DCHECK_RUN_ON(network_thread_);
+ return last_ping_sent_;
+}
+
void Connection::Ping(int64_t now) {
+ RTC_DCHECK_RUN_ON(network_thread_);
last_ping_sent_ = now;
ConnectionRequest* req = new ConnectionRequest(this);
// If not using renomination, we use "1" to mean "nominated" and "0" to mean
@@ -865,13 +976,38 @@
num_pings_sent_++;
}
+int64_t Connection::last_ping_response_received() const {
+ RTC_DCHECK_RUN_ON(network_thread_);
+ return last_ping_response_received_;
+}
+
+const absl::optional<std::string>& Connection::last_ping_id_received() const {
+ RTC_DCHECK_RUN_ON(network_thread_);
+ return last_ping_id_received_;
+}
+
+// Used to check if any STUN ping response has been received.
+int Connection::rtt_samples() const {
+ RTC_DCHECK_RUN_ON(network_thread_);
+ return rtt_samples_;
+}
+
+// Called whenever a valid ping is received on this connection. This is
+// public because the connection intercepts the first ping for us.
+int64_t Connection::last_ping_received() const {
+ RTC_DCHECK_RUN_ON(network_thread_);
+ return last_ping_received_;
+}
+
void Connection::ReceivedPing(const absl::optional<std::string>& request_id) {
+ RTC_DCHECK_RUN_ON(network_thread_);
last_ping_received_ = rtc::TimeMillis();
last_ping_id_received_ = request_id;
UpdateReceiving(last_ping_received_);
}
void Connection::HandlePiggybackCheckAcknowledgementIfAny(StunMessage* msg) {
+ RTC_DCHECK_RUN_ON(network_thread_);
RTC_DCHECK(msg->type() == STUN_BINDING_REQUEST ||
msg->type() == GOOG_PING_REQUEST);
const StunByteStringAttribute* last_ice_check_received_attr =
@@ -892,10 +1028,21 @@
}
}
+int64_t Connection::last_send_data() const {
+ RTC_DCHECK_RUN_ON(network_thread_);
+ return last_send_data_;
+}
+
+int64_t Connection::last_data_received() const {
+ RTC_DCHECK_RUN_ON(network_thread_);
+ return last_data_received_;
+}
+
void Connection::ReceivedPingResponse(
int rtt,
const std::string& request_id,
const absl::optional<uint32_t>& nomination) {
+ RTC_DCHECK_RUN_ON(network_thread_);
RTC_DCHECK_GE(rtt, 0);
// We've already validated that this is a STUN binding response with
// the correct local and remote username for this connection.
@@ -924,7 +1071,39 @@
rtt_samples_++;
}
+Connection::WriteState Connection::write_state() const {
+ RTC_DCHECK_RUN_ON(network_thread_);
+ return write_state_;
+}
+
+bool Connection::writable() const {
+ RTC_DCHECK_RUN_ON(network_thread_);
+ return write_state_ == STATE_WRITABLE;
+}
+
+bool Connection::receiving() const {
+ RTC_DCHECK_RUN_ON(network_thread_);
+ return receiving_;
+}
+
+// Determines whether the connection has finished connecting. This can only
+// be false for TCP connections.
+bool Connection::connected() const {
+ RTC_DCHECK_RUN_ON(network_thread_);
+ return connected_;
+}
+
+bool Connection::weak() const {
+ return !(writable() && receiving() && connected());
+}
+
+bool Connection::active() const {
+ RTC_DCHECK_RUN_ON(network_thread_);
+ return write_state_ != STATE_WRITE_TIMEOUT;
+}
+
bool Connection::dead(int64_t now) const {
+ RTC_DCHECK_RUN_ON(network_thread_);
if (last_received() > 0) {
// If it has ever received anything, we keep it alive
// - if it has recevied last DEAD_CONNECTION_RECEIVE_TIMEOUT (30s)
@@ -968,6 +1147,11 @@
return now > (time_created_ms_ + MIN_CONNECTION_LIFETIME);
}
+int Connection::rtt() const {
+ RTC_DCHECK_RUN_ON(network_thread_);
+ return rtt_;
+}
+
bool Connection::stable(int64_t now) const {
// A connection is stable if it's RTT has converged and it isn't missing any
// responses. We should send pings at a higher rate until the RTT converges
@@ -986,6 +1170,7 @@
}
std::string Connection::ToString() const {
+ RTC_DCHECK_RUN_ON(network_thread_);
const absl::string_view CONNECT_STATE_ABBREV[2] = {
"-", // not connected (false)
"C", // connected (true)
@@ -1022,8 +1207,8 @@
<< ":" << remote.address().ToSensitiveString() << "|"
<< CONNECT_STATE_ABBREV[connected()] << RECEIVE_STATE_ABBREV[receiving()]
<< WRITE_STATE_ABBREV[write_state()] << ICESTATE[static_cast<int>(state())]
- << "|" << SELECTED_STATE_ABBREV[selected()] << "|" << remote_nomination()
- << "|" << nomination() << "|" << priority() << "|";
+ << "|" << SELECTED_STATE_ABBREV[selected_] << "|" << remote_nomination()
+ << "|" << nomination_ << "|" << priority() << "|";
if (rtt_ < DEFAULT_RTT) {
ss << rtt_ << "]";
} else {
@@ -1037,6 +1222,7 @@
}
const webrtc::IceCandidatePairDescription& Connection::ToLogDescription() {
+ RTC_DCHECK_RUN_ON(network_thread_);
if (log_description_.has_value()) {
return log_description_.value();
}
@@ -1060,6 +1246,12 @@
return log_description_.value();
}
+void Connection::set_ice_event_log(webrtc::IceEventLog* ice_event_log) {
+ RTC_DCHECK_RUN_ON(network_thread_);
+ ice_event_log_ = ice_event_log;
+}
+
+// RTC_RUN_ON(network_thread_)
void Connection::LogCandidatePairConfig(
webrtc::IceCandidatePairConfigType type) {
if (ice_event_log_ == nullptr) {
@@ -1068,6 +1260,7 @@
ice_event_log_->LogCandidatePairConfig(type, id(), ToLogDescription());
}
+// RTC_RUN_ON(network_thread_)
void Connection::LogCandidatePairEvent(webrtc::IceCandidatePairEventType type,
uint32_t transaction_id) {
if (ice_event_log_ == nullptr) {
@@ -1078,6 +1271,7 @@
void Connection::OnConnectionRequestResponse(ConnectionRequest* request,
StunMessage* response) {
+ RTC_DCHECK_RUN_ON(network_thread_);
// Log at LS_INFO if we receive a ping response on an unwritable
// connection.
rtc::LoggingSeverity sev = !writable() ? rtc::LS_INFO : rtc::LS_VERBOSE;
@@ -1167,6 +1361,7 @@
<< request->Elapsed() << " ms";
}
+// RTC_RUN_ON(network_thread_).
void Connection::OnConnectionRequestSent(ConnectionRequest* request) {
// Log at LS_INFO if we send a ping on an unwritable connection.
rtc::LoggingSeverity sev = !writable() ? rtc::LS_INFO : rtc::LS_VERBOSE;
@@ -1174,7 +1369,7 @@
<< StunMethodToString(request->msg()->type())
<< ", id=" << rtc::hex_encode(request->id())
<< ", use_candidate=" << use_candidate_attr()
- << ", nomination=" << nomination();
+ << ", nomination=" << nomination_;
stats_.sent_ping_requests_total++;
LogCandidatePairEvent(webrtc::IceCandidatePairEventType::kCheckSent,
request->reduced_transaction_id());
@@ -1187,6 +1382,16 @@
port_->SignalRoleConflict(port_);
}
+IceCandidatePairState Connection::state() const {
+ RTC_DCHECK_RUN_ON(network_thread_);
+ return state_;
+}
+
+int Connection::num_pings_sent() const {
+ RTC_DCHECK_RUN_ON(network_thread_);
+ return num_pings_sent_;
+}
+
void Connection::MaybeSetRemoteIceParametersAndGeneration(
const IceParameters& ice_params,
int generation) {
@@ -1218,6 +1423,7 @@
}
void Connection::OnMessage(rtc::Message* pmsg) {
+ RTC_DCHECK_RUN_ON(network_thread_);
RTC_DCHECK(pmsg->message_id == MSG_DELETE);
RTC_LOG(LS_INFO) << "Connection deleted with number of pings sent: "
<< num_pings_sent_;
@@ -1226,11 +1432,18 @@
}
int64_t Connection::last_received() const {
+ RTC_DCHECK_RUN_ON(network_thread_);
return std::max(last_data_received_,
std::max(last_ping_received_, last_ping_response_received_));
}
+int64_t Connection::receiving_unchanged_since() const {
+ RTC_DCHECK_RUN_ON(network_thread_);
+ return receiving_unchanged_since_;
+}
+
ConnectionInfo Connection::stats() {
+ RTC_DCHECK_RUN_ON(network_thread_);
stats_.recv_bytes_second = round(recv_rate_tracker_.ComputeRate());
stats_.recv_total_bytes = recv_rate_tracker_.TotalSampleCount();
stats_.sent_bytes_second = round(send_rate_tracker_.ComputeRate());
@@ -1317,10 +1530,12 @@
}
bool Connection::rtt_converged() const {
+ RTC_DCHECK_RUN_ON(network_thread_);
return rtt_samples_ > (RTT_RATIO + 1);
}
bool Connection::missing_responses(int64_t now) const {
+ RTC_DCHECK_RUN_ON(network_thread_);
if (pings_since_last_response_.empty()) {
return false;
}
@@ -1331,6 +1546,7 @@
bool Connection::TooManyOutstandingPings(
const absl::optional<int>& max_outstanding_pings) const {
+ RTC_DCHECK_RUN_ON(network_thread_);
if (!max_outstanding_pings.has_value()) {
return false;
}
@@ -1341,6 +1557,7 @@
return true;
}
+// RTC_RUN_ON(network_thread_).
bool Connection::ShouldSendGoogPing(const StunMessage* message) {
if (remote_support_goog_ping_ == true && cached_stun_binding_ &&
cached_stun_binding_->EqualAttributes(message, [](int type) {
@@ -1358,6 +1575,7 @@
}
void Connection::ForgetLearnedState() {
+ RTC_DCHECK_RUN_ON(network_thread_);
RTC_LOG(LS_INFO) << ToString() << ": Connection forget learned state";
requests_.Clear();
receiving_ = false;
diff --git a/p2p/base/connection.h b/p2p/base/connection.h
index 9fb1e79..c102194 100644
--- a/p2p/base/connection.h
+++ b/p2p/base/connection.h
@@ -111,34 +111,28 @@
STATE_WRITE_TIMEOUT = 3, // we have had a large number of ping failures
};
- WriteState write_state() const { return write_state_; }
- bool writable() const { return write_state_ == STATE_WRITABLE; }
- bool receiving() const { return receiving_; }
+ WriteState write_state() const;
+ bool writable() const;
+ bool receiving() const;
// Determines whether the connection has finished connecting. This can only
// be false for TCP connections.
- bool connected() const { return connected_; }
- bool weak() const { return !(writable() && receiving() && connected()); }
- bool active() const { return write_state_ != STATE_WRITE_TIMEOUT; }
+ bool connected() const;
+ bool weak() const;
+ bool active() const;
// A connection is dead if it can be safely deleted.
bool dead(int64_t now) const;
// Estimate of the round-trip time over this connection.
- int rtt() const { return rtt_; }
+ int rtt() const;
int unwritable_timeout() const;
- void set_unwritable_timeout(const absl::optional<int>& value_ms) {
- unwritable_timeout_ = value_ms;
- }
+ void set_unwritable_timeout(const absl::optional<int>& value_ms);
int unwritable_min_checks() const;
- void set_unwritable_min_checks(const absl::optional<int>& value) {
- unwritable_min_checks_ = value;
- }
+ void set_unwritable_min_checks(const absl::optional<int>& value);
int inactive_timeout() const;
- void set_inactive_timeout(const absl::optional<int>& value) {
- inactive_timeout_ = value;
- }
+ void set_inactive_timeout(const absl::optional<int>& value);
// Gets the `ConnectionInfo` stats, where `best_connection` has not been
// populated (default value false).
@@ -174,15 +168,15 @@
// still keep it around in case the other side wants to use it. But we can
// safely stop pinging on it and we can allow it to time out if the other
// side stops using it as well.
- bool pruned() const { return pruned_; }
+ bool pruned() const;
void Prune();
- bool use_candidate_attr() const { return use_candidate_attr_; }
+ bool use_candidate_attr() const;
void set_use_candidate_attr(bool enable);
- void set_nomination(uint32_t value) { nomination_ = value; }
+ void set_nomination(uint32_t value);
- uint32_t remote_nomination() const { return remote_nomination_; }
+ uint32_t remote_nomination() const;
// One or several pairs may be nominated based on if Regular or Aggressive
// Nomination is used. https://tools.ietf.org/html/rfc5245#section-8
// `nominated` is defined both for the controlling or controlled agent based
@@ -190,12 +184,10 @@
// gets its `remote_nomination_` set when pinged by the controlling agent with
// a nomination value. The controlling agent gets its `acked_nomination_` set
// when receiving a response to a nominating ping.
- bool nominated() const { return acked_nomination_ || remote_nomination_; }
+ bool nominated() const;
int receiving_timeout() const;
- void set_receiving_timeout(absl::optional<int> receiving_timeout_ms) {
- receiving_timeout_ = receiving_timeout_ms;
- }
+ void set_receiving_timeout(absl::optional<int> receiving_timeout_ms);
// Makes the connection go away.
void Destroy();
@@ -212,24 +204,23 @@
void UpdateState(int64_t now);
// Called when this connection should try checking writability again.
- int64_t last_ping_sent() const { return last_ping_sent_; }
+ int64_t last_ping_sent() const;
void Ping(int64_t now);
void ReceivedPingResponse(
int rtt,
const std::string& request_id,
const absl::optional<uint32_t>& nomination = absl::nullopt);
- int64_t last_ping_response_received() const {
- return last_ping_response_received_;
- }
- const absl::optional<std::string>& last_ping_id_received() const {
- return last_ping_id_received_;
- }
+
+ int64_t last_ping_response_received() const;
+ const absl::optional<std::string>& last_ping_id_received() const;
+
// Used to check if any STUN ping response has been received.
- int rtt_samples() const { return rtt_samples_; }
+ int rtt_samples() const;
// Called whenever a valid ping is received on this connection. This is
// public because the connection intercepts the first ping for us.
- int64_t last_ping_received() const { return last_ping_received_; }
+ int64_t last_ping_received() const;
+
void ReceivedPing(
const absl::optional<std::string>& request_id = absl::nullopt);
// Handles the binding request; sends a response if this is a valid request.
@@ -239,8 +230,8 @@
// connectivity check from the peer.
void HandlePiggybackCheckAcknowledgementIfAny(StunMessage* msg);
// Timestamp when data was last sent (or attempted to be sent).
- int64_t last_send_data() const { return last_send_data_; }
- int64_t last_data_received() const { return last_data_received_; }
+ int64_t last_send_data() const;
+ int64_t last_data_received() const;
// Debugging description of this connection
std::string ToDebugId() const;
@@ -248,19 +239,19 @@
std::string ToSensitiveString() const;
// Structured description of this candidate pair.
const webrtc::IceCandidatePairDescription& ToLogDescription();
- void set_ice_event_log(webrtc::IceEventLog* ice_event_log) {
- ice_event_log_ = ice_event_log;
- }
+ void set_ice_event_log(webrtc::IceEventLog* ice_event_log);
+
// Prints pings_since_last_response_ into a string.
void PrintPingsSinceLastResponse(std::string* pings, size_t max);
- bool reported() const { return reported_; }
- void set_reported(bool reported) { reported_ = reported; }
- // The following two methods are only used for logging in ToString above, and
- // this flag is set true by P2PTransportChannel for its selected candidate
- // pair.
- bool selected() const { return selected_; }
- void set_selected(bool selected) { selected_ = selected; }
+ bool reported() const;
+ void set_reported(bool reported);
+
+ // `set_selected` is only used for logging in ToString above. The flag is
+ // set true by P2PTransportChannel for its selected candidate pair.
+ // TODO(tommi): Remove `selected()` once not referenced downstream.
+ bool selected() const;
+ void set_selected(bool selected);
// This signal will be fired if this connection is nominated by the
// controlling side.
@@ -269,9 +260,9 @@
// Invoked when Connection receives STUN error response with 487 code.
void HandleRoleConflictFromPeer();
- IceCandidatePairState state() const { return state_; }
+ IceCandidatePairState state() const;
- int num_pings_sent() const { return num_pings_sent_; }
+ int num_pings_sent() const;
uint32_t ComputeNetworkCost() const;
@@ -290,9 +281,7 @@
// response in milliseconds
int64_t last_received() const;
// Returns the last time when the connection changed its receiving state.
- int64_t receiving_unchanged_since() const {
- return receiving_unchanged_since_;
- }
+ int64_t receiving_unchanged_since() const;
bool stable(int64_t now) const;
@@ -327,12 +316,8 @@
const Port* PortForTest() const { return port_; }
// Public for unit tests.
- uint32_t acked_nomination() const { return acked_nomination_; }
-
- // Public for unit tests.
- void set_remote_nomination(uint32_t remote_nomination) {
- remote_nomination_ = remote_nomination;
- }
+ uint32_t acked_nomination() const;
+ void set_remote_nomination(uint32_t remote_nomination);
protected:
enum { MSG_DELETE = 0, MSG_FIRST_AVAILABLE };
@@ -347,9 +332,12 @@
virtual void OnConnectionRequestResponse(ConnectionRequest* req,
StunMessage* response);
void OnConnectionRequestErrorResponse(ConnectionRequest* req,
- StunMessage* response);
- void OnConnectionRequestTimeout(ConnectionRequest* req);
- void OnConnectionRequestSent(ConnectionRequest* req);
+ StunMessage* response)
+ RTC_RUN_ON(network_thread_);
+ void OnConnectionRequestTimeout(ConnectionRequest* req)
+ RTC_RUN_ON(network_thread_);
+ void OnConnectionRequestSent(ConnectionRequest* req)
+ RTC_RUN_ON(network_thread_);
bool rtt_converged() const;
@@ -363,8 +351,6 @@
void set_state(IceCandidatePairState state);
void set_connected(bool value);
- uint32_t nomination() const { return nomination_; }
-
void OnMessage(rtc::Message* pmsg) override;
// The local port where this connection sends and receives packets.
@@ -379,7 +365,7 @@
webrtc::TaskQueueBase* const network_thread_;
const uint32_t id_;
Port* const port_;
- size_t local_candidate_index_;
+ size_t local_candidate_index_ RTC_GUARDED_BY(network_thread_);
Candidate remote_candidate_;
ConnectionInfo stats_;
@@ -391,80 +377,93 @@
// Update the local candidate based on the mapped address attribute.
// If the local candidate changed, fires SignalStateChange.
void MaybeUpdateLocalCandidate(ConnectionRequest* request,
- StunMessage* response);
+ StunMessage* response)
+ RTC_RUN_ON(network_thread_);
- void LogCandidatePairConfig(webrtc::IceCandidatePairConfigType type);
+ void LogCandidatePairConfig(webrtc::IceCandidatePairConfigType type)
+ RTC_RUN_ON(network_thread_);
void LogCandidatePairEvent(webrtc::IceCandidatePairEventType type,
- uint32_t transaction_id);
+ uint32_t transaction_id)
+ RTC_RUN_ON(network_thread_);
// Check if this IceMessage is identical
// to last message ack:ed STUN_BINDING_REQUEST.
- bool ShouldSendGoogPing(const StunMessage* message);
+ bool ShouldSendGoogPing(const StunMessage* message)
+ RTC_RUN_ON(network_thread_);
- WriteState write_state_;
- bool receiving_;
- bool connected_;
- bool pruned_;
- bool selected_ = false;
+ WriteState write_state_ RTC_GUARDED_BY(network_thread_);
+ bool receiving_ RTC_GUARDED_BY(network_thread_);
+ bool connected_ RTC_GUARDED_BY(network_thread_);
+ bool pruned_ RTC_GUARDED_BY(network_thread_);
+ bool selected_ RTC_GUARDED_BY(network_thread_) = false;
// By default `use_candidate_attr_` flag will be true,
// as we will be using aggressive nomination.
// But when peer is ice-lite, this flag "must" be initialized to false and
// turn on when connection becomes "best connection".
- bool use_candidate_attr_;
+ bool use_candidate_attr_ RTC_GUARDED_BY(network_thread_);
// Used by the controlling side to indicate that this connection will be
// selected for transmission if the peer supports ICE-renomination when this
// value is positive. A larger-value indicates that a connection is nominated
// later and should be selected by the controlled side with higher precedence.
// A zero-value indicates not nominating this connection.
- uint32_t nomination_ = 0;
+ uint32_t nomination_ RTC_GUARDED_BY(network_thread_) = 0;
// The last nomination that has been acknowledged.
- uint32_t acked_nomination_ = 0;
+ uint32_t acked_nomination_ RTC_GUARDED_BY(network_thread_) = 0;
// Used by the controlled side to remember the nomination value received from
// the controlling side. When the peer does not support ICE re-nomination, its
// value will be 1 if the connection has been nominated.
- uint32_t remote_nomination_ = 0;
+ uint32_t remote_nomination_ RTC_GUARDED_BY(network_thread_) = 0;
- StunRequestManager requests_;
- int rtt_;
- int rtt_samples_ = 0;
+ StunRequestManager requests_ RTC_GUARDED_BY(network_thread_);
+ int rtt_ RTC_GUARDED_BY(network_thread_);
+ int rtt_samples_ RTC_GUARDED_BY(network_thread_) = 0;
// https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-totalroundtriptime
- uint64_t total_round_trip_time_ms_ = 0;
+ uint64_t total_round_trip_time_ms_ RTC_GUARDED_BY(network_thread_) = 0;
// https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-currentroundtriptime
- absl::optional<uint32_t> current_round_trip_time_ms_;
- int64_t last_ping_sent_; // last time we sent a ping to the other side
- int64_t last_ping_received_; // last time we received a ping from the other
- // side
- int64_t last_data_received_;
- int64_t last_ping_response_received_;
- int64_t receiving_unchanged_since_ = 0;
- std::vector<SentPing> pings_since_last_response_;
+ absl::optional<uint32_t> current_round_trip_time_ms_
+ RTC_GUARDED_BY(network_thread_);
+ int64_t last_ping_sent_ RTC_GUARDED_BY(
+ network_thread_); // last time we sent a ping to the other side
+ int64_t last_ping_received_
+ RTC_GUARDED_BY(network_thread_); // last time we received a ping from the
+ // other side
+ int64_t last_data_received_ RTC_GUARDED_BY(network_thread_);
+ int64_t last_ping_response_received_ RTC_GUARDED_BY(network_thread_);
+ int64_t receiving_unchanged_since_ RTC_GUARDED_BY(network_thread_) = 0;
+ std::vector<SentPing> pings_since_last_response_
+ RTC_GUARDED_BY(network_thread_);
// Transaction ID of the last connectivity check received. Null if having not
// received a ping yet.
- absl::optional<std::string> last_ping_id_received_;
+ absl::optional<std::string> last_ping_id_received_
+ RTC_GUARDED_BY(network_thread_);
- absl::optional<int> unwritable_timeout_;
- absl::optional<int> unwritable_min_checks_;
- absl::optional<int> inactive_timeout_;
+ absl::optional<int> unwritable_timeout_ RTC_GUARDED_BY(network_thread_);
+ absl::optional<int> unwritable_min_checks_ RTC_GUARDED_BY(network_thread_);
+ absl::optional<int> inactive_timeout_ RTC_GUARDED_BY(network_thread_);
- bool reported_;
- IceCandidatePairState state_;
+ bool reported_ RTC_GUARDED_BY(network_thread_);
+ IceCandidatePairState state_ RTC_GUARDED_BY(network_thread_);
// Time duration to switch from receiving to not receiving.
- absl::optional<int> receiving_timeout_;
- int64_t time_created_ms_;
- int num_pings_sent_ = 0;
+ absl::optional<int> receiving_timeout_ RTC_GUARDED_BY(network_thread_);
+ int64_t time_created_ms_ RTC_GUARDED_BY(network_thread_);
+ int num_pings_sent_ RTC_GUARDED_BY(network_thread_) = 0;
- absl::optional<webrtc::IceCandidatePairDescription> log_description_;
- webrtc::IceEventLog* ice_event_log_ = nullptr;
+ absl::optional<webrtc::IceCandidatePairDescription> log_description_
+ RTC_GUARDED_BY(network_thread_);
+ webrtc::IceEventLog* ice_event_log_ RTC_GUARDED_BY(network_thread_) = nullptr;
// GOOG_PING_REQUEST is sent in place of STUN_BINDING_REQUEST
// if configured via field trial, the remote peer supports it (signaled
// in STUN_BINDING) and if the last STUN BINDING is identical to the one
// that is about to be sent.
- absl::optional<bool> remote_support_goog_ping_;
- std::unique_ptr<StunMessage> cached_stun_binding_;
+ absl::optional<bool> remote_support_goog_ping_
+ RTC_GUARDED_BY(network_thread_);
+ std::unique_ptr<StunMessage> cached_stun_binding_
+ RTC_GUARDED_BY(network_thread_);
const IceFieldTrials* field_trials_;
- rtc::EventBasedExponentialMovingAverage rtt_estimate_;
+ rtc::EventBasedExponentialMovingAverage rtt_estimate_
+ RTC_GUARDED_BY(network_thread_);
friend class Port;
friend class ConnectionRequest;