1 /*
2 * Copyright (c) 2018-present, Facebook, Inc.
3 * All rights reserved.
4 *
5 * This source code is licensed under the BSD-style license found in the
6 * LICENSE file in the root directory of this source tree.
7 */
8
9 #include <folly/portability/GMock.h>
10 #include <folly/portability/GTest.h>
11
12 #include <fizz/server/AsyncFizzServer.h>
13
14 #include <fizz/extensions/tokenbinding/Types.h>
15 #include <fizz/server/test/Mocks.h>
16 #include <folly/io/async/test/MockAsyncTransport.h>
17
18 namespace fizz {
19 namespace server {
20 namespace test {
21
22 using namespace fizz::extensions;
23 using namespace folly;
24 using namespace folly::test;
25 using namespace testing;
26
27 template <typename... Args>
actions(Args &&...act)28 AsyncActions actions(Args&&... act) {
29 return fizz::server::detail::actions(std::forward<Args>(act)...);
30 }
31
32 class MockServerStateMachineInstance : public MockServerStateMachine {
33 public:
MockServerStateMachineInstance()34 MockServerStateMachineInstance() {
35 instance = this;
36 }
37 static MockServerStateMachineInstance* instance;
38 };
39 MockServerStateMachineInstance* MockServerStateMachineInstance::instance;
40
41 class AsyncFizzServerTest : public Test {
42 public:
SetUp()43 void SetUp() override {
44 context_ = std::make_shared<FizzServerContext>();
45 socket_ = new MockAsyncTransport();
46 auto transport = AsyncTransportWrapper::UniquePtr(socket_);
47 server_.reset(new AsyncFizzServerT<MockServerStateMachineInstance>(
48 std::move(transport),
49 context_,
50 std::make_shared<MockServerExtensions>()));
51 machine_ = MockServerStateMachineInstance::instance;
52 ON_CALL(*socket_, good()).WillByDefault(Return(true));
53 ON_CALL(readCallback_, isBufferMovable_()).WillByDefault(Return(true));
54 }
55
56 protected:
expectTransportReadCallback()57 void expectTransportReadCallback() {
58 EXPECT_CALL(*socket_, setReadCB(_))
59 .WillRepeatedly(SaveArg<0>(&socketReadCallback_));
60 }
61
expectAppClose()62 void expectAppClose() {
63 EXPECT_CALL(*machine_, _processAppClose(_))
64 .WillOnce(InvokeWithoutArgs([]() {
65 WriteToSocket write;
66 TLSContent record;
67 record.contentType = ContentType::alert;
68 record.encryptionLevel = EncryptionLevel::Handshake;
69 record.data = IOBuf::copyBuffer("closenotify");
70 write.contents.emplace_back(std::move(record));
71 return detail::actions(
72 MutateState(
73 [](State& newState) { newState.state() = StateEnum::Error; }),
74 std::move(write));
75 }));
76 }
77
expectAppCloseImmediate()78 void expectAppCloseImmediate() {
79 EXPECT_CALL(*machine_, _processAppCloseImmediate(_))
80 .WillOnce(InvokeWithoutArgs([]() {
81 WriteToSocket write;
82 TLSContent record;
83 record.contentType = ContentType::alert;
84 record.encryptionLevel = EncryptionLevel::Handshake;
85 record.data = IOBuf::copyBuffer("closenotify");
86 write.contents.emplace_back(std::move(record));
87 return detail::actions(
88 MutateState(
89 [](State& newState) { newState.state() = StateEnum::Error; }),
90 std::move(write));
91 }));
92 }
93
accept()94 void accept() {
95 expectTransportReadCallback();
96 EXPECT_CALL(*socket_, getEventBase()).WillOnce(Return(&evb_));
97 EXPECT_CALL(*machine_, _processAccept(_, &evb_, _, _))
98 .WillOnce(InvokeWithoutArgs([]() { return actions(); }));
99 server_->accept(&handshakeCallback_);
100 }
101
fullHandshakeSuccess(std::shared_ptr<const Cert> clientCert=nullptr,std::shared_ptr<const Cert> serverCert=nullptr)102 void fullHandshakeSuccess(
103 std::shared_ptr<const Cert> clientCert = nullptr,
104 std::shared_ptr<const Cert> serverCert = nullptr) {
105 EXPECT_CALL(*machine_, _processSocketData(_, _, _))
106 .WillOnce(InvokeWithoutArgs([clientCert,
107 serverCert,
108 cipher = negotiatedCipher_,
109 protocolVersion = protocolVersion_]() {
110 MutateState addExporterToState([=](State& newState) {
111 auto exporterMaster =
112 folly::IOBuf::copyBuffer("12345678901234567890123456789012");
113 newState.exporterMasterSecret() = std::move(exporterMaster);
114 newState.cipher() = cipher;
115 newState.version() = protocolVersion;
116 newState.clientCert() = clientCert;
117 newState.serverCert() = serverCert;
118 });
119 return actions(
120 std::move(addExporterToState),
121 ReportHandshakeSuccess(),
122 WaitForData());
123 }));
124 socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("ClientHello"));
125 }
126
completeHandshake()127 void completeHandshake() {
128 accept();
129 EXPECT_CALL(handshakeCallback_, _fizzHandshakeSuccess());
130 fullHandshakeSuccess();
131 }
132
133 AsyncFizzServerT<MockServerStateMachineInstance>::UniquePtr server_;
134 std::shared_ptr<FizzServerContext> context_;
135 MockAsyncTransport* socket_;
136 MockServerStateMachineInstance* machine_;
137 AsyncTransportWrapper::ReadCallback* socketReadCallback_;
138 MockHandshakeCallbackT<MockServerStateMachineInstance> handshakeCallback_;
139 MockReadCallback readCallback_;
140 MockWriteCallback writeCallback_;
141 EventBase evb_;
142 CipherSuite negotiatedCipher_ = CipherSuite::TLS_AES_128_GCM_SHA256;
143 ProtocolVersion protocolVersion_ = ProtocolVersion::tls_1_3;
144 };
145
146 MATCHER_P(BufMatches, expected, "") {
147 folly::IOBufEqualTo eq;
148 return eq(*arg, *expected);
149 }
150
TEST_F(AsyncFizzServerTest,TestAccept)151 TEST_F(AsyncFizzServerTest, TestAccept) {
152 accept();
153 }
154
TEST_F(AsyncFizzServerTest,TestReadSingle)155 TEST_F(AsyncFizzServerTest, TestReadSingle) {
156 accept();
157 EXPECT_CALL(*machine_, _processSocketData(_, _, _))
158 .WillOnce(InvokeWithoutArgs([]() { return actions(WaitForData()); }));
159 socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("ClientHello"));
160 }
161
TEST_F(AsyncFizzServerTest,TestReadMulti)162 TEST_F(AsyncFizzServerTest, TestReadMulti) {
163 accept();
164 EXPECT_CALL(*machine_, _processSocketData(_, _, _))
165 .WillOnce(InvokeWithoutArgs([]() { return actions(); }))
166 .WillOnce(InvokeWithoutArgs([]() { return actions(WaitForData()); }));
167 socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("ClientHello"));
168 }
169
TEST_F(AsyncFizzServerTest,TestWrite)170 TEST_F(AsyncFizzServerTest, TestWrite) {
171 accept();
172 EXPECT_CALL(*machine_, _processAppWrite(_, _))
173 .WillOnce(InvokeWithoutArgs([]() { return actions(); }));
174 server_->writeChain(nullptr, IOBuf::copyBuffer("HTTP GET"));
175 }
176
TEST_F(AsyncFizzServerTest,TestWriteMulti)177 TEST_F(AsyncFizzServerTest, TestWriteMulti) {
178 accept();
179 EXPECT_CALL(*machine_, _processAppWrite(_, _))
180 .WillOnce(InvokeWithoutArgs([]() { return actions(); }));
181 server_->writeChain(nullptr, IOBuf::copyBuffer("HTTP GET"));
182 EXPECT_CALL(*machine_, _processAppWrite(_, _))
183 .WillOnce(InvokeWithoutArgs([]() { return actions(); }));
184 server_->writeChain(nullptr, IOBuf::copyBuffer("HTTP POST"));
185 }
186
TEST_F(AsyncFizzServerTest,TestWriteErrorState)187 TEST_F(AsyncFizzServerTest, TestWriteErrorState) {
188 accept();
189 ON_CALL(*socket_, error()).WillByDefault(Return(true));
190 EXPECT_CALL(writeCallback_, writeErr_(0, _));
191 server_->writeChain(&writeCallback_, IOBuf::copyBuffer("test"));
192 }
193
TEST_F(AsyncFizzServerTest,TestWriteNotGoodState)194 TEST_F(AsyncFizzServerTest, TestWriteNotGoodState) {
195 accept();
196 ON_CALL(*socket_, good()).WillByDefault(Return(false));
197 EXPECT_CALL(writeCallback_, writeErr_(0, _));
198 server_->writeChain(&writeCallback_, IOBuf::copyBuffer("test"));
199 }
200
TEST_F(AsyncFizzServerTest,TestHandshake)201 TEST_F(AsyncFizzServerTest, TestHandshake) {
202 completeHandshake();
203 }
204
TEST_F(AsyncFizzServerTest,TestExporterAPISimple)205 TEST_F(AsyncFizzServerTest, TestExporterAPISimple) {
206 completeHandshake();
207 server_->getEkm(kTokenBindingExporterLabel, nullptr, 32);
208 }
209
TEST_F(AsyncFizzServerTest,TestExporterAPIIncompleteHandshake)210 TEST_F(AsyncFizzServerTest, TestExporterAPIIncompleteHandshake) {
211 EXPECT_THROW(
212 server_->getEkm(kTokenBindingExporterLabel, nullptr, 32),
213 std::runtime_error);
214 }
215
TEST_F(AsyncFizzServerTest,TestHandshakeError)216 TEST_F(AsyncFizzServerTest, TestHandshakeError) {
217 accept();
218 EXPECT_CALL(*machine_, _processSocketData(_, _, _))
219 .WillOnce(InvokeWithoutArgs(
220 []() { return actions(ReportError("unit test"), WaitForData()); }));
221 EXPECT_CALL(handshakeCallback_, _fizzHandshakeError(_));
222 socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("ClientHello"));
223 }
224
TEST_F(AsyncFizzServerTest,TestDeliverAppData)225 TEST_F(AsyncFizzServerTest, TestDeliverAppData) {
226 completeHandshake();
227 server_->setReadCB(&readCallback_);
228 EXPECT_CALL(*machine_, _processSocketData(_, _, _))
229 .WillOnce(InvokeWithoutArgs([]() {
230 return actions(DeliverAppData{IOBuf::copyBuffer("HI")}, WaitForData());
231 }));
232 EXPECT_CALL(readCallback_, readBufferAvailable_(_));
233 socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("ClientHello"));
234 }
235
TEST_F(AsyncFizzServerTest,TestSendTicketWithAppToken)236 TEST_F(AsyncFizzServerTest, TestSendTicketWithAppToken) {
237 completeHandshake();
238 EXPECT_CALL(*machine_, _processWriteNewSessionTicket(_, _))
239 .WillOnce(InvokeWithoutArgs([]() {
240 WriteToSocket write;
241 TLSContent record;
242 record.contentType = ContentType::handshake;
243 record.encryptionLevel = EncryptionLevel::AppTraffic;
244 record.data = IOBuf::copyBuffer("XYZ");
245 write.contents.emplace_back(std::move(record));
246 return actions(std::move(write));
247 }));
248 EXPECT_CALL(*socket_, writeChain(_, _, _));
249 server_->sendTicketWithAppToken(IOBuf::copyBuffer("testAppToken"));
250 }
251
TEST_F(AsyncFizzServerTest,TestWriteToSocket)252 TEST_F(AsyncFizzServerTest, TestWriteToSocket) {
253 completeHandshake();
254 server_->setReadCB(&readCallback_);
255 EXPECT_CALL(*machine_, _processSocketData(_, _, _))
256 .WillOnce(InvokeWithoutArgs([]() {
257 WriteToSocket write;
258 TLSContent record;
259 record.contentType = ContentType::application_data;
260 record.encryptionLevel = EncryptionLevel::AppTraffic;
261 record.data = IOBuf::copyBuffer("XYZ");
262 write.contents.emplace_back(std::move(record));
263 return actions(std::move(write), WaitForData());
264 }));
265 EXPECT_CALL(*socket_, writeChain(_, _, _));
266 socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("ClientHello"));
267 }
268
TEST_F(AsyncFizzServerTest,TestMutateState)269 TEST_F(AsyncFizzServerTest, TestMutateState) {
270 completeHandshake();
271 server_->setReadCB(&readCallback_);
272 uint32_t numTimesRun = 0;
273 EXPECT_CALL(*machine_, _processSocketData(_, _, _))
274 .WillOnce(InvokeWithoutArgs([&numTimesRun]() {
275 return actions(
276 MutateState([&numTimesRun](State& newState) {
277 numTimesRun++;
278 newState.state() = StateEnum::Error;
279 }),
280 WaitForData());
281 }));
282 socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("ClientHello"));
283 EXPECT_EQ(server_->getState().state(), StateEnum::Error);
284 EXPECT_EQ(numTimesRun, 1);
285 }
286
TEST_F(AsyncFizzServerTest,TestAttemptVersionFallback)287 TEST_F(AsyncFizzServerTest, TestAttemptVersionFallback) {
288 accept();
289 EXPECT_CALL(*machine_, _processSocketData(_, _, _))
290 .WillOnce(InvokeWithoutArgs([]() {
291 return actions(
292 MutateState(
293 [](State& newState) { newState.state() = StateEnum::Error; }),
294 AttemptVersionFallback{IOBuf::copyBuffer("ClientHello")});
295 }));
296 EXPECT_CALL(handshakeCallback_, _fizzHandshakeAttemptFallback(_))
297 .WillOnce(Invoke([&](std::unique_ptr<IOBuf>& clientHello) {
298 // The mock machine does not move the read buffer so there will be a 2nd
299 // ClientHello.
300 EXPECT_TRUE(IOBufEqualTo()(
301 clientHello, IOBuf::copyBuffer("ClientHelloClientHello")));
302 server_.reset();
303 }));
304 socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("ClientHello"));
305 }
306
TEST_F(AsyncFizzServerTest,TestDeleteAsyncEvent)307 TEST_F(AsyncFizzServerTest, TestDeleteAsyncEvent) {
308 accept();
309 Promise<Actions> p1;
310 EXPECT_CALL(*machine_, _processSocketData(_, _, _))
311 .WillOnce(
312 InvokeWithoutArgs([&p1]() { return AsyncActions(p1.getFuture()); }));
313 socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("ClientHello"));
314 server_.reset();
315 Promise<Actions> p2;
316 EXPECT_CALL(*machine_, _processSocketData(_, _, _))
317 .WillOnce(
318 InvokeWithoutArgs([&p2]() { return AsyncActions(p2.getFuture()); }));
319 p1.setValue(detail::actions());
320 p2.setValue(detail::actions(WaitForData()));
321 }
322
TEST_F(AsyncFizzServerTest,TestCloseHandshake)323 TEST_F(AsyncFizzServerTest, TestCloseHandshake) {
324 accept();
325 expectAppCloseImmediate();
326 EXPECT_CALL(handshakeCallback_, _fizzHandshakeError(_));
327 EXPECT_CALL(*socket_, closeNow()).Times(AtLeast(1));
328 server_->closeNow();
329 }
330
TEST_F(AsyncFizzServerTest,TestTLSShutdown)331 TEST_F(AsyncFizzServerTest, TestTLSShutdown) {
332 accept();
333 expectAppClose();
334 EXPECT_CALL(*socket_, close()).Times(0);
335 server_->tlsShutdown();
336 }
337
TEST_F(AsyncFizzServerTest,TestCloseNowInFlightAction)338 TEST_F(AsyncFizzServerTest, TestCloseNowInFlightAction) {
339 completeHandshake();
340 server_->setReadCB(&readCallback_);
341 Promise<Actions> p;
342 EXPECT_CALL(*machine_, _processSocketData(_, _, _))
343 .WillOnce(
344 InvokeWithoutArgs([&p]() { return AsyncActions(p.getFuture()); }));
345 socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("Data"));
346 server_->writeChain(&writeCallback_, IOBuf::copyBuffer("queued write"));
347 EXPECT_CALL(writeCallback_, writeErr_(0, _));
348 EXPECT_CALL(readCallback_, readEOF_());
349 EXPECT_CALL(*socket_, closeNow()).Times(AtLeast(1));
350 server_->closeNow();
351 p.setValue(detail::actions(WaitForData()));
352 }
353
TEST_F(AsyncFizzServerTest,TestCloseInFlightAction)354 TEST_F(AsyncFizzServerTest, TestCloseInFlightAction) {
355 completeHandshake();
356 server_->setReadCB(&readCallback_);
357 Promise<Actions> p;
358 EXPECT_CALL(*machine_, _processSocketData(_, _, _))
359 .WillOnce(
360 InvokeWithoutArgs([&p]() { return AsyncActions(p.getFuture()); }));
361 socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("Data"));
362 server_->writeChain(&writeCallback_, IOBuf::copyBuffer("queued write"));
363 server_->close();
364
365 EXPECT_CALL(*machine_, _processAppWrite(_, _))
366 .WillOnce(InvokeWithoutArgs([]() { return actions(); }));
367 expectAppCloseImmediate();
368 p.setValue(detail::actions(WaitForData()));
369 }
370
TEST_F(AsyncFizzServerTest,TestIsDetachable)371 TEST_F(AsyncFizzServerTest, TestIsDetachable) {
372 completeHandshake();
373 AsyncTransportWrapper::ReadCallback* readCb = socketReadCallback_;
374 ON_CALL(*socket_, isDetachable()).WillByDefault(Return(false));
375 EXPECT_FALSE(server_->isDetachable());
376 ON_CALL(*socket_, isDetachable()).WillByDefault(Return(true));
377 EXPECT_TRUE(server_->isDetachable());
378 Promise<Actions> p;
379
380 EXPECT_CALL(*machine_, _processSocketData(_, _, _))
381 .WillOnce(
382 InvokeWithoutArgs([&p]() { return AsyncActions(p.getFuture()); }));
383 socket_->setReadCB(readCb);
384 socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("Data"));
385 EXPECT_FALSE(server_->isDetachable());
386 p.setValue(detail::actions(WaitForData()));
387 EXPECT_TRUE(server_->isDetachable());
388 }
389
TEST_F(AsyncFizzServerTest,TestConnecting)390 TEST_F(AsyncFizzServerTest, TestConnecting) {
391 ON_CALL(*socket_, connecting()).WillByDefault(Return(true));
392 EXPECT_TRUE(server_->connecting());
393 ON_CALL(*socket_, connecting()).WillByDefault(Return(false));
394 accept();
395 EXPECT_TRUE(server_->connecting());
396 EXPECT_CALL(*machine_, _processSocketData(_, _, _))
397 .WillOnce(InvokeWithoutArgs(
398 []() { return actions(ReportHandshakeSuccess(), WaitForData()); }));
399 EXPECT_CALL(handshakeCallback_, _fizzHandshakeSuccess());
400 socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("ClientHello"));
401 EXPECT_FALSE(server_->connecting());
402 }
403
TEST_F(AsyncFizzServerTest,TestGoodSocket)404 TEST_F(AsyncFizzServerTest, TestGoodSocket) {
405 accept();
406 ON_CALL(*socket_, good()).WillByDefault(Return(true));
407 EXPECT_TRUE(server_->good());
408 ON_CALL(*socket_, good()).WillByDefault(Return(false));
409 EXPECT_FALSE(server_->good());
410 }
411
TEST_F(AsyncFizzServerTest,TestGoodState)412 TEST_F(AsyncFizzServerTest, TestGoodState) {
413 completeHandshake();
414 ON_CALL(*socket_, good()).WillByDefault(Return(true));
415 EXPECT_TRUE(server_->good());
416 EXPECT_CALL(*machine_, _processSocketData(_, _, _))
417 .WillOnce(InvokeWithoutArgs([]() {
418 return actions(MutateState(
419 [](State& newState) { newState.state() = StateEnum::Error; }));
420 }));
421 socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("Data"));
422 EXPECT_FALSE(server_->good());
423 }
424
TEST_F(AsyncFizzServerTest,TestEarlySuccess)425 TEST_F(AsyncFizzServerTest, TestEarlySuccess) {
426 accept();
427 EXPECT_CALL(*machine_, _processSocketData(_, _, _))
428 .WillOnce(InvokeWithoutArgs([]() {
429 return actions(ReportEarlyHandshakeSuccess(), WaitForData());
430 }));
431 EXPECT_CALL(handshakeCallback_, _fizzHandshakeSuccess());
432 socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("ClientHello"));
433
434 fullHandshakeSuccess();
435 }
436
TEST_F(AsyncFizzServerTest,TestErrorStopsActions)437 TEST_F(AsyncFizzServerTest, TestErrorStopsActions) {
438 completeHandshake();
439 server_->setReadCB(&readCallback_);
440 EXPECT_CALL(*machine_, _processSocketData(_, _, _))
441 .WillOnce(InvokeWithoutArgs([]() {
442 return actions(
443 MutateState(
444 [](State& newState) { newState.state() = StateEnum::Error; }),
445 ReportError("unit test"));
446 }));
447 EXPECT_FALSE(server_->error());
448 EXPECT_TRUE(server_->good());
449 socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("Data"));
450 EXPECT_TRUE(server_->error());
451 EXPECT_FALSE(server_->good());
452 }
453
TEST_F(AsyncFizzServerTest,TestTransportError)454 TEST_F(AsyncFizzServerTest, TestTransportError) {
455 completeHandshake();
456 server_->setReadCB(&readCallback_);
457 EXPECT_CALL(*machine_, _processSocketData(_, _, _)).Times(0);
458 EXPECT_FALSE(server_->error());
459 EXPECT_TRUE(server_->good());
460 ON_CALL(*socket_, error()).WillByDefault(Return(true));
461 AsyncSocketException ase(AsyncSocketException::UNKNOWN, "unit test");
462 socketReadCallback_->readErr(ase);
463 EXPECT_TRUE(server_->error());
464 EXPECT_FALSE(server_->good());
465 socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("Data"));
466 EXPECT_TRUE(server_->error());
467 EXPECT_FALSE(server_->good());
468 }
469
TEST_F(AsyncFizzServerTest,TestTransportEof)470 TEST_F(AsyncFizzServerTest, TestTransportEof) {
471 completeHandshake();
472 server_->setReadCB(&readCallback_);
473 EXPECT_CALL(*machine_, _processSocketData(_, _, _)).Times(0);
474 EXPECT_FALSE(server_->error());
475 EXPECT_TRUE(server_->good());
476 ON_CALL(*socket_, good()).WillByDefault(Return(false));
477 socketReadCallback_->readEOF();
478 EXPECT_FALSE(server_->error());
479 EXPECT_FALSE(server_->good());
480 socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("Data"));
481 EXPECT_FALSE(server_->error());
482 EXPECT_FALSE(server_->good());
483 }
484
TEST_F(AsyncFizzServerTest,TestGetCertsNone)485 TEST_F(AsyncFizzServerTest, TestGetCertsNone) {
486 completeHandshake();
487 EXPECT_EQ(server_->getSelfCertificate(), nullptr);
488 EXPECT_EQ(server_->getPeerCertificate(), nullptr);
489 }
490
TEST_F(AsyncFizzServerTest,TestGetCerts)491 TEST_F(AsyncFizzServerTest, TestGetCerts) {
492 auto clientCert = std::make_shared<MockCert>();
493 auto serverCert = std::make_shared<MockCert>();
494 accept();
495 EXPECT_CALL(handshakeCallback_, _fizzHandshakeSuccess());
496 fullHandshakeSuccess(clientCert, serverCert);
497 EXPECT_NE(server_->getSelfCertificate(), nullptr);
498 EXPECT_NE(server_->getPeerCertificate(), nullptr);
499 }
500
TEST_F(AsyncFizzServerTest,TestTransportNotGoodOnSuccess)501 TEST_F(AsyncFizzServerTest, TestTransportNotGoodOnSuccess) {
502 accept();
503 EXPECT_CALL(handshakeCallback_, _fizzHandshakeError(_));
504 EXPECT_CALL(*machine_, _processSocketData(_, _, _))
505 .WillOnce(InvokeWithoutArgs([&]() {
506 // Make the socket return not good
507 EXPECT_CALL(*socket_, good()).WillOnce(Return(false));
508 return actions(ReportHandshakeSuccess());
509 }));
510 socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("ClientHello"));
511 EXPECT_FALSE(server_->good());
512 }
513
TEST_F(AsyncFizzServerTest,TestTransportNotGoodOnEarlySuccess)514 TEST_F(AsyncFizzServerTest, TestTransportNotGoodOnEarlySuccess) {
515 accept();
516 EXPECT_CALL(handshakeCallback_, _fizzHandshakeError(_));
517 EXPECT_CALL(*machine_, _processSocketData(_, _, _))
518 .WillOnce(InvokeWithoutArgs([&]() {
519 // Make the socket return not good
520 EXPECT_CALL(*socket_, good()).WillOnce(Return(false));
521 return actions(ReportEarlyHandshakeSuccess());
522 }));
523 socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("ClientHello"));
524 EXPECT_FALSE(server_->good());
525 }
526
TEST_F(AsyncFizzServerTest,TestRemoteClosed)527 TEST_F(AsyncFizzServerTest, TestRemoteClosed) {
528 completeHandshake();
529 server_->setReadCB(&readCallback_);
530 EXPECT_CALL(readCallback_, readEOF_());
531 EXPECT_CALL(*machine_, _processSocketData(_, _, _))
532 .WillOnce(InvokeWithoutArgs([]() {
533 return actions(
534 MutateState([](State& s) { s.state() = StateEnum::Closed; }),
535 EndOfData());
536 }));
537 EXPECT_CALL(*socket_, closeNow());
538 EXPECT_TRUE(server_->good());
539 socketReadCallback_->readBufferAvailable(IOBuf::copyBuffer("Data"));
540 EXPECT_FALSE(server_->good());
541 }
542
TEST_F(AsyncFizzServerTest,TestHandshakeRecordAlignedReads)543 TEST_F(AsyncFizzServerTest, TestHandshakeRecordAlignedReads) {
544 server_->setHandshakeRecordAlignedReads(true);
545
546 accept();
547
548 void* buf;
549 size_t len;
550 socketReadCallback_->getReadBuffer(&buf, &len);
551
552 // Handshake record aligned reads begin with a read of 5 bytes for the
553 // record header.
554 EXPECT_EQ(len, 5);
555
556 EXPECT_CALL(*machine_, _processSocketData(_, _, _))
557 .WillOnce(InvokeWithoutArgs([] { return actions(WaitForData{10}); }));
558 socketReadCallback_->readDataAvailable(5);
559
560 socketReadCallback_->getReadBuffer(&buf, &len);
561 EXPECT_EQ(len, 10);
562
563 EXPECT_CALL(*machine_, _processSocketData(_, _, _))
564 .WillOnce(Invoke([](auto&&, auto&& queue, auto&&) {
565 queue.move();
566 return actions(WaitForData{5});
567 }));
568 socketReadCallback_->readDataAvailable(10);
569
570 // Handshake successs event should have now transitioned the socket to
571 // not perform record aligned reads, so subsequent allocations should be
572 // larger
573 fullHandshakeSuccess();
574 socketReadCallback_->getReadBuffer(&buf, &len);
575
576 // Not caring about record alignment, we should be able to get a buffer of
577 // at least AsyncFizzBase::kMinReadSize
578 EXPECT_GE(len, 1460);
579 }
580
581 } // namespace test
582 } // namespace server
583 } // namespace fizz
584