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

@ -493,6 +493,10 @@ class PeerConnectionInterface : public rtc::RefCountInterface {
// (STUN pings), 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_candidate_keepalive_interval;
// ICE Periodic Regathering
// If set, WebRTC will periodically create and propose candidates without
// starting a new ICE generation. The regathering happens continuously with

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:

View File

@ -636,6 +636,7 @@ bool PeerConnectionInterface::RTCConfiguration::operator==(
bool enable_ice_renomination;
bool redetermine_role_on_ice_restart;
rtc::Optional<int> ice_check_min_interval;
rtc::Optional<int> stun_candidate_keepalive_interval;
rtc::Optional<rtc::IntervalRange> ice_regather_interval_range;
webrtc::TurnCustomizer* turn_customizer;
SdpSemantics sdp_semantics;
@ -675,6 +676,8 @@ bool PeerConnectionInterface::RTCConfiguration::operator==(
enable_ice_renomination == o.enable_ice_renomination &&
redetermine_role_on_ice_restart == o.redetermine_role_on_ice_restart &&
ice_check_min_interval == o.ice_check_min_interval &&
stun_candidate_keepalive_interval ==
o.stun_candidate_keepalive_interval &&
ice_regather_interval_range == o.ice_regather_interval_range &&
turn_customizer == o.turn_customizer &&
sdp_semantics == o.sdp_semantics &&
@ -2654,6 +2657,8 @@ bool PeerConnection::SetConfiguration(const RTCConfiguration& configuration,
configuration.ice_candidate_pool_size;
modified_config.prune_turn_ports = configuration.prune_turn_ports;
modified_config.ice_check_min_interval = configuration.ice_check_min_interval;
modified_config.stun_candidate_keepalive_interval =
configuration.stun_candidate_keepalive_interval;
modified_config.turn_customizer = configuration.turn_customizer;
modified_config.network_preference = configuration.network_preference;
if (configuration != modified_config) {
@ -2690,7 +2695,8 @@ bool PeerConnection::SetConfiguration(const RTCConfiguration& configuration,
stun_servers, turn_servers, modified_config.type,
modified_config.ice_candidate_pool_size,
modified_config.prune_turn_ports,
modified_config.turn_customizer))) {
modified_config.turn_customizer,
modified_config.stun_candidate_keepalive_interval))) {
RTC_LOG(LS_ERROR) << "Failed to apply configuration to PortAllocator.";
return SafeSetError(RTCErrorType::INTERNAL_ERROR, error);
}
@ -4394,10 +4400,10 @@ bool PeerConnection::InitializePortAllocator_n(
// Call this last since it may create pooled allocator sessions using the
// properties set above.
port_allocator_->SetConfiguration(stun_servers, turn_servers,
configuration.ice_candidate_pool_size,
configuration.prune_turn_ports,
configuration.turn_customizer);
port_allocator_->SetConfiguration(
stun_servers, turn_servers, configuration.ice_candidate_pool_size,
configuration.prune_turn_ports, configuration.turn_customizer,
configuration.stun_candidate_keepalive_interval);
return true;
}
@ -4407,14 +4413,15 @@ bool PeerConnection::ReconfigurePortAllocator_n(
IceTransportsType type,
int candidate_pool_size,
bool prune_turn_ports,
webrtc::TurnCustomizer* turn_customizer) {
webrtc::TurnCustomizer* turn_customizer,
rtc::Optional<int> stun_candidate_keepalive_interval) {
port_allocator_->set_candidate_filter(
ConvertIceTransportTypeToCandidateFilter(type));
// Call this last since it may create pooled allocator sessions using the
// candidate filter set above.
return port_allocator_->SetConfiguration(
stun_servers, turn_servers, candidate_pool_size, prune_turn_ports,
turn_customizer);
turn_customizer, stun_candidate_keepalive_interval);
}
cricket::ChannelManager* PeerConnection::channel_manager() const {
@ -4778,6 +4785,7 @@ cricket::IceConfig PeerConnection::ParseIceConfig(
ice_config.presume_writable_when_fully_relayed =
config.presume_writable_when_fully_relayed;
ice_config.ice_check_min_interval = config.ice_check_min_interval;
ice_config.stun_keepalive_interval = config.stun_candidate_keepalive_interval;
ice_config.regather_all_networks_interval_range =
config.ice_regather_interval_range;
ice_config.network_preference = config.network_preference;

View File

@ -661,7 +661,8 @@ class PeerConnection : public PeerConnectionInternal,
IceTransportsType type,
int candidate_pool_size,
bool prune_turn_ports,
webrtc::TurnCustomizer* turn_customizer);
webrtc::TurnCustomizer* turn_customizer,
rtc::Optional<int> stun_candidate_keepalive_interval);
// Starts output of an RTC event log to the given output object.
// This function should only be called from the worker thread.

View File

@ -342,6 +342,7 @@ public class PeerConnection {
}
/** Java version of PeerConnectionInterface.RTCConfiguration */
// TODO(qingsi): Resolve the naming inconsistency of fields with/without units.
public static class RTCConfiguration {
public IceTransportsType iceTransportsType;
public List<IceServer> iceServers;
@ -359,6 +360,10 @@ public class PeerConnection {
public boolean pruneTurnPorts;
public boolean presumeWritableWhenFullyRelayed;
public Integer iceCheckMinInterval;
// The interval in milliseconds at which STUN candidates will resend STUN binding requests
// to keep NAT bindings open.
// The default value in the implementation is used if this field is null.
public Integer stunCandidateKeepaliveIntervalMs;
public boolean disableIPv6OnWifi;
// By default, PeerConnection will use a limited number of IPv6 network
// interfaces, in order to avoid too many ICE candidate pairs being created
@ -405,6 +410,7 @@ public class PeerConnection {
pruneTurnPorts = false;
presumeWritableWhenFullyRelayed = false;
iceCheckMinInterval = null;
stunCandidateKeepaliveIntervalMs = null;
disableIPv6OnWifi = false;
maxIPv6Networks = 5;
iceRegatherIntervalRange = null;
@ -499,6 +505,11 @@ public class PeerConnection {
return iceCheckMinInterval;
}
@CalledByNative("RTCConfiguration")
Integer getStunCandidateKeepaliveInterval() {
return stunCandidateKeepaliveIntervalMs;
}
@CalledByNative("RTCConfiguration")
boolean getDisableIPv6OnWifi() {
return disableIPv6OnWifi;

View File

@ -156,6 +156,11 @@ void JavaToNativeRTCConfiguration(
Java_RTCConfiguration_getIceCheckMinInterval(jni, j_rtc_config);
rtc_config->ice_check_min_interval =
JavaToNativeOptionalInt(jni, j_ice_check_min_interval);
ScopedJavaLocalRef<jobject> j_stun_candidate_keepalive_interval =
Java_RTCConfiguration_getStunCandidateKeepaliveInterval(jni,
j_rtc_config);
rtc_config->stun_candidate_keepalive_interval =
JavaToNativeOptionalInt(jni, j_stun_candidate_keepalive_interval);
rtc_config->disable_ipv6_on_wifi =
Java_RTCConfiguration_getDisableIPv6OnWifi(jni, j_rtc_config);
rtc_config->max_ipv6_networks =