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.
23///
24/// Usage example:
25/// @snippet src/engine/io/tls_wrapper_test.cpp TLS wrapper usage
26class [[nodiscard]] TlsWrapper final : public RwBase {
27 public:
28 /// Starts a TLS client on an opened socket
29 static TlsWrapper StartTlsClient(Socket&& socket,
30 const std::string& server_name,
31 Deadline deadline);
32
33 /// Starts a TLS server on an opened socket
34 static TlsWrapper StartTlsServer(
35 Socket&& socket, const crypto::Certificate& cert,
36 const crypto::PrivateKey& key, Deadline deadline,
37 const std::vector<crypto::Certificate>& cert_authorities = {});
38
39 ~TlsWrapper() override;
40
41 TlsWrapper(const TlsWrapper&) = delete;
42 TlsWrapper(TlsWrapper&&) noexcept;
43
44 /// Whether the socket is valid.
45 explicit operator bool() const { return IsValid(); }
46
47 /// Whether the socket is valid.
48 bool IsValid() const override;
49
50 /// Suspends current task until the socket has data available.
51 [[nodiscard]] bool WaitReadable(Deadline) override;
52
53 /// Suspends current task until the socket can accept more data.
54 [[nodiscard]] bool WaitWriteable(Deadline) override;
55
56 /// @brief Receives at least one byte from the socket.
57 /// @returns 0 if connection is closed on one side and no data could be
58 /// received any more, received bytes count otherwise.
59 [[nodiscard]] size_t RecvSome(void* buf, size_t len, Deadline deadline);
60
61 /// @brief Receives exactly len bytes from the socket.
62 /// @note Can return less than len if socket is closed by peer.
63 [[nodiscard]] size_t RecvAll(void* buf, size_t len, Deadline deadline);
64
65 /// @brief Sends exactly len bytes to the socket.
66 /// @note Can return less than len if socket is closed by peer.
67 [[nodiscard]] size_t SendAll(const void* buf, size_t len, Deadline deadline);
68
69 /// @brief Finishes TLS session and returns the socket.
70 /// @warning Wrapper becomes invalid on entry and can only be used to retry
71 /// socket extraction if interrupted.
72 [[nodiscard]] Socket StopTls(Deadline deadline);
73
74 /// @brief Receives at least one byte from the socket.
75 /// @returns 0 if connection is closed on one side and no data could be
76 /// received any more, received bytes count otherwise.
77 [[nodiscard]] size_t ReadSome(void* buf, size_t len,
78 Deadline deadline) override {
79 return RecvSome(buf, len, deadline);
80 }
81
82 /// @brief Receives exactly len bytes from the socket.
83 /// @note Can return less than len if socket is closed by peer.
84 [[nodiscard]] size_t ReadAll(void* buf, size_t len,
85 Deadline deadline) override {
86 return RecvAll(buf, len, deadline);
87 }
88
89 /// @brief Writes exactly len bytes to the socket.
90 /// @note Can return less than len if socket is closed by peer.
91 [[nodiscard]] size_t WriteAll(const void* buf, size_t len,
92 Deadline deadline) override {
93 return SendAll(buf, len, deadline);
94 }
95
96 int GetRawFd();
97
98 private:
99 explicit TlsWrapper(Socket&&);
100
101 class Impl;
102 constexpr static size_t kSize = 296;
103 constexpr static size_t kAlignment = 8;
104 utils::FastPimpl<Impl, kSize, kAlignment> impl_;
105};
106
107} // namespace engine::io
108
109USERVER_NAMESPACE_END