blob: 8c894434dee5ca5c2cfe0ecab78088aa1374af1a [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// 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 "net/third_party/quiche/src/quic/tools/quic_server.h"
6
7#include "net/third_party/quiche/src/quic/core/crypto/quic_random.h"
8#include "net/third_party/quiche/src/quic/core/quic_epoll_alarm_factory.h"
9#include "net/third_party/quiche/src/quic/core/quic_epoll_connection_helper.h"
10#include "net/third_party/quiche/src/quic/core/quic_utils.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050011#include "net/third_party/quiche/src/quic/platform/api/quic_arraysize.h"
12#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
13#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
14#include "net/third_party/quiche/src/quic/platform/api/quic_port_utils.h"
15#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h"
16#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
17#include "net/third_party/quiche/src/quic/platform/api/quic_test_loopback.h"
18#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
19#include "net/third_party/quiche/src/quic/test_tools/mock_quic_dispatcher.h"
20#include "net/third_party/quiche/src/quic/test_tools/quic_server_peer.h"
21#include "net/third_party/quiche/src/quic/tools/quic_memory_cache_backend.h"
22#include "net/third_party/quiche/src/quic/tools/quic_simple_crypto_server_stream_helper.h"
23
24namespace quic {
25namespace test {
26
27using ::testing::_;
28
29namespace {
30
31class MockQuicSimpleDispatcher : public QuicSimpleDispatcher {
32 public:
33 MockQuicSimpleDispatcher(
34 const QuicConfig* config,
35 const QuicCryptoServerConfig* crypto_config,
36 QuicVersionManager* version_manager,
37 std::unique_ptr<QuicConnectionHelperInterface> helper,
38 std::unique_ptr<QuicCryptoServerStream::Helper> session_helper,
39 std::unique_ptr<QuicAlarmFactory> alarm_factory,
40 QuicSimpleServerBackend* quic_simple_server_backend)
41 : QuicSimpleDispatcher(config,
42 crypto_config,
43 version_manager,
44 std::move(helper),
45 std::move(session_helper),
46 std::move(alarm_factory),
47 quic_simple_server_backend,
48 kQuicDefaultConnectionIdLength) {}
49 ~MockQuicSimpleDispatcher() override = default;
50
51 MOCK_METHOD0(OnCanWrite, void());
52 MOCK_CONST_METHOD0(HasPendingWrites, bool());
53 MOCK_CONST_METHOD0(HasChlosBuffered, bool());
54 MOCK_METHOD1(ProcessBufferedChlos, void(size_t));
55};
56
57class TestQuicServer : public QuicServer {
58 public:
59 TestQuicServer()
60 : QuicServer(crypto_test_utils::ProofSourceForTesting(),
61 &quic_simple_server_backend_) {}
62
63 ~TestQuicServer() override = default;
64
65 MockQuicSimpleDispatcher* mock_dispatcher() { return mock_dispatcher_; }
66
67 protected:
68 QuicDispatcher* CreateQuicDispatcher() override {
69 mock_dispatcher_ = new MockQuicSimpleDispatcher(
70 &config(), &crypto_config(), version_manager(),
71 std::unique_ptr<QuicEpollConnectionHelper>(
72 new QuicEpollConnectionHelper(epoll_server(),
73 QuicAllocator::BUFFER_POOL)),
74 std::unique_ptr<QuicCryptoServerStream::Helper>(
wub662a3d62019-08-16 14:10:50 -070075 new QuicSimpleCryptoServerStreamHelper()),
QUICHE teama6ef0a62019-03-07 20:34:33 -050076 std::unique_ptr<QuicEpollAlarmFactory>(
77 new QuicEpollAlarmFactory(epoll_server())),
78 &quic_simple_server_backend_);
79 return mock_dispatcher_;
80 }
81
82 MockQuicSimpleDispatcher* mock_dispatcher_ = nullptr;
83 QuicMemoryCacheBackend quic_simple_server_backend_;
84};
85
86class QuicServerEpollInTest : public QuicTest {
87 public:
88 QuicServerEpollInTest()
rch13cfcae2019-08-26 14:48:08 -070089 : port_(QuicPickServerPortForTestsOrDie()),
QUICHE teama6ef0a62019-03-07 20:34:33 -050090 server_address_(TestLoopback(), port_) {}
91
92 void StartListening() {
93 server_.CreateUDPSocketAndListen(server_address_);
rch13cfcae2019-08-26 14:48:08 -070094 server_address_ = QuicSocketAddress(server_address_.host(), server_.port());
95
QUICHE teama6ef0a62019-03-07 20:34:33 -050096 ASSERT_TRUE(QuicServerPeer::SetSmallSocket(&server_));
97
98 if (!server_.overflow_supported()) {
99 QUIC_LOG(WARNING) << "Overflow not supported. Not testing.";
100 return;
101 }
102 }
103
104 protected:
105 int port_;
106 QuicSocketAddress server_address_;
107 TestQuicServer server_;
108};
109
110// Tests that if dispatcher has CHLOs waiting for connection creation, EPOLLIN
111// event should try to create connections for them. And set epoll mask with
112// EPOLLIN if there are still CHLOs remaining at the end of epoll event.
113TEST_F(QuicServerEpollInTest, ProcessBufferedCHLOsOnEpollin) {
114 // Given an EPOLLIN event, try to create session for buffered CHLOs. In first
115 // event, dispatcher can't create session for all of CHLOs. So listener should
116 // register another EPOLLIN event by itself. Even without new packet arrival,
117 // the rest CHLOs should be process in next epoll event.
118 StartListening();
119 bool more_chlos = true;
120 MockQuicSimpleDispatcher* dispatcher_ = server_.mock_dispatcher();
121 DCHECK(dispatcher_ != nullptr);
122 EXPECT_CALL(*dispatcher_, OnCanWrite()).Times(testing::AnyNumber());
123 EXPECT_CALL(*dispatcher_, ProcessBufferedChlos(_)).Times(2);
124 EXPECT_CALL(*dispatcher_, HasPendingWrites()).Times(testing::AnyNumber());
125 // Expect there are still CHLOs buffered after 1st event. But not any more
126 // after 2nd event.
127 EXPECT_CALL(*dispatcher_, HasChlosBuffered())
128 .WillOnce(testing::Return(true))
129 .WillOnce(
130 DoAll(testing::Assign(&more_chlos, false), testing::Return(false)));
131
132 // Send a packet to trigger epoll event.
133 int fd = socket(
134 AddressFamilyUnderTest() == IpAddressFamily::IP_V4 ? AF_INET : AF_INET6,
135 SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP);
136 ASSERT_LT(0, fd);
137
138 char buf[1024];
139 memset(buf, 0, QUIC_ARRAYSIZE(buf));
140 sockaddr_storage storage = server_address_.generic_address();
141 int rc = sendto(fd, buf, QUIC_ARRAYSIZE(buf), 0,
142 reinterpret_cast<sockaddr*>(&storage), sizeof(storage));
143 if (rc < 0) {
144 QUIC_DLOG(INFO) << errno << " " << strerror(errno);
145 }
146
147 while (more_chlos) {
148 server_.WaitForEvents();
149 }
150}
151
152class QuicServerDispatchPacketTest : public QuicTest {
153 public:
154 QuicServerDispatchPacketTest()
155 : crypto_config_("blah",
156 QuicRandom::GetInstance(),
157 crypto_test_utils::ProofSourceForTesting(),
nharper6ebe83b2019-06-13 17:43:52 -0700158 KeyExchangeSource::Default()),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500159 version_manager_(AllSupportedVersions()),
160 dispatcher_(
161 &config_,
162 &crypto_config_,
163 &version_manager_,
164 std::unique_ptr<QuicEpollConnectionHelper>(
165 new QuicEpollConnectionHelper(&eps_,
166 QuicAllocator::BUFFER_POOL)),
167 std::unique_ptr<QuicCryptoServerStream::Helper>(
wub662a3d62019-08-16 14:10:50 -0700168 new QuicSimpleCryptoServerStreamHelper()),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500169 std::unique_ptr<QuicEpollAlarmFactory>(
170 new QuicEpollAlarmFactory(&eps_)),
171 &quic_simple_server_backend_) {
172 dispatcher_.InitializeWithWriter(new QuicDefaultPacketWriter(1234));
173 }
174
175 void DispatchPacket(const QuicReceivedPacket& packet) {
176 QuicSocketAddress client_addr, server_addr;
177 dispatcher_.ProcessPacket(server_addr, client_addr, packet);
178 }
179
180 protected:
181 QuicConfig config_;
182 QuicCryptoServerConfig crypto_config_;
183 QuicVersionManager version_manager_;
184 QuicEpollServer eps_;
185 QuicMemoryCacheBackend quic_simple_server_backend_;
186 MockQuicDispatcher dispatcher_;
187};
188
189TEST_F(QuicServerDispatchPacketTest, DispatchPacket) {
190 // clang-format off
191 unsigned char valid_packet[] = {
192 // public flags (8 byte connection_id)
193 0x3C,
194 // connection_id
195 0x10, 0x32, 0x54, 0x76,
196 0x98, 0xBA, 0xDC, 0xFE,
197 // packet number
198 0xBC, 0x9A, 0x78, 0x56,
199 0x34, 0x12,
200 // private flags
201 0x00
202 };
203 // clang-format on
204 QuicReceivedPacket encrypted_valid_packet(
205 reinterpret_cast<char*>(valid_packet), QUIC_ARRAYSIZE(valid_packet),
206 QuicTime::Zero(), false);
207
208 EXPECT_CALL(dispatcher_, ProcessPacket(_, _, _)).Times(1);
209 DispatchPacket(encrypted_valid_packet);
210}
211
212} // namespace
213} // namespace test
214} // namespace quic