userver: userver/engine/io/tls_wrapper.hpp Source File
Loading...
Searching...
No Matches
tls_wrapper.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/engine/io/tls_wrapper.hpp
4/// @brief TLS socket wrappers
5
6#include <string>
7#include <vector>
8
9#include <userver/crypto/certificate.hpp>
10#include <userver/crypto/private_key.hpp>
11#include <userver/engine/deadline.hpp>
12#include <userver/engine/io/common.hpp>
13#include <userver/engine/io/socket.hpp>
14#include <userver/utils/fast_pimpl.hpp>
15
16USERVER_NAMESPACE_BEGIN
17
18namespace engine::io {
19
20/// Class for TLS communications over a Socket.
21///
22/// Not thread safe. E.g. you MAY NOT read and write concurrently from multiple
23/// coroutines.
24///
25/// Usage example:
26/// @snippet src/engine/io/tls_wrapper_test.cpp TLS wrapper usage
27class [[nodiscard]] TlsWrapper final : public RwBase {
28 public:
29 /// Starts a TLS client on an opened socket
30 static TlsWrapper StartTlsClient(Socket&& socket,
31 const std::string& server_name,
32 Deadline deadline);
33
34 /// Starts a TLS server on an opened socket
35 static TlsWrapper StartTlsServer(
36 Socket&& socket, const crypto::Certificate& cert,
37 const crypto::PrivateKey& key, Deadline deadline,
38 const std::vector<crypto::Certificate>& cert_authorities = {});
39
40 ~TlsWrapper() override;
41
42 TlsWrapper(const TlsWrapper&) = delete;
43 TlsWrapper(TlsWrapper&&) noexcept;
44
45 /// Whether the socket is valid.
46 explicit operator bool() const { return IsValid(); }
47
48 /// Whether the socket is valid.
49 bool IsValid() const override;
50
51 /// Suspends current task until the socket has data available.
52 [[nodiscard]] bool WaitReadable(Deadline) override;
53
54 /// Suspends current task until the socket can accept more data.
55 [[nodiscard]] bool WaitWriteable(Deadline) override;
56
57 /// @brief Receives at least one byte from the socket.
58 /// @returns 0 if connection is closed on one side and no data could be
59 /// received any more, received bytes count otherwise.
60 [[nodiscard]] size_t RecvSome(void* buf, size_t len, Deadline deadline);
61
62 /// @brief Receives exactly len bytes from the socket.
63 /// @note Can return less than len if socket is closed by peer.
64 [[nodiscard]] size_t RecvAll(void* buf, size_t len, Deadline deadline);
65
66 /// @brief Sends exactly len bytes to the socket.
67 /// @note Can return less than len if socket is closed by peer.
68 [[nodiscard]] size_t SendAll(const void* buf, size_t len, Deadline deadline);
69
70 /// @brief Finishes TLS session and returns the socket.
71 /// @warning Wrapper becomes invalid on entry and can only be used to retry
72 /// socket extraction if interrupted.
73 [[nodiscard]] Socket StopTls(Deadline deadline);
74
75 /// @brief Receives at least one byte from the socket.
76 /// @returns 0 if connection is closed on one side and no data could be
77 /// received any more, received bytes count otherwise.
78 [[nodiscard]] size_t ReadSome(void* buf, size_t len,
79 Deadline deadline) override {
80 return RecvSome(buf, len, deadline);
81 }
82
83 /// @brief Receives exactly len bytes from the socket.
84 /// @note Can return less than len if socket is closed by peer.
85 [[nodiscard]] size_t ReadAll(void* buf, size_t len,
86 Deadline deadline) override {
87 return RecvAll(buf, len, deadline);
88 }
89
90 /// @brief Writes exactly len bytes to the socket.
91 /// @note Can return less than len if socket is closed by peer.
92 [[nodiscard]] size_t WriteAll(const void* buf, size_t len,
93 Deadline deadline) override {
94 return SendAll(buf, len, deadline);
95 }
96
97 int GetRawFd();
98
99 private:
100 explicit TlsWrapper(Socket&&);
101
102 void SetupContextAccessors();
103
104 class Impl;
105 class ReadContextAccessor;
106 constexpr static size_t kSize = 336;
107 constexpr static size_t kAlignment = 8;
108 utils::FastPimpl<Impl, kSize, kAlignment> impl_;
109};
110
111} // namespace engine::io
112
113USERVER_NAMESPACE_END