xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/tools/quic_server_test.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "quiche/quic/tools/quic_server.h"
6 
7 #include <memory>
8 
9 #include "absl/base/macros.h"
10 #include "quiche/quic/core/crypto/quic_random.h"
11 #include "quiche/quic/core/deterministic_connection_id_generator.h"
12 #include "quiche/quic/core/io/quic_default_event_loop.h"
13 #include "quiche/quic/core/io/quic_event_loop.h"
14 #include "quiche/quic/core/quic_default_clock.h"
15 #include "quiche/quic/core/quic_default_connection_helper.h"
16 #include "quiche/quic/core/quic_default_packet_writer.h"
17 #include "quiche/quic/core/quic_utils.h"
18 #include "quiche/quic/platform/api/quic_flags.h"
19 #include "quiche/quic/platform/api/quic_logging.h"
20 #include "quiche/quic/platform/api/quic_socket_address.h"
21 #include "quiche/quic/platform/api/quic_test.h"
22 #include "quiche/quic/platform/api/quic_test_loopback.h"
23 #include "quiche/quic/test_tools/crypto_test_utils.h"
24 #include "quiche/quic/test_tools/mock_quic_dispatcher.h"
25 #include "quiche/quic/test_tools/quic_server_peer.h"
26 #include "quiche/quic/tools/quic_memory_cache_backend.h"
27 #include "quiche/quic/tools/quic_simple_crypto_server_stream_helper.h"
28 
29 namespace quic {
30 namespace test {
31 
32 using ::testing::_;
33 
34 namespace {
35 
36 class MockQuicSimpleDispatcher : public QuicSimpleDispatcher {
37  public:
MockQuicSimpleDispatcher(const QuicConfig * config,const QuicCryptoServerConfig * crypto_config,QuicVersionManager * version_manager,std::unique_ptr<QuicConnectionHelperInterface> helper,std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,std::unique_ptr<QuicAlarmFactory> alarm_factory,QuicSimpleServerBackend * quic_simple_server_backend,ConnectionIdGeneratorInterface & generator)38   MockQuicSimpleDispatcher(
39       const QuicConfig* config, const QuicCryptoServerConfig* crypto_config,
40       QuicVersionManager* version_manager,
41       std::unique_ptr<QuicConnectionHelperInterface> helper,
42       std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
43       std::unique_ptr<QuicAlarmFactory> alarm_factory,
44       QuicSimpleServerBackend* quic_simple_server_backend,
45       ConnectionIdGeneratorInterface& generator)
46       : QuicSimpleDispatcher(config, crypto_config, version_manager,
47                              std::move(helper), std::move(session_helper),
48                              std::move(alarm_factory),
49                              quic_simple_server_backend,
50                              kQuicDefaultConnectionIdLength, generator) {}
51   ~MockQuicSimpleDispatcher() override = default;
52 
53   MOCK_METHOD(void, OnCanWrite, (), (override));
54   MOCK_METHOD(bool, HasPendingWrites, (), (const, override));
55   MOCK_METHOD(bool, HasChlosBuffered, (), (const, override));
56   MOCK_METHOD(void, ProcessBufferedChlos, (size_t), (override));
57 };
58 
59 class TestQuicServer : public QuicServer {
60  public:
TestQuicServer(QuicEventLoopFactory * event_loop_factory,QuicMemoryCacheBackend * quic_simple_server_backend)61   explicit TestQuicServer(QuicEventLoopFactory* event_loop_factory,
62                           QuicMemoryCacheBackend* quic_simple_server_backend)
63       : QuicServer(crypto_test_utils::ProofSourceForTesting(),
64                    quic_simple_server_backend),
65         quic_simple_server_backend_(quic_simple_server_backend),
66         event_loop_factory_(event_loop_factory) {}
67 
68   ~TestQuicServer() override = default;
69 
mock_dispatcher()70   MockQuicSimpleDispatcher* mock_dispatcher() { return mock_dispatcher_; }
71 
72  protected:
CreateQuicDispatcher()73   QuicDispatcher* CreateQuicDispatcher() override {
74     mock_dispatcher_ = new MockQuicSimpleDispatcher(
75         &config(), &crypto_config(), version_manager(),
76         std::make_unique<QuicDefaultConnectionHelper>(),
77         std::unique_ptr<QuicCryptoServerStreamBase::Helper>(
78             new QuicSimpleCryptoServerStreamHelper()),
79         event_loop()->CreateAlarmFactory(), quic_simple_server_backend_,
80         connection_id_generator());
81     return mock_dispatcher_;
82   }
83 
CreateEventLoop()84   std::unique_ptr<QuicEventLoop> CreateEventLoop() override {
85     return event_loop_factory_->Create(QuicDefaultClock::Get());
86   }
87 
88   MockQuicSimpleDispatcher* mock_dispatcher_ = nullptr;
89   QuicMemoryCacheBackend* quic_simple_server_backend_;
90   QuicEventLoopFactory* event_loop_factory_;
91 };
92 
93 class QuicServerEpollInTest : public QuicTestWithParam<QuicEventLoopFactory*> {
94  public:
QuicServerEpollInTest()95   QuicServerEpollInTest()
96       : server_address_(TestLoopback(), 0),
97         server_(GetParam(), &quic_simple_server_backend_) {}
98 
StartListening()99   void StartListening() {
100     server_.CreateUDPSocketAndListen(server_address_);
101     server_address_ = QuicSocketAddress(server_address_.host(), server_.port());
102 
103     ASSERT_TRUE(QuicServerPeer::SetSmallSocket(&server_));
104 
105     if (!server_.overflow_supported()) {
106       QUIC_LOG(WARNING) << "Overflow not supported.  Not testing.";
107       return;
108     }
109   }
110 
111  protected:
112   QuicSocketAddress server_address_;
113   QuicMemoryCacheBackend quic_simple_server_backend_;
114   TestQuicServer server_;
115 };
116 
GetTestParamName(::testing::TestParamInfo<QuicEventLoopFactory * > info)117 std::string GetTestParamName(
118     ::testing::TestParamInfo<QuicEventLoopFactory*> info) {
119   return EscapeTestParamName(info.param->GetName());
120 }
121 
122 INSTANTIATE_TEST_SUITE_P(QuicServerEpollInTests, QuicServerEpollInTest,
123                          ::testing::ValuesIn(GetAllSupportedEventLoops()),
124                          GetTestParamName);
125 
126 // Tests that if dispatcher has CHLOs waiting for connection creation, EPOLLIN
127 // event should try to create connections for them. And set epoll mask with
128 // EPOLLIN if there are still CHLOs remaining at the end of epoll event.
TEST_P(QuicServerEpollInTest,ProcessBufferedCHLOsOnEpollin)129 TEST_P(QuicServerEpollInTest, ProcessBufferedCHLOsOnEpollin) {
130   // Given an EPOLLIN event, try to create session for buffered CHLOs. In first
131   // event, dispatcher can't create session for all of CHLOs. So listener should
132   // register another EPOLLIN event by itself. Even without new packet arrival,
133   // the rest CHLOs should be process in next epoll event.
134   StartListening();
135   bool more_chlos = true;
136   MockQuicSimpleDispatcher* dispatcher_ = server_.mock_dispatcher();
137   QUICHE_DCHECK(dispatcher_ != nullptr);
138   EXPECT_CALL(*dispatcher_, OnCanWrite()).Times(testing::AnyNumber());
139   EXPECT_CALL(*dispatcher_, ProcessBufferedChlos(_)).Times(2);
140   EXPECT_CALL(*dispatcher_, HasPendingWrites()).Times(testing::AnyNumber());
141   // Expect there are still CHLOs buffered after 1st event. But not any more
142   // after 2nd event.
143   EXPECT_CALL(*dispatcher_, HasChlosBuffered())
144       .WillOnce(testing::Return(true))
145       .WillOnce(
146           DoAll(testing::Assign(&more_chlos, false), testing::Return(false)));
147 
148   // Send a packet to trigger epoll event.
149   QuicUdpSocketApi socket_api;
150   SocketFd fd =
151       socket_api.Create(server_address_.host().AddressFamilyToInt(),
152                         /*receive_buffer_size =*/kDefaultSocketReceiveBuffer,
153                         /*send_buffer_size =*/kDefaultSocketReceiveBuffer);
154   ASSERT_NE(fd, kQuicInvalidSocketFd);
155 
156   char buf[1024];
157   memset(buf, 0, ABSL_ARRAYSIZE(buf));
158   QuicUdpPacketInfo packet_info;
159   packet_info.SetPeerAddress(server_address_);
160   WriteResult result =
161       socket_api.WritePacket(fd, buf, sizeof(buf), packet_info);
162   if (result.status != WRITE_STATUS_OK) {
163     QUIC_LOG(ERROR) << "Write error for UDP packet: " << result.error_code;
164   }
165 
166   while (more_chlos) {
167     server_.WaitForEvents();
168   }
169 }
170 
171 class QuicServerDispatchPacketTest : public QuicTest {
172  public:
QuicServerDispatchPacketTest()173   QuicServerDispatchPacketTest()
174       : crypto_config_("blah", QuicRandom::GetInstance(),
175                        crypto_test_utils::ProofSourceForTesting(),
176                        KeyExchangeSource::Default()),
177         version_manager_(AllSupportedVersions()),
178         event_loop_(GetDefaultEventLoop()->Create(QuicDefaultClock::Get())),
179         connection_id_generator_(kQuicDefaultConnectionIdLength),
180         dispatcher_(&config_, &crypto_config_, &version_manager_,
181                     std::make_unique<QuicDefaultConnectionHelper>(),
182                     std::make_unique<QuicSimpleCryptoServerStreamHelper>(),
183                     event_loop_->CreateAlarmFactory(),
184                     &quic_simple_server_backend_, connection_id_generator_) {
185     dispatcher_.InitializeWithWriter(new QuicDefaultPacketWriter(1234));
186   }
187 
DispatchPacket(const QuicReceivedPacket & packet)188   void DispatchPacket(const QuicReceivedPacket& packet) {
189     QuicSocketAddress client_addr, server_addr;
190     dispatcher_.ProcessPacket(server_addr, client_addr, packet);
191   }
192 
193  protected:
194   QuicConfig config_;
195   QuicCryptoServerConfig crypto_config_;
196   QuicVersionManager version_manager_;
197   std::unique_ptr<QuicEventLoop> event_loop_;
198   QuicMemoryCacheBackend quic_simple_server_backend_;
199   DeterministicConnectionIdGenerator connection_id_generator_;
200   MockQuicDispatcher dispatcher_;
201 };
202 
TEST_F(QuicServerDispatchPacketTest,DispatchPacket)203 TEST_F(QuicServerDispatchPacketTest, DispatchPacket) {
204   // clang-format off
205   unsigned char valid_packet[] = {
206     // public flags (8 byte connection_id)
207     0x3C,
208     // connection_id
209     0x10, 0x32, 0x54, 0x76,
210     0x98, 0xBA, 0xDC, 0xFE,
211     // packet number
212     0xBC, 0x9A, 0x78, 0x56,
213     0x34, 0x12,
214     // private flags
215     0x00
216   };
217   // clang-format on
218   QuicReceivedPacket encrypted_valid_packet(
219       reinterpret_cast<char*>(valid_packet), ABSL_ARRAYSIZE(valid_packet),
220       QuicTime::Zero(), false);
221 
222   EXPECT_CALL(dispatcher_, ProcessPacket(_, _, _)).Times(1);
223   DispatchPacket(encrypted_valid_packet);
224 }
225 
226 }  // namespace
227 }  // namespace test
228 }  // namespace quic
229