summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/p2p/base/stun_server_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/p2p/base/stun_server_unittest.cc')
-rw-r--r--third_party/libwebrtc/p2p/base/stun_server_unittest.cc145
1 files changed, 145 insertions, 0 deletions
diff --git a/third_party/libwebrtc/p2p/base/stun_server_unittest.cc b/third_party/libwebrtc/p2p/base/stun_server_unittest.cc
new file mode 100644
index 0000000000..5d3f31fb98
--- /dev/null
+++ b/third_party/libwebrtc/p2p/base/stun_server_unittest.cc
@@ -0,0 +1,145 @@
+/*
+ * 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 <string.h>
+
+#include <memory>
+#include <string>
+
+#include "absl/memory/memory.h"
+#include "rtc_base/byte_buffer.h"
+#include "rtc_base/ip_address.h"
+#include "rtc_base/logging.h"
+#include "rtc_base/test_client.h"
+#include "rtc_base/thread.h"
+#include "rtc_base/virtual_socket_server.h"
+#include "test/gtest.h"
+
+namespace cricket {
+
+namespace {
+const rtc::SocketAddress server_addr("99.99.99.1", 3478);
+const rtc::SocketAddress client_addr("1.2.3.4", 1234);
+} // namespace
+
+class StunServerTest : public ::testing::Test {
+ public:
+ StunServerTest() : ss_(new rtc::VirtualSocketServer()), network_(ss_.get()) {
+ server_.reset(
+ new StunServer(rtc::AsyncUDPSocket::Create(ss_.get(), server_addr)));
+ client_.reset(new rtc::TestClient(
+ absl::WrapUnique(rtc::AsyncUDPSocket::Create(ss_.get(), client_addr))));
+
+ network_.Start();
+ }
+ ~StunServerTest() override { network_.Stop(); }
+
+ void Send(const StunMessage& msg) {
+ rtc::ByteBufferWriter buf;
+ msg.Write(&buf);
+ Send(buf.Data(), static_cast<int>(buf.Length()));
+ }
+ void Send(const char* buf, int len) {
+ client_->SendTo(buf, len, server_addr);
+ }
+ bool ReceiveFails() { return (client_->CheckNoPacket()); }
+ StunMessage* Receive() {
+ StunMessage* msg = NULL;
+ std::unique_ptr<rtc::TestClient::Packet> packet =
+ client_->NextPacket(rtc::TestClient::kTimeoutMs);
+ if (packet) {
+ rtc::ByteBufferReader buf(packet->buf, packet->size);
+ msg = new StunMessage();
+ msg->Read(&buf);
+ }
+ return msg;
+ }
+
+ private:
+ rtc::AutoThread main_thread;
+ std::unique_ptr<rtc::VirtualSocketServer> ss_;
+ rtc::Thread network_;
+ std::unique_ptr<StunServer> server_;
+ std::unique_ptr<rtc::TestClient> client_;
+};
+
+TEST_F(StunServerTest, TestGood) {
+ // kStunLegacyTransactionIdLength = 16 for legacy RFC 3489 request
+ std::string transaction_id = "0123456789abcdef";
+ StunMessage req(STUN_BINDING_REQUEST, transaction_id);
+ Send(req);
+
+ StunMessage* msg = Receive();
+ ASSERT_TRUE(msg != NULL);
+ EXPECT_EQ(STUN_BINDING_RESPONSE, msg->type());
+ EXPECT_EQ(req.transaction_id(), msg->transaction_id());
+
+ const StunAddressAttribute* mapped_addr =
+ msg->GetAddress(STUN_ATTR_MAPPED_ADDRESS);
+ EXPECT_TRUE(mapped_addr != NULL);
+ EXPECT_EQ(1, mapped_addr->family());
+ EXPECT_EQ(client_addr.port(), mapped_addr->port());
+
+ delete msg;
+}
+
+TEST_F(StunServerTest, TestGoodXorMappedAddr) {
+ // kStunTransactionIdLength = 12 for RFC 5389 request
+ // StunMessage::Write will automatically insert magic cookie (0x2112A442)
+ std::string transaction_id = "0123456789ab";
+ StunMessage req(STUN_BINDING_REQUEST, transaction_id);
+ Send(req);
+
+ StunMessage* msg = Receive();
+ ASSERT_TRUE(msg != NULL);
+ EXPECT_EQ(STUN_BINDING_RESPONSE, msg->type());
+ EXPECT_EQ(req.transaction_id(), msg->transaction_id());
+
+ const StunAddressAttribute* mapped_addr =
+ msg->GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
+ EXPECT_TRUE(mapped_addr != NULL);
+ EXPECT_EQ(1, mapped_addr->family());
+ EXPECT_EQ(client_addr.port(), mapped_addr->port());
+
+ delete msg;
+}
+
+// Send legacy RFC 3489 request, should not get xor mapped addr
+TEST_F(StunServerTest, TestNoXorMappedAddr) {
+ // kStunLegacyTransactionIdLength = 16 for legacy RFC 3489 request
+ std::string transaction_id = "0123456789abcdef";
+ StunMessage req(STUN_BINDING_REQUEST, transaction_id);
+ Send(req);
+
+ StunMessage* msg = Receive();
+ ASSERT_TRUE(msg != NULL);
+ EXPECT_EQ(STUN_BINDING_RESPONSE, msg->type());
+ EXPECT_EQ(req.transaction_id(), msg->transaction_id());
+
+ const StunAddressAttribute* mapped_addr =
+ msg->GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
+ EXPECT_TRUE(mapped_addr == NULL);
+
+ delete msg;
+}
+
+TEST_F(StunServerTest, TestBad) {
+ const char* bad =
+ "this is a completely nonsensical message whose only "
+ "purpose is to make the parser go 'ack'. it doesn't "
+ "look anything like a normal stun message";
+ Send(bad, static_cast<int>(strlen(bad)));
+
+ ASSERT_TRUE(ReceiveFails());
+}
+
+} // namespace cricket