Add field trial for adding remote ufrag CreatePermission

This patch adds a field trial for appending an extra
attribute which contains the remote ufrag for the permission.

The attribute is put into the comprehension-optional range
so that a TURN server should ignore it if it doesn't know if.
https://tools.ietf.org/html/rfc5389#section-18.2

Bug: webrtc:10350
Change-Id: I7d62ab94e947bddd670d8eb53d4ff89b1d1e275c
Reviewed-on: https://webrtc-review.googlesource.com/c/123901
Commit-Queue: Jonas Oreland <jonaso@webrtc.org>
Reviewed-by: Qingsi Wang <qingsi@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26859}
This commit is contained in:
Jonas Oreland 2019-02-26 17:51:43 +01:00 committed by Commit Bot
parent 546ee613a4
commit 39b69ccf14
3 changed files with 57 additions and 11 deletions

View File

@ -640,6 +640,9 @@ void P2PTransportChannel::SetIceConfig(const IceConfig& config) {
if (webrtc::field_trial::IsEnabled("WebRTC-ExtraICEPing")) {
RTC_LOG(LS_INFO) << "Set WebRTC-ExtraICEPing: Enabled";
}
if (webrtc::field_trial::IsEnabled("WebRTC-TurnAddMultiMapping")) {
RTC_LOG(LS_INFO) << "Set WebRTC-TurnAddMultiMapping: Enabled";
}
webrtc::BasicRegatheringController::Config regathering_config(
config_.regather_all_networks_interval_range,

View File

@ -25,12 +25,15 @@
#include "rtc_base/net_helpers.h"
#include "rtc_base/socket_address.h"
#include "rtc_base/strings/string_builder.h"
#include "system_wrappers/include/field_trial.h"
namespace cricket {
// TODO(juberti): Move to stun.h when relay messages have been renamed.
static const int TURN_ALLOCATE_REQUEST = STUN_ALLOCATE_REQUEST;
static const int STUN_ATTR_MULTI_MAPPING = 0xff04;
// TODO(juberti): Extract to turnmessage.h
static const int TURN_DEFAULT_PORT = 3478;
static const int TURN_CHANNEL_NUMBER_START = 0x4000;
@ -98,7 +101,8 @@ class TurnCreatePermissionRequest : public StunRequest,
public:
TurnCreatePermissionRequest(TurnPort* port,
TurnEntry* entry,
const rtc::SocketAddress& ext_addr);
const rtc::SocketAddress& ext_addr,
const std::string& remote_ufrag);
void Prepare(StunMessage* request) override;
void OnSent() override;
void OnResponse(StunMessage* response) override;
@ -111,6 +115,7 @@ class TurnCreatePermissionRequest : public StunRequest,
TurnPort* port_;
TurnEntry* entry_;
rtc::SocketAddress ext_addr_;
std::string remote_ufrag_;
};
class TurnChannelBindRequest : public StunRequest, public sigslot::has_slots<> {
@ -139,7 +144,10 @@ class TurnChannelBindRequest : public StunRequest, public sigslot::has_slots<> {
class TurnEntry : public sigslot::has_slots<> {
public:
enum BindState { STATE_UNBOUND, STATE_BINDING, STATE_BOUND };
TurnEntry(TurnPort* port, int channel_id, const rtc::SocketAddress& ext_addr);
TurnEntry(TurnPort* port,
int channel_id,
const rtc::SocketAddress& ext_addr,
const std::string remote_ufrag);
TurnPort* port() { return port_; }
@ -179,6 +187,11 @@ class TurnEntry : public sigslot::has_slots<> {
// Signal sent when TurnEntry is destroyed.
sigslot::signal1<TurnEntry*> SignalDestroyed;
const std::string& get_remote_ufrag() const { return remote_ufrag_; }
void set_remote_ufrag(const std::string& remote_ufrag) {
remote_ufrag_ = remote_ufrag;
}
private:
TurnPort* port_;
int channel_id_;
@ -189,6 +202,8 @@ class TurnEntry : public sigslot::has_slots<> {
// actually fires, the TurnEntry will be destroyed only if the timestamp here
// matches the one in the firing event.
absl::optional<int64_t> destruction_timestamp_;
std::string remote_ufrag_;
};
TurnPort::TurnPort(rtc::Thread* thread,
@ -526,8 +541,8 @@ Connection* TurnPort::CreateConnection(const Candidate& remote_candidate,
remote_candidate.address().family()) {
// Create an entry, if needed, so we can get our permissions set up
// correctly.
if (CreateOrRefreshEntry(remote_candidate.address(),
next_channel_number_)) {
if (CreateOrRefreshEntry(remote_candidate.address(), next_channel_number_,
remote_candidate.username())) {
// An entry was created.
next_channel_number_++;
}
@ -1143,9 +1158,15 @@ bool TurnPort::EntryExists(TurnEntry* e) {
bool TurnPort::CreateOrRefreshEntry(const rtc::SocketAddress& addr,
int channel_number) {
return CreateOrRefreshEntry(addr, channel_number, "");
}
bool TurnPort::CreateOrRefreshEntry(const rtc::SocketAddress& addr,
int channel_number,
const std::string& remote_ufrag) {
TurnEntry* entry = FindEntry(addr);
if (entry == nullptr) {
entry = new TurnEntry(this, channel_number, addr);
entry = new TurnEntry(this, channel_number, addr, remote_ufrag);
entries_.push_back(entry);
return true;
} else {
@ -1164,6 +1185,15 @@ bool TurnPort::CreateOrRefreshEntry(const rtc::SocketAddress& addr,
// there's still one connection.
RTC_DCHECK(GetConnection(addr));
}
if (webrtc::field_trial::IsEnabled("WebRTC-TurnAddMultiMapping")) {
if (entry->get_remote_ufrag() != remote_ufrag) {
RTC_LOG(LS_INFO) << ToString() << ": remote ufrag updated."
<< " Sending new permission request";
entry->set_remote_ufrag(remote_ufrag);
entry->SendCreatePermissionRequest(0);
}
}
}
return false;
}
@ -1528,11 +1558,13 @@ void TurnRefreshRequest::OnTimeout() {
TurnCreatePermissionRequest::TurnCreatePermissionRequest(
TurnPort* port,
TurnEntry* entry,
const rtc::SocketAddress& ext_addr)
const rtc::SocketAddress& ext_addr,
const std::string& remote_ufrag)
: StunRequest(new TurnMessage()),
port_(port),
entry_(entry),
ext_addr_(ext_addr) {
ext_addr_(ext_addr),
remote_ufrag_(remote_ufrag) {
entry_->SignalDestroyed.connect(
this, &TurnCreatePermissionRequest::OnEntryDestroyed);
}
@ -1542,6 +1574,10 @@ void TurnCreatePermissionRequest::Prepare(StunMessage* request) {
request->SetType(TURN_CREATE_PERMISSION_REQUEST);
request->AddAttribute(absl::make_unique<StunXorAddressAttribute>(
STUN_ATTR_XOR_PEER_ADDRESS, ext_addr_));
if (webrtc::field_trial::IsEnabled("WebRTC-TurnAddMultiMapping")) {
request->AddAttribute(absl::make_unique<cricket::StunByteStringAttribute>(
STUN_ATTR_MULTI_MAPPING, remote_ufrag_));
}
port_->AddRequestAuthInfo(request);
port_->TurnCustomizerMaybeModifyOutgoingStunMessage(request);
}
@ -1670,18 +1706,21 @@ void TurnChannelBindRequest::OnEntryDestroyed(TurnEntry* entry) {
TurnEntry::TurnEntry(TurnPort* port,
int channel_id,
const rtc::SocketAddress& ext_addr)
const rtc::SocketAddress& ext_addr,
const std::string remote_ufrag)
: port_(port),
channel_id_(channel_id),
ext_addr_(ext_addr),
state_(STATE_UNBOUND) {
state_(STATE_UNBOUND),
remote_ufrag_(remote_ufrag) {
// Creating permission for |ext_addr_|.
SendCreatePermissionRequest(0);
}
void TurnEntry::SendCreatePermissionRequest(int delay) {
port_->SendRequest(new TurnCreatePermissionRequest(port_, this, ext_addr_),
delay);
port_->SendRequest(
new TurnCreatePermissionRequest(port_, this, ext_addr_, remote_ufrag_),
delay);
}
void TurnEntry::SendChannelBindRequest(int delay) {

View File

@ -266,6 +266,10 @@ class TurnPort : public Port {
bool CreateOrRefreshEntry(const rtc::SocketAddress& addr,
int channel_number);
bool CreateOrRefreshEntry(const rtc::SocketAddress& addr,
int channel_number,
const std::string& remote_ufrag);
rtc::DiffServCodePoint StunDscpValue() const override;
private: