userver: userver/engine/io/tls_wrapper.hpp Source File
⚠️ This is the documentation for an old userver version. Click here to switch to the latest version.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
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 [[nodiscard]] size_t WriteAll(std::initializer_list<IoData> list,
98 Deadline deadline) override;
99
100 int GetRawFd();
101
102 private:
103 explicit TlsWrapper(Socket&&);
104
105 void SetupContextAccessors();
106
107 class Impl;
108 class ReadContextAccessor;
109 constexpr static size_t kSize = 336;
110 constexpr static size_t kAlignment = 8;
111 utils::FastPimpl<Impl, kSize, kAlignment> impl_;
112};
113
114} // namespace engine::io
115
116USERVER_NAMESPACE_END