Add configurable STUN binding request interval.

STUN candidates use STUN binding requests to keep NAT bindings open. The
interval at which the STUN keepalive pings are sent is configurable now
via RTCConfiguration.

TBR=sakal@webrtc.org

Bug: None
Change-Id: I5f99ea3fe1e9042fa2bf7dcab0aace78f57739e6
Reviewed-on: https://webrtc-review.googlesource.com/54180
Commit-Queue: Qingsi Wang <qingsi@google.com>
Reviewed-by: Taylor Brandstetter <deadbeef@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22109}
This commit is contained in:
Qingsi Wang
2018-02-20 14:45:49 -08:00
committed by Commit Bot
parent ed1eceaba5
commit db53f8e604
13 changed files with 98 additions and 14 deletions

View File

@ -114,6 +114,9 @@ struct IceConfig {
// than this, no matter what other settings there are.
// Measure in milliseconds.
rtc::Optional<int> ice_check_min_interval;
// The interval in milliseconds at which STUN candidates will resend STUN
// binding requests to keep NAT bindings open.
rtc::Optional<int> stun_keepalive_interval;
rtc::Optional<rtc::AdapterType> network_preference;

View File

@ -541,6 +541,18 @@ void P2PTransportChannel::SetIceConfig(const IceConfig& config) {
? config_.network_preference.value()
: 0);
}
// TODO(qingsi): Resolve the naming conflict of stun_keepalive_delay in
// UDPPort and stun_keepalive_interval.
if (config_.stun_keepalive_interval != config.stun_keepalive_interval) {
config_.stun_keepalive_interval = config.stun_keepalive_interval;
allocator_session()->SetStunKeepaliveIntervalForReadyPorts(
config_.stun_keepalive_interval);
RTC_LOG(LS_INFO) << "Set STUN keepalive interval to "
<< (config.stun_keepalive_interval.has_value()
? config_.stun_keepalive_interval.value()
: -1);
}
}
const IceConfig& P2PTransportChannel::config() const {

View File

@ -103,7 +103,8 @@ bool PortAllocator::SetConfiguration(
const std::vector<RelayServerConfig>& turn_servers,
int candidate_pool_size,
bool prune_turn_ports,
webrtc::TurnCustomizer* turn_customizer) {
webrtc::TurnCustomizer* turn_customizer,
const rtc::Optional<int>& stun_candidate_keepalive_interval) {
bool ice_servers_changed =
(stun_servers != stun_servers_ || turn_servers != turn_servers_);
stun_servers_ = stun_servers;
@ -142,6 +143,16 @@ bool PortAllocator::SetConfiguration(
pooled_sessions_.pop_front();
}
// |stun_candidate_keepalive_interval_| will be used in STUN port allocation
// in future sessions. We also update the ready ports in the pooled sessions.
// Ports in sessions that are taken and owned by P2PTransportChannel will be
// updated there via IceConfig.
stun_candidate_keepalive_interval_ = stun_candidate_keepalive_interval;
for (const auto& session : pooled_sessions_) {
session->SetStunKeepaliveIntervalForReadyPorts(
stun_candidate_keepalive_interval_);
}
// If |candidate_pool_size_| is greater than the number of pooled sessions,
// create new sessions.
while (static_cast<int>(pooled_sessions_.size()) < candidate_pool_size_) {

View File

@ -244,7 +244,12 @@ class PortAllocatorSession : public sigslot::has_slots<> {
virtual void RegatherOnFailedNetworks() {}
// Re-gathers candidates on all networks.
virtual void RegatherOnAllNetworks() {}
// Set the interval at which STUN candidates will resend STUN binding requests
// on the underlying ports to keep NAT bindings open.
// The default value of the interval in implementation is restored if a null
// optional value is passed.
virtual void SetStunKeepaliveIntervalForReadyPorts(
const rtc::Optional<int>& stun_keepalive_interval) {}
// Another way of getting the information provided by the signals below.
//
// Ports and candidates are not guaranteed to be in the same order as the
@ -347,7 +352,9 @@ class PortAllocator : public sigslot::has_slots<> {
const std::vector<RelayServerConfig>& turn_servers,
int candidate_pool_size,
bool prune_turn_ports,
webrtc::TurnCustomizer* turn_customizer = nullptr);
webrtc::TurnCustomizer* turn_customizer = nullptr,
const rtc::Optional<int>&
stun_candidate_keepalive_interval = rtc::nullopt);
const ServerAddresses& stun_servers() const { return stun_servers_; }
@ -356,6 +363,9 @@ class PortAllocator : public sigslot::has_slots<> {
}
int candidate_pool_size() const { return candidate_pool_size_; }
const rtc::Optional<int>& stun_candidate_keepalive_interval() const {
return stun_candidate_keepalive_interval_;
}
// Sets the network types to ignore.
// Values are defined by the AdapterType enum.
@ -506,6 +516,8 @@ class PortAllocator : public sigslot::has_slots<> {
// The instance is owned by application and will be shared among
// all TurnPort(s) created.
webrtc::TurnCustomizer* turn_customizer_ = nullptr;
rtc::Optional<int> stun_candidate_keepalive_interval_;
};
} // namespace cricket

View File

@ -317,6 +317,10 @@ ProtocolType UDPPort::GetProtocol() const {
return PROTO_UDP;
}
void UDPPort::set_stun_keepalive_delay(const rtc::Optional<int>& delay) {
stun_keepalive_delay_ = (delay.has_value() ? delay.value() : KEEPALIVE_DELAY);
}
void UDPPort::OnLocalAddressReady(rtc::AsyncPacketSocket* socket,
const rtc::SocketAddress& address) {
// When adapter enumeration is disabled and binding to the any address, the

View File

@ -101,9 +101,7 @@ class UDPPort : public Port {
bool SupportsProtocol(const std::string& protocol) const override;
ProtocolType GetProtocol() const override;
void set_stun_keepalive_delay(int delay) {
stun_keepalive_delay_ = delay;
}
void set_stun_keepalive_delay(const rtc::Optional<int>& delay);
int stun_keepalive_delay() const {
return stun_keepalive_delay_;
}

View File

@ -429,6 +429,17 @@ void BasicPortAllocatorSession::Regather(
}
}
void BasicPortAllocatorSession::SetStunKeepaliveIntervalForReadyPorts(
const rtc::Optional<int>& stun_keepalive_interval) {
auto ports = ReadyPorts();
for (PortInterface* port : ports) {
if (port->Type() == STUN_PORT_TYPE) {
static_cast<UDPPort*>(port)->set_stun_keepalive_delay(
stun_keepalive_interval);
}
}
}
std::vector<PortInterface*> BasicPortAllocatorSession::ReadyPorts() const {
std::vector<PortInterface*> ret;
for (const PortData& data : ports_) {
@ -1357,6 +1368,8 @@ void AllocationSequence::CreateStunPorts() {
session_->username(), session_->password(), config_->StunServers(),
session_->allocator()->origin());
if (port) {
port->set_stun_keepalive_delay(
session_->allocator()->stun_candidate_keepalive_interval());
session_->AddAllocatedPort(port, this, true);
// Since StunPort is not created using shared socket, |port| will not be
// added to the dequeue.

View File

@ -127,6 +127,8 @@ class BasicPortAllocatorSession : public PortAllocatorSession,
bool CandidatesAllocationDone() const override;
void RegatherOnFailedNetworks() override;
void RegatherOnAllNetworks() override;
void SetStunKeepaliveIntervalForReadyPorts(
const rtc::Optional<int>& stun_keepalive_interval) override;
void PruneAllPorts() override;
protected: