DiscordCoreAPI
A Discord bot library written in C++, with custom asynchronous coroutines.
Loading...
Searching...
No Matches
SSLClients.hpp
Go to the documentation of this file.
1/*
2 DiscordCoreAPI, A bot library for Discord, written in C++, and featuring explicit multithreading through the usage of custom, asynchronous C++ CoRoutines.
3
4 Copyright 2021, 2022 Chris M. (RealTimeChris)
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
19 USA
20*/
21/// SSLClents.hpp - Header file for the "SSL Client" stuff.
22/// Dec 12, 2021
23/// https://discordcoreapi.com
24/// \file SSLClients.hpp
25
26#pragma once
27
30
31#ifndef OPENSSL_NO_DEPRECATED
32 #define OPENSSL_NO_DEPRECATED
33#endif
34
35#include <openssl/err.h>
36#include <openssl/ssl.h>
37
38#ifdef _WIN32
39 #pragma comment(lib, "Ws2_32.lib")
40 #include <WinSock2.h>
41 #include <WS2tcpip.h>
42 #ifdef errno
43 #undef errno
44 #define errno WSAGetLastError()
45 #endif
46 #ifdef EWOULDBLOCK
47 #undef EWOULDBLOCK
48 #define EWOULDBLOCK WSAEWOULDBLOCK
49 #endif
50 #define poll(fd_set, fd_count, timeout) WSAPoll(fd_set, fd_count, timeout)
51 #define pollfd WSAPOLLFD
52 #define close closesocket
53 #define SHUT_RDWR SD_BOTH
54 #ifdef max
55 #undef max
56 #endif
57 #ifdef min
58 #undef min
59 #endif
60#elif __linux__
61 #include <netinet/tcp.h>
62 #include <netinet/in.h>
63 #include <sys/socket.h>
64 #include <sys/types.h>
65 #include <netdb.h>
66 #include <fcntl.h>
67 #include <poll.h>
68#endif
69
70namespace DiscordCoreInternal {
71
72#ifndef SOCKET_ERROR
73 #define SOCKET_ERROR (-1)
74#endif
75
76#ifndef INVALID_SOCKET
77 #define INVALID_SOCKET (~0)
78#endif
79
80#ifndef _WIN32
81 using SOCKET = int32_t;
82#endif
83
84 struct DiscordCoreAPI_Dll PollFDWrapper {
85 std::vector<size_t> indices{};
86 std::vector<pollfd> polls{};
87 };
88
89#ifdef _WIN32
90 struct DiscordCoreAPI_Dll WSADataWrapper {
91 struct DiscordCoreAPI_Dll WSADataDeleter {
92 void operator()(WSADATA* other);
93 };
94
95 WSADataWrapper();
96
97 protected:
98 std::unique_ptr<WSADATA, WSADataDeleter> ptr{ std::make_unique<WSADATA>().release(), WSADataDeleter{} };
99 };
100#endif
101
102 struct DiscordCoreAPI_Dll SSL_CTXWrapper {
103 struct DiscordCoreAPI_Dll SSL_CTXDeleter {
104 void operator()(SSL_CTX* other);
105 };
106
107 SSL_CTXWrapper& operator=(SSL_CTX* other);
108
109 operator SSL_CTX*();
110
111 protected:
112 std::unique_ptr<SSL_CTX, SSL_CTXDeleter> ptr{ nullptr, SSL_CTXDeleter{} };
113 };
114
115 struct DiscordCoreAPI_Dll SSLWrapper {
116 struct DiscordCoreAPI_Dll SSLDeleter {
117 void operator()(SSL* other);
118 };
119
120 SSLWrapper& operator=(nullptr_t other);
121
122 SSLWrapper& operator=(SSL* other);
123
124 operator SSL*();
125
126 protected:
127 std::unique_ptr<SSL, SSLDeleter> ptr{ nullptr, SSLDeleter{} };
128 };
129
130 struct DiscordCoreAPI_Dll SOCKETWrapper {
131 struct DiscordCoreAPI_Dll SOCKETDeleter {
132 void operator()(SOCKET* other);
133 };
134
135 SOCKETWrapper& operator=(SOCKET other) noexcept;
136
137 SOCKETWrapper(SOCKET other) noexcept;
138
139 operator SOCKET*() noexcept;
140
141 operator SOCKET() noexcept;
142
143 SOCKETWrapper() noexcept = default;
144
145 protected:
146 std::unique_ptr<SOCKET, SOCKETDeleter> ptr{ std::make_unique<SOCKET>(INVALID_SOCKET).release(), SOCKETDeleter{} };
147 };
148
149 struct DiscordCoreAPI_Dll addrinfoWrapper {
150 addrinfo* operator->();
151
152 operator addrinfo**();
153
154 operator addrinfo*();
155
156 protected:
157 addrinfo value{};
158 addrinfo* ptr{ &this->value };
159 };
160
161 class DiscordCoreAPI_Dll SSLConnectionInterface {
162 public:
163 virtual bool connect(const std::string& baseUrl, const uint16_t portNew, bool doWePrintErrorMessages,
164 bool areWeAStandaloneSocket) noexcept = 0;
165
166 virtual bool areWeStillConnected() noexcept = 0;
167
168 virtual void disconnect() noexcept = 0;
169
170 static bool initialize() noexcept;
171
172 virtual ~SSLConnectionInterface() noexcept = default;
173
174 protected:
175 static SSL_CTXWrapper context;
176 static std::mutex mutex;
177
178 SOCKETWrapper socket{};
179 SSLWrapper ssl{};
180 };
181
182 enum class ProcessIOResult : uint8_t { No_Error = 0, Error = 1 };
183
184 class DiscordCoreAPI_Dll SSLDataInterface {
185 public:
186 friend class HttpsClient;
187
188 virtual ProcessIOResult writeData(std::string_view dataToWrite, bool priority) noexcept = 0;
189
190 virtual std::string_view getInputBuffer() noexcept = 0;
191
192 virtual ~SSLDataInterface() noexcept = default;
193
194 protected:
195 const uint64_t maxBufferSize{ (1024 * 16) - 1 };
196 RingBuffer<char, 16> outputBuffer{};
197 RingBuffer<char, 64> inputBuffer{};
198 int64_t bytesRead{};
199 };
200
201 class DiscordCoreAPI_Dll TCPSSLClient : public SSLDataInterface, public SSLConnectionInterface {
202 public:
203 virtual void handleBuffer() noexcept = 0;
204
205 bool connect(const std::string& baseUrl, const uint16_t portNew, bool doWePrintErrorMessages, bool areWeAStandaloneSocket) noexcept;
206
207 static std::vector<TCPSSLClient*> processIO(std::unordered_map<uint32_t, std::unique_ptr<WebSocketClient>>& shardMap) noexcept;
208
209 ProcessIOResult writeData(std::string_view dataToWrite, bool priority) noexcept;
210
211 ProcessIOResult processIO(int32_t msToWait) noexcept;
212
213 std::string_view getInputBuffer() noexcept;
214
215 bool areWeStillConnected() noexcept;
216
217 bool processWriteData() noexcept;
218
219 bool processReadData() noexcept;
220
221 int64_t getBytesRead() noexcept;
222
223 virtual ~TCPSSLClient() noexcept = default;
224
225 protected:
226 bool doWePrintErrorMessages{};
227 bool areWeAStandaloneSocket{};
228 };
229
230 enum class ProcessIOType { Both = 0, Read_Only = 1, Write_Only = 2 };
231
232 class DiscordCoreAPI_Dll UDPConnection {
233 public:
235
236 UDPConnection(DiscordCoreAPI::StreamType streamType, bool doWePrintErrors) noexcept;
237
238 bool connect(const std::string& baseUrlNew, uint16_t portNew, std::stop_token token = std::stop_token{}) noexcept;
239
240 void writeData(std::basic_string_view<std::byte> dataToWrite) noexcept;
241
242 std::basic_string_view<std::byte> getInputBuffer() noexcept;
243
244 ProcessIOResult processIO(ProcessIOType type) noexcept;
245
246 virtual void handleAudioBuffer() noexcept = 0;
247
248 bool areWeStillConnected() noexcept;
249
250 bool processWriteData() noexcept;
251
252 bool processReadData() noexcept;
253
254 void disconnect() noexcept;
255
256 ~UDPConnection() noexcept;
257
258 protected:
259 const uint64_t maxBufferSize{ (1024 * 16) };
260 RingBuffer<std::byte, 16> outputBuffer{};
261 RingBuffer<std::byte, 16> inputBuffer{};
262 DiscordCoreAPI::StreamType streamType{};
263 addrinfoWrapper address{};
264 bool doWePrintErrors{};
265 SOCKETWrapper socket{};
266 std::string baseUrl{};
267 int64_t bytesRead{};
268 uint16_t port{};
269 };
270}
StreamType
For selecting the type of streamer that the given bot is, one must be one server and one of client pe...
Definition: Utilities.hpp:179
VoiceConnection class - represents the connection to a given voice Channel.