xref: /aosp_15_r20/external/webrtc/p2p/base/stun_server_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker 
11*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/stun_server.h"
12*d9f75844SAndroid Build Coastguard Worker 
13*d9f75844SAndroid Build Coastguard Worker #include <string.h>
14*d9f75844SAndroid Build Coastguard Worker 
15*d9f75844SAndroid Build Coastguard Worker #include <memory>
16*d9f75844SAndroid Build Coastguard Worker #include <string>
17*d9f75844SAndroid Build Coastguard Worker 
18*d9f75844SAndroid Build Coastguard Worker #include "absl/memory/memory.h"
19*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/byte_buffer.h"
20*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/ip_address.h"
21*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/logging.h"
22*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/test_client.h"
23*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/thread.h"
24*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/virtual_socket_server.h"
25*d9f75844SAndroid Build Coastguard Worker #include "test/gtest.h"
26*d9f75844SAndroid Build Coastguard Worker 
27*d9f75844SAndroid Build Coastguard Worker namespace cricket {
28*d9f75844SAndroid Build Coastguard Worker 
29*d9f75844SAndroid Build Coastguard Worker namespace {
30*d9f75844SAndroid Build Coastguard Worker const rtc::SocketAddress server_addr("99.99.99.1", 3478);
31*d9f75844SAndroid Build Coastguard Worker const rtc::SocketAddress client_addr("1.2.3.4", 1234);
32*d9f75844SAndroid Build Coastguard Worker }  // namespace
33*d9f75844SAndroid Build Coastguard Worker 
34*d9f75844SAndroid Build Coastguard Worker class StunServerTest : public ::testing::Test {
35*d9f75844SAndroid Build Coastguard Worker  public:
StunServerTest()36*d9f75844SAndroid Build Coastguard Worker   StunServerTest() : ss_(new rtc::VirtualSocketServer()), network_(ss_.get()) {
37*d9f75844SAndroid Build Coastguard Worker     server_.reset(
38*d9f75844SAndroid Build Coastguard Worker         new StunServer(rtc::AsyncUDPSocket::Create(ss_.get(), server_addr)));
39*d9f75844SAndroid Build Coastguard Worker     client_.reset(new rtc::TestClient(
40*d9f75844SAndroid Build Coastguard Worker         absl::WrapUnique(rtc::AsyncUDPSocket::Create(ss_.get(), client_addr))));
41*d9f75844SAndroid Build Coastguard Worker 
42*d9f75844SAndroid Build Coastguard Worker     network_.Start();
43*d9f75844SAndroid Build Coastguard Worker   }
~StunServerTest()44*d9f75844SAndroid Build Coastguard Worker   ~StunServerTest() override { network_.Stop(); }
45*d9f75844SAndroid Build Coastguard Worker 
Send(const StunMessage & msg)46*d9f75844SAndroid Build Coastguard Worker   void Send(const StunMessage& msg) {
47*d9f75844SAndroid Build Coastguard Worker     rtc::ByteBufferWriter buf;
48*d9f75844SAndroid Build Coastguard Worker     msg.Write(&buf);
49*d9f75844SAndroid Build Coastguard Worker     Send(buf.Data(), static_cast<int>(buf.Length()));
50*d9f75844SAndroid Build Coastguard Worker   }
Send(const char * buf,int len)51*d9f75844SAndroid Build Coastguard Worker   void Send(const char* buf, int len) {
52*d9f75844SAndroid Build Coastguard Worker     client_->SendTo(buf, len, server_addr);
53*d9f75844SAndroid Build Coastguard Worker   }
ReceiveFails()54*d9f75844SAndroid Build Coastguard Worker   bool ReceiveFails() { return (client_->CheckNoPacket()); }
Receive()55*d9f75844SAndroid Build Coastguard Worker   StunMessage* Receive() {
56*d9f75844SAndroid Build Coastguard Worker     StunMessage* msg = NULL;
57*d9f75844SAndroid Build Coastguard Worker     std::unique_ptr<rtc::TestClient::Packet> packet =
58*d9f75844SAndroid Build Coastguard Worker         client_->NextPacket(rtc::TestClient::kTimeoutMs);
59*d9f75844SAndroid Build Coastguard Worker     if (packet) {
60*d9f75844SAndroid Build Coastguard Worker       rtc::ByteBufferReader buf(packet->buf, packet->size);
61*d9f75844SAndroid Build Coastguard Worker       msg = new StunMessage();
62*d9f75844SAndroid Build Coastguard Worker       msg->Read(&buf);
63*d9f75844SAndroid Build Coastguard Worker     }
64*d9f75844SAndroid Build Coastguard Worker     return msg;
65*d9f75844SAndroid Build Coastguard Worker   }
66*d9f75844SAndroid Build Coastguard Worker 
67*d9f75844SAndroid Build Coastguard Worker  private:
68*d9f75844SAndroid Build Coastguard Worker   rtc::AutoThread main_thread;
69*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<rtc::VirtualSocketServer> ss_;
70*d9f75844SAndroid Build Coastguard Worker   rtc::Thread network_;
71*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<StunServer> server_;
72*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<rtc::TestClient> client_;
73*d9f75844SAndroid Build Coastguard Worker };
74*d9f75844SAndroid Build Coastguard Worker 
TEST_F(StunServerTest,TestGood)75*d9f75844SAndroid Build Coastguard Worker TEST_F(StunServerTest, TestGood) {
76*d9f75844SAndroid Build Coastguard Worker   // kStunLegacyTransactionIdLength = 16 for legacy RFC 3489 request
77*d9f75844SAndroid Build Coastguard Worker   std::string transaction_id = "0123456789abcdef";
78*d9f75844SAndroid Build Coastguard Worker   StunMessage req(STUN_BINDING_REQUEST, transaction_id);
79*d9f75844SAndroid Build Coastguard Worker   Send(req);
80*d9f75844SAndroid Build Coastguard Worker 
81*d9f75844SAndroid Build Coastguard Worker   StunMessage* msg = Receive();
82*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(msg != NULL);
83*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(STUN_BINDING_RESPONSE, msg->type());
84*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(req.transaction_id(), msg->transaction_id());
85*d9f75844SAndroid Build Coastguard Worker 
86*d9f75844SAndroid Build Coastguard Worker   const StunAddressAttribute* mapped_addr =
87*d9f75844SAndroid Build Coastguard Worker       msg->GetAddress(STUN_ATTR_MAPPED_ADDRESS);
88*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(mapped_addr != NULL);
89*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1, mapped_addr->family());
90*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(client_addr.port(), mapped_addr->port());
91*d9f75844SAndroid Build Coastguard Worker 
92*d9f75844SAndroid Build Coastguard Worker   delete msg;
93*d9f75844SAndroid Build Coastguard Worker }
94*d9f75844SAndroid Build Coastguard Worker 
TEST_F(StunServerTest,TestGoodXorMappedAddr)95*d9f75844SAndroid Build Coastguard Worker TEST_F(StunServerTest, TestGoodXorMappedAddr) {
96*d9f75844SAndroid Build Coastguard Worker   // kStunTransactionIdLength = 12 for RFC 5389 request
97*d9f75844SAndroid Build Coastguard Worker   // StunMessage::Write will automatically insert magic cookie (0x2112A442)
98*d9f75844SAndroid Build Coastguard Worker   std::string transaction_id = "0123456789ab";
99*d9f75844SAndroid Build Coastguard Worker   StunMessage req(STUN_BINDING_REQUEST, transaction_id);
100*d9f75844SAndroid Build Coastguard Worker   Send(req);
101*d9f75844SAndroid Build Coastguard Worker 
102*d9f75844SAndroid Build Coastguard Worker   StunMessage* msg = Receive();
103*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(msg != NULL);
104*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(STUN_BINDING_RESPONSE, msg->type());
105*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(req.transaction_id(), msg->transaction_id());
106*d9f75844SAndroid Build Coastguard Worker 
107*d9f75844SAndroid Build Coastguard Worker   const StunAddressAttribute* mapped_addr =
108*d9f75844SAndroid Build Coastguard Worker       msg->GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
109*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(mapped_addr != NULL);
110*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1, mapped_addr->family());
111*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(client_addr.port(), mapped_addr->port());
112*d9f75844SAndroid Build Coastguard Worker 
113*d9f75844SAndroid Build Coastguard Worker   delete msg;
114*d9f75844SAndroid Build Coastguard Worker }
115*d9f75844SAndroid Build Coastguard Worker 
116*d9f75844SAndroid Build Coastguard Worker // Send legacy RFC 3489 request, should not get xor mapped addr
TEST_F(StunServerTest,TestNoXorMappedAddr)117*d9f75844SAndroid Build Coastguard Worker TEST_F(StunServerTest, TestNoXorMappedAddr) {
118*d9f75844SAndroid Build Coastguard Worker   // kStunLegacyTransactionIdLength = 16 for legacy RFC 3489 request
119*d9f75844SAndroid Build Coastguard Worker   std::string transaction_id = "0123456789abcdef";
120*d9f75844SAndroid Build Coastguard Worker   StunMessage req(STUN_BINDING_REQUEST, transaction_id);
121*d9f75844SAndroid Build Coastguard Worker   Send(req);
122*d9f75844SAndroid Build Coastguard Worker 
123*d9f75844SAndroid Build Coastguard Worker   StunMessage* msg = Receive();
124*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(msg != NULL);
125*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(STUN_BINDING_RESPONSE, msg->type());
126*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(req.transaction_id(), msg->transaction_id());
127*d9f75844SAndroid Build Coastguard Worker 
128*d9f75844SAndroid Build Coastguard Worker   const StunAddressAttribute* mapped_addr =
129*d9f75844SAndroid Build Coastguard Worker       msg->GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
130*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(mapped_addr == NULL);
131*d9f75844SAndroid Build Coastguard Worker 
132*d9f75844SAndroid Build Coastguard Worker   delete msg;
133*d9f75844SAndroid Build Coastguard Worker }
134*d9f75844SAndroid Build Coastguard Worker 
TEST_F(StunServerTest,TestBad)135*d9f75844SAndroid Build Coastguard Worker TEST_F(StunServerTest, TestBad) {
136*d9f75844SAndroid Build Coastguard Worker   const char* bad =
137*d9f75844SAndroid Build Coastguard Worker       "this is a completely nonsensical message whose only "
138*d9f75844SAndroid Build Coastguard Worker       "purpose is to make the parser go 'ack'.  it doesn't "
139*d9f75844SAndroid Build Coastguard Worker       "look anything like a normal stun message";
140*d9f75844SAndroid Build Coastguard Worker   Send(bad, static_cast<int>(strlen(bad)));
141*d9f75844SAndroid Build Coastguard Worker 
142*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(ReceiveFails());
143*d9f75844SAndroid Build Coastguard Worker }
144*d9f75844SAndroid Build Coastguard Worker 
145*d9f75844SAndroid Build Coastguard Worker }  // namespace cricket
146