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