Prepare for per-media DSCP values. Push dscp for stun packets to the port layer where they are created.
Bug: webrtc:5008 Change-Id: Iaf4788ef2170fa67a8cdee6e9ea6b8c158f286cb Reviewed-on: https://webrtc-review.googlesource.com/c/92940 Reviewed-by: Stefan Holmer <stefan@webrtc.org> Commit-Queue: Tim Haloun <thaloun@google.com> Cr-Commit-Position: refs/heads/master@{#24963}
This commit is contained in:
parent
d2739ced19
commit
6ca98363ee
@ -109,6 +109,7 @@ class FakeNetworkInterface : public MediaChannel::NetworkInterface,
|
||||
int sendbuf_size() const { return sendbuf_size_; }
|
||||
int recvbuf_size() const { return recvbuf_size_; }
|
||||
rtc::DiffServCodePoint dscp() const { return dscp_; }
|
||||
rtc::PacketOptions options() const { return options_; }
|
||||
|
||||
protected:
|
||||
virtual bool SendPacket(rtc::CopyOnWriteBuffer* packet,
|
||||
@ -120,6 +121,7 @@ class FakeNetworkInterface : public MediaChannel::NetworkInterface,
|
||||
return false;
|
||||
}
|
||||
sent_ssrcs_[cur_ssrc]++;
|
||||
options_ = options;
|
||||
|
||||
rtp_packets_.push_back(*packet);
|
||||
if (conf_) {
|
||||
@ -139,6 +141,7 @@ class FakeNetworkInterface : public MediaChannel::NetworkInterface,
|
||||
const rtc::PacketOptions& options) {
|
||||
rtc::CritScope cs(&crit_);
|
||||
rtcp_packets_.push_back(*packet);
|
||||
options_ = options;
|
||||
if (!conf_) {
|
||||
// don't worry about RTCP in conf mode for now
|
||||
PostMessage(ST_RTCP, *packet);
|
||||
@ -215,6 +218,8 @@ class FakeNetworkInterface : public MediaChannel::NetworkInterface,
|
||||
int sendbuf_size_;
|
||||
int recvbuf_size_;
|
||||
rtc::DiffServCodePoint dscp_;
|
||||
// Options of the most recently sent packet.
|
||||
rtc::PacketOptions options_;
|
||||
};
|
||||
|
||||
} // namespace cricket
|
||||
|
||||
@ -21,14 +21,14 @@ void MediaChannel::SetInterface(NetworkInterface* iface) {
|
||||
SetDscp(enable_dscp_ ? PreferredDscp() : rtc::DSCP_DEFAULT);
|
||||
}
|
||||
|
||||
rtc::DiffServCodePoint MediaChannel::PreferredDscp() const {
|
||||
return rtc::DSCP_DEFAULT;
|
||||
}
|
||||
|
||||
int MediaChannel::GetRtpSendTimeExtnId() const {
|
||||
return -1;
|
||||
}
|
||||
|
||||
rtc::DiffServCodePoint MediaChannel::PreferredDscp() const {
|
||||
return rtc::DSCP_DEFAULT;
|
||||
}
|
||||
|
||||
void MediaChannel::SetFrameEncryptor(
|
||||
webrtc::FrameEncryptorInterface* frame_encryptor) {
|
||||
frame_encryptor_ = frame_encryptor;
|
||||
|
||||
@ -186,7 +186,6 @@ class MediaChannel : public sigslot::has_slots<> {
|
||||
|
||||
// Sets the abstract interface class for sending RTP/RTCP data.
|
||||
virtual void SetInterface(NetworkInterface* iface);
|
||||
virtual rtc::DiffServCodePoint PreferredDscp() const;
|
||||
// Called when a RTP packet is received.
|
||||
virtual void OnPacketReceived(rtc::CopyOnWriteBuffer* packet,
|
||||
const rtc::PacketTime& packet_time) = 0;
|
||||
@ -249,6 +248,11 @@ class MediaChannel : public sigslot::has_slots<> {
|
||||
return network_interface_->SetOption(type, opt, option);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual rtc::DiffServCodePoint PreferredDscp() const;
|
||||
|
||||
bool DscpEnabled() const { return enable_dscp_; }
|
||||
|
||||
private:
|
||||
// This method sets DSCP |value| on both RTP and RTCP channels.
|
||||
int SetDscp(rtc::DiffServCodePoint value) {
|
||||
|
||||
@ -1471,12 +1471,19 @@ bool WebRtcVideoChannel::SendRtp(const uint8_t* data,
|
||||
rtc::CopyOnWriteBuffer packet(data, len, kMaxRtpPacketLen);
|
||||
rtc::PacketOptions rtc_options;
|
||||
rtc_options.packet_id = options.packet_id;
|
||||
if (DscpEnabled()) {
|
||||
rtc_options.dscp = PreferredDscp();
|
||||
}
|
||||
return MediaChannel::SendPacket(&packet, rtc_options);
|
||||
}
|
||||
|
||||
bool WebRtcVideoChannel::SendRtcp(const uint8_t* data, size_t len) {
|
||||
rtc::CopyOnWriteBuffer packet(data, len, kMaxRtpPacketLen);
|
||||
return MediaChannel::SendRtcp(&packet, rtc::PacketOptions());
|
||||
rtc::PacketOptions rtc_options;
|
||||
if (DscpEnabled()) {
|
||||
rtc_options.dscp = PreferredDscp();
|
||||
}
|
||||
return MediaChannel::SendRtcp(&packet, rtc_options);
|
||||
}
|
||||
|
||||
WebRtcVideoChannel::WebRtcVideoSendStream::VideoSendStreamParameters::
|
||||
|
||||
@ -4574,22 +4574,31 @@ TEST_F(WebRtcVideoChannelTest, TestSetDscpOptions) {
|
||||
std::unique_ptr<cricket::FakeNetworkInterface> network_interface(
|
||||
new cricket::FakeNetworkInterface);
|
||||
MediaConfig config;
|
||||
std::unique_ptr<VideoMediaChannel> channel;
|
||||
std::unique_ptr<cricket::WebRtcVideoChannel> channel;
|
||||
|
||||
channel.reset(engine_.CreateChannel(call_.get(), config, VideoOptions()));
|
||||
channel.reset(static_cast<cricket::WebRtcVideoChannel*>(
|
||||
engine_.CreateChannel(call_.get(), config, VideoOptions())));
|
||||
channel->SetInterface(network_interface.get());
|
||||
// Default value when DSCP is disabled should be DSCP_DEFAULT.
|
||||
EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
|
||||
|
||||
config.enable_dscp = true;
|
||||
channel.reset(engine_.CreateChannel(call_.get(), config, VideoOptions()));
|
||||
channel.reset(static_cast<cricket::WebRtcVideoChannel*>(
|
||||
engine_.CreateChannel(call_.get(), config, VideoOptions())));
|
||||
channel->SetInterface(network_interface.get());
|
||||
EXPECT_EQ(rtc::DSCP_AF41, network_interface->dscp());
|
||||
|
||||
// Packets should also self-identify their dscp in PacketOptions.
|
||||
const uint8_t kData[10] = {0};
|
||||
EXPECT_TRUE(static_cast<webrtc::Transport*>(channel.get())
|
||||
->SendRtcp(kData, sizeof(kData)));
|
||||
EXPECT_EQ(rtc::DSCP_AF41, network_interface->options().dscp);
|
||||
|
||||
// Verify that setting the option to false resets the
|
||||
// DiffServCodePoint.
|
||||
config.enable_dscp = false;
|
||||
channel.reset(engine_.CreateChannel(call_.get(), config, VideoOptions()));
|
||||
channel.reset(static_cast<cricket::WebRtcVideoChannel*>(
|
||||
engine_.CreateChannel(call_.get(), config, VideoOptions())));
|
||||
channel->SetInterface(network_interface.get());
|
||||
EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
|
||||
}
|
||||
|
||||
@ -200,12 +200,18 @@ class WebRtcVoiceMediaChannel final : public VoiceMediaChannel,
|
||||
rtc::CopyOnWriteBuffer packet(data, len, kMaxRtpPacketLen);
|
||||
rtc::PacketOptions rtc_options;
|
||||
rtc_options.packet_id = options.packet_id;
|
||||
if (DscpEnabled()) {
|
||||
rtc_options.dscp = PreferredDscp();
|
||||
}
|
||||
return VoiceMediaChannel::SendPacket(&packet, rtc_options);
|
||||
}
|
||||
|
||||
bool SendRtcp(const uint8_t* data, size_t len) override {
|
||||
rtc::CopyOnWriteBuffer packet(data, len, kMaxRtpPacketLen);
|
||||
rtc::PacketOptions rtc_options;
|
||||
if (DscpEnabled()) {
|
||||
rtc_options.dscp = PreferredDscp();
|
||||
}
|
||||
return VoiceMediaChannel::SendRtcp(&packet, rtc_options);
|
||||
}
|
||||
|
||||
|
||||
@ -3016,7 +3016,7 @@ TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
|
||||
EXPECT_TRUE(SetupSendStream());
|
||||
cricket::FakeNetworkInterface network_interface;
|
||||
cricket::MediaConfig config;
|
||||
std::unique_ptr<cricket::VoiceMediaChannel> channel;
|
||||
std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel;
|
||||
|
||||
webrtc::AudioProcessing::Config apm_config;
|
||||
EXPECT_CALL(*apm_, GetConfig())
|
||||
@ -3025,23 +3025,28 @@ TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
|
||||
.WillRepeatedly(SaveArg<0>(&apm_config));
|
||||
EXPECT_CALL(*apm_, SetExtraOptions(testing::_)).Times(3);
|
||||
|
||||
channel.reset(
|
||||
engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
|
||||
channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
|
||||
engine_->CreateChannel(&call_, config, cricket::AudioOptions())));
|
||||
channel->SetInterface(&network_interface);
|
||||
// Default value when DSCP is disabled should be DSCP_DEFAULT.
|
||||
EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
|
||||
|
||||
config.enable_dscp = true;
|
||||
channel.reset(
|
||||
engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
|
||||
channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
|
||||
engine_->CreateChannel(&call_, config, cricket::AudioOptions())));
|
||||
channel->SetInterface(&network_interface);
|
||||
EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
|
||||
|
||||
// Packets should also self-identify their dscp in PacketOptions.
|
||||
const uint8_t kData[10] = {0};
|
||||
EXPECT_TRUE(channel->SendRtcp(kData, sizeof(kData)));
|
||||
EXPECT_EQ(rtc::DSCP_EF, network_interface.options().dscp);
|
||||
|
||||
// Verify that setting the option to false resets the
|
||||
// DiffServCodePoint.
|
||||
config.enable_dscp = false;
|
||||
channel.reset(
|
||||
engine_->CreateChannel(&call_, config, cricket::AudioOptions()));
|
||||
channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
|
||||
engine_->CreateChannel(&call_, config, cricket::AudioOptions())));
|
||||
channel->SetInterface(&network_interface);
|
||||
// Default value when DSCP is disabled should be DSCP_DEFAULT.
|
||||
EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
|
||||
|
||||
@ -670,6 +670,11 @@ bool Port::IsCompatibleAddress(const rtc::SocketAddress& addr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
rtc::DiffServCodePoint Port::StunDscpValue() const {
|
||||
// By default, inherit from whatever the MediaChannel sends.
|
||||
return rtc::DSCP_NO_CHANGE;
|
||||
}
|
||||
|
||||
bool Port::ParseStunUsername(const StunMessage* stun_msg,
|
||||
std::string* local_ufrag,
|
||||
std::string* remote_ufrag) const {
|
||||
@ -818,7 +823,7 @@ void Port::SendBindingResponse(StunMessage* request,
|
||||
// Send the response message.
|
||||
rtc::ByteBufferWriter buf;
|
||||
response.Write(&buf);
|
||||
rtc::PacketOptions options(DefaultDscpValue());
|
||||
rtc::PacketOptions options(StunDscpValue());
|
||||
options.info_signaled_after_sent.packet_type =
|
||||
rtc::PacketType::kIceConnectivityCheckResponse;
|
||||
auto err = SendTo(buf.Data(), buf.Length(), addr, options, false);
|
||||
@ -871,7 +876,7 @@ void Port::SendBindingErrorResponse(StunMessage* request,
|
||||
// Send the response message.
|
||||
rtc::ByteBufferWriter buf;
|
||||
response.Write(&buf);
|
||||
rtc::PacketOptions options(DefaultDscpValue());
|
||||
rtc::PacketOptions options(StunDscpValue());
|
||||
options.info_signaled_after_sent.packet_type =
|
||||
rtc::PacketType::kIceConnectivityCheckResponse;
|
||||
SendTo(buf.Data(), buf.Length(), addr, options, false);
|
||||
@ -1216,7 +1221,7 @@ int Connection::receiving_timeout() const {
|
||||
void Connection::OnSendStunPacket(const void* data,
|
||||
size_t size,
|
||||
StunRequest* req) {
|
||||
rtc::PacketOptions options(port_->DefaultDscpValue());
|
||||
rtc::PacketOptions options(port_->StunDscpValue());
|
||||
options.info_signaled_after_sent.packet_type =
|
||||
rtc::PacketType::kIceConnectivityCheck;
|
||||
auto err =
|
||||
|
||||
@ -435,11 +435,8 @@ class Port : public PortInterface,
|
||||
// Checks if the address in addr is compatible with the port's ip.
|
||||
bool IsCompatibleAddress(const rtc::SocketAddress& addr);
|
||||
|
||||
// Returns default DSCP value.
|
||||
rtc::DiffServCodePoint DefaultDscpValue() const {
|
||||
// No change from what MediaChannel set.
|
||||
return rtc::DSCP_NO_CHANGE;
|
||||
}
|
||||
// Returns DSCP value packets generated by the port itself should use.
|
||||
virtual rtc::DiffServCodePoint StunDscpValue() const;
|
||||
|
||||
// Extra work to be done in subclasses when a connection is destroyed.
|
||||
virtual void HandleConnectionDestroyed(Connection* conn) {}
|
||||
|
||||
@ -62,6 +62,7 @@ class RelayConnection : public sigslot::has_slots<> {
|
||||
rtc::AsyncPacketSocket* socket_;
|
||||
const ProtocolAddress* protocol_address_;
|
||||
StunRequestManager* request_manager_;
|
||||
rtc::DiffServCodePoint dscp_;
|
||||
};
|
||||
|
||||
// Manages a number of connections to the relayserver, one for each
|
||||
@ -407,7 +408,9 @@ void RelayPort::OnReadPacket(const char* data,
|
||||
RelayConnection::RelayConnection(const ProtocolAddress* protocol_address,
|
||||
rtc::AsyncPacketSocket* socket,
|
||||
rtc::Thread* thread)
|
||||
: socket_(socket), protocol_address_(protocol_address) {
|
||||
: socket_(socket),
|
||||
protocol_address_(protocol_address),
|
||||
dscp_(rtc::DSCP_NO_CHANGE) {
|
||||
request_manager_ = new StunRequestManager(thread);
|
||||
request_manager_->SignalSendPacket.connect(this,
|
||||
&RelayConnection::OnSendPacket);
|
||||
@ -419,6 +422,9 @@ RelayConnection::~RelayConnection() {
|
||||
}
|
||||
|
||||
int RelayConnection::SetSocketOption(rtc::Socket::Option opt, int value) {
|
||||
if (opt == rtc::Socket::OPT_DSCP) {
|
||||
dscp_ = static_cast<rtc::DiffServCodePoint>(value);
|
||||
}
|
||||
if (socket_) {
|
||||
return socket_->SetOption(opt, value);
|
||||
}
|
||||
@ -432,8 +438,7 @@ bool RelayConnection::CheckResponse(StunMessage* msg) {
|
||||
void RelayConnection::OnSendPacket(const void* data,
|
||||
size_t size,
|
||||
StunRequest* req) {
|
||||
// TODO(mallinath) Find a way to get DSCP value from Port.
|
||||
rtc::PacketOptions options; // Default dscp set to NO_CHANGE.
|
||||
rtc::PacketOptions options(dscp_);
|
||||
int sent = socket_->SendTo(data, size, GetAddress(), options);
|
||||
if (sent <= 0) {
|
||||
RTC_LOG(LS_VERBOSE) << "OnSendPacket: failed sending to "
|
||||
|
||||
@ -173,6 +173,7 @@ UDPPort::UDPPort(rtc::Thread* thread,
|
||||
error_(0),
|
||||
ready_(false),
|
||||
stun_keepalive_delay_(STUN_KEEPALIVE_INTERVAL),
|
||||
dscp_(rtc::DSCP_NO_CHANGE),
|
||||
emit_local_for_anyaddress_(emit_local_for_anyaddress) {
|
||||
requests_.set_origin(origin);
|
||||
}
|
||||
@ -199,6 +200,7 @@ UDPPort::UDPPort(rtc::Thread* thread,
|
||||
error_(0),
|
||||
ready_(false),
|
||||
stun_keepalive_delay_(STUN_KEEPALIVE_INTERVAL),
|
||||
dscp_(rtc::DSCP_NO_CHANGE),
|
||||
emit_local_for_anyaddress_(emit_local_for_anyaddress) {
|
||||
requests_.set_origin(origin);
|
||||
}
|
||||
@ -293,7 +295,15 @@ void UDPPort::UpdateNetworkCost() {
|
||||
stun_keepalive_lifetime_ = GetStunKeepaliveLifetime();
|
||||
}
|
||||
|
||||
rtc::DiffServCodePoint UDPPort::StunDscpValue() const {
|
||||
return dscp_;
|
||||
}
|
||||
|
||||
int UDPPort::SetOption(rtc::Socket::Option opt, int value) {
|
||||
if (opt == rtc::Socket::OPT_DSCP) {
|
||||
// Save value for future packets we instantiate.
|
||||
dscp_ = static_cast<rtc::DiffServCodePoint>(value);
|
||||
}
|
||||
return socket_->SetOption(opt, value);
|
||||
}
|
||||
|
||||
@ -534,7 +544,7 @@ void UDPPort::MaybeSetPortCompleteOrError() {
|
||||
// TODO(?): merge this with SendTo above.
|
||||
void UDPPort::OnSendPacket(const void* data, size_t size, StunRequest* req) {
|
||||
StunBindingRequest* sreq = static_cast<StunBindingRequest*>(req);
|
||||
rtc::PacketOptions options(DefaultDscpValue());
|
||||
rtc::PacketOptions options(StunDscpValue());
|
||||
options.info_signaled_after_sent.packet_type = rtc::PacketType::kStunMessage;
|
||||
CopyPortInformationToPacketInfo(&options.info_signaled_after_sent);
|
||||
if (socket_->SendTo(data, size, sreq->server_addr(), options) < 0) {
|
||||
|
||||
@ -152,6 +152,8 @@ class UDPPort : public Port {
|
||||
|
||||
void UpdateNetworkCost() override;
|
||||
|
||||
rtc::DiffServCodePoint StunDscpValue() const override;
|
||||
|
||||
void OnLocalAddressReady(rtc::AsyncPacketSocket* socket,
|
||||
const rtc::SocketAddress& address);
|
||||
void OnReadPacket(rtc::AsyncPacketSocket* socket,
|
||||
@ -247,6 +249,7 @@ class UDPPort : public Port {
|
||||
bool ready_;
|
||||
int stun_keepalive_delay_;
|
||||
int stun_keepalive_lifetime_ = INFINITE_LIFETIME;
|
||||
rtc::DiffServCodePoint dscp_;
|
||||
|
||||
StunStats stats_;
|
||||
|
||||
|
||||
@ -18,9 +18,12 @@
|
||||
#include "rtc_base/socketaddress.h"
|
||||
#include "rtc_base/ssladapter.h"
|
||||
#include "rtc_base/virtualsocketserver.h"
|
||||
#include "test/gmock.h"
|
||||
|
||||
using cricket::ServerAddresses;
|
||||
using rtc::SocketAddress;
|
||||
using ::testing::_;
|
||||
using ::testing::Return;
|
||||
|
||||
static const SocketAddress kLocalAddr("127.0.0.1", 0);
|
||||
static const SocketAddress kStunAddr1("127.0.0.1", 5000);
|
||||
@ -57,6 +60,7 @@ class StunPortTestBase : public testing::Test, public sigslot::has_slots<> {
|
||||
}
|
||||
|
||||
cricket::UDPPort* port() const { return stun_port_.get(); }
|
||||
rtc::AsyncPacketSocket* socket() const { return socket_.get(); }
|
||||
bool done() const { return done_; }
|
||||
bool error() const { return error_; }
|
||||
|
||||
@ -86,9 +90,14 @@ class StunPortTestBase : public testing::Test, public sigslot::has_slots<> {
|
||||
stun_port_->SignalPortError.connect(this, &StunPortTestBase::OnPortError);
|
||||
}
|
||||
|
||||
void CreateSharedUdpPort(const rtc::SocketAddress& server_addr) {
|
||||
socket_.reset(socket_factory_.CreateUdpSocket(
|
||||
rtc::SocketAddress(kLocalAddr.ipaddr(), 0), 0, 0));
|
||||
void CreateSharedUdpPort(const rtc::SocketAddress& server_addr,
|
||||
rtc::AsyncPacketSocket* socket) {
|
||||
if (socket) {
|
||||
socket_.reset(socket);
|
||||
} else {
|
||||
socket_.reset(socket_factory_.CreateUdpSocket(
|
||||
rtc::SocketAddress(kLocalAddr.ipaddr(), 0), 0, 0));
|
||||
}
|
||||
ASSERT_TRUE(socket_ != NULL);
|
||||
socket_->SignalReadPacket.connect(this, &StunPortTestBase::OnReadPacket);
|
||||
stun_port_.reset(cricket::UDPPort::Create(
|
||||
@ -178,7 +187,7 @@ TEST_F(StunPortTest, TestCreateStunPort) {
|
||||
|
||||
// Test that we can create a UDP port.
|
||||
TEST_F(StunPortTest, TestCreateUdpPort) {
|
||||
CreateSharedUdpPort(kStunAddr1);
|
||||
CreateSharedUdpPort(kStunAddr1, nullptr);
|
||||
EXPECT_EQ("local", port()->Type());
|
||||
EXPECT_EQ(0U, port()->Candidates().size());
|
||||
}
|
||||
@ -245,7 +254,7 @@ TEST_F(StunPortTest, TestKeepAliveResponse) {
|
||||
|
||||
// Test that a local candidate can be generated using a shared socket.
|
||||
TEST_F(StunPortTest, TestSharedSocketPrepareAddress) {
|
||||
CreateSharedUdpPort(kStunAddr1);
|
||||
CreateSharedUdpPort(kStunAddr1, nullptr);
|
||||
PrepareAddress();
|
||||
EXPECT_TRUE_SIMULATED_WAIT(done(), kTimeoutMs, fake_clock);
|
||||
ASSERT_EQ(1U, port()->Candidates().size());
|
||||
@ -257,7 +266,7 @@ TEST_F(StunPortTest, TestSharedSocketPrepareAddress) {
|
||||
// resolved.
|
||||
TEST_F(StunPortTestWithRealClock,
|
||||
TestSharedSocketPrepareAddressInvalidHostname) {
|
||||
CreateSharedUdpPort(kBadHostnameAddr);
|
||||
CreateSharedUdpPort(kBadHostnameAddr, nullptr);
|
||||
PrepareAddress();
|
||||
EXPECT_TRUE_WAIT(done(), kTimeoutMs);
|
||||
ASSERT_EQ(1U, port()->Candidates().size());
|
||||
@ -339,7 +348,7 @@ TEST_F(StunPortTest, TestStunPortGetStunKeepaliveLifetime) {
|
||||
// if the network type changes.
|
||||
TEST_F(StunPortTest, TestUdpPortGetStunKeepaliveLifetime) {
|
||||
// Lifetime for the default (unknown) network type is |kInfiniteLifetime|.
|
||||
CreateSharedUdpPort(kStunAddr1);
|
||||
CreateSharedUdpPort(kStunAddr1, nullptr);
|
||||
EXPECT_EQ(kInfiniteLifetime, port()->stun_keepalive_lifetime());
|
||||
// Lifetime for the cellular network is |kHighCostPortKeepaliveLifetimeMs|.
|
||||
SetNetworkType(rtc::ADAPTER_TYPE_CELLULAR);
|
||||
@ -348,7 +357,7 @@ TEST_F(StunPortTest, TestUdpPortGetStunKeepaliveLifetime) {
|
||||
|
||||
// Lifetime for the wifi network type is |kInfiniteLifetime|.
|
||||
SetNetworkType(rtc::ADAPTER_TYPE_WIFI);
|
||||
CreateSharedUdpPort(kStunAddr2);
|
||||
CreateSharedUdpPort(kStunAddr2, nullptr);
|
||||
EXPECT_EQ(kInfiniteLifetime, port()->stun_keepalive_lifetime());
|
||||
}
|
||||
|
||||
@ -375,3 +384,52 @@ TEST_F(StunPortTest, TestStunBindingRequestLongLifetime) {
|
||||
port()->HasPendingRequest(cricket::STUN_BINDING_REQUEST), 1000,
|
||||
fake_clock);
|
||||
}
|
||||
|
||||
class MockAsyncPacketSocket : public rtc::AsyncPacketSocket {
|
||||
public:
|
||||
~MockAsyncPacketSocket() = default;
|
||||
|
||||
MOCK_CONST_METHOD0(GetLocalAddress, SocketAddress());
|
||||
MOCK_CONST_METHOD0(GetRemoteAddress, SocketAddress());
|
||||
MOCK_METHOD3(Send,
|
||||
int(const void* pv,
|
||||
size_t cb,
|
||||
const rtc::PacketOptions& options));
|
||||
|
||||
MOCK_METHOD4(SendTo,
|
||||
int(const void* pv,
|
||||
size_t cb,
|
||||
const SocketAddress& addr,
|
||||
const rtc::PacketOptions& options));
|
||||
MOCK_METHOD0(Close, int());
|
||||
MOCK_CONST_METHOD0(GetState, State());
|
||||
MOCK_METHOD2(GetOption, int(rtc::Socket::Option opt, int* value));
|
||||
MOCK_METHOD2(SetOption, int(rtc::Socket::Option opt, int value));
|
||||
MOCK_CONST_METHOD0(GetError, int());
|
||||
MOCK_METHOD1(SetError, void(int error));
|
||||
};
|
||||
|
||||
// Test that outbound packets inherit the dscp value assigned to the socket.
|
||||
TEST_F(StunPortTest, TestStunPacketsHaveDscpPacketOption) {
|
||||
MockAsyncPacketSocket* socket = new MockAsyncPacketSocket();
|
||||
CreateSharedUdpPort(kStunAddr1, socket);
|
||||
EXPECT_CALL(*socket, GetLocalAddress()).WillRepeatedly(Return(kLocalAddr));
|
||||
EXPECT_CALL(*socket, GetState())
|
||||
.WillRepeatedly(Return(rtc::AsyncPacketSocket::STATE_BOUND));
|
||||
EXPECT_CALL(*socket, SetOption(_, _)).WillRepeatedly(Return(0));
|
||||
|
||||
// If DSCP is not set on the socket, stun packets should have no value.
|
||||
EXPECT_CALL(*socket, SendTo(_, _, _,
|
||||
testing::Field(&rtc::PacketOptions::dscp,
|
||||
testing::Eq(rtc::DSCP_NO_CHANGE))))
|
||||
.WillOnce(Return(100));
|
||||
PrepareAddress();
|
||||
|
||||
// Once it is set transport wide, they should inherit that value.
|
||||
port()->SetOption(rtc::Socket::OPT_DSCP, rtc::DSCP_AF41);
|
||||
EXPECT_CALL(*socket, SendTo(_, _, _,
|
||||
testing::Field(&rtc::PacketOptions::dscp,
|
||||
testing::Eq(rtc::DSCP_AF41))))
|
||||
.WillRepeatedly(Return(100));
|
||||
EXPECT_TRUE_SIMULATED_WAIT(done(), kTimeoutMs, fake_clock);
|
||||
}
|
||||
|
||||
@ -210,6 +210,7 @@ TurnPort::TurnPort(rtc::Thread* thread,
|
||||
socket_(socket),
|
||||
resolver_(NULL),
|
||||
error_(0),
|
||||
stun_dscp_value_(rtc::DSCP_NO_CHANGE),
|
||||
request_manager_(thread),
|
||||
next_channel_number_(TURN_CHANNEL_NUMBER_START),
|
||||
state_(STATE_CONNECTING),
|
||||
@ -251,6 +252,7 @@ TurnPort::TurnPort(rtc::Thread* thread,
|
||||
socket_(NULL),
|
||||
resolver_(NULL),
|
||||
error_(0),
|
||||
stun_dscp_value_(rtc::DSCP_NO_CHANGE),
|
||||
request_manager_(thread),
|
||||
next_channel_number_(TURN_CHANNEL_NUMBER_START),
|
||||
state_(STATE_CONNECTING),
|
||||
@ -551,6 +553,10 @@ bool TurnPort::FailAndPruneConnection(const rtc::SocketAddress& address) {
|
||||
}
|
||||
|
||||
int TurnPort::SetOption(rtc::Socket::Option opt, int value) {
|
||||
// Remember the last requested DSCP value, for STUN traffic.
|
||||
if (opt == rtc::Socket::OPT_DSCP)
|
||||
stun_dscp_value_ = static_cast<rtc::DiffServCodePoint>(value);
|
||||
|
||||
if (!socket_) {
|
||||
// If socket is not created yet, these options will be applied during socket
|
||||
// creation.
|
||||
@ -795,7 +801,7 @@ void TurnPort::OnSendStunPacket(const void* data,
|
||||
size_t size,
|
||||
StunRequest* request) {
|
||||
RTC_DCHECK(connected());
|
||||
rtc::PacketOptions options(DefaultDscpValue());
|
||||
rtc::PacketOptions options(StunDscpValue());
|
||||
options.info_signaled_after_sent.packet_type = rtc::PacketType::kTurnMessage;
|
||||
CopyPortInformationToPacketInfo(&options.info_signaled_after_sent);
|
||||
if (Send(data, size, options) < 0) {
|
||||
@ -881,6 +887,10 @@ void TurnPort::Close() {
|
||||
SignalTurnPortClosed(this);
|
||||
}
|
||||
|
||||
rtc::DiffServCodePoint TurnPort::StunDscpValue() const {
|
||||
return stun_dscp_value_;
|
||||
}
|
||||
|
||||
void TurnPort::OnMessage(rtc::Message* message) {
|
||||
switch (message->message_id) {
|
||||
case MSG_ALLOCATE_ERROR:
|
||||
|
||||
@ -225,6 +225,8 @@ class TurnPort : public Port {
|
||||
bool CreateOrRefreshEntry(const rtc::SocketAddress& addr,
|
||||
int channel_number);
|
||||
|
||||
rtc::DiffServCodePoint StunDscpValue() const override;
|
||||
|
||||
private:
|
||||
enum {
|
||||
MSG_ALLOCATE_ERROR = MSG_FIRST_AVAILABLE,
|
||||
@ -315,6 +317,7 @@ class TurnPort : public Port {
|
||||
SocketOptionsMap socket_options_;
|
||||
rtc::AsyncResolverInterface* resolver_;
|
||||
int error_;
|
||||
rtc::DiffServCodePoint stun_dscp_value_;
|
||||
|
||||
StunRequestManager request_manager_;
|
||||
std::string realm_; // From 401/438 response message.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user