SNode.C
Loading...
Searching...
No Matches
TlsLegacySocketContext.cpp
Go to the documentation of this file.
1/*
2 * SNode.C - A Slim Toolkit for Network Communication
3 * Copyright (C) Volker Christian <me@vchrist.at>
4 * 2020, 2021, 2022, 2023, 2024, 2025, 2026
5 */
6
8
9#include "core/socket/stream/SocketConnection.h"
10#include "log/Logger.h"
11
12#include <functional>
13
14namespace {
15 constexpr const char* TLS_HELLO = "TLS_HELLO\n";
16 constexpr const char* TLS_ACK = "TLS_ACK\n";
17 constexpr const char* LEGACY_HELLO = "LEGACY_HELLO\n";
18 constexpr const char* LEGACY_ACK = "LEGACY_ACK\n";
19} // namespace
20
21namespace apps::tlslegacy {
22
24 : core::socket::stream::SocketContext(socketConnection)
25 , role(role) {
26 }
27
36
41
43 return true;
44 }
45
46 void TlsLegacySocketContext::startLegacyRetryTimer(const std::string& payload) {
48
50 [this, payload](const std::function<void()>& stop) {
52 stop();
53 return;
54 }
55
56 sendToPeer(payload);
57 VLOG(1) << getSocketConnection()->getConnectionName() << ": trying post-TLS legacy payload: " << payload;
58 },
59 utils::Timeval(0.5));
60 }
61
62 void TlsLegacySocketContext::onClientLine(const std::string& line) {
63 if (line == TLS_ACK && !tlsReplySeen) {
64 tlsReplySeen = true;
65 VLOG(1) << getSocketConnection()->getConnectionName() << ": got TLS ack, initiating TLS shutdown handshake (close_notify) "
66 << line;
69 } else if (line == LEGACY_ACK && !legacyReplySeen) {
70 legacyReplySeen = true;
72 VLOG(1) << getSocketConnection()->getConnectionName() << ": got LEGACY ack -> post-TLS plaintext path works " << line;
74 }
75 }
76
77 void TlsLegacySocketContext::onServerLine(const std::string& line) {
78 if (line == TLS_HELLO && !tlsReplySeen) {
79 tlsReplySeen = true;
81 VLOG(1) << getSocketConnection()->getConnectionName() << ": TLS phase complete, waiting for peer close_notify " << line;
82 } else if (line == LEGACY_HELLO && !legacyPayloadSeen) {
83 legacyPayloadSeen = true;
86 VLOG(1) << getSocketConnection()->getConnectionName() << ": received LEGACY payload after TLS shutdown " << line;
88 }
89 }
90
92 char chunk[4096];
93 const std::size_t chunkLen = readFromPeer(chunk, sizeof(chunk));
94
95 if (chunkLen == 0) {
96 return 0;
97 }
98
99 inboundBuffer.append(chunk, chunkLen);
100
101 std::size_t pos = std::string::npos;
102 while ((pos = inboundBuffer.find('\n')) != std::string::npos) {
103 const std::string line = inboundBuffer.substr(0, pos + 1);
104 inboundBuffer.erase(0, pos + 1);
105
106 if (role == Role::CLIENT) {
107 onClientLine(line);
108 } else {
109 onServerLine(line);
110 }
111 }
112
113 return chunkLen;
114 }
115
116 core::socket::stream::SocketContext*
120
121 core::socket::stream::SocketContext*
125
126} // namespace apps::tlslegacy
#define VLOG(level)
Definition Logger.h:164
core::socket::stream::SocketContext * create(core::socket::stream::SocketConnection *socketConnection) override
core::socket::stream::SocketContext * create(core::socket::stream::SocketConnection *socketConnection) override
void startLegacyRetryTimer(const std::string &payload)
TlsLegacySocketContext(core::socket::stream::SocketConnection *socketConnection, Role role)
void cancel()
Definition Timer.cpp:84
void sendToPeer(const std::string &data) const
const std::string & getConnectionName() const
SocketConnection * getSocketConnection() const
SocketContext(core::socket::stream::SocketConnection *socketConnection)
std::size_t readFromPeer(char *chunk, std::size_t chunklen) const final
Timer & operator=(Timer &&timer) noexcept=default
static Timer intervalTimer(const std::function< void(const std::function< void()> &)> &dispatcher, const utils::Timeval &timeout)
Definition Timer.cpp:61
LogMessage(Level level, int verboseLevel=-1, bool withErrno=false)
Definition Logger.cpp:280
Timeval(double time) noexcept
Definition Timeval.cpp:65
Definition Timer.h:59