proxygen
FizzAcceptorHandshakeHelper.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2016-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
19 
20 using namespace fizz::extensions;
21 using namespace fizz::server;
22 
23 namespace wangle {
24 
28  callback_ = callback;
29  sslContext_ = sock->getSSLContext();
30 
31  if (tokenBindingContext_) {
32  extension_ =
33  std::make_shared<TokenBindingServerExtension>(tokenBindingContext_);
34  }
35 
36  transport_ = createFizzServer(std::move(sock), context_, extension_);
37  transport_->accept(this);
38 }
39 
40 AsyncFizzServer::UniquePtr FizzAcceptorHandshakeHelper::createFizzServer(
42  const std::shared_ptr<FizzServerContext>& fizzContext,
43  const std::shared_ptr<fizz::ServerExtensions>& extensions) {
45  new folly::AsyncSocket(std::move(sslSock)));
46  asyncSock->cacheAddresses();
48  new AsyncFizzServer(std::move(asyncSock), fizzContext, extensions));
49 }
50 
51 void FizzAcceptorHandshakeHelper::fizzHandshakeSuccess(
52  AsyncFizzServer* transport) noexcept {
53  if (loggingCallback_) {
54  loggingCallback_->logFizzHandshakeSuccess(*transport);
55  }
56 
57  VLOG(3) << "Fizz handshake success";
58 
59  tinfo_.acceptTime = acceptTime_;
60  tinfo_.secure = true;
61  tinfo_.securityType = transport->getSecurityProtocol();
62  tinfo_.sslSetupTime = std::chrono::duration_cast<std::chrono::milliseconds>(
63  std::chrono::steady_clock::now() - acceptTime_);
64  if (extension_ && extension_->getNegotiatedKeyParam().hasValue()) {
65  tinfo_.negotiatedTokenBindingKeyParameters =
66  static_cast<uint8_t>(*extension_->getNegotiatedKeyParam());
67  }
68 
69  auto* handshakeLogging = transport->getState().handshakeLogging();
70  if (handshakeLogging && handshakeLogging->clientSni) {
71  tinfo_.sslServerName =
72  std::make_shared<std::string>(*handshakeLogging->clientSni);
73  }
74 
75  auto appProto = transport->getApplicationProtocol();
76  callback_->connectionReady(std::move(transport_),
77  std::move(appProto),
78  SecureTransportType::TLS,
79  SSLErrorEnum::NO_ERROR);
80 }
81 
82 void FizzAcceptorHandshakeHelper::fizzHandshakeError(
84  if (loggingCallback_) {
85  loggingCallback_->logFizzHandshakeError(*transport, ex);
86  }
87 
88  auto elapsedTime = std::chrono::duration_cast<std::chrono::milliseconds>(
89  std::chrono::steady_clock::now() - acceptTime_);
90  VLOG(3) << "Fizz handshake error after " << elapsedTime.count() << " ms; "
91  << transport->getRawBytesReceived() << " bytes received & "
92  << transport->getRawBytesWritten() << " bytes sent: " << ex.what();
93 
94  auto handshakeException =
95  folly::make_exception_wrapper<FizzHandshakeException>(
96  sslError_, elapsedTime, transport->getRawBytesReceived());
97 
98  callback_->connectionError(
99  transport_.get(), std::move(handshakeException), sslError_);
100 }
101 
102 folly::AsyncSSLSocket::UniquePtr FizzAcceptorHandshakeHelper::createSSLSocket(
103  const std::shared_ptr<folly::SSLContext>& context,
104  folly::EventBase* evb,
105  int fd) {
107  context, evb, fd));
108 }
109 
110 void FizzAcceptorHandshakeHelper::fizzHandshakeAttemptFallback(
111  std::unique_ptr<folly::IOBuf> clientHello) {
112  VLOG(3) << "Fallback to OpenSSL";
113 
114  auto evb = transport_->getEventBase();
115  auto fd =
116  transport_->getUnderlyingTransport<folly::AsyncSocket>()->detachFd();
117  transport_.reset();
118 
119  sslSocket_ = createSSLSocket(sslContext_, evb, fd);
120  sslSocket_->setPreReceivedData(std::move(clientHello));
121  sslSocket_->enableClientHelloParsing();
122  sslSocket_->forceCacheAddrOnFailure(true);
123  sslSocket_->sslAccept(this);
124 }
125 
126 void FizzAcceptorHandshakeHelper::handshakeSuc(
128  auto appProto = sock->getApplicationProtocol();
129  if (!appProto.empty()) {
130  VLOG(3) << "Client selected next protocol " << appProto;
131  } else {
132  VLOG(3) << "Client did not select a next protocol";
133  }
134 
135  // fill in SSL-related fields from TransportInfo
136  // the other fields like RTT are filled in the Acceptor
137  tinfo_.acceptTime = acceptTime_;
138  tinfo_.sslSetupTime = std::chrono::duration_cast<std::chrono::milliseconds>(
139  std::chrono::steady_clock::now() - acceptTime_);
141 
142  // The callback will delete this.
143  callback_->connectionReady(std::move(sslSocket_),
144  std::move(appProto),
145  SecureTransportType::TLS,
146  SSLErrorEnum::NO_ERROR);
147 }
148 
149 void FizzAcceptorHandshakeHelper::handshakeErr(
150  folly::AsyncSSLSocket* sock,
152  auto elapsedTime = std::chrono::duration_cast<std::chrono::milliseconds>(
153  std::chrono::steady_clock::now() - acceptTime_);
154  VLOG(3) << "SSL handshake error after " << elapsedTime.count() << " ms; "
155  << sock->getRawBytesReceived() << " bytes received & "
156  << sock->getRawBytesWritten() << " bytes sent: " << ex.what();
157 
158  auto sslEx = folly::make_exception_wrapper<SSLException>(
159  sslError_, elapsedTime, sock->getRawBytesReceived());
160 
161  // The callback will delete this.
162  callback_->connectionError(sslSocket_.get(), sslEx, sslError_);
163 }
164 }
context
Definition: CMakeCache.txt:563
std::chrono::steady_clock::time_point now()
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
requires E e noexcept(noexcept(s.error(std::move(e))))
std::unique_ptr< AsyncSSLSocket, Destructor > UniquePtr
AsyncSSLSocket::UniquePtr sslSocket_
static void fillSSLTransportInfoFields(folly::AsyncSSLSocket *sock, TransportInfo &tinfo)
auto start
std::unique_ptr< AsyncFizzServerT, folly::DelayedDestruction::Destructor > UniquePtr
AsyncFizzClient::UniquePtr transport_
folly::Function< void()> callback_
AsyncFizzServerT< ServerStateMachine > AsyncFizzServer
std::unique_ptr< AsyncSocket, Destructor > UniquePtr
Definition: AsyncSocket.h:83