2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
42#include "core/socket/stream/SocketConnection.hpp"
43#include "core/socket/stream/tls/SocketConnection.h"
44#include "core/socket/stream/tls/TLSHandshake.h"
45#include "core/socket/stream/tls/TLSShutdown.h"
47#ifndef DOXYGEN_SHOULD_SKIP_THIS
49#include "core/socket/stream/tls/ssl_utils.h"
50#include "log/Logger.h"
52#include <openssl/ssl.h>
60 template <
typename PhysicalSocket,
typename Config>
61 SocketConnection<PhysicalSocket, Config>::
SocketConnection(PhysicalSocket&& physicalSocket,
62 const std::function<
void(SocketConnection*)>& onDisconnect,
63 const std::shared_ptr<Config>& config)
65 std::move(physicalSocket),
66 [onDisconnect,
this]() {
72 template <
typename PhysicalSocket,
typename Config>
73 SSL* SocketConnection<PhysicalSocket, Config>::
getSSL()
const {
77 template <
typename PhysicalSocket,
typename Config>
78 SSL* SocketConnection<PhysicalSocket, Config>::
startSSL(
79 int fd, SSL_CTX* ctx,
const utils::
Timeval& sslInitTimeout,
const utils::
Timeval& sslShutdownTimeout,
bool closeNotifyIsEOF) {
86 SSL_set_ex_data(
ssl, 0,
const_cast<std::string*>(&Super::getConnectionName()));
88 if (SSL_set_fd(
ssl, fd) == 1) {
89 SocketReader::ssl =
ssl;
90 SocketWriter::ssl =
ssl;
91 SocketReader::closeNotifyIsEOF = closeNotifyIsEOF;
92 SocketWriter::closeNotifyIsEOF = closeNotifyIsEOF;
103 template <
typename PhysicalSocket,
typename Config>
104 void SocketConnection<PhysicalSocket, Config>::
stopSSL() {
105 if (
ssl !=
nullptr) {
109 SocketReader::ssl =
nullptr;
110 SocketWriter::ssl =
nullptr;
114 template <
typename PhysicalSocket,
typename Config>
115 bool SocketConnection<PhysicalSocket, Config>::
doSSLHandshake(
const std::function<
void()>& onSuccess,
116 const std::function<
void()>& onTimeout,
117 const std::function<
void(
int)>& onStatus) {
118 if (
ssl !=
nullptr) {
119 if (!SocketReader::isSuspended()) {
120 SocketReader::suspend();
122 if (!SocketWriter::isSuspended()) {
123 SocketWriter::suspend();
127 Super::getConnectionName()
,
129 [onSuccess,
this]() {
130 SocketReader::span();
136 [onStatus](
int sslErr) {
142 return ssl !=
nullptr;
145 template <
typename PhysicalSocket,
typename Config>
147 bool resumeSocketReader =
false;
148 bool resumeSocketWriter =
false;
150 if (!SocketReader::isSuspended()) {
151 SocketReader::suspend();
152 resumeSocketReader =
true;
155 if (!SocketWriter::isSuspended()) {
156 SocketWriter::suspend();
157 resumeSocketWriter =
true;
161 Super::getConnectionName()
,
163 [
this, resumeSocketReader, resumeSocketWriter]() {
164 if (resumeSocketReader) {
165 SocketReader::resume();
167 if (resumeSocketWriter) {
168 SocketWriter::resume();
170 if (SSL_get_shutdown(
ssl) == (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN)) {
171 LOG(DEBUG) << Super::getConnectionName() <<
" SSL/TLS: Close_notify received and sent";
173 LOG(DEBUG) << Super::getConnectionName() <<
" SSL/TLS: Close_notify sent";
175 if (SSL_get_shutdown(
ssl) == SSL_SENT_SHUTDOWN && SocketWriter::closeNotifyIsEOF) {
176 LOG(TRACE) << Super::getConnectionName() <<
" SSL/TLS: Close_notify is EOF: setting sslShutdownTimeout to "
182 [
this, resumeSocketReader, resumeSocketWriter]() {
183 if (resumeSocketReader) {
184 SocketReader::resume();
186 if (resumeSocketWriter) {
187 SocketWriter::resume();
189 LOG(ERROR) << Super::getConnectionName() <<
" SSL/TLS: Shutdown handshake timed out";
190 Super::doWriteShutdown([
this]() {
191 SocketConnection::close();
194 [
this, resumeSocketReader, resumeSocketWriter](
int sslErr) {
195 if (resumeSocketReader) {
196 SocketReader::resume();
198 if (resumeSocketWriter) {
199 SocketWriter::resume();
201 ssl_log(Super::getConnectionName() +
" SSL/TLS: Shutdown handshake failed", sslErr);
202 Super::doWriteShutdown([
this]() {
203 SocketConnection::close();
209 template <
typename PhysicalSocket,
typename Config>
211 if ((SSL_get_shutdown(
ssl) & SSL_RECEIVED_SHUTDOWN) != 0) {
212 if ((SSL_get_shutdown(
ssl) & SSL_SENT_SHUTDOWN) != 0) {
213 LOG(DEBUG) << Super::getConnectionName() <<
" SSL/TLS: Close_notify sent and received";
215 SocketWriter::shutdownInProgress =
false;
217 LOG(DEBUG) << Super::getConnectionName() <<
" SSL/TLS: Close_notify received";
222 LOG(ERROR) << Super::getConnectionName() <<
" SSL/TLS: Unexpected EOF error";
224 SocketWriter::shutdownInProgress =
false;
225 SSL_set_shutdown(
ssl, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
229 template <
typename PhysicalSocket,
typename Config>
230 void SocketConnection<PhysicalSocket, Config>::
doWriteShutdown(
const std::function<
void()>& onShutdown) {
231 if ((SSL_get_shutdown(
ssl) & SSL_SENT_SHUTDOWN) == 0) {
232 LOG(DEBUG) << Super::getConnectionName() <<
" SSL/TLS: Send close_notify";
236 Super::doWriteShutdown(onShutdown);
utils::Timeval sslShutdownTimeout
SocketConnection(PhysicalSocket &&physicalSocket, const std::function< void(SocketConnection *)> &onDisconnect, const std::shared_ptr< Config > &config)
void doWriteShutdown(const std::function< void()> &onShutdown) final
SSL * startSSL(int fd, SSL_CTX *ctx, const utils::Timeval &sslInitTimeout, const utils::Timeval &sslShutdownTimeout, bool closeNotifyIsEOF)
utils::Timeval sslInitTimeout
void onReadShutdown() final
bool doSSLHandshake(const std::function< void()> &onSuccess, const std::function< void()> &onTimeout, const std::function< void(int)> &onStatus) final
static void doHandshake(const std::string &instanceName, SSL *ssl, const std::function< void(void)> &onSuccess, const std::function< void(void)> &onTimeout, const std::function< void(int)> &onStatus, const utils::Timeval &timeout)
static void doShutdown(const std::string &instanceName, SSL *ssl, const std::function< void(void)> &onSuccess, const std::function< void(void)> &onTimeout, const std::function< void(int)> &onStatus, const utils::Timeval &timeout)
Timeval & operator=(const Timeval &timeVal)