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