From 36d22d82aa202bb199967e9512281e9a53db42c9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 21:33:14 +0200 Subject: Adding upstream version 115.7.0esr. Signed-off-by: Daniel Baumann --- third_party/libwebrtc/p2p/base/stun_server.cc | 104 ++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 third_party/libwebrtc/p2p/base/stun_server.cc (limited to 'third_party/libwebrtc/p2p/base/stun_server.cc') diff --git a/third_party/libwebrtc/p2p/base/stun_server.cc b/third_party/libwebrtc/p2p/base/stun_server.cc new file mode 100644 index 0000000000..7827a0bb81 --- /dev/null +++ b/third_party/libwebrtc/p2p/base/stun_server.cc @@ -0,0 +1,104 @@ +/* + * Copyright 2004 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 "p2p/base/stun_server.h" + +#include +#include + +#include "absl/strings/string_view.h" +#include "rtc_base/byte_buffer.h" +#include "rtc_base/logging.h" + +namespace cricket { + +StunServer::StunServer(rtc::AsyncUDPSocket* socket) : socket_(socket) { + socket_->SignalReadPacket.connect(this, &StunServer::OnPacket); +} + +StunServer::~StunServer() { + socket_->SignalReadPacket.disconnect(this); +} + +void StunServer::OnPacket(rtc::AsyncPacketSocket* socket, + const char* buf, + size_t size, + const rtc::SocketAddress& remote_addr, + const int64_t& /* packet_time_us */) { + // Parse the STUN message; eat any messages that fail to parse. + rtc::ByteBufferReader bbuf(buf, size); + StunMessage msg; + if (!msg.Read(&bbuf)) { + return; + } + + // 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); + break; + + default: + SendErrorResponse(msg, remote_addr, 600, "Operation Not Supported"); + } +} + +void StunServer::OnBindingRequest(StunMessage* msg, + const rtc::SocketAddress& remote_addr) { + StunMessage response(STUN_BINDING_RESPONSE, msg->transaction_id()); + GetStunBindResponse(msg, remote_addr, &response); + SendResponse(response, remote_addr); +} + +void StunServer::SendErrorResponse(const StunMessage& msg, + const rtc::SocketAddress& addr, + int error_code, + absl::string_view error_desc) { + StunMessage err_msg(GetStunErrorResponseType(msg.type()), + msg.transaction_id()); + + auto err_code = StunAttribute::CreateErrorCode(); + err_code->SetCode(error_code); + err_code->SetReason(std::string(error_desc)); + err_msg.AddAttribute(std::move(err_code)); + + SendResponse(err_msg, addr); +} + +void StunServer::SendResponse(const StunMessage& msg, + const rtc::SocketAddress& addr) { + rtc::ByteBufferWriter buf; + msg.Write(&buf); + rtc::PacketOptions options; + if (socket_->SendTo(buf.Data(), buf.Length(), addr, options) < 0) + RTC_LOG_ERR(LS_ERROR) << "sendto"; +} + +void StunServer::GetStunBindResponse(StunMessage* message, + const rtc::SocketAddress& remote_addr, + StunMessage* response) const { + RTC_DCHECK_EQ(response->type(), STUN_BINDING_RESPONSE); + RTC_DCHECK_EQ(response->transaction_id(), message->transaction_id()); + + // Tell the user the address that we received their message from. + std::unique_ptr mapped_addr; + if (message->IsLegacy()) { + mapped_addr = StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS); + } else { + mapped_addr = StunAttribute::CreateXorAddress(STUN_ATTR_XOR_MAPPED_ADDRESS); + } + mapped_addr->SetAddress(remote_addr); + response->AddAttribute(std::move(mapped_addr)); +} + +} // namespace cricket -- cgit v1.2.3