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
# base of lastest vendoring
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.
# ./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.
# ./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;
}
rtc::Thread* pthMain = rtc::Thread::Current();
rtc::Thread* pthMain = rtc::ThreadManager::Instance()->WrapCurrentThread();
RTC_DCHECK(pthMain);
rtc::AsyncUDPSocket* server_socket =
rtc::AsyncUDPSocket::Create(pthMain->socketserver(), server_addr);

View File

@ -1560,7 +1560,7 @@ index 0474e7bc17..1953923f81 100644
std::unique_ptr<ScalableVideoController> svc_controller_;
absl::optional<ScalabilityMode> scalability_mode_;
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
+++ b/rtc_base/BUILD.gn
@@ -463,6 +463,12 @@ rtc_library("logging") {

View File

@ -1009,7 +1009,7 @@ index 730ec9bfdd..d473dbb74c 100644
"/config/external/nspr",
"/nsprpub/lib/ds",
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
+++ b/rtc_base/BUILD.gn
@@ -327,6 +327,7 @@ rtc_library("sample_counter") {
@ -1199,7 +1199,7 @@ index 64b220af10..60eb0f4ddc 100644
rtc_source_set("gtest_prod") {
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") {
visibility = [ "*" ]
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
+++ b/rtc_base/BUILD.gn
@@ -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:ssl",
"../rtc_base:stringutils",
"../rtc_base/network:received_packet",
"../rtc_base/third_party/sigslot",
]
absl_deps = [

View File

@ -285,7 +285,7 @@ class P2PTransportChannelTestBase : public ::testing::Test,
ss_(new rtc::FirewallSocketServer(nss_.get())),
socket_factory_(new rtc::BasicPacketSocketFactory(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),
socks_server1_(ss_.get(),
kSocksProxyAddrs[0],
@ -1025,7 +1025,7 @@ class P2PTransportChannelTestBase : public ::testing::Test,
rtc::AutoSocketServerThread main_;
rtc::scoped_refptr<PendingTaskSafetyFlag> safety_ =
PendingTaskSafetyFlag::Create();
std::unique_ptr<TestStunServer> stun_server_;
TestStunServer::StunServerPtr stun_server_;
TestTurnServer turn_server_;
rtc::SocksProxyServer socks_server1_;
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_socket_factory1_(&nat_factory1_),
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),
username_(rtc::CreateRandomString(ICE_UFRAG_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::BasicPacketSocketFactory nat_socket_factory1_;
rtc::BasicPacketSocketFactory nat_socket_factory2_;
std::unique_ptr<TestStunServer> stun_server_;
TestStunServer::StunServerPtr stun_server_;
TestTurnServer turn_server_;
std::string username_;
std::string password_;

View File

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

View File

@ -14,43 +14,49 @@
#include <utility>
#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/logging.h"
#include "rtc_base/network/received_packet.h"
namespace cricket {
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() {
socket_->SignalReadPacket.disconnect(this);
RTC_DCHECK_RUN_ON(&sequence_checker_);
socket_->DeregisterReceivedPacketCallback();
}
void StunServer::OnPacket(rtc::AsyncPacketSocket* socket,
const char* buf,
size_t size,
const rtc::SocketAddress& remote_addr,
const int64_t& /* packet_time_us */) {
const rtc::ReceivedPacket& packet) {
RTC_DCHECK_RUN_ON(&sequence_checker_);
// Parse the STUN message; eat any messages that fail to parse.
rtc::ByteBufferReader bbuf(
rtc::MakeArrayView(reinterpret_cast<const uint8_t*>(buf), size));
rtc::ByteBufferReader bbuf(packet.payload());
StunMessage msg;
if (!msg.Read(&bbuf)) {
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.
// Send the message to the appropriate handler function.
switch (msg.type()) {
case STUN_BINDING_REQUEST:
OnBindingRequest(&msg, remote_addr);
OnBindingRequest(&msg, packet.source_address());
break;
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_
#include <stddef.h>
#include <stdint.h>
#include <memory>
@ -21,26 +20,22 @@
#include "rtc_base/async_packet_socket.h"
#include "rtc_base/async_udp_socket.h"
#include "rtc_base/socket_address.h"
#include "rtc_base/third_party/sigslot/sigslot.h"
namespace cricket {
const int STUN_SERVER_PORT = 3478;
class StunServer : public sigslot::has_slots<> {
class StunServer {
public:
// Creates a STUN server, which will listen on the given socket.
explicit StunServer(rtc::AsyncUDPSocket* socket);
// Removes the STUN server from the socket and deletes the socket.
~StunServer() override;
virtual ~StunServer();
protected:
// Slot for Socket.PacketRead:
// Callback for packets from socket.
void OnPacket(rtc::AsyncPacketSocket* socket,
const char* buf,
size_t size,
const rtc::SocketAddress& remote_addr,
const int64_t& packet_time_us);
const rtc::ReceivedPacket& packet);
// Handlers for the different types of STUN/TURN requests:
virtual void OnBindingRequest(StunMessage* msg,
@ -64,6 +59,7 @@ class StunServer : public sigslot::has_slots<> {
StunMessage* response) const;
private:
webrtc::SequenceChecker sequence_checker_;
std::unique_ptr<rtc::AsyncUDPSocket> socket_;
};

View File

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

View File

@ -11,19 +11,25 @@
#ifndef P2P_BASE_TEST_STUN_SERVER_H_
#define P2P_BASE_TEST_STUN_SERVER_H_
#include <memory>
#include "api/transport/stun.h"
#include "p2p/base/stun_server.h"
#include "rtc_base/async_udp_socket.h"
#include "rtc_base/socket_address.h"
#include "rtc_base/socket_server.h"
#include "rtc_base/thread.h"
namespace cricket {
// A test STUN server. Useful for unit tests.
class TestStunServer : StunServer {
public:
static TestStunServer* Create(rtc::SocketServer* ss,
const rtc::SocketAddress& addr);
using StunServerPtr =
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.
void set_fake_stun_addr(const rtc::SocketAddress& addr) {
@ -31,13 +37,17 @@ class TestStunServer : StunServer {
}
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,
const rtc::SocketAddress& remote_addr) override;
private:
rtc::SocketAddress fake_stun_addr_;
rtc::Thread& network_thread_;
};
} // 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:
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) {
(*channel_data_counter_)++;
}

View File

@ -102,7 +102,11 @@ void TurnServer::AddInternalSocket(rtc::AsyncPacketSocket* socket,
RTC_DCHECK_RUN_ON(thread_);
RTC_DCHECK(server_sockets_.end() == server_sockets_.find(socket));
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(
@ -163,40 +167,35 @@ void TurnServer::OnInternalSocketClose(rtc::AsyncPacketSocket* socket,
}
void TurnServer::OnInternalPacket(rtc::AsyncPacketSocket* socket,
const char* data,
size_t size,
const rtc::SocketAddress& addr,
const int64_t& /* packet_time_us */) {
const rtc::ReceivedPacket& packet) {
RTC_DCHECK_RUN_ON(thread_);
// 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;
}
InternalSocketMap::iterator iter = server_sockets_.find(socket);
RTC_DCHECK(iter != server_sockets_.end());
TurnServerConnection conn(addr, iter->second, socket);
uint16_t msg_type = rtc::GetBE16(data);
TurnServerConnection conn(packet.source_address(), iter->second, socket);
uint16_t msg_type = rtc::GetBE16(packet.payload().data());
if (!IsTurnChannelData(msg_type)) {
// This is a STUN message.
HandleStunMessage(&conn, data, size);
HandleStunMessage(&conn, packet.payload());
} else {
// This is a channel message; let the allocation handle it.
TurnServerAllocation* allocation = FindAllocation(&conn);
if (allocation) {
allocation->HandleChannelData(data, size);
allocation->HandleChannelData(packet.payload());
}
if (stun_message_observer_ != nullptr) {
stun_message_observer_->ReceivedChannelData(data, size);
stun_message_observer_->ReceivedChannelData(packet.payload());
}
}
}
void TurnServer::HandleStunMessage(TurnServerConnection* conn,
const char* data,
size_t size) {
rtc::ArrayView<const uint8_t> payload) {
TurnMessage msg;
rtc::ByteBufferReader buf(
rtc::MakeArrayView(reinterpret_cast<const uint8_t*>(data), size));
rtc::ByteBufferReader buf(payload);
if (!msg.Read(&buf) || (buf.Length() > 0)) {
RTC_LOG(LS_WARNING) << "Received invalid STUN message";
return;
@ -232,7 +231,7 @@ void TurnServer::HandleStunMessage(TurnServerConnection* conn,
// Ensure the message is authorized; only needed for requests.
if (IsStunRequestType(msg.type())) {
if (!CheckAuthorization(conn, &msg, data, size, key)) {
if (!CheckAuthorization(conn, &msg, key)) {
return;
}
}
@ -273,8 +272,6 @@ bool TurnServer::GetKey(const StunMessage* msg, std::string* key) {
bool TurnServer::CheckAuthorization(TurnServerConnection* conn,
StunMessage* msg,
const char* data,
size_t size,
absl::string_view key) {
// RFC 5389, 10.2.2.
RTC_DCHECK(IsStunRequestType(msg->type()));
@ -517,7 +514,7 @@ void TurnServer::DestroyInternalSocket(rtc::AsyncPacketSocket* socket) {
if (iter != server_sockets_.end()) {
rtc::AsyncPacketSocket* socket = iter->first;
socket->UnsubscribeCloseEvent(this);
socket->SignalReadPacket.disconnect(this);
socket->DeregisterReceivedPacketCallback();
server_sockets_.erase(iter);
std::unique_ptr<rtc::AsyncPacketSocket> socket_to_delete =
absl::WrapUnique(socket);
@ -562,8 +559,11 @@ TurnServerAllocation::TurnServerAllocation(TurnServer* server,
conn_(conn),
external_socket_(socket),
key_(key) {
external_socket_->SignalReadPacket.connect(
this, &TurnServerAllocation::OnExternalPacket);
external_socket_->RegisterReceivedPacketCallback(
[&](rtc::AsyncPacketSocket* socket, const rtc::ReceivedPacket& packet) {
RTC_DCHECK_RUN_ON(thread_);
OnExternalPacket(socket, packet);
});
}
TurnServerAllocation::~TurnServerAllocation() {
@ -759,14 +759,15 @@ void TurnServerAllocation::HandleChannelBindRequest(const TurnMessage* msg) {
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.
uint16_t channel_id = rtc::GetBE16(data);
uint16_t channel_id = rtc::GetBE16(payload.data());
auto channel = FindChannel(channel_id);
if (channel != channels_.end()) {
// Send the data to the peer address.
SendExternal(data + TURN_CHANNEL_HEADER_SIZE,
size - TURN_CHANNEL_HEADER_SIZE, channel->peer);
SendExternal(payload.data() + TURN_CHANNEL_HEADER_SIZE,
payload.size() - TURN_CHANNEL_HEADER_SIZE, channel->peer);
} else {
RTC_LOG(LS_WARNING) << ToString()
<< ": Received channel data for invalid channel, id="
@ -774,34 +775,31 @@ void TurnServerAllocation::HandleChannelData(const char* data, size_t size) {
}
}
void TurnServerAllocation::OnExternalPacket(
rtc::AsyncPacketSocket* socket,
const char* data,
size_t size,
const rtc::SocketAddress& addr,
const int64_t& /* packet_time_us */) {
void TurnServerAllocation::OnExternalPacket(rtc::AsyncPacketSocket* socket,
const rtc::ReceivedPacket& packet) {
RTC_DCHECK(external_socket_.get() == socket);
auto channel = FindChannel(addr);
auto channel = FindChannel(packet.source_address());
if (channel != channels_.end()) {
// There is a channel bound to this address. Send as a channel message.
rtc::ByteBufferWriter buf;
buf.WriteUInt16(channel->id);
buf.WriteUInt16(static_cast<uint16_t>(size));
buf.WriteBytes(data, size);
buf.WriteUInt16(static_cast<uint16_t>(packet.payload().size()));
buf.WriteBytes(reinterpret_cast<const char*>(packet.payload().data()),
packet.payload().size());
server_->Send(&conn_, buf);
} 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.
TurnMessage msg(TURN_DATA_INDICATION);
msg.AddAttribute(std::make_unique<StunXorAddressAttribute>(
STUN_ATTR_XOR_PEER_ADDRESS, addr));
msg.AddAttribute(
std::make_unique<StunByteStringAttribute>(STUN_ATTR_DATA, data, size));
STUN_ATTR_XOR_PEER_ADDRESS, packet.source_address()));
msg.AddAttribute(std::make_unique<StunByteStringAttribute>(
STUN_ATTR_DATA, packet.payload().data(), packet.payload().size()));
server_->SendStun(&conn_, &msg);
} else {
RTC_LOG(LS_WARNING)
<< 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 "p2p/base/port_interface.h"
#include "rtc_base/async_packet_socket.h"
#include "rtc_base/network/received_packet.h"
#include "rtc_base/socket_address.h"
#include "rtc_base/ssl_adapter.h"
#include "rtc_base/third_party/sigslot/sigslot.h"
@ -69,14 +70,14 @@ class TurnServerConnection {
// handles TURN messages (via HandleTurnMessage) and channel data messages
// (via HandleChannelData) for this allocation when received by the server.
// The object informs the server when its lifetime timer expires.
class TurnServerAllocation : public sigslot::has_slots<> {
class TurnServerAllocation {
public:
TurnServerAllocation(TurnServer* server_,
webrtc::TaskQueueBase* thread,
const TurnServerConnection& conn,
rtc::AsyncPacketSocket* server_socket,
absl::string_view key);
~TurnServerAllocation() override;
virtual ~TurnServerAllocation();
TurnServerConnection* conn() { return &conn_; }
const std::string& key() const { return key_; }
@ -90,7 +91,7 @@ class TurnServerAllocation : public sigslot::has_slots<> {
std::string ToString() const;
void HandleTurnMessage(const TurnMessage* msg);
void HandleChannelData(const char* data, size_t size);
void HandleChannelData(rtc::ArrayView<const uint8_t> payload);
private:
struct Channel {
@ -114,10 +115,7 @@ class TurnServerAllocation : public sigslot::has_slots<> {
void HandleChannelBindRequest(const TurnMessage* msg);
void OnExternalPacket(rtc::AsyncPacketSocket* socket,
const char* data,
size_t size,
const rtc::SocketAddress& addr,
const int64_t& packet_time_us);
const rtc::ReceivedPacket& packet);
static webrtc::TimeDelta ComputeLifetime(const TurnMessage& msg);
bool HasPermission(const rtc::IPAddress& addr);
@ -171,7 +169,7 @@ class TurnRedirectInterface {
class StunMessageObserver {
public:
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() {}
};
@ -266,14 +264,11 @@ class TurnServer : public sigslot::has_slots<> {
private:
// All private member functions and variables should have access restricted to
// thread_. But compile-time annotations are missing for members access from
// TurnServerAllocation (via friend declaration), and the On* methods, which
// are called via sigslot.
// TurnServerAllocation (via friend declaration).
std::string GenerateNonce(int64_t now) const RTC_RUN_ON(thread_);
void OnInternalPacket(rtc::AsyncPacketSocket* socket,
const char* data,
size_t size,
const rtc::SocketAddress& address,
const int64_t& packet_time_us);
const rtc::ReceivedPacket& packet) RTC_RUN_ON(thread_);
void OnNewInternalConnection(rtc::Socket* socket);
@ -282,8 +277,8 @@ class TurnServer : public sigslot::has_slots<> {
void OnInternalSocketClose(rtc::AsyncPacketSocket* socket, int err);
void HandleStunMessage(TurnServerConnection* conn,
const char* data,
size_t size) RTC_RUN_ON(thread_);
rtc::ArrayView<const uint8_t> payload)
RTC_RUN_ON(thread_);
void HandleBindingRequest(TurnServerConnection* conn, const StunMessage* msg)
RTC_RUN_ON(thread_);
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 CheckAuthorization(TurnServerConnection* conn,
StunMessage* msg,
const char* data,
size_t size,
absl::string_view key) 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.
nat_factory_(vss_.get(), kNatUdpAddr, kNatTcpAddr),
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(),
fss_.get(),
kTurnUdpIntAddr,
@ -521,7 +521,7 @@ class BasicPortAllocatorTestBase : public ::testing::Test,
std::unique_ptr<rtc::NATServer> nat_server_;
rtc::NATSocketFactory nat_factory_;
std::unique_ptr<rtc::BasicPacketSocketFactory> nat_socket_factory_;
std::unique_ptr<TestStunServer> stun_server_;
TestStunServer::StunServerPtr stun_server_;
TestTurnServer turn_server_;
rtc::FakeNetworkManager network_manager_;
std::unique_ptr<BasicPortAllocator> allocator_;

View File

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

View File

@ -1755,8 +1755,8 @@ class PeerConnectionIntegrationIceStatesTest
}
void StartStunServer(const SocketAddress& server_address) {
stun_server_.reset(
cricket::TestStunServer::Create(firewall(), server_address));
stun_server_ = cricket::TestStunServer::Create(firewall(), server_address,
*network_thread());
}
bool TestIPv6() {
@ -1802,7 +1802,7 @@ class PeerConnectionIntegrationIceStatesTest
private:
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).

View File

@ -262,8 +262,8 @@ class PeerConnectionIntegrationIceStatesTest
}
void StartStunServer(const SocketAddress& server_address) {
stun_server_.reset(
cricket::TestStunServer::Create(firewall(), server_address));
stun_server_ = cricket::TestStunServer::Create(firewall(), server_address,
*network_thread());
}
bool TestIPv6() {
@ -309,7 +309,7 @@ class PeerConnectionIntegrationIceStatesTest
private:
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).

View File

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

View File

@ -21,6 +21,7 @@
#include "absl/memory/memory.h"
#include "rtc_base/async_packet_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_address.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);
if (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(
this, [this](AsyncPacketSocket* s, int err) { OnClose(s, err); });
client_sockets_.push_back(packet_socket);
}
}
void OnPacket(AsyncPacketSocket* socket,
const char* buf,
size_t size,
const SocketAddress& remote_addr,
const int64_t& /* packet_time_us */) {
void OnPacket(AsyncPacketSocket* socket, const rtc::ReceivedPacket& packet) {
rtc::PacketOptions options;
socket->Send(buf, size, options);
socket->Send(packet.payload().data(), packet.payload().size(), options);
}
void OnClose(AsyncPacketSocket* socket, int err) {
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:threading",
"../../rtc_base/memory:always_valid_pointer",
"../../rtc_base/network:received_packet",
"../../rtc_base/synchronization:mutex",
"../../rtc_base/system:no_unique_address",
"../../rtc_base/task_utils:repeating_task",

View File

@ -14,6 +14,7 @@
#include <utility>
#include "api/packet_socket_factory.h"
#include "rtc_base/network/received_packet.h"
#include "rtc_base/strings/string_builder.h"
#include "rtc_base/task_queue_for_test.h"
@ -22,55 +23,6 @@ namespace {
static const char kTestRealm[] = "example.org";
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.
class PacketSocketFactoryWrapper : public rtc::PacketSocketFactory {
public:
@ -116,6 +68,59 @@ class PacketSocketFactoryWrapper : public rtc::PacketSocketFactory {
namespace webrtc {
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,
EmulatedEndpoint* client,
EmulatedEndpoint* peer)
@ -170,9 +175,8 @@ void EmulatedTURNServer::OnPacketReceived(webrtc::EmulatedIpPacket packet) {
RTC_DCHECK_RUN_ON(thread_.get());
auto it = sockets_.find(packet.to);
if (it != sockets_.end()) {
it->second->SignalReadPacket(
it->second, reinterpret_cast<const char*>(packet.cdata()),
packet.size(), packet.from, packet.arrival_time.ms());
it->second->NotifyPacketReceived(
rtc::ReceivedPacket(packet.data, packet.from, packet.arrival_time));
}
});
}

View File

@ -84,7 +84,8 @@ class EmulatedTURNServer : public EmulatedTURNServerInterface,
EmulatedEndpoint* const client_;
EmulatedEndpoint* const peer_;
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_);
// Wraps a EmulatedEndpoint in a AsyncPacketSocket to bridge interaction