Bug 1876843 - Vendor libwebrtc from 14630a7e37

Upstream commit: https://webrtc.googlesource.com/src/+/14630a7e37951441267ef65d9c50b423f840841f
    Use rtc::ReceivedPacket in Stun and TurnServer

    StunServer is updated to ensure registring for receiving packet from the socket is happening on the same thread as where the packets are recevied.

    Bug: webrtc:15368, webrtc:11943
    Change-Id: I94cc3a47278d5489de7f170c8d43015d1551c437
    Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/328120
    Commit-Queue: Per Kjellander <perkj@webrtc.org>
    Reviewed-by: Jonas Oreland <jonaso@webrtc.org>
    Reviewed-by: Harald Alvestrand <hta@webrtc.org>
    Cr-Commit-Position: refs/heads/main@{#41219}
This commit is contained in:
Jan-Ivar Bruaroey 2024-02-10 13:35:00 -05:00
parent d1436c8d2c
commit 537af3a6cc
26 changed files with 209 additions and 176 deletions

View File

@ -27381,3 +27381,6 @@ d0269937a0
# MOZ_LIBWEBRTC_SRC=/Users/jan-ivar/moz/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh # MOZ_LIBWEBRTC_SRC=/Users/jan-ivar/moz/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh
# base of lastest vendoring # base of lastest vendoring
0b78094234 0b78094234
# MOZ_LIBWEBRTC_SRC=/Users/jan-ivar/moz/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh
# base of lastest vendoring
14630a7e37

View File

@ -18278,3 +18278,5 @@ libwebrtc updated from /Users/jan-ivar/moz/elm/.moz-fast-forward/moz-libwebrtc c
libwebrtc updated from /Users/jan-ivar/moz/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2024-02-10T18:32:48.261373. libwebrtc updated from /Users/jan-ivar/moz/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2024-02-10T18:32:48.261373.
# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /Users/jan-ivar/moz/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc # ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /Users/jan-ivar/moz/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc
libwebrtc updated from /Users/jan-ivar/moz/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2024-02-10T18:33:49.172661. libwebrtc updated from /Users/jan-ivar/moz/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2024-02-10T18:33:49.172661.
# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /Users/jan-ivar/moz/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc
libwebrtc updated from /Users/jan-ivar/moz/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2024-02-10T18:34:51.240146.

View File

@ -29,7 +29,8 @@ int main(int argc, char* argv[]) {
return 1; return 1;
} }
rtc::Thread* pthMain = rtc::Thread::Current(); rtc::Thread* pthMain = rtc::ThreadManager::Instance()->WrapCurrentThread();
RTC_DCHECK(pthMain);
rtc::AsyncUDPSocket* server_socket = rtc::AsyncUDPSocket* server_socket =
rtc::AsyncUDPSocket::Create(pthMain->socketserver(), server_addr); rtc::AsyncUDPSocket::Create(pthMain->socketserver(), server_addr);

View File

@ -1560,7 +1560,7 @@ index 0474e7bc17..1953923f81 100644
std::unique_ptr<ScalableVideoController> svc_controller_; std::unique_ptr<ScalableVideoController> svc_controller_;
absl::optional<ScalabilityMode> scalability_mode_; absl::optional<ScalabilityMode> scalability_mode_;
diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn
index 51e15b57f7..64b220af10 100644 index 0baeb956c5..ee24689772 100644
--- a/rtc_base/BUILD.gn --- a/rtc_base/BUILD.gn
+++ b/rtc_base/BUILD.gn +++ b/rtc_base/BUILD.gn
@@ -463,6 +463,12 @@ rtc_library("logging") { @@ -463,6 +463,12 @@ rtc_library("logging") {

View File

@ -1009,7 +1009,7 @@ index 730ec9bfdd..d473dbb74c 100644
"/config/external/nspr", "/config/external/nspr",
"/nsprpub/lib/ds", "/nsprpub/lib/ds",
diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn
index 64b220af10..60eb0f4ddc 100644 index ee24689772..718c97ff80 100644
--- a/rtc_base/BUILD.gn --- a/rtc_base/BUILD.gn
+++ b/rtc_base/BUILD.gn +++ b/rtc_base/BUILD.gn
@@ -327,6 +327,7 @@ rtc_library("sample_counter") { @@ -327,6 +327,7 @@ rtc_library("sample_counter") {
@ -1199,7 +1199,7 @@ index 64b220af10..60eb0f4ddc 100644
rtc_source_set("gtest_prod") { rtc_source_set("gtest_prod") {
sources = [ "gtest_prod_util.h" ] sources = [ "gtest_prod_util.h" ]
@@ -2204,7 +2232,7 @@ if (rtc_include_tests) { @@ -2205,7 +2233,7 @@ if (rtc_include_tests) {
} }
} }

View File

@ -29,7 +29,7 @@ index 8d845e2735..760ceaa3ef 100644
rtc_library("task_queue_test") { rtc_library("task_queue_test") {
visibility = [ "*" ] visibility = [ "*" ]
diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn
index 60eb0f4ddc..8f962f5820 100644 index 718c97ff80..f52497ed13 100644
--- a/rtc_base/BUILD.gn --- a/rtc_base/BUILD.gn
+++ b/rtc_base/BUILD.gn +++ b/rtc_base/BUILD.gn
@@ -743,10 +743,14 @@ if (is_mac || is_ios) { @@ -743,10 +743,14 @@ if (is_mac || is_ios) {

View File

@ -378,6 +378,7 @@ rtc_library("p2p_server_utils") {
"../rtc_base:socket_address", "../rtc_base:socket_address",
"../rtc_base:ssl", "../rtc_base:ssl",
"../rtc_base:stringutils", "../rtc_base:stringutils",
"../rtc_base/network:received_packet",
"../rtc_base/third_party/sigslot", "../rtc_base/third_party/sigslot",
] ]
absl_deps = [ absl_deps = [

View File

@ -285,7 +285,7 @@ class P2PTransportChannelTestBase : public ::testing::Test,
ss_(new rtc::FirewallSocketServer(nss_.get())), ss_(new rtc::FirewallSocketServer(nss_.get())),
socket_factory_(new rtc::BasicPacketSocketFactory(ss_.get())), socket_factory_(new rtc::BasicPacketSocketFactory(ss_.get())),
main_(ss_.get()), main_(ss_.get()),
stun_server_(TestStunServer::Create(ss_.get(), kStunAddr)), stun_server_(TestStunServer::Create(ss_.get(), kStunAddr, main_)),
turn_server_(&main_, ss_.get(), kTurnUdpIntAddr, kTurnUdpExtAddr), turn_server_(&main_, ss_.get(), kTurnUdpIntAddr, kTurnUdpExtAddr),
socks_server1_(ss_.get(), socks_server1_(ss_.get(),
kSocksProxyAddrs[0], kSocksProxyAddrs[0],
@ -1025,7 +1025,7 @@ class P2PTransportChannelTestBase : public ::testing::Test,
rtc::AutoSocketServerThread main_; rtc::AutoSocketServerThread main_;
rtc::scoped_refptr<PendingTaskSafetyFlag> safety_ = rtc::scoped_refptr<PendingTaskSafetyFlag> safety_ =
PendingTaskSafetyFlag::Create(); PendingTaskSafetyFlag::Create();
std::unique_ptr<TestStunServer> stun_server_; TestStunServer::StunServerPtr stun_server_;
TestTurnServer turn_server_; TestTurnServer turn_server_;
rtc::SocksProxyServer socks_server1_; rtc::SocksProxyServer socks_server1_;
rtc::SocksProxyServer socks_server2_; rtc::SocksProxyServer socks_server2_;

View File

@ -421,7 +421,7 @@ class PortTest : public ::testing::Test, public sigslot::has_slots<> {
nat_factory2_(ss_.get(), kNatAddr2, SocketAddress()), nat_factory2_(ss_.get(), kNatAddr2, SocketAddress()),
nat_socket_factory1_(&nat_factory1_), nat_socket_factory1_(&nat_factory1_),
nat_socket_factory2_(&nat_factory2_), nat_socket_factory2_(&nat_factory2_),
stun_server_(TestStunServer::Create(ss_.get(), kStunAddr)), stun_server_(TestStunServer::Create(ss_.get(), kStunAddr, main_)),
turn_server_(&main_, ss_.get(), kTurnUdpIntAddr, kTurnUdpExtAddr), turn_server_(&main_, ss_.get(), kTurnUdpIntAddr, kTurnUdpExtAddr),
username_(rtc::CreateRandomString(ICE_UFRAG_LENGTH)), username_(rtc::CreateRandomString(ICE_UFRAG_LENGTH)),
password_(rtc::CreateRandomString(ICE_PWD_LENGTH)), password_(rtc::CreateRandomString(ICE_PWD_LENGTH)),
@ -873,7 +873,7 @@ class PortTest : public ::testing::Test, public sigslot::has_slots<> {
rtc::NATSocketFactory nat_factory2_; rtc::NATSocketFactory nat_factory2_;
rtc::BasicPacketSocketFactory nat_socket_factory1_; rtc::BasicPacketSocketFactory nat_socket_factory1_;
rtc::BasicPacketSocketFactory nat_socket_factory2_; rtc::BasicPacketSocketFactory nat_socket_factory2_;
std::unique_ptr<TestStunServer> stun_server_; TestStunServer::StunServerPtr stun_server_;
TestTurnServer turn_server_; TestTurnServer turn_server_;
std::string username_; std::string username_;
std::string password_; std::string password_;

View File

@ -96,8 +96,10 @@ class StunPortTestBase : public ::testing::Test, public sigslot::has_slots<> {
thread_(ss_.get()), thread_(ss_.get()),
network_(network), network_(network),
socket_factory_(ss_.get()), socket_factory_(ss_.get()),
stun_server_1_(cricket::TestStunServer::Create(ss_.get(), kStunAddr1)), stun_server_1_(
stun_server_2_(cricket::TestStunServer::Create(ss_.get(), kStunAddr2)), cricket::TestStunServer::Create(ss_.get(), kStunAddr1, thread_)),
stun_server_2_(
cricket::TestStunServer::Create(ss_.get(), kStunAddr2, thread_)),
mdns_responder_provider_(new FakeMdnsResponderProvider()), mdns_responder_provider_(new FakeMdnsResponderProvider()),
done_(false), done_(false),
error_(false), error_(false),
@ -226,14 +228,16 @@ class StunPortTestBase : public ::testing::Test, public sigslot::has_slots<> {
cricket::TestStunServer* stun_server_1() { return stun_server_1_.get(); } cricket::TestStunServer* stun_server_1() { return stun_server_1_.get(); }
cricket::TestStunServer* stun_server_2() { return stun_server_2_.get(); } cricket::TestStunServer* stun_server_2() { return stun_server_2_.get(); }
rtc::AutoSocketServerThread& thread() { return thread_; }
private: private:
std::unique_ptr<rtc::VirtualSocketServer> ss_; std::unique_ptr<rtc::VirtualSocketServer> ss_;
rtc::AutoSocketServerThread thread_; rtc::AutoSocketServerThread thread_;
rtc::Network network_; rtc::Network network_;
rtc::BasicPacketSocketFactory socket_factory_; rtc::BasicPacketSocketFactory socket_factory_;
std::unique_ptr<cricket::UDPPort> stun_port_; std::unique_ptr<cricket::UDPPort> stun_port_;
std::unique_ptr<cricket::TestStunServer> stun_server_1_; cricket::TestStunServer::StunServerPtr stun_server_1_;
std::unique_ptr<cricket::TestStunServer> stun_server_2_; cricket::TestStunServer::StunServerPtr stun_server_2_;
std::unique_ptr<rtc::AsyncPacketSocket> socket_; std::unique_ptr<rtc::AsyncPacketSocket> socket_;
std::unique_ptr<rtc::MdnsResponderProvider> mdns_responder_provider_; std::unique_ptr<rtc::MdnsResponderProvider> mdns_responder_provider_;
bool done_; bool done_;
@ -620,12 +624,12 @@ class StunIPv6PortTestBase : public StunPortTestBase {
kIPv6LocalAddr.ipaddr(), kIPv6LocalAddr.ipaddr(),
128), 128),
kIPv6LocalAddr.ipaddr()) { kIPv6LocalAddr.ipaddr()) {
stun_server_ipv6_1_.reset( stun_server_ipv6_1_ =
cricket::TestStunServer::Create(ss(), kIPv6StunAddr1)); cricket::TestStunServer::Create(ss(), kIPv6StunAddr1, thread());
} }
protected: protected:
std::unique_ptr<cricket::TestStunServer> stun_server_ipv6_1_; cricket::TestStunServer::StunServerPtr stun_server_ipv6_1_;
}; };
class StunIPv6PortTestWithRealClock : public StunIPv6PortTestBase {}; class StunIPv6PortTestWithRealClock : public StunIPv6PortTestBase {};

View File

@ -14,43 +14,49 @@
#include <utility> #include <utility>
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
#include "api/sequence_checker.h"
#include "rtc_base/async_packet_socket.h"
#include "rtc_base/byte_buffer.h" #include "rtc_base/byte_buffer.h"
#include "rtc_base/logging.h" #include "rtc_base/logging.h"
#include "rtc_base/network/received_packet.h"
namespace cricket { namespace cricket {
StunServer::StunServer(rtc::AsyncUDPSocket* socket) : socket_(socket) { StunServer::StunServer(rtc::AsyncUDPSocket* socket) : socket_(socket) {
socket_->SignalReadPacket.connect(this, &StunServer::OnPacket); socket_->RegisterReceivedPacketCallback(
[&](rtc::AsyncPacketSocket* socket, const rtc::ReceivedPacket& packet) {
OnPacket(socket, packet);
});
} }
StunServer::~StunServer() { StunServer::~StunServer() {
socket_->SignalReadPacket.disconnect(this); RTC_DCHECK_RUN_ON(&sequence_checker_);
socket_->DeregisterReceivedPacketCallback();
} }
void StunServer::OnPacket(rtc::AsyncPacketSocket* socket, void StunServer::OnPacket(rtc::AsyncPacketSocket* socket,
const char* buf, const rtc::ReceivedPacket& packet) {
size_t size, RTC_DCHECK_RUN_ON(&sequence_checker_);
const rtc::SocketAddress& remote_addr,
const int64_t& /* packet_time_us */) {
// Parse the STUN message; eat any messages that fail to parse. // Parse the STUN message; eat any messages that fail to parse.
rtc::ByteBufferReader bbuf( rtc::ByteBufferReader bbuf(packet.payload());
rtc::MakeArrayView(reinterpret_cast<const uint8_t*>(buf), size));
StunMessage msg; StunMessage msg;
if (!msg.Read(&bbuf)) { if (!msg.Read(&bbuf)) {
return; return;
} }
// TODO(?): If unknown non-optional (<= 0x7fff) attributes are found, send a // TODO(?): If unknown non-optional (<= 0x7fff) attributes are found,
// send a
// 420 "Unknown Attribute" response. // 420 "Unknown Attribute" response.
// Send the message to the appropriate handler function. // Send the message to the appropriate handler function.
switch (msg.type()) { switch (msg.type()) {
case STUN_BINDING_REQUEST: case STUN_BINDING_REQUEST:
OnBindingRequest(&msg, remote_addr); OnBindingRequest(&msg, packet.source_address());
break; break;
default: default:
SendErrorResponse(msg, remote_addr, 600, "Operation Not Supported"); SendErrorResponse(msg, packet.source_address(), 600,
"Operation Not Supported");
} }
} }

View File

@ -12,7 +12,6 @@
#define P2P_BASE_STUN_SERVER_H_ #define P2P_BASE_STUN_SERVER_H_
#include <stddef.h> #include <stddef.h>
#include <stdint.h>
#include <memory> #include <memory>
@ -21,26 +20,22 @@
#include "rtc_base/async_packet_socket.h" #include "rtc_base/async_packet_socket.h"
#include "rtc_base/async_udp_socket.h" #include "rtc_base/async_udp_socket.h"
#include "rtc_base/socket_address.h" #include "rtc_base/socket_address.h"
#include "rtc_base/third_party/sigslot/sigslot.h"
namespace cricket { namespace cricket {
const int STUN_SERVER_PORT = 3478; const int STUN_SERVER_PORT = 3478;
class StunServer : public sigslot::has_slots<> { class StunServer {
public: public:
// Creates a STUN server, which will listen on the given socket. // Creates a STUN server, which will listen on the given socket.
explicit StunServer(rtc::AsyncUDPSocket* socket); explicit StunServer(rtc::AsyncUDPSocket* socket);
// Removes the STUN server from the socket and deletes the socket. // Removes the STUN server from the socket and deletes the socket.
~StunServer() override; virtual ~StunServer();
protected: protected:
// Slot for Socket.PacketRead: // Callback for packets from socket.
void OnPacket(rtc::AsyncPacketSocket* socket, void OnPacket(rtc::AsyncPacketSocket* socket,
const char* buf, const rtc::ReceivedPacket& packet);
size_t size,
const rtc::SocketAddress& remote_addr,
const int64_t& packet_time_us);
// Handlers for the different types of STUN/TURN requests: // Handlers for the different types of STUN/TURN requests:
virtual void OnBindingRequest(StunMessage* msg, virtual void OnBindingRequest(StunMessage* msg,
@ -64,6 +59,7 @@ class StunServer : public sigslot::has_slots<> {
StunMessage* response) const; StunMessage* response) const;
private: private:
webrtc::SequenceChecker sequence_checker_;
std::unique_ptr<rtc::AsyncUDPSocket> socket_; std::unique_ptr<rtc::AsyncUDPSocket> socket_;
}; };

View File

@ -10,21 +10,32 @@
#include "p2p/base/test_stun_server.h" #include "p2p/base/test_stun_server.h"
#include <memory>
#include "rtc_base/socket.h" #include "rtc_base/socket.h"
#include "rtc_base/socket_server.h" #include "rtc_base/socket_server.h"
namespace cricket { namespace cricket {
TestStunServer* TestStunServer::Create(rtc::SocketServer* ss, std::unique_ptr<TestStunServer, std::function<void(TestStunServer*)>>
const rtc::SocketAddress& addr) { TestStunServer::Create(rtc::SocketServer* ss,
const rtc::SocketAddress& addr,
rtc::Thread& network_thread) {
rtc::Socket* socket = ss->CreateSocket(addr.family(), SOCK_DGRAM); rtc::Socket* socket = ss->CreateSocket(addr.family(), SOCK_DGRAM);
rtc::AsyncUDPSocket* udp_socket = rtc::AsyncUDPSocket::Create(socket, addr); rtc::AsyncUDPSocket* udp_socket = rtc::AsyncUDPSocket::Create(socket, addr);
TestStunServer* server = nullptr;
return new TestStunServer(udp_socket); network_thread.BlockingCall(
[&]() { server = new TestStunServer(udp_socket, network_thread); });
std::unique_ptr<TestStunServer, std::function<void(TestStunServer*)>> result(
server, [&](TestStunServer* server) {
network_thread.BlockingCall([server]() { delete server; });
});
return result;
} }
void TestStunServer::OnBindingRequest(StunMessage* msg, void TestStunServer::OnBindingRequest(StunMessage* msg,
const rtc::SocketAddress& remote_addr) { const rtc::SocketAddress& remote_addr) {
RTC_DCHECK_RUN_ON(&network_thread_);
if (fake_stun_addr_.IsNil()) { if (fake_stun_addr_.IsNil()) {
StunServer::OnBindingRequest(msg, remote_addr); StunServer::OnBindingRequest(msg, remote_addr);
} else { } else {

View File

@ -11,19 +11,25 @@
#ifndef P2P_BASE_TEST_STUN_SERVER_H_ #ifndef P2P_BASE_TEST_STUN_SERVER_H_
#define P2P_BASE_TEST_STUN_SERVER_H_ #define P2P_BASE_TEST_STUN_SERVER_H_
#include <memory>
#include "api/transport/stun.h" #include "api/transport/stun.h"
#include "p2p/base/stun_server.h" #include "p2p/base/stun_server.h"
#include "rtc_base/async_udp_socket.h" #include "rtc_base/async_udp_socket.h"
#include "rtc_base/socket_address.h" #include "rtc_base/socket_address.h"
#include "rtc_base/socket_server.h" #include "rtc_base/socket_server.h"
#include "rtc_base/thread.h"
namespace cricket { namespace cricket {
// A test STUN server. Useful for unit tests. // A test STUN server. Useful for unit tests.
class TestStunServer : StunServer { class TestStunServer : StunServer {
public: public:
static TestStunServer* Create(rtc::SocketServer* ss, using StunServerPtr =
const rtc::SocketAddress& addr); std::unique_ptr<TestStunServer, std::function<void(TestStunServer*)>>;
static StunServerPtr Create(rtc::SocketServer* ss,
const rtc::SocketAddress& addr,
rtc::Thread& network_thread);
// Set a fake STUN address to return to the client. // Set a fake STUN address to return to the client.
void set_fake_stun_addr(const rtc::SocketAddress& addr) { void set_fake_stun_addr(const rtc::SocketAddress& addr) {
@ -31,13 +37,17 @@ class TestStunServer : StunServer {
} }
private: private:
explicit TestStunServer(rtc::AsyncUDPSocket* socket) : StunServer(socket) {} static void DeleteOnNetworkThread(TestStunServer* server);
TestStunServer(rtc::AsyncUDPSocket* socket, rtc::Thread& network_thread)
: StunServer(socket), network_thread_(network_thread) {}
void OnBindingRequest(StunMessage* msg, void OnBindingRequest(StunMessage* msg,
const rtc::SocketAddress& remote_addr) override; const rtc::SocketAddress& remote_addr) override;
private: private:
rtc::SocketAddress fake_stun_addr_; rtc::SocketAddress fake_stun_addr_;
rtc::Thread& network_thread_;
}; };
} // namespace cricket } // namespace cricket

View File

@ -932,7 +932,7 @@ class TurnLoggingIdValidator : public StunMessageObserver {
} }
} }
} }
void ReceivedChannelData(const char* data, size_t size) override {} void ReceivedChannelData(rtc::ArrayView<const uint8_t> packet) override {}
private: private:
const char* expect_val_; const char* expect_val_;
@ -1734,7 +1734,7 @@ class MessageObserver : public StunMessageObserver {
} }
} }
void ReceivedChannelData(const char* data, size_t size) override { void ReceivedChannelData(rtc::ArrayView<const uint8_t> payload) override {
if (channel_data_counter_ != nullptr) { if (channel_data_counter_ != nullptr) {
(*channel_data_counter_)++; (*channel_data_counter_)++;
} }

View File

@ -102,7 +102,11 @@ void TurnServer::AddInternalSocket(rtc::AsyncPacketSocket* socket,
RTC_DCHECK_RUN_ON(thread_); RTC_DCHECK_RUN_ON(thread_);
RTC_DCHECK(server_sockets_.end() == server_sockets_.find(socket)); RTC_DCHECK(server_sockets_.end() == server_sockets_.find(socket));
server_sockets_[socket] = proto; server_sockets_[socket] = proto;
socket->SignalReadPacket.connect(this, &TurnServer::OnInternalPacket); socket->RegisterReceivedPacketCallback(
[&](rtc::AsyncPacketSocket* socket, const rtc::ReceivedPacket& packet) {
RTC_DCHECK_RUN_ON(thread_);
OnInternalPacket(socket, packet);
});
} }
void TurnServer::AddInternalServerSocket( void TurnServer::AddInternalServerSocket(
@ -163,40 +167,35 @@ void TurnServer::OnInternalSocketClose(rtc::AsyncPacketSocket* socket,
} }
void TurnServer::OnInternalPacket(rtc::AsyncPacketSocket* socket, void TurnServer::OnInternalPacket(rtc::AsyncPacketSocket* socket,
const char* data, const rtc::ReceivedPacket& packet) {
size_t size,
const rtc::SocketAddress& addr,
const int64_t& /* packet_time_us */) {
RTC_DCHECK_RUN_ON(thread_); RTC_DCHECK_RUN_ON(thread_);
// Fail if the packet is too small to even contain a channel header. // Fail if the packet is too small to even contain a channel header.
if (size < TURN_CHANNEL_HEADER_SIZE) { if (packet.payload().size() < TURN_CHANNEL_HEADER_SIZE) {
return; return;
} }
InternalSocketMap::iterator iter = server_sockets_.find(socket); InternalSocketMap::iterator iter = server_sockets_.find(socket);
RTC_DCHECK(iter != server_sockets_.end()); RTC_DCHECK(iter != server_sockets_.end());
TurnServerConnection conn(addr, iter->second, socket); TurnServerConnection conn(packet.source_address(), iter->second, socket);
uint16_t msg_type = rtc::GetBE16(data); uint16_t msg_type = rtc::GetBE16(packet.payload().data());
if (!IsTurnChannelData(msg_type)) { if (!IsTurnChannelData(msg_type)) {
// This is a STUN message. // This is a STUN message.
HandleStunMessage(&conn, data, size); HandleStunMessage(&conn, packet.payload());
} else { } else {
// This is a channel message; let the allocation handle it. // This is a channel message; let the allocation handle it.
TurnServerAllocation* allocation = FindAllocation(&conn); TurnServerAllocation* allocation = FindAllocation(&conn);
if (allocation) { if (allocation) {
allocation->HandleChannelData(data, size); allocation->HandleChannelData(packet.payload());
} }
if (stun_message_observer_ != nullptr) { if (stun_message_observer_ != nullptr) {
stun_message_observer_->ReceivedChannelData(data, size); stun_message_observer_->ReceivedChannelData(packet.payload());
} }
} }
} }
void TurnServer::HandleStunMessage(TurnServerConnection* conn, void TurnServer::HandleStunMessage(TurnServerConnection* conn,
const char* data, rtc::ArrayView<const uint8_t> payload) {
size_t size) {
TurnMessage msg; TurnMessage msg;
rtc::ByteBufferReader buf( rtc::ByteBufferReader buf(payload);
rtc::MakeArrayView(reinterpret_cast<const uint8_t*>(data), size));
if (!msg.Read(&buf) || (buf.Length() > 0)) { if (!msg.Read(&buf) || (buf.Length() > 0)) {
RTC_LOG(LS_WARNING) << "Received invalid STUN message"; RTC_LOG(LS_WARNING) << "Received invalid STUN message";
return; return;
@ -232,7 +231,7 @@ void TurnServer::HandleStunMessage(TurnServerConnection* conn,
// Ensure the message is authorized; only needed for requests. // Ensure the message is authorized; only needed for requests.
if (IsStunRequestType(msg.type())) { if (IsStunRequestType(msg.type())) {
if (!CheckAuthorization(conn, &msg, data, size, key)) { if (!CheckAuthorization(conn, &msg, key)) {
return; return;
} }
} }
@ -273,8 +272,6 @@ bool TurnServer::GetKey(const StunMessage* msg, std::string* key) {
bool TurnServer::CheckAuthorization(TurnServerConnection* conn, bool TurnServer::CheckAuthorization(TurnServerConnection* conn,
StunMessage* msg, StunMessage* msg,
const char* data,
size_t size,
absl::string_view key) { absl::string_view key) {
// RFC 5389, 10.2.2. // RFC 5389, 10.2.2.
RTC_DCHECK(IsStunRequestType(msg->type())); RTC_DCHECK(IsStunRequestType(msg->type()));
@ -517,7 +514,7 @@ void TurnServer::DestroyInternalSocket(rtc::AsyncPacketSocket* socket) {
if (iter != server_sockets_.end()) { if (iter != server_sockets_.end()) {
rtc::AsyncPacketSocket* socket = iter->first; rtc::AsyncPacketSocket* socket = iter->first;
socket->UnsubscribeCloseEvent(this); socket->UnsubscribeCloseEvent(this);
socket->SignalReadPacket.disconnect(this); socket->DeregisterReceivedPacketCallback();
server_sockets_.erase(iter); server_sockets_.erase(iter);
std::unique_ptr<rtc::AsyncPacketSocket> socket_to_delete = std::unique_ptr<rtc::AsyncPacketSocket> socket_to_delete =
absl::WrapUnique(socket); absl::WrapUnique(socket);
@ -562,8 +559,11 @@ TurnServerAllocation::TurnServerAllocation(TurnServer* server,
conn_(conn), conn_(conn),
external_socket_(socket), external_socket_(socket),
key_(key) { key_(key) {
external_socket_->SignalReadPacket.connect( external_socket_->RegisterReceivedPacketCallback(
this, &TurnServerAllocation::OnExternalPacket); [&](rtc::AsyncPacketSocket* socket, const rtc::ReceivedPacket& packet) {
RTC_DCHECK_RUN_ON(thread_);
OnExternalPacket(socket, packet);
});
} }
TurnServerAllocation::~TurnServerAllocation() { TurnServerAllocation::~TurnServerAllocation() {
@ -759,14 +759,15 @@ void TurnServerAllocation::HandleChannelBindRequest(const TurnMessage* msg) {
SendResponse(&response); SendResponse(&response);
} }
void TurnServerAllocation::HandleChannelData(const char* data, size_t size) { void TurnServerAllocation::HandleChannelData(
rtc::ArrayView<const uint8_t> payload) {
// Extract the channel number from the data. // Extract the channel number from the data.
uint16_t channel_id = rtc::GetBE16(data); uint16_t channel_id = rtc::GetBE16(payload.data());
auto channel = FindChannel(channel_id); auto channel = FindChannel(channel_id);
if (channel != channels_.end()) { if (channel != channels_.end()) {
// Send the data to the peer address. // Send the data to the peer address.
SendExternal(data + TURN_CHANNEL_HEADER_SIZE, SendExternal(payload.data() + TURN_CHANNEL_HEADER_SIZE,
size - TURN_CHANNEL_HEADER_SIZE, channel->peer); payload.size() - TURN_CHANNEL_HEADER_SIZE, channel->peer);
} else { } else {
RTC_LOG(LS_WARNING) << ToString() RTC_LOG(LS_WARNING) << ToString()
<< ": Received channel data for invalid channel, id=" << ": Received channel data for invalid channel, id="
@ -774,34 +775,31 @@ void TurnServerAllocation::HandleChannelData(const char* data, size_t size) {
} }
} }
void TurnServerAllocation::OnExternalPacket( void TurnServerAllocation::OnExternalPacket(rtc::AsyncPacketSocket* socket,
rtc::AsyncPacketSocket* socket, const rtc::ReceivedPacket& packet) {
const char* data,
size_t size,
const rtc::SocketAddress& addr,
const int64_t& /* packet_time_us */) {
RTC_DCHECK(external_socket_.get() == socket); RTC_DCHECK(external_socket_.get() == socket);
auto channel = FindChannel(addr); auto channel = FindChannel(packet.source_address());
if (channel != channels_.end()) { if (channel != channels_.end()) {
// There is a channel bound to this address. Send as a channel message. // There is a channel bound to this address. Send as a channel message.
rtc::ByteBufferWriter buf; rtc::ByteBufferWriter buf;
buf.WriteUInt16(channel->id); buf.WriteUInt16(channel->id);
buf.WriteUInt16(static_cast<uint16_t>(size)); buf.WriteUInt16(static_cast<uint16_t>(packet.payload().size()));
buf.WriteBytes(data, size); buf.WriteBytes(reinterpret_cast<const char*>(packet.payload().data()),
packet.payload().size());
server_->Send(&conn_, buf); server_->Send(&conn_, buf);
} else if (!server_->enable_permission_checks_ || } else if (!server_->enable_permission_checks_ ||
HasPermission(addr.ipaddr())) { HasPermission(packet.source_address().ipaddr())) {
// No channel, but a permission exists. Send as a data indication. // No channel, but a permission exists. Send as a data indication.
TurnMessage msg(TURN_DATA_INDICATION); TurnMessage msg(TURN_DATA_INDICATION);
msg.AddAttribute(std::make_unique<StunXorAddressAttribute>( msg.AddAttribute(std::make_unique<StunXorAddressAttribute>(
STUN_ATTR_XOR_PEER_ADDRESS, addr)); STUN_ATTR_XOR_PEER_ADDRESS, packet.source_address()));
msg.AddAttribute( msg.AddAttribute(std::make_unique<StunByteStringAttribute>(
std::make_unique<StunByteStringAttribute>(STUN_ATTR_DATA, data, size)); STUN_ATTR_DATA, packet.payload().data(), packet.payload().size()));
server_->SendStun(&conn_, &msg); server_->SendStun(&conn_, &msg);
} else { } else {
RTC_LOG(LS_WARNING) RTC_LOG(LS_WARNING)
<< ToString() << ": Received external packet without permission, peer=" << ToString() << ": Received external packet without permission, peer="
<< addr.ToSensitiveString(); << packet.source_address().ToSensitiveString();
} }
} }

View File

@ -26,6 +26,7 @@
#include "api/units/time_delta.h" #include "api/units/time_delta.h"
#include "p2p/base/port_interface.h" #include "p2p/base/port_interface.h"
#include "rtc_base/async_packet_socket.h" #include "rtc_base/async_packet_socket.h"
#include "rtc_base/network/received_packet.h"
#include "rtc_base/socket_address.h" #include "rtc_base/socket_address.h"
#include "rtc_base/ssl_adapter.h" #include "rtc_base/ssl_adapter.h"
#include "rtc_base/third_party/sigslot/sigslot.h" #include "rtc_base/third_party/sigslot/sigslot.h"
@ -69,14 +70,14 @@ class TurnServerConnection {
// handles TURN messages (via HandleTurnMessage) and channel data messages // handles TURN messages (via HandleTurnMessage) and channel data messages
// (via HandleChannelData) for this allocation when received by the server. // (via HandleChannelData) for this allocation when received by the server.
// The object informs the server when its lifetime timer expires. // The object informs the server when its lifetime timer expires.
class TurnServerAllocation : public sigslot::has_slots<> { class TurnServerAllocation {
public: public:
TurnServerAllocation(TurnServer* server_, TurnServerAllocation(TurnServer* server_,
webrtc::TaskQueueBase* thread, webrtc::TaskQueueBase* thread,
const TurnServerConnection& conn, const TurnServerConnection& conn,
rtc::AsyncPacketSocket* server_socket, rtc::AsyncPacketSocket* server_socket,
absl::string_view key); absl::string_view key);
~TurnServerAllocation() override; virtual ~TurnServerAllocation();
TurnServerConnection* conn() { return &conn_; } TurnServerConnection* conn() { return &conn_; }
const std::string& key() const { return key_; } const std::string& key() const { return key_; }
@ -90,7 +91,7 @@ class TurnServerAllocation : public sigslot::has_slots<> {
std::string ToString() const; std::string ToString() const;
void HandleTurnMessage(const TurnMessage* msg); void HandleTurnMessage(const TurnMessage* msg);
void HandleChannelData(const char* data, size_t size); void HandleChannelData(rtc::ArrayView<const uint8_t> payload);
private: private:
struct Channel { struct Channel {
@ -114,10 +115,7 @@ class TurnServerAllocation : public sigslot::has_slots<> {
void HandleChannelBindRequest(const TurnMessage* msg); void HandleChannelBindRequest(const TurnMessage* msg);
void OnExternalPacket(rtc::AsyncPacketSocket* socket, void OnExternalPacket(rtc::AsyncPacketSocket* socket,
const char* data, const rtc::ReceivedPacket& packet);
size_t size,
const rtc::SocketAddress& addr,
const int64_t& packet_time_us);
static webrtc::TimeDelta ComputeLifetime(const TurnMessage& msg); static webrtc::TimeDelta ComputeLifetime(const TurnMessage& msg);
bool HasPermission(const rtc::IPAddress& addr); bool HasPermission(const rtc::IPAddress& addr);
@ -171,7 +169,7 @@ class TurnRedirectInterface {
class StunMessageObserver { class StunMessageObserver {
public: public:
virtual void ReceivedMessage(const TurnMessage* msg) = 0; virtual void ReceivedMessage(const TurnMessage* msg) = 0;
virtual void ReceivedChannelData(const char* data, size_t size) = 0; virtual void ReceivedChannelData(rtc::ArrayView<const uint8_t> payload) = 0;
virtual ~StunMessageObserver() {} virtual ~StunMessageObserver() {}
}; };
@ -266,14 +264,11 @@ class TurnServer : public sigslot::has_slots<> {
private: private:
// All private member functions and variables should have access restricted to // All private member functions and variables should have access restricted to
// thread_. But compile-time annotations are missing for members access from // thread_. But compile-time annotations are missing for members access from
// TurnServerAllocation (via friend declaration), and the On* methods, which // TurnServerAllocation (via friend declaration).
// are called via sigslot.
std::string GenerateNonce(int64_t now) const RTC_RUN_ON(thread_); std::string GenerateNonce(int64_t now) const RTC_RUN_ON(thread_);
void OnInternalPacket(rtc::AsyncPacketSocket* socket, void OnInternalPacket(rtc::AsyncPacketSocket* socket,
const char* data, const rtc::ReceivedPacket& packet) RTC_RUN_ON(thread_);
size_t size,
const rtc::SocketAddress& address,
const int64_t& packet_time_us);
void OnNewInternalConnection(rtc::Socket* socket); void OnNewInternalConnection(rtc::Socket* socket);
@ -282,8 +277,8 @@ class TurnServer : public sigslot::has_slots<> {
void OnInternalSocketClose(rtc::AsyncPacketSocket* socket, int err); void OnInternalSocketClose(rtc::AsyncPacketSocket* socket, int err);
void HandleStunMessage(TurnServerConnection* conn, void HandleStunMessage(TurnServerConnection* conn,
const char* data, rtc::ArrayView<const uint8_t> payload)
size_t size) RTC_RUN_ON(thread_); RTC_RUN_ON(thread_);
void HandleBindingRequest(TurnServerConnection* conn, const StunMessage* msg) void HandleBindingRequest(TurnServerConnection* conn, const StunMessage* msg)
RTC_RUN_ON(thread_); RTC_RUN_ON(thread_);
void HandleAllocateRequest(TurnServerConnection* conn, void HandleAllocateRequest(TurnServerConnection* conn,
@ -293,8 +288,6 @@ class TurnServer : public sigslot::has_slots<> {
bool GetKey(const StunMessage* msg, std::string* key) RTC_RUN_ON(thread_); bool GetKey(const StunMessage* msg, std::string* key) RTC_RUN_ON(thread_);
bool CheckAuthorization(TurnServerConnection* conn, bool CheckAuthorization(TurnServerConnection* conn,
StunMessage* msg, StunMessage* msg,
const char* data,
size_t size,
absl::string_view key) RTC_RUN_ON(thread_); absl::string_view key) RTC_RUN_ON(thread_);
bool ValidateNonce(absl::string_view nonce) const RTC_RUN_ON(thread_); bool ValidateNonce(absl::string_view nonce) const RTC_RUN_ON(thread_);

View File

@ -163,7 +163,7 @@ class BasicPortAllocatorTestBase : public ::testing::Test,
// must be called. // must be called.
nat_factory_(vss_.get(), kNatUdpAddr, kNatTcpAddr), nat_factory_(vss_.get(), kNatUdpAddr, kNatTcpAddr),
nat_socket_factory_(new rtc::BasicPacketSocketFactory(&nat_factory_)), nat_socket_factory_(new rtc::BasicPacketSocketFactory(&nat_factory_)),
stun_server_(TestStunServer::Create(fss_.get(), kStunAddr)), stun_server_(TestStunServer::Create(fss_.get(), kStunAddr, thread_)),
turn_server_(rtc::Thread::Current(), turn_server_(rtc::Thread::Current(),
fss_.get(), fss_.get(),
kTurnUdpIntAddr, kTurnUdpIntAddr,
@ -521,7 +521,7 @@ class BasicPortAllocatorTestBase : public ::testing::Test,
std::unique_ptr<rtc::NATServer> nat_server_; std::unique_ptr<rtc::NATServer> nat_server_;
rtc::NATSocketFactory nat_factory_; rtc::NATSocketFactory nat_factory_;
std::unique_ptr<rtc::BasicPacketSocketFactory> nat_socket_factory_; std::unique_ptr<rtc::BasicPacketSocketFactory> nat_socket_factory_;
std::unique_ptr<TestStunServer> stun_server_; TestStunServer::StunServerPtr stun_server_;
TestTurnServer turn_server_; TestTurnServer turn_server_;
rtc::FakeNetworkManager network_manager_; rtc::FakeNetworkManager network_manager_;
std::unique_ptr<BasicPortAllocator> allocator_; std::unique_ptr<BasicPortAllocator> allocator_;

View File

@ -44,8 +44,10 @@ class StunProberTest : public ::testing::Test {
: ss_(std::make_unique<rtc::VirtualSocketServer>()), : ss_(std::make_unique<rtc::VirtualSocketServer>()),
main_(ss_.get()), main_(ss_.get()),
result_(StunProber::SUCCESS), result_(StunProber::SUCCESS),
stun_server_1_(cricket::TestStunServer::Create(ss_.get(), kStunAddr1)), stun_server_1_(
stun_server_2_(cricket::TestStunServer::Create(ss_.get(), kStunAddr2)) { cricket::TestStunServer::Create(ss_.get(), kStunAddr1, main_)),
stun_server_2_(
cricket::TestStunServer::Create(ss_.get(), kStunAddr2, main_)) {
stun_server_1_->set_fake_stun_addr(kStunMappedAddr); stun_server_1_->set_fake_stun_addr(kStunMappedAddr);
stun_server_2_->set_fake_stun_addr(kStunMappedAddr); stun_server_2_->set_fake_stun_addr(kStunMappedAddr);
rtc::InitializeSSL(); rtc::InitializeSSL();
@ -57,8 +59,8 @@ class StunProberTest : public ::testing::Test {
void CreateProber(rtc::PacketSocketFactory* socket_factory, void CreateProber(rtc::PacketSocketFactory* socket_factory,
std::vector<const rtc::Network*> networks) { std::vector<const rtc::Network*> networks) {
prober_ = std::make_unique<StunProber>( prober_ = std::make_unique<StunProber>(socket_factory, &main_,
socket_factory, rtc::Thread::Current(), std::move(networks)); std::move(networks));
} }
void StartProbing(rtc::PacketSocketFactory* socket_factory, void StartProbing(rtc::PacketSocketFactory* socket_factory,
@ -137,8 +139,8 @@ class StunProberTest : public ::testing::Test {
std::unique_ptr<StunProber> prober_; std::unique_ptr<StunProber> prober_;
int result_ = 0; int result_ = 0;
bool stopped_ = false; bool stopped_ = false;
std::unique_ptr<cricket::TestStunServer> stun_server_1_; cricket::TestStunServer::StunServerPtr stun_server_1_;
std::unique_ptr<cricket::TestStunServer> stun_server_2_; cricket::TestStunServer::StunServerPtr stun_server_2_;
StunProber::Stats stats_; StunProber::Stats stats_;
}; };

View File

@ -1755,8 +1755,8 @@ class PeerConnectionIntegrationIceStatesTest
} }
void StartStunServer(const SocketAddress& server_address) { void StartStunServer(const SocketAddress& server_address) {
stun_server_.reset( stun_server_ = cricket::TestStunServer::Create(firewall(), server_address,
cricket::TestStunServer::Create(firewall(), server_address)); *network_thread());
} }
bool TestIPv6() { bool TestIPv6() {
@ -1802,7 +1802,7 @@ class PeerConnectionIntegrationIceStatesTest
private: private:
uint32_t port_allocator_flags_; uint32_t port_allocator_flags_;
std::unique_ptr<cricket::TestStunServer> stun_server_; cricket::TestStunServer::StunServerPtr stun_server_;
}; };
// Ensure FakeClockForTest is constructed first (see class for rationale). // Ensure FakeClockForTest is constructed first (see class for rationale).

View File

@ -262,8 +262,8 @@ class PeerConnectionIntegrationIceStatesTest
} }
void StartStunServer(const SocketAddress& server_address) { void StartStunServer(const SocketAddress& server_address) {
stun_server_.reset( stun_server_ = cricket::TestStunServer::Create(firewall(), server_address,
cricket::TestStunServer::Create(firewall(), server_address)); *network_thread());
} }
bool TestIPv6() { bool TestIPv6() {
@ -309,7 +309,7 @@ class PeerConnectionIntegrationIceStatesTest
private: private:
uint32_t port_allocator_flags_; uint32_t port_allocator_flags_;
std::unique_ptr<cricket::TestStunServer> stun_server_; cricket::TestStunServer::StunServerPtr stun_server_;
}; };
// Ensure FakeClockForTest is constructed first (see class for rationale). // Ensure FakeClockForTest is constructed first (see class for rationale).

View File

@ -1798,6 +1798,7 @@ rtc_library("rtc_base_tests_utils") {
"../test:scoped_key_value_config", "../test:scoped_key_value_config",
"memory:always_valid_pointer", "memory:always_valid_pointer",
"memory:fifo_buffer", "memory:fifo_buffer",
"network:received_packet",
"synchronization:mutex", "synchronization:mutex",
"third_party/sigslot", "third_party/sigslot",
] ]

View File

@ -21,6 +21,7 @@
#include "absl/memory/memory.h" #include "absl/memory/memory.h"
#include "rtc_base/async_packet_socket.h" #include "rtc_base/async_packet_socket.h"
#include "rtc_base/async_tcp_socket.h" #include "rtc_base/async_tcp_socket.h"
#include "rtc_base/network/received_packet.h"
#include "rtc_base/socket.h" #include "rtc_base/socket.h"
#include "rtc_base/socket_address.h" #include "rtc_base/socket_address.h"
#include "rtc_base/third_party/sigslot/sigslot.h" #include "rtc_base/third_party/sigslot/sigslot.h"
@ -45,19 +46,17 @@ class TestEchoServer : public sigslot::has_slots<> {
Socket* raw_socket = socket->Accept(nullptr); Socket* raw_socket = socket->Accept(nullptr);
if (raw_socket) { if (raw_socket) {
AsyncTCPSocket* packet_socket = new AsyncTCPSocket(raw_socket); AsyncTCPSocket* packet_socket = new AsyncTCPSocket(raw_socket);
packet_socket->SignalReadPacket.connect(this, &TestEchoServer::OnPacket); packet_socket->RegisterReceivedPacketCallback(
[&](rtc::AsyncPacketSocket* socket,
const rtc::ReceivedPacket& packet) { OnPacket(socket, packet); });
packet_socket->SubscribeCloseEvent( packet_socket->SubscribeCloseEvent(
this, [this](AsyncPacketSocket* s, int err) { OnClose(s, err); }); this, [this](AsyncPacketSocket* s, int err) { OnClose(s, err); });
client_sockets_.push_back(packet_socket); client_sockets_.push_back(packet_socket);
} }
} }
void OnPacket(AsyncPacketSocket* socket, void OnPacket(AsyncPacketSocket* socket, const rtc::ReceivedPacket& packet) {
const char* buf,
size_t size,
const SocketAddress& remote_addr,
const int64_t& /* packet_time_us */) {
rtc::PacketOptions options; rtc::PacketOptions options;
socket->Send(buf, size, options); socket->Send(packet.payload().data(), packet.payload().size(), options);
} }
void OnClose(AsyncPacketSocket* socket, int err) { void OnClose(AsyncPacketSocket* socket, int err) {
ClientList::iterator it = absl::c_find(client_sockets_, socket); ClientList::iterator it = absl::c_find(client_sockets_, socket);

View File

@ -76,6 +76,7 @@ rtc_library("emulated_network") {
"../../rtc_base:task_queue_for_test", "../../rtc_base:task_queue_for_test",
"../../rtc_base:threading", "../../rtc_base:threading",
"../../rtc_base/memory:always_valid_pointer", "../../rtc_base/memory:always_valid_pointer",
"../../rtc_base/network:received_packet",
"../../rtc_base/synchronization:mutex", "../../rtc_base/synchronization:mutex",
"../../rtc_base/system:no_unique_address", "../../rtc_base/system:no_unique_address",
"../../rtc_base/task_utils:repeating_task", "../../rtc_base/task_utils:repeating_task",

View File

@ -14,6 +14,7 @@
#include <utility> #include <utility>
#include "api/packet_socket_factory.h" #include "api/packet_socket_factory.h"
#include "rtc_base/network/received_packet.h"
#include "rtc_base/strings/string_builder.h" #include "rtc_base/strings/string_builder.h"
#include "rtc_base/task_queue_for_test.h" #include "rtc_base/task_queue_for_test.h"
@ -22,55 +23,6 @@ namespace {
static const char kTestRealm[] = "example.org"; static const char kTestRealm[] = "example.org";
static const char kTestSoftware[] = "TestTurnServer"; static const char kTestSoftware[] = "TestTurnServer";
// A wrapper class for copying data between an AsyncPacketSocket and a
// EmulatedEndpoint. This is used by the cricket::TurnServer when
// sending data back into the emulated network.
class AsyncPacketSocketWrapper : public rtc::AsyncPacketSocket {
public:
AsyncPacketSocketWrapper(webrtc::test::EmulatedTURNServer* turn_server,
webrtc::EmulatedEndpoint* endpoint,
uint16_t port)
: turn_server_(turn_server),
endpoint_(endpoint),
local_address_(
rtc::SocketAddress(endpoint_->GetPeerLocalAddress(), port)) {}
~AsyncPacketSocketWrapper() { turn_server_->Unbind(local_address_); }
rtc::SocketAddress GetLocalAddress() const override { return local_address_; }
rtc::SocketAddress GetRemoteAddress() const override {
return rtc::SocketAddress();
}
int Send(const void* pv,
size_t cb,
const rtc::PacketOptions& options) override {
RTC_CHECK(false) << "TCP not implemented";
return -1;
}
int SendTo(const void* pv,
size_t cb,
const rtc::SocketAddress& addr,
const rtc::PacketOptions& options) override {
// Copy from rtc::AsyncPacketSocket to EmulatedEndpoint.
rtc::CopyOnWriteBuffer buf(reinterpret_cast<const char*>(pv), cb);
endpoint_->SendPacket(local_address_, addr, buf);
return cb;
}
int Close() override { return 0; }
rtc::AsyncPacketSocket::State GetState() const override {
return rtc::AsyncPacketSocket::STATE_BOUND;
}
int GetOption(rtc::Socket::Option opt, int* value) override { return 0; }
int SetOption(rtc::Socket::Option opt, int value) override { return 0; }
int GetError() const override { return 0; }
void SetError(int error) override {}
private:
webrtc::test::EmulatedTURNServer* const turn_server_;
webrtc::EmulatedEndpoint* const endpoint_;
const rtc::SocketAddress local_address_;
};
// A wrapper class for cricket::TurnServer to allocate sockets. // A wrapper class for cricket::TurnServer to allocate sockets.
class PacketSocketFactoryWrapper : public rtc::PacketSocketFactory { class PacketSocketFactoryWrapper : public rtc::PacketSocketFactory {
public: public:
@ -116,6 +68,59 @@ class PacketSocketFactoryWrapper : public rtc::PacketSocketFactory {
namespace webrtc { namespace webrtc {
namespace test { namespace test {
// A wrapper class for copying data between an AsyncPacketSocket and a
// EmulatedEndpoint. This is used by the cricket::TurnServer when
// sending data back into the emulated network.
class EmulatedTURNServer::AsyncPacketSocketWrapper
: public rtc::AsyncPacketSocket {
public:
AsyncPacketSocketWrapper(webrtc::test::EmulatedTURNServer* turn_server,
webrtc::EmulatedEndpoint* endpoint,
uint16_t port)
: turn_server_(turn_server),
endpoint_(endpoint),
local_address_(
rtc::SocketAddress(endpoint_->GetPeerLocalAddress(), port)) {}
~AsyncPacketSocketWrapper() { turn_server_->Unbind(local_address_); }
rtc::SocketAddress GetLocalAddress() const override { return local_address_; }
rtc::SocketAddress GetRemoteAddress() const override {
return rtc::SocketAddress();
}
int Send(const void* pv,
size_t cb,
const rtc::PacketOptions& options) override {
RTC_CHECK(false) << "TCP not implemented";
return -1;
}
int SendTo(const void* pv,
size_t cb,
const rtc::SocketAddress& addr,
const rtc::PacketOptions& options) override {
// Copy from rtc::AsyncPacketSocket to EmulatedEndpoint.
rtc::CopyOnWriteBuffer buf(reinterpret_cast<const char*>(pv), cb);
endpoint_->SendPacket(local_address_, addr, buf);
return cb;
}
int Close() override { return 0; }
void NotifyPacketReceived(const rtc::ReceivedPacket& packet) {
rtc::AsyncPacketSocket::NotifyPacketReceived(packet);
}
rtc::AsyncPacketSocket::State GetState() const override {
return rtc::AsyncPacketSocket::STATE_BOUND;
}
int GetOption(rtc::Socket::Option opt, int* value) override { return 0; }
int SetOption(rtc::Socket::Option opt, int value) override { return 0; }
int GetError() const override { return 0; }
void SetError(int error) override {}
private:
webrtc::test::EmulatedTURNServer* const turn_server_;
webrtc::EmulatedEndpoint* const endpoint_;
const rtc::SocketAddress local_address_;
};
EmulatedTURNServer::EmulatedTURNServer(std::unique_ptr<rtc::Thread> thread, EmulatedTURNServer::EmulatedTURNServer(std::unique_ptr<rtc::Thread> thread,
EmulatedEndpoint* client, EmulatedEndpoint* client,
EmulatedEndpoint* peer) EmulatedEndpoint* peer)
@ -170,9 +175,8 @@ void EmulatedTURNServer::OnPacketReceived(webrtc::EmulatedIpPacket packet) {
RTC_DCHECK_RUN_ON(thread_.get()); RTC_DCHECK_RUN_ON(thread_.get());
auto it = sockets_.find(packet.to); auto it = sockets_.find(packet.to);
if (it != sockets_.end()) { if (it != sockets_.end()) {
it->second->SignalReadPacket( it->second->NotifyPacketReceived(
it->second, reinterpret_cast<const char*>(packet.cdata()), rtc::ReceivedPacket(packet.data, packet.from, packet.arrival_time));
packet.size(), packet.from, packet.arrival_time.ms());
} }
}); });
} }

View File

@ -84,7 +84,8 @@ class EmulatedTURNServer : public EmulatedTURNServerInterface,
EmulatedEndpoint* const client_; EmulatedEndpoint* const client_;
EmulatedEndpoint* const peer_; EmulatedEndpoint* const peer_;
std::unique_ptr<cricket::TurnServer> turn_server_ RTC_GUARDED_BY(&thread_); std::unique_ptr<cricket::TurnServer> turn_server_ RTC_GUARDED_BY(&thread_);
std::map<rtc::SocketAddress, rtc::AsyncPacketSocket*> sockets_ class AsyncPacketSocketWrapper;
std::map<rtc::SocketAddress, AsyncPacketSocketWrapper*> sockets_
RTC_GUARDED_BY(&thread_); RTC_GUARDED_BY(&thread_);
// Wraps a EmulatedEndpoint in a AsyncPacketSocket to bridge interaction // Wraps a EmulatedEndpoint in a AsyncPacketSocket to bridge interaction