diff options
Diffstat (limited to 'third_party/libwebrtc/rtc_base')
18 files changed, 90 insertions, 547 deletions
diff --git a/third_party/libwebrtc/rtc_base/BUILD.gn b/third_party/libwebrtc/rtc_base/BUILD.gn index 57a9c11f01..eb88039d33 100644 --- a/third_party/libwebrtc/rtc_base/BUILD.gn +++ b/third_party/libwebrtc/rtc_base/BUILD.gn @@ -1120,6 +1120,7 @@ rtc_library("socket") { ] deps = [ ":buffer", + ":checks", ":macromagic", ":socket_address", "../api/units:timestamp", @@ -1756,6 +1757,7 @@ rtc_library("rtc_base_tests_utils") { ":async_socket", ":async_tcp_socket", ":async_udp_socket", + ":buffer", ":byte_buffer", ":checks", ":ip_address", @@ -1775,6 +1777,7 @@ rtc_library("rtc_base_tests_utils") { ":stringutils", ":threading", ":timeutils", + "../api:array_view", "../api:make_ref_counted", "../api:refcountedbase", "../api:scoped_refptr", @@ -1890,6 +1893,7 @@ if (rtc_include_tests) { ":threading", ":timeutils", "../api/units:time_delta", + "../api/units:timestamp", "../system_wrappers", "../test:field_trial", "../test:fileutils", @@ -2122,7 +2126,6 @@ if (rtc_include_tests) { "nat_unittest.cc", "network_route_unittest.cc", "network_unittest.cc", - "proxy_unittest.cc", "rolling_accumulator_unittest.cc", "rtc_certificate_generator_unittest.cc", "rtc_certificate_unittest.cc", diff --git a/third_party/libwebrtc/rtc_base/ip_address.h b/third_party/libwebrtc/rtc_base/ip_address.h index 897e165565..c015206ab3 100644 --- a/third_party/libwebrtc/rtc_base/ip_address.h +++ b/third_party/libwebrtc/rtc_base/ip_address.h @@ -162,8 +162,8 @@ RTC_EXPORT bool IPFromString(absl::string_view str, int flags, InterfaceAddress* out); bool IPIsAny(const IPAddress& ip); -bool IPIsLoopback(const IPAddress& ip); -bool IPIsLinkLocal(const IPAddress& ip); +RTC_EXPORT bool IPIsLoopback(const IPAddress& ip); +RTC_EXPORT bool IPIsLinkLocal(const IPAddress& ip); // Identify a private network address like "192.168.111.222" // (see https://en.wikipedia.org/wiki/Private_network ) bool IPIsPrivateNetwork(const IPAddress& ip); diff --git a/third_party/libwebrtc/rtc_base/nat_server.cc b/third_party/libwebrtc/rtc_base/nat_server.cc index c274cedf18..f21d404bd3 100644 --- a/third_party/libwebrtc/rtc_base/nat_server.cc +++ b/third_party/libwebrtc/rtc_base/nat_server.cc @@ -11,8 +11,10 @@ #include "rtc_base/nat_server.h" #include <cstddef> +#include <cstdint> #include <memory> +#include "api/array_view.h" #include "rtc_base/checks.h" #include "rtc_base/logging.h" #include "rtc_base/nat_socket_factory.h" @@ -97,8 +99,9 @@ class NATProxyServerSocket : public AsyncProxyServerSocket { } SocketAddress dest_addr; - size_t address_length = UnpackAddressFromNAT(data, *len, &dest_addr); - + size_t address_length = UnpackAddressFromNAT( + MakeArrayView(reinterpret_cast<const uint8_t*>(data), *len), + &dest_addr); *len -= address_length; if (*len > 0) { memmove(data, data + address_length, *len); @@ -171,15 +174,12 @@ NATServer::~NATServer() { void NATServer::OnInternalUDPPacket(AsyncPacketSocket* socket, const rtc::ReceivedPacket& packet) { RTC_DCHECK(internal_socket_thread_.IsCurrent()); - const char* buf = reinterpret_cast<const char*>(packet.payload().data()); - size_t size = packet.payload().size(); - const SocketAddress& addr = packet.source_address(); // Read the intended destination from the wire. SocketAddress dest_addr; - size_t length = UnpackAddressFromNAT(buf, size, &dest_addr); + size_t length = UnpackAddressFromNAT(packet.payload(), &dest_addr); // Find the translation for these addresses (allocating one if necessary). - SocketAddressPair route(addr, dest_addr); + SocketAddressPair route(packet.source_address(), dest_addr); InternalMap::iterator iter = int_map_->find(route); if (iter == int_map_->end()) { Translate(route); @@ -192,6 +192,8 @@ void NATServer::OnInternalUDPPacket(AsyncPacketSocket* socket, // Send the packet to its intended destination. rtc::PacketOptions options; + const char* buf = reinterpret_cast<const char*>(packet.payload().data()); + size_t size = packet.payload().size(); iter->second->socket->SendTo(buf + length, size - length, dest_addr, options); } diff --git a/third_party/libwebrtc/rtc_base/nat_socket_factory.cc b/third_party/libwebrtc/rtc_base/nat_socket_factory.cc index 83ec2bc327..66e4f84cd7 100644 --- a/third_party/libwebrtc/rtc_base/nat_socket_factory.cc +++ b/third_party/libwebrtc/rtc_base/nat_socket_factory.cc @@ -10,7 +10,9 @@ #include "rtc_base/nat_socket_factory.h" +#include "api/units/timestamp.h" #include "rtc_base/arraysize.h" +#include "rtc_base/buffer.h" #include "rtc_base/checks.h" #include "rtc_base/logging.h" #include "rtc_base/nat_server.h" @@ -47,21 +49,20 @@ size_t PackAddressForNAT(char* buf, // Decodes the remote address from a packet that has been encoded with the nat's // quasi-STUN format. Returns the length of the address (i.e., the offset into // data where the original packet starts). -size_t UnpackAddressFromNAT(const char* buf, - size_t buf_size, +size_t UnpackAddressFromNAT(rtc::ArrayView<const uint8_t> buf, SocketAddress* remote_addr) { - RTC_DCHECK(buf_size >= 8); - RTC_DCHECK(buf[0] == 0); + RTC_CHECK(buf.size() >= 8); + RTC_DCHECK(buf.data()[0] == 0); int family = buf[1]; uint16_t port = - NetworkToHost16(*(reinterpret_cast<const uint16_t*>(&buf[2]))); + NetworkToHost16(*(reinterpret_cast<const uint16_t*>(&buf.data()[2]))); if (family == AF_INET) { - const in_addr* v4addr = reinterpret_cast<const in_addr*>(&buf[4]); + const in_addr* v4addr = reinterpret_cast<const in_addr*>(&buf.data()[4]); *remote_addr = SocketAddress(IPAddress(*v4addr), port); return kNATEncodedIPv4AddressSize; } else if (family == AF_INET6) { - RTC_DCHECK(buf_size >= 20); - const in6_addr* v6addr = reinterpret_cast<const in6_addr*>(&buf[4]); + RTC_DCHECK(buf.size() >= 20); + const in6_addr* v6addr = reinterpret_cast<const in6_addr*>(&buf.data()[4]); *remote_addr = SocketAddress(IPAddress(*v6addr), port); return kNATEncodedIPv6AddressSize; } @@ -76,14 +77,9 @@ class NATSocket : public Socket, public sigslot::has_slots<> { family_(family), type_(type), connected_(false), - socket_(nullptr), - buf_(nullptr), - size_(0) {} + socket_(nullptr) {} - ~NATSocket() override { - delete socket_; - delete[] buf_; - } + ~NATSocket() override { delete socket_; } SocketAddress GetLocalAddress() const override { return (socket_) ? socket_->GetLocalAddress() : SocketAddress(); @@ -165,23 +161,21 @@ class NATSocket : public Socket, public sigslot::has_slots<> { } // Make sure we have enough room to read the requested amount plus the // largest possible header address. - SocketAddress remote_addr; - Grow(size + kNATEncodedIPv6AddressSize); + buf_.EnsureCapacity(size + kNATEncodedIPv6AddressSize); // Read the packet from the socket. - int result = socket_->RecvFrom(buf_, size_, &remote_addr, timestamp); + Socket::ReceiveBuffer receive_buffer(buf_); + int result = socket_->RecvFrom(receive_buffer); if (result >= 0) { - RTC_DCHECK(remote_addr == server_addr_); - - // TODO: we need better framing so we know how many bytes we can - // return before we need to read the next address. For UDP, this will be - // fine as long as the reader always reads everything in the packet. - RTC_DCHECK((size_t)result < size_); + RTC_DCHECK(receive_buffer.source_address == server_addr_); + *timestamp = + receive_buffer.arrival_time.value_or(webrtc::Timestamp::Micros(0)) + .us(); // Decode the wire packet into the actual results. SocketAddress real_remote_addr; - size_t addrlength = UnpackAddressFromNAT(buf_, result, &real_remote_addr); - memcpy(data, buf_ + addrlength, result - addrlength); + size_t addrlength = UnpackAddressFromNAT(buf_, &real_remote_addr); + memcpy(data, buf_.data() + addrlength, result - addrlength); // Make sure this packet should be delivered before returning it. if (!connected_ || (real_remote_addr == remote_addr_)) { @@ -285,15 +279,6 @@ class NATSocket : public Socket, public sigslot::has_slots<> { return result; } - // Makes sure the buffer is at least the given size. - void Grow(size_t new_size) { - if (size_ < new_size) { - delete[] buf_; - size_ = new_size; - buf_ = new char[size_]; - } - } - // Sends the destination address to the server to tell it to connect. void SendConnectRequest() { char buf[kNATEncodedIPv6AddressSize]; @@ -323,8 +308,7 @@ class NATSocket : public Socket, public sigslot::has_slots<> { Socket* socket_; // Need to hold error in case it occurs before the socket is created. int error_ = 0; - char* buf_; - size_t size_; + Buffer buf_; }; // NATSocketFactory diff --git a/third_party/libwebrtc/rtc_base/nat_socket_factory.h b/third_party/libwebrtc/rtc_base/nat_socket_factory.h index f803496b05..5adcaa5dfd 100644 --- a/third_party/libwebrtc/rtc_base/nat_socket_factory.h +++ b/third_party/libwebrtc/rtc_base/nat_socket_factory.h @@ -13,10 +13,13 @@ #include <stddef.h> +#include <cstdint> #include <map> #include <memory> #include <set> +#include "api/array_view.h" +#include "rtc_base/buffer.h" #include "rtc_base/nat_server.h" #include "rtc_base/nat_types.h" #include "rtc_base/socket.h" @@ -172,8 +175,7 @@ class NATSocketServer : public SocketServer, public NATInternalSocketFactory { size_t PackAddressForNAT(char* buf, size_t buf_size, const SocketAddress& remote_addr); -size_t UnpackAddressFromNAT(const char* buf, - size_t buf_size, +size_t UnpackAddressFromNAT(rtc::ArrayView<const uint8_t> buf, SocketAddress* remote_addr); } // namespace rtc diff --git a/third_party/libwebrtc/rtc_base/nat_unittest.cc b/third_party/libwebrtc/rtc_base/nat_unittest.cc index 742e0d6ee7..978a30aefe 100644 --- a/third_party/libwebrtc/rtc_base/nat_unittest.cc +++ b/third_party/libwebrtc/rtc_base/nat_unittest.cc @@ -233,12 +233,12 @@ bool TestConnectivity(const SocketAddress& src, const IPAddress& dst) { const char* buf = "hello other socket"; size_t len = strlen(buf); int sent = client->SendTo(buf, len, server->GetLocalAddress()); - SocketAddress addr; - const size_t kRecvBufSize = 64; - char recvbuf[kRecvBufSize]; + Thread::Current()->SleepMs(100); - int received = server->RecvFrom(recvbuf, kRecvBufSize, &addr, nullptr); - return received == sent && ::memcmp(buf, recvbuf, len) == 0; + rtc::Buffer payload; + Socket::ReceiveBuffer receive_buffer(payload); + int received = server->RecvFrom(receive_buffer); + return received == sent && ::memcmp(buf, payload.data(), len) == 0; } void TestPhysicalInternal(const SocketAddress& int_addr) { diff --git a/third_party/libwebrtc/rtc_base/physical_socket_server.cc b/third_party/libwebrtc/rtc_base/physical_socket_server.cc index 95ba130e91..a5fe32722b 100644 --- a/third_party/libwebrtc/rtc_base/physical_socket_server.cc +++ b/third_party/libwebrtc/rtc_base/physical_socket_server.cc @@ -435,6 +435,31 @@ int PhysicalSocket::RecvFrom(void* buffer, SocketAddress* out_addr, int64_t* timestamp) { int received = DoReadFromSocket(buffer, length, out_addr, timestamp); + + UpdateLastError(); + int error = GetError(); + bool success = (received >= 0) || IsBlockingError(error); + if (udp_ || success) { + EnableEvents(DE_READ); + } + if (!success) { + RTC_LOG_F(LS_VERBOSE) << "Error = " << error; + } + return received; +} + +int PhysicalSocket::RecvFrom(ReceiveBuffer& buffer) { + int64_t timestamp = -1; + static constexpr int BUF_SIZE = 64 * 1024; + buffer.payload.EnsureCapacity(BUF_SIZE); + + int received = + DoReadFromSocket(buffer.payload.data(), buffer.payload.capacity(), + &buffer.source_address, ×tamp); + buffer.payload.SetSize(received > 0 ? received : 0); + if (received > 0 && timestamp != -1) { + buffer.arrival_time = webrtc::Timestamp::Micros(timestamp); + } UpdateLastError(); int error = GetError(); bool success = (received >= 0) || IsBlockingError(error); diff --git a/third_party/libwebrtc/rtc_base/physical_socket_server.h b/third_party/libwebrtc/rtc_base/physical_socket_server.h index 584f42a188..2af563a3ca 100644 --- a/third_party/libwebrtc/rtc_base/physical_socket_server.h +++ b/third_party/libwebrtc/rtc_base/physical_socket_server.h @@ -188,10 +188,12 @@ class PhysicalSocket : public Socket, public sigslot::has_slots<> { const SocketAddress& addr) override; int Recv(void* buffer, size_t length, int64_t* timestamp) override; + // TODO(webrtc:15368): Deprecate and remove. int RecvFrom(void* buffer, size_t length, SocketAddress* out_addr, int64_t* timestamp) override; + int RecvFrom(ReceiveBuffer& buffer) override; int Listen(int backlog) override; Socket* Accept(SocketAddress* out_addr) override; diff --git a/third_party/libwebrtc/rtc_base/proxy_server.cc b/third_party/libwebrtc/rtc_base/proxy_server.cc index 84c96213c3..f8fe23da2a 100644 --- a/third_party/libwebrtc/rtc_base/proxy_server.cc +++ b/third_party/libwebrtc/rtc_base/proxy_server.cc @@ -149,8 +149,4 @@ void ProxyBinding::Destroy() { SignalDestroyed(this); } -AsyncProxyServerSocket* SocksProxyServer::WrapSocket(Socket* socket) { - return new AsyncSocksProxyServerSocket(socket); -} - } // namespace rtc diff --git a/third_party/libwebrtc/rtc_base/proxy_server.h b/third_party/libwebrtc/rtc_base/proxy_server.h index 0b9b655a5e..033dd82118 100644 --- a/third_party/libwebrtc/rtc_base/proxy_server.h +++ b/third_party/libwebrtc/rtc_base/proxy_server.h @@ -89,22 +89,6 @@ class ProxyServer : public sigslot::has_slots<> { std::vector<std::unique_ptr<ProxyBinding>> bindings_; }; -// SocksProxyServer is a simple extension of ProxyServer to implement SOCKS. -class SocksProxyServer : public ProxyServer { - public: - SocksProxyServer(SocketFactory* int_factory, - const SocketAddress& int_addr, - SocketFactory* ext_factory, - const SocketAddress& ext_ip) - : ProxyServer(int_factory, int_addr, ext_factory, ext_ip) {} - - SocksProxyServer(const SocksProxyServer&) = delete; - SocksProxyServer& operator=(const SocksProxyServer&) = delete; - - protected: - AsyncProxyServerSocket* WrapSocket(Socket* socket) override; -}; - } // namespace rtc #endif // RTC_BASE_PROXY_SERVER_H_ diff --git a/third_party/libwebrtc/rtc_base/proxy_unittest.cc b/third_party/libwebrtc/rtc_base/proxy_unittest.cc deleted file mode 100644 index 9e3898e430..0000000000 --- a/third_party/libwebrtc/rtc_base/proxy_unittest.cc +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2009 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include <memory> -#include <string> - -#include "rtc_base/gunit.h" -#include "rtc_base/proxy_server.h" -#include "rtc_base/socket_adapters.h" -#include "rtc_base/test_client.h" -#include "rtc_base/test_echo_server.h" -#include "rtc_base/virtual_socket_server.h" - -using rtc::Socket; -using rtc::SocketAddress; - -static const SocketAddress kSocksProxyIntAddr("1.2.3.4", 1080); -static const SocketAddress kSocksProxyExtAddr("1.2.3.5", 0); -static const SocketAddress kBogusProxyIntAddr("1.2.3.4", 999); - -// Sets up a virtual socket server and a SOCKS5 proxy server. -class ProxyTest : public ::testing::Test { - public: - ProxyTest() : ss_(new rtc::VirtualSocketServer()), thread_(ss_.get()) { - socks_.reset(new rtc::SocksProxyServer(ss_.get(), kSocksProxyIntAddr, - ss_.get(), kSocksProxyExtAddr)); - } - - rtc::SocketServer* ss() { return ss_.get(); } - - private: - std::unique_ptr<rtc::SocketServer> ss_; - rtc::AutoSocketServerThread thread_; - std::unique_ptr<rtc::SocksProxyServer> socks_; -}; - -// Tests whether we can use a SOCKS5 proxy to connect to a server. -TEST_F(ProxyTest, TestSocks5Connect) { - rtc::Socket* socket = - ss()->CreateSocket(kSocksProxyIntAddr.family(), SOCK_STREAM); - rtc::AsyncSocksProxySocket* proxy_socket = new rtc::AsyncSocksProxySocket( - socket, kSocksProxyIntAddr, "", rtc::CryptString()); - // TODO: IPv6-ize these tests when proxy supports IPv6. - - rtc::TestEchoServer server(rtc::Thread::Current(), - SocketAddress(INADDR_ANY, 0)); - - std::unique_ptr<rtc::AsyncTCPSocket> packet_socket( - rtc::AsyncTCPSocket::Create(proxy_socket, SocketAddress(INADDR_ANY, 0), - server.address())); - EXPECT_TRUE(packet_socket != nullptr); - rtc::TestClient client(std::move(packet_socket)); - - EXPECT_EQ(Socket::CS_CONNECTING, proxy_socket->GetState()); - EXPECT_TRUE(client.CheckConnected()); - EXPECT_EQ(Socket::CS_CONNECTED, proxy_socket->GetState()); - EXPECT_EQ(server.address(), client.remote_address()); - client.Send("foo", 3); - EXPECT_TRUE(client.CheckNextPacket("foo", 3, nullptr)); - EXPECT_TRUE(client.CheckNoPacket()); -} diff --git a/third_party/libwebrtc/rtc_base/server_socket_adapters.cc b/third_party/libwebrtc/rtc_base/server_socket_adapters.cc index 0bef752f1e..5a4db26dd2 100644 --- a/third_party/libwebrtc/rtc_base/server_socket_adapters.cc +++ b/third_party/libwebrtc/rtc_base/server_socket_adapters.cc @@ -55,135 +55,4 @@ void AsyncSSLServerSocket::ProcessInput(char* data, size_t* len) { BufferInput(false); } -AsyncSocksProxyServerSocket::AsyncSocksProxyServerSocket(Socket* socket) - : AsyncProxyServerSocket(socket, kBufferSize), state_(SS_HELLO) { - BufferInput(true); -} - -void AsyncSocksProxyServerSocket::ProcessInput(char* data, size_t* len) { - RTC_DCHECK(state_ < SS_CONNECT_PENDING); - - ByteBufferReader response( - rtc::MakeArrayView(reinterpret_cast<const uint8_t*>(data), *len)); - if (state_ == SS_HELLO) { - HandleHello(&response); - } else if (state_ == SS_AUTH) { - HandleAuth(&response); - } else if (state_ == SS_CONNECT) { - HandleConnect(&response); - } - - // Consume parsed data - *len = response.Length(); - if (response.Length() > 0) { - memmove(data, response.DataView().data(), *len); - } -} - -void AsyncSocksProxyServerSocket::DirectSend(const ByteBufferWriter& buf) { - BufferedReadAdapter::DirectSend(buf.Data(), buf.Length()); -} - -void AsyncSocksProxyServerSocket::HandleHello(ByteBufferReader* request) { - uint8_t ver, num_methods; - if (!request->ReadUInt8(&ver) || !request->ReadUInt8(&num_methods)) { - Error(0); - return; - } - - if (ver != 5) { - Error(0); - return; - } - - // Handle either no-auth (0) or user/pass auth (2) - uint8_t method = 0xFF; - if (num_methods > 0 && !request->ReadUInt8(&method)) { - Error(0); - return; - } - - SendHelloReply(method); - if (method == 0) { - state_ = SS_CONNECT; - } else if (method == 2) { - state_ = SS_AUTH; - } else { - state_ = SS_ERROR; - } -} - -void AsyncSocksProxyServerSocket::SendHelloReply(uint8_t method) { - ByteBufferWriter response; - response.WriteUInt8(5); // Socks Version - response.WriteUInt8(method); // Auth method - DirectSend(response); -} - -void AsyncSocksProxyServerSocket::HandleAuth(ByteBufferReader* request) { - uint8_t ver, user_len, pass_len; - std::string user, pass; - if (!request->ReadUInt8(&ver) || !request->ReadUInt8(&user_len) || - !request->ReadString(&user, user_len) || !request->ReadUInt8(&pass_len) || - !request->ReadString(&pass, pass_len)) { - Error(0); - return; - } - - SendAuthReply(0); - state_ = SS_CONNECT; -} - -void AsyncSocksProxyServerSocket::SendAuthReply(uint8_t result) { - ByteBufferWriter response; - response.WriteUInt8(1); // Negotiation Version - response.WriteUInt8(result); - DirectSend(response); -} - -void AsyncSocksProxyServerSocket::HandleConnect(ByteBufferReader* request) { - uint8_t ver, command, reserved, addr_type; - uint32_t ip; - uint16_t port; - if (!request->ReadUInt8(&ver) || !request->ReadUInt8(&command) || - !request->ReadUInt8(&reserved) || !request->ReadUInt8(&addr_type) || - !request->ReadUInt32(&ip) || !request->ReadUInt16(&port)) { - Error(0); - return; - } - - if (ver != 5 || command != 1 || reserved != 0 || addr_type != 1) { - Error(0); - return; - } - - SignalConnectRequest(this, SocketAddress(ip, port)); - state_ = SS_CONNECT_PENDING; -} - -void AsyncSocksProxyServerSocket::SendConnectResult(int result, - const SocketAddress& addr) { - if (state_ != SS_CONNECT_PENDING) - return; - - ByteBufferWriter response; - response.WriteUInt8(5); // Socks version - response.WriteUInt8((result != 0)); // 0x01 is generic error - response.WriteUInt8(0); // reserved - response.WriteUInt8(1); // IPv4 address - response.WriteUInt32(addr.ip()); - response.WriteUInt16(addr.port()); - DirectSend(response); - BufferInput(false); - state_ = SS_TUNNEL; -} - -void AsyncSocksProxyServerSocket::Error(int error) { - state_ = SS_ERROR; - BufferInput(false); - Close(); - SetError(SOCKET_EACCES); - SignalCloseEvent(this, error); -} - } // namespace rtc diff --git a/third_party/libwebrtc/rtc_base/server_socket_adapters.h b/third_party/libwebrtc/rtc_base/server_socket_adapters.h index b18c7a6a65..05dcd292f8 100644 --- a/third_party/libwebrtc/rtc_base/server_socket_adapters.h +++ b/third_party/libwebrtc/rtc_base/server_socket_adapters.h @@ -38,40 +38,6 @@ class AsyncSSLServerSocket : public BufferedReadAdapter { void ProcessInput(char* data, size_t* len) override; }; -// Implements a proxy server socket for the SOCKS protocol. -class AsyncSocksProxyServerSocket : public AsyncProxyServerSocket { - public: - explicit AsyncSocksProxyServerSocket(Socket* socket); - - AsyncSocksProxyServerSocket(const AsyncSocksProxyServerSocket&) = delete; - AsyncSocksProxyServerSocket& operator=(const AsyncSocksProxyServerSocket&) = - delete; - - private: - void ProcessInput(char* data, size_t* len) override; - void DirectSend(const ByteBufferWriter& buf); - - void HandleHello(ByteBufferReader* request); - void SendHelloReply(uint8_t method); - void HandleAuth(ByteBufferReader* request); - void SendAuthReply(uint8_t result); - void HandleConnect(ByteBufferReader* request); - void SendConnectResult(int result, const SocketAddress& addr) override; - - void Error(int error); - - static const int kBufferSize = 1024; - enum State { - SS_HELLO, - SS_AUTH, - SS_CONNECT, - SS_CONNECT_PENDING, - SS_TUNNEL, - SS_ERROR - }; - State state_; -}; - } // namespace rtc #endif // RTC_BASE_SERVER_SOCKET_ADAPTERS_H_ diff --git a/third_party/libwebrtc/rtc_base/socket.h b/third_party/libwebrtc/rtc_base/socket.h index fac75aca94..98e468e754 100644 --- a/third_party/libwebrtc/rtc_base/socket.h +++ b/third_party/libwebrtc/rtc_base/socket.h @@ -14,6 +14,7 @@ #include <errno.h> #include "absl/types/optional.h" +#include "rtc_base/checks.h" #if defined(WEBRTC_POSIX) #include <arpa/inet.h> @@ -86,11 +87,11 @@ inline bool IsBlockingError(int e) { class RTC_EXPORT Socket { public: struct ReceiveBuffer { - ReceiveBuffer(rtc::Buffer& payload) : payload(payload) {} + ReceiveBuffer(Buffer& payload) : payload(payload) {} absl::optional<webrtc::Timestamp> arrival_time; SocketAddress source_address; - rtc::Buffer& payload; + Buffer& payload; }; virtual ~Socket() {} @@ -111,10 +112,14 @@ class RTC_EXPORT Socket { virtual int SendTo(const void* pv, size_t cb, const SocketAddress& addr) = 0; // `timestamp` is in units of microseconds. virtual int Recv(void* pv, size_t cb, int64_t* timestamp) = 0; + // TODO(webrtc:15368): Deprecate and remove. virtual int RecvFrom(void* pv, size_t cb, SocketAddress* paddr, - int64_t* timestamp) = 0; + int64_t* timestamp) { + // Not implemented. Use RecvFrom(ReceiveBuffer& buffer). + RTC_CHECK_NOTREACHED(); + } // Intended to replace RecvFrom(void* ...). // Default implementation calls RecvFrom(void* ...) with 64Kbyte buffer. // Returns number of bytes received or a negative value on error. diff --git a/third_party/libwebrtc/rtc_base/socket_adapters.cc b/third_party/libwebrtc/rtc_base/socket_adapters.cc index a1eee5bd67..f6fa182f5d 100644 --- a/third_party/libwebrtc/rtc_base/socket_adapters.cc +++ b/third_party/libwebrtc/rtc_base/socket_adapters.cc @@ -469,198 +469,4 @@ void AsyncHttpsProxySocket::Error(int error) { SignalCloseEvent(this, error); } -/////////////////////////////////////////////////////////////////////////////// - -AsyncSocksProxySocket::AsyncSocksProxySocket(Socket* socket, - const SocketAddress& proxy, - absl::string_view username, - const CryptString& password) - : BufferedReadAdapter(socket, 1024), - state_(SS_ERROR), - proxy_(proxy), - user_(username), - pass_(password) {} - -AsyncSocksProxySocket::~AsyncSocksProxySocket() = default; - -int AsyncSocksProxySocket::Connect(const SocketAddress& addr) { - int ret; - dest_ = addr; - state_ = SS_INIT; - BufferInput(true); - ret = BufferedReadAdapter::Connect(proxy_); - // TODO: Set state_ appropriately if Connect fails. - return ret; -} - -SocketAddress AsyncSocksProxySocket::GetRemoteAddress() const { - return dest_; -} - -int AsyncSocksProxySocket::Close() { - state_ = SS_ERROR; - dest_.Clear(); - return BufferedReadAdapter::Close(); -} - -Socket::ConnState AsyncSocksProxySocket::GetState() const { - if (state_ < SS_TUNNEL) { - return CS_CONNECTING; - } else if (state_ == SS_TUNNEL) { - return CS_CONNECTED; - } else { - return CS_CLOSED; - } -} - -void AsyncSocksProxySocket::OnConnectEvent(Socket* socket) { - SendHello(); -} - -void AsyncSocksProxySocket::ProcessInput(char* data, size_t* len) { - RTC_DCHECK(state_ < SS_TUNNEL); - - ByteBufferReader response( - rtc::MakeArrayView(reinterpret_cast<uint8_t*>(data), *len)); - - if (state_ == SS_HELLO) { - uint8_t ver, method; - if (!response.ReadUInt8(&ver) || !response.ReadUInt8(&method)) - return; - - if (ver != 5) { - Error(0); - return; - } - - if (method == 0) { - SendConnect(); - } else if (method == 2) { - SendAuth(); - } else { - Error(0); - return; - } - } else if (state_ == SS_AUTH) { - uint8_t ver, status; - if (!response.ReadUInt8(&ver) || !response.ReadUInt8(&status)) - return; - - if ((ver != 1) || (status != 0)) { - Error(SOCKET_EACCES); - return; - } - - SendConnect(); - } else if (state_ == SS_CONNECT) { - uint8_t ver, rep, rsv, atyp; - if (!response.ReadUInt8(&ver) || !response.ReadUInt8(&rep) || - !response.ReadUInt8(&rsv) || !response.ReadUInt8(&atyp)) - return; - - if ((ver != 5) || (rep != 0)) { - Error(0); - return; - } - - uint16_t port; - if (atyp == 1) { - uint32_t addr; - if (!response.ReadUInt32(&addr) || !response.ReadUInt16(&port)) - return; - RTC_LOG(LS_VERBOSE) << "Bound on " << addr << ":" << port; - } else if (atyp == 3) { - uint8_t length; - std::string addr; - if (!response.ReadUInt8(&length) || !response.ReadString(&addr, length) || - !response.ReadUInt16(&port)) - return; - RTC_LOG(LS_VERBOSE) << "Bound on " << addr << ":" << port; - } else if (atyp == 4) { - std::string addr; - if (!response.ReadString(&addr, 16) || !response.ReadUInt16(&port)) - return; - RTC_LOG(LS_VERBOSE) << "Bound on <IPV6>:" << port; - } else { - Error(0); - return; - } - - state_ = SS_TUNNEL; - } - - // Consume parsed data - *len = response.Length(); - memmove(data, response.Data(), *len); - - if (state_ != SS_TUNNEL) - return; - - bool remainder = (*len > 0); - BufferInput(false); - SignalConnectEvent(this); - - // FIX: if SignalConnect causes the socket to be destroyed, we are in trouble - if (remainder) - SignalReadEvent(this); // TODO: signal this?? -} - -void AsyncSocksProxySocket::SendHello() { - ByteBufferWriter request; - request.WriteUInt8(5); // Socks Version - if (user_.empty()) { - request.WriteUInt8(1); // Authentication Mechanisms - request.WriteUInt8(0); // No authentication - } else { - request.WriteUInt8(2); // Authentication Mechanisms - request.WriteUInt8(0); // No authentication - request.WriteUInt8(2); // Username/Password - } - DirectSend(request.Data(), request.Length()); - state_ = SS_HELLO; -} - -void AsyncSocksProxySocket::SendAuth() { - ByteBufferWriterT<ZeroOnFreeBuffer<char>> request; - request.WriteUInt8(1); // Negotiation Version - request.WriteUInt8(static_cast<uint8_t>(user_.size())); - request.WriteString(user_); // Username - request.WriteUInt8(static_cast<uint8_t>(pass_.GetLength())); - size_t len = pass_.GetLength() + 1; - char* sensitive = new char[len]; - pass_.CopyTo(sensitive, true); - request.WriteString(std::string(sensitive, pass_.GetLength())); // Password - ExplicitZeroMemory(sensitive, len); - delete[] sensitive; - DirectSend(request.Data(), request.Length()); - state_ = SS_AUTH; -} - -void AsyncSocksProxySocket::SendConnect() { - ByteBufferWriter request; - request.WriteUInt8(5); // Socks Version - request.WriteUInt8(1); // CONNECT - request.WriteUInt8(0); // Reserved - if (dest_.IsUnresolvedIP()) { - std::string hostname = dest_.hostname(); - request.WriteUInt8(3); // DOMAINNAME - request.WriteUInt8(static_cast<uint8_t>(hostname.size())); - request.WriteString(hostname); // Destination Hostname - } else { - request.WriteUInt8(1); // IPV4 - request.WriteUInt32(dest_.ip()); // Destination IP - } - request.WriteUInt16(dest_.port()); // Destination Port - DirectSend(request.Data(), request.Length()); - state_ = SS_CONNECT; -} - -void AsyncSocksProxySocket::Error(int error) { - state_ = SS_ERROR; - BufferInput(false); - Close(); - SetError(SOCKET_EACCES); - SignalCloseEvent(this, error); -} - } // namespace rtc diff --git a/third_party/libwebrtc/rtc_base/socket_adapters.h b/third_party/libwebrtc/rtc_base/socket_adapters.h index e78ee18a27..e67c8d4db9 100644 --- a/third_party/libwebrtc/rtc_base/socket_adapters.h +++ b/third_party/libwebrtc/rtc_base/socket_adapters.h @@ -137,42 +137,6 @@ class AsyncHttpsProxySocket : public BufferedReadAdapter { std::string unknown_mechanisms_; }; -/////////////////////////////////////////////////////////////////////////////// - -// Implements a socket adapter that speaks the SOCKS proxy protocol. -class AsyncSocksProxySocket : public BufferedReadAdapter { - public: - AsyncSocksProxySocket(Socket* socket, - const SocketAddress& proxy, - absl::string_view username, - const CryptString& password); - ~AsyncSocksProxySocket() override; - - AsyncSocksProxySocket(const AsyncSocksProxySocket&) = delete; - AsyncSocksProxySocket& operator=(const AsyncSocksProxySocket&) = delete; - - int Connect(const SocketAddress& addr) override; - SocketAddress GetRemoteAddress() const override; - int Close() override; - ConnState GetState() const override; - - protected: - void OnConnectEvent(Socket* socket) override; - void ProcessInput(char* data, size_t* len) override; - - void SendHello(); - void SendConnect(); - void SendAuth(); - void Error(int error); - - private: - enum State { SS_INIT, SS_HELLO, SS_AUTH, SS_CONNECT, SS_TUNNEL, SS_ERROR }; - State state_; - SocketAddress proxy_, dest_; - std::string user_; - CryptString pass_; -}; - } // namespace rtc #endif // RTC_BASE_SOCKET_ADAPTERS_H_ diff --git a/third_party/libwebrtc/rtc_base/socket_unittest.cc b/third_party/libwebrtc/rtc_base/socket_unittest.cc index f5ef2a33fc..5314128d0a 100644 --- a/third_party/libwebrtc/rtc_base/socket_unittest.cc +++ b/third_party/libwebrtc/rtc_base/socket_unittest.cc @@ -20,6 +20,7 @@ #include "absl/memory/memory.h" #include "absl/strings/string_view.h" +#include "api/units/timestamp.h" #include "rtc_base/arraysize.h" #include "rtc_base/async_packet_socket.h" #include "rtc_base/async_udp_socket.h" @@ -1092,11 +1093,11 @@ void SocketTest::SocketRecvTimestamp(const IPAddress& loopback) { int64_t send_time_1 = TimeMicros(); socket->SendTo("foo", 3, address); - int64_t recv_timestamp_1; // Wait until data is available. EXPECT_TRUE_WAIT(sink.Check(socket.get(), SSE_READ), kTimeout); - char buffer[3]; - ASSERT_GT(socket->RecvFrom(buffer, 3, nullptr, &recv_timestamp_1), 0); + rtc::Buffer buffer; + Socket::ReceiveBuffer receive_buffer_1(buffer); + ASSERT_GT(socket->RecvFrom(receive_buffer_1), 0); const int64_t kTimeBetweenPacketsMs = 100; Thread::SleepMs(kTimeBetweenPacketsMs); @@ -1105,11 +1106,12 @@ void SocketTest::SocketRecvTimestamp(const IPAddress& loopback) { socket->SendTo("bar", 3, address); // Wait until data is available. EXPECT_TRUE_WAIT(sink.Check(socket.get(), SSE_READ), kTimeout); - int64_t recv_timestamp_2; - ASSERT_GT(socket->RecvFrom(buffer, 3, nullptr, &recv_timestamp_2), 0); + Socket::ReceiveBuffer receive_buffer_2(buffer); + ASSERT_GT(socket->RecvFrom(receive_buffer_2), 0); int64_t system_time_diff = send_time_2 - send_time_1; - int64_t recv_timestamp_diff = recv_timestamp_2 - recv_timestamp_1; + int64_t recv_timestamp_diff = + receive_buffer_2.arrival_time->us() - receive_buffer_1.arrival_time->us(); // Compare against the system time at the point of sending, because // SleepMs may not sleep for exactly the requested time. EXPECT_NEAR(system_time_diff, recv_timestamp_diff, 10000); diff --git a/third_party/libwebrtc/rtc_base/system/file_wrapper_unittest.cc b/third_party/libwebrtc/rtc_base/system/file_wrapper_unittest.cc index 980b565c73..b83c1df933 100644 --- a/third_party/libwebrtc/rtc_base/system/file_wrapper_unittest.cc +++ b/third_party/libwebrtc/rtc_base/system/file_wrapper_unittest.cc @@ -21,7 +21,8 @@ TEST(FileWrapper, FileSize) { std::string test_name = std::string(test_info->test_case_name()) + "_" + test_info->name(); std::replace(test_name.begin(), test_name.end(), '/', '_'); - const std::string temp_filename = test::OutputPath() + test_name; + const std::string temp_filename = + test::OutputPathWithRandomDirectory() + test_name; // Write { |