11
2- #ifndef SIMPLE_SOCKET_SOCKET_HPP
3- #define SIMPLE_SOCKET_SOCKET_HPP
2+ #ifndef SIMPLE_SOCKET_TLSCONNECTION_HPP
3+ #define SIMPLE_SOCKET_TLSCONNECTION_HPP
44
55#include " simple_socket/SimpleConnection.hpp"
66#include " simple_socket/socket_common.hpp"
77
8- #ifdef SIMPLE_SOCKET_WITH_TLS
98#include < openssl/err.h>
109#include < openssl/ssl.h>
11- #endif
1210
1311#ifndef _WIN32
1412#include < fcntl.h>
1513#endif
1614
17-
1815namespace simple_socket {
1916
20- struct Socket : SimpleConnection {
21-
22- explicit Socket (SOCKET socket)
23- : sockfd_(socket) {}
24-
25- int read (unsigned char * buffer, size_t size) override {
26-
27- #ifdef _WIN32
28- const auto read = recv (sockfd_, reinterpret_cast <char *>(buffer), static_cast <int >(size), 0 );
29- #else
30- const auto read = ::read (sockfd_, buffer, size);
31- #endif
32-
33- return (read != SOCKET_ERROR) && (read != 0 ) ? read : -1 ;
34- }
35-
36- bool write (const unsigned char * data, size_t size) override {
37-
38- #ifdef _WIN32
39- return send (sockfd_, reinterpret_cast <const char *>(data), static_cast <int >(size), 0 ) != SOCKET_ERROR;
40- #else
41- return ::write (sockfd_, data, size) != SOCKET_ERROR;
42- #endif
43- }
44-
45- void close () override {
46-
47- closeSocket (sockfd_);
48- }
49-
50- ~Socket () override {
51-
52- closeSocket (sockfd_);
53- }
54-
55- SOCKET sockfd_;
56- };
57-
58- #ifdef SIMPLE_SOCKET_WITH_TLS
59-
60-
61- // Helper: put socket into non-blocking mode
62- inline void set_nonblocking (SOCKET s) {
63- #ifdef _WIN32
64- u_long mode = 1 ;
65- ioctlsocket (s, FIONBIO, &mode);
66- #else
67- int flags = fcntl (s, F_GETFL, 0 );
68- if (flags >= 0 ) fcntl (s, F_SETFL, flags | O_NONBLOCK);
69- #endif
70- }
71-
72-
7317 class TLSConnection : public SimpleConnection {
7418 public:
75- TLSConnection (SOCKET sock, SSL* ssl, SSL_CTX* ctx = nullptr )
76- : sockfd_(sock), ssl_(ssl), ctx_(ctx) {
19+ TLSConnection (SOCKET sock, const std::string& ip)
20+ : sockfd_(sock) {
21+
22+ SSL_library_init ();
23+ SSL_load_error_strings ();
24+ const SSL_METHOD* method = TLS_client_method ();
25+ ctx_ = SSL_CTX_new (method);
26+ if (!ctx_) throw std::runtime_error (" Failed to create SSL context" );
27+
28+ ssl_ = SSL_new (ctx_);
29+ SSL_set_fd (ssl_, static_cast <int >(sock));
30+ SSL_set_tlsext_host_name (ssl_, ip.c_str ());
31+ if (SSL_connect (ssl_) <= 0 ) {
32+ ERR_print_errors_fp (stderr);
33+ throw std::runtime_error (" Failed to connect to TLS host" );
34+ }
7735
7836 set_nonblocking (sockfd_);
7937 // Ensure AUTO_RETRY is off for non-blocking semantics
8038 SSL_clear_mode (ssl_, SSL_MODE_AUTO_RETRY);
8139 }
8240
83-
8441 bool write (const uint8_t * buf, size_t len) override {
8542 if (!ssl_) return false ;
8643
@@ -93,9 +50,9 @@ namespace simple_socket {
9350 }
9451 const int err = SSL_get_error (ssl_, n);
9552 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
96- continue ; // retry
53+ continue ;// retry
9754 }
98- return false ; // fatal
55+ return false ;// fatal
9956 }
10057 return true ;
10158 }
@@ -108,12 +65,12 @@ namespace simple_socket {
10865 if (n > 0 ) return n;
10966
11067 const int err = SSL_get_error (ssl_, n);
111- if (err == SSL_ERROR_ZERO_RETURN) return 0 ; // clean TLS shutdown
68+ if (err == SSL_ERROR_ZERO_RETURN) return 0 ;// clean TLS shutdown
11269 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
11370 // retry until caller cancels via close()
11471 continue ;
11572 }
116- return -1 ; // fatal
73+ return -1 ;// fatal
11774 }
11875 }
11976
@@ -141,9 +98,19 @@ namespace simple_socket {
14198 SSL* ssl_;
14299 SSL_CTX* ctx_;
143100
144- };
101+ // Helper: put socket into non-blocking mode
102+ static void set_nonblocking (SOCKET s) {
103+ #ifdef _WIN32
104+ u_long mode = 1 ;
105+ ioctlsocket (s, FIONBIO, &mode);
106+ #else
107+ int flags = fcntl (s, F_GETFL, 0 );
108+ if (flags >= 0 ) fcntl (s, F_SETFL, flags | O_NONBLOCK);
145109#endif
110+ }
111+ };
112+
146113
147- }// namespace simple_socket
114+ }
148115
149- #endif // SIMPLE_SOCKET_SOCKET_HPP
116+ #endif // TLSCONNECTION_HPP
0 commit comments