25#ifndef __JOIN_SOCKET_HPP__
26#define __JOIN_SOCKET_HPP__
37#include <openssl/err.h>
44#include <netinet/tcp.h>
45#include <linux/icmp.h>
58 template <
class Protocol>
62 using Ptr = std::unique_ptr <BasicSocket <Protocol>>;
153 other._protocol = Protocol ();
165 this->
_state = other._state;
166 this->
_mode = other._mode;
173 other._protocol = Protocol ();
209 lastError = std::make_error_code (
static_cast <std::errc
> (errno));
245 if (endpoint.protocol ().family () == AF_PACKET)
247 if (
reinterpret_cast <const struct sockaddr_ll*
> (endpoint.addr ())->sll_ifindex == 0)
249 lastError = std::make_error_code (std::errc::no_such_device);
253 else if ((endpoint.protocol ().family () == AF_INET6) || (endpoint.protocol ().family () == AF_INET))
257 else if (endpoint.protocol ().family () == AF_UNIX)
259 ::unlink (endpoint.device ().c_str ());
262 if (
::bind (this->
_handle, endpoint.addr (), endpoint.length ()) == -1)
264 lastError = std::make_error_code (
static_cast <std::errc
> (errno));
280 if (::ioctl (this->
_handle, FIONREAD, &available) == -1)
282 lastError = std::make_error_code (
static_cast <std::errc
> (errno));
296 return (this->
wait (
true,
false, timeout) == 0);
305 virtual int read (
char *data,
unsigned long maxSize)
noexcept
309 iov.iov_len = maxSize;
311 struct msghdr message;
312 message.msg_name =
nullptr;
313 message.msg_namelen = 0;
314 message.msg_iov = &iov;
315 message.msg_iovlen = 1;
316 message.msg_control =
nullptr;
317 message.msg_controllen = 0;
319 int size = ::recvmsg (this->
_handle, &message, 0);
324 lastError = std::make_error_code (
static_cast <std::errc
> (errno));
343 return (this->
wait (
false,
true, timeout) == 0);
352 virtual int write (
const char *data,
unsigned long maxSize)
noexcept
355 iov.iov_base =
const_cast <char *
> (data);
356 iov.iov_len = maxSize;
358 struct msghdr message;
359 message.msg_name =
nullptr;
360 message.msg_namelen = 0;
361 message.msg_iov = &iov;
362 message.msg_iovlen = 1;
363 message.msg_control =
nullptr;
364 message.msg_controllen = 0;
366 int result = ::sendmsg (this->
_handle, &message, 0);
369 lastError = std::make_error_code (
static_cast <std::errc
> (errno));
386 int flags = ::fcntl (this->
_handle, F_GETFL, 0);
390 flags = flags | O_NONBLOCK;
394 flags = flags & ~O_NONBLOCK;
397 ::fcntl (this->
_handle, F_SETFL, flags);
409 int optlevel, optname;
414 optlevel = SOL_SOCKET;
415 optname = SO_KEEPALIVE;
419 optlevel = SOL_SOCKET;
424 optlevel = SOL_SOCKET;
429 optlevel = SOL_SOCKET;
430 optname = SO_TIMESTAMP;
434 optlevel = SOL_SOCKET;
435 optname = SO_REUSEADDR;
439 optlevel = SOL_SOCKET;
440 optname = SO_REUSEPORT;
444 optlevel = SOL_SOCKET;
445 optname = SO_BROADCAST;
449 optlevel = SOL_PACKET;
450 optname = PACKET_AUXDATA;
458 int result = ::setsockopt (this->
_handle, optlevel, optname, &value,
sizeof (value));
461 lastError = std::make_error_code (
static_cast <std::errc
> (errno));
474 struct sockaddr_storage sa;
475 socklen_t sa_len =
sizeof (
struct sockaddr_storage);
477 if (::getsockname (this->
_handle,
reinterpret_cast <struct sockaddr*
> (&sa), &sa_len) == -1)
482 return Endpoint (
reinterpret_cast <struct sockaddr*
> (&sa), sa_len);
546 static uint16_t
checksum (
const uint16_t* data,
size_t len, uint16_t current = 0)
548 uint32_t sum = current;
558 #if __BYTE_ORDER == __LITTLE_ENDIAN
559 sum += *
reinterpret_cast <const uint8_t *
> (data);
561 sum += *
reinterpret_cast <const uint8_t *
> (data) << 8;
565 sum = (sum >> 16) + (sum & 0xffff);
568 return static_cast <uint16_t
> (~sum);
579 int wait (
bool wantRead,
bool wantWrite,
int timeout)
const noexcept
581 struct pollfd
handle { .fd = this->_handle, .events = 0, .revents = 0 };
593 int nset = (
handle.fd > -1) ? ::poll (&
handle, 1, timeout) : -1;
602 lastError = std::make_error_code (
static_cast <std::errc
> (errno));
634 template <
class Protocol>
635 constexpr bool operator< (
const BasicSocket <Protocol>& a,
const BasicSocket <Protocol>& b)
noexcept
637 return a.handle () < b.handle ();
643 template <
class Protocol>
647 using Ptr = std::unique_ptr <BasicDatagramSocket <Protocol>>;
703 BasicSocket <Protocol>::operator= (std::move (other));
705 _remote = std::move (other._remote);
723 virtual int open (
const Protocol&
protocol = Protocol ()) noexcept
override
733 if ((
protocol.protocol () == IPPROTO_UDP) || (
protocol.protocol () == IPPROTO_TCP))
735 if ((
protocol.family () == AF_INET6) && (::setsockopt (this->_handle, IPPROTO_IPV6, IPV6_V6ONLY, &off, sizeof (off)) == -1))
737 lastError = std::make_error_code (
static_cast <std::errc
> (errno));
743 if ((
protocol.protocol () == IPPROTO_ICMPV6) || (
protocol.protocol () == IPPROTO_ICMP))
745 if ((
protocol.family () == AF_INET) && (::setsockopt (this->_handle, IPPROTO_IP, IP_HDRINCL, &off, sizeof (off)) == -1))
747 lastError = std::make_error_code (
static_cast <std::errc
> (errno));
766 if (this->
_state == State::Closed)
772 if (this->
_state == State::Connected)
778 if ((this->
_protocol.family () == AF_INET6) || (this->_protocol.family () == AF_INET))
783 int result = setsockopt (this->
_handle, SOL_SOCKET, SO_BINDTODEVICE, device.c_str (), device.size ());
786 lastError = std::make_error_code (
static_cast <std::errc
> (errno));
800 if ((this->
_state != State::Closed) && (this->
_state != State::Disconnected))
806 if ((this->
_state == State::Closed) && (this->
open (endpoint.protocol ()) == -1))
811 int result =
::connect (this->
_handle, endpoint.addr (), endpoint.length ());
813 this->
_state = State::Connecting;
818 lastError = std::make_error_code (
static_cast <std::errc
> (errno));
819 if (lastError != std::errc::operation_in_progress)
826 this->
_state = State::Connected;
837 if (this->
_state == State::Connected)
839 struct sockaddr_storage nullAddr;
840 ::memset (&nullAddr, 0,
sizeof (nullAddr));
842 nullAddr.ss_family = AF_UNSPEC;
844 int result =
::connect (this->
_handle,
reinterpret_cast <struct sockaddr*
> (&nullAddr),
sizeof (
struct sockaddr_storage));
847 if (errno != EAFNOSUPPORT)
849 lastError = std::make_error_code (
static_cast <std::errc
> (errno));
854 this->
_state = State::Disconnected;
864 virtual void close () noexcept
override
876 virtual int read (
char *data,
unsigned long maxSize)
noexcept override
888 virtual int readFrom (
char* data,
unsigned long maxSize,
Endpoint* endpoint =
nullptr) noexcept
890 struct sockaddr_storage sa;
891 socklen_t sa_len =
sizeof (
struct sockaddr_storage);
893 int size = ::recvfrom (this->
_handle, data, maxSize, 0,
reinterpret_cast <struct sockaddr*
> (&sa), &sa_len);
898 lastError = std::make_error_code (
static_cast <std::errc
> (errno));
903 this->
_state = State::Disconnected;
909 if (endpoint !=
nullptr)
911 *endpoint =
Endpoint (
reinterpret_cast <struct sockaddr*
> (&sa), sa_len);
923 virtual int write (
const char *data,
unsigned long maxSize)
noexcept override
935 virtual int writeTo (
const char* data,
unsigned long maxSize,
const Endpoint& endpoint)
noexcept
937 if ((this->
_state == State::Closed) && (this->
open (endpoint.protocol ()) == -1))
942 int result = ::sendto (this->
_handle, data, maxSize, 0, endpoint.addr (), endpoint.length ());
945 lastError = std::make_error_code (
static_cast <std::errc
> (errno));
960 if (this->
_state == State::Closed)
966 int optlevel, optname;
971 if (this->
family () == AF_INET6)
973 optlevel = IPPROTO_IPV6;
974 optname = IPV6_UNICAST_HOPS;
978 optlevel = IPPROTO_IP;
983 case Option::MulticastLoop:
984 if (this->
family () == AF_INET6)
986 optlevel = IPPROTO_IPV6;
987 optname = IPV6_MULTICAST_LOOP;
991 optlevel = IPPROTO_IP;
992 optname = IP_MULTICAST_LOOP;
996 case Option::MulticastTtl:
997 if (this->
family () == AF_INET6)
999 optlevel = IPPROTO_IPV6;
1000 optname = IPV6_MULTICAST_HOPS;
1004 optlevel = IPPROTO_IP;
1005 optname = IP_MULTICAST_TTL;
1009 case Option::PathMtuDiscover:
1010 if (this->
family () == AF_INET6)
1012 optlevel = IPPROTO_IPV6;
1013 optname = IPV6_MTU_DISCOVER;
1017 optlevel = IPPROTO_IP;
1018 optname = IP_MTU_DISCOVER;
1022 case Option::RcvError:
1023 if (this->
family () == AF_INET6)
1025 optlevel = IPPROTO_IPV6;
1026 optname = IPV6_RECVERR;
1030 optlevel = IPPROTO_IP;
1031 optname = IP_RECVERR;
1039 int result = ::setsockopt (this->
_handle, optlevel, optname, &value,
sizeof (value));
1042 lastError = std::make_error_code (
static_cast <std::errc
> (errno));
1064 return (this->
_state == State::Connected);
1073 if (this->
_state == State::Closed)
1079 int result = -1, value = -1;
1080 socklen_t valueLen =
sizeof (value);
1082 if (this->
_protocol.family () == AF_INET6)
1084 result = ::getsockopt (this->
_handle, IPPROTO_IPV6, IPV6_MTU, &value, &valueLen);
1086 else if (this->
_protocol.family () == AF_INET)
1088 result = ::getsockopt (this->
_handle, IPPROTO_IP, IP_MTU, &value, &valueLen);
1098 lastError = std::make_error_code (
static_cast <std::errc
> (errno));
1128 template <
class Protocol>
1129 constexpr bool operator< (
const BasicDatagramSocket <Protocol>& a,
const BasicDatagramSocket <Protocol>& b)
noexcept
1131 return a.handle () < b.handle ();
1137 template <
class Protocol>
1141 using Ptr = std::unique_ptr <BasicStreamSocket <Protocol>>;
1193 BasicDatagramSocket <Protocol>::operator= (std::move (other));
1210 if (this->
_state != State::Connected)
1212 if (this->
_state != State::Connecting)
1235 if (this->
_state == State::Connected)
1237 ::shutdown (this->
_handle, SHUT_WR);
1238 this->
_state = State::Disconnecting;
1241 if (this->
_state == State::Disconnecting)
1249 int result = this->
read (buffer,
sizeof (buffer));
1261 ::shutdown (this->
_handle, SHUT_RD);
1262 this->
_state = State::Disconnected;
1277 if ((this->
_state != State::Disconnected) && (this->
_state != State::Closed))
1279 if (this->
_state != State::Disconnecting)
1285 auto start = std::chrono::steady_clock::now ();
1302 elapsed = std::chrono::duration_cast <std::chrono::milliseconds> (std::chrono::steady_clock::now () - start).count ();
1321 unsigned long numRead = 0;
1323 while (numRead < size)
1325 int result = this->
read (data + numRead, size - numRead);
1350 int readExactly (std::string& data,
unsigned long size,
int timeout = 0)
1365 unsigned long numWrite = 0;
1367 while (numWrite < size)
1369 int result = this->
write (data + numWrite, size - numWrite);
1395 if (this->
_state == State::Closed)
1401 int optlevel, optname;
1405 case Option::NoDelay:
1406 optlevel = IPPROTO_TCP;
1407 optname = TCP_NODELAY;
1410 case Option::KeepIdle:
1411 optlevel = IPPROTO_TCP;
1412 optname = TCP_KEEPIDLE;
1415 case Option::KeepIntvl:
1416 optlevel = IPPROTO_TCP;
1417 optname = TCP_KEEPINTVL;
1420 case Option::KeepCount:
1421 optlevel = IPPROTO_TCP;
1422 optname = TCP_KEEPCNT;
1429 int result = ::setsockopt (this->
_handle, optlevel, optname, &value,
sizeof (value));
1432 lastError = std::make_error_code (
static_cast <std::errc
> (errno));
1445 return (this->
_state == State::Connecting);
1454 if (this->
_state == State::Connected)
1458 else if (this->
_state != State::Connecting)
1464 socklen_t optlen =
sizeof (optval);
1466 int result = ::getsockopt (this->
_handle, SOL_SOCKET, SO_ERROR, &optval, &optlen);
1467 if ((result == -1) || (optval != 0))
1472 this->
_state = State::Connected;
1487 template <
class Protocol>
1488 constexpr bool operator< (
const BasicStreamSocket <Protocol>& a,
const BasicStreamSocket <Protocol>& b)
noexcept
1490 return a.handle () < b.handle ();
1512 virtual const char*
name ()
const noexcept;
1519 virtual std::string
message (
int code)
const;
1545 template <
class Protocol>
1549 using Ptr = std::unique_ptr <BasicTlsSocket <Protocol>>;
1572 SSL_CTX_set_options (this->
_tlsContext.get (), SSL_OP_ALL);
1575 SSL_CTX_set_options (this->
_tlsContext.get (), SSL_OP_NO_COMPRESSION);
1578 SSL_CTX_set_options (this->
_tlsContext.get (), SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1);
1581 SSL_CTX_set_mode (this->
_tlsContext.get (), SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
1584 SSL_CTX_set_mode (this->
_tlsContext.get (), SSL_MODE_AUTO_RETRY);
1587 SSL_CTX_set_session_cache_mode (this->
_tlsContext.get (), SSL_SESS_CACHE_CLIENT);
1590 SSL_CTX_set_verify (this->
_tlsContext.get (), SSL_VERIFY_NONE,
nullptr);
1619 throw std::invalid_argument (
"OpenSSL context is invalid");
1648 SSL_set_app_data (this->
_tlsHandle.get (),
this);
1661 BasicStreamSocket <Protocol>::operator= (std::move (other));
1663 this->
_tlsContext = std::move (other._tlsContext);
1664 this->
_tlsHandle = std::move (other._tlsHandle);
1669 SSL_set_app_data (this->
_tlsHandle.get (),
this);
1718 if (SSL_set_fd (this->
_tlsHandle.get (), this->_handle) != 1)
1725 if (SSL_is_server (this->
_tlsHandle.get ()) == 0)
1727 if (!this->
_remote.hostname ().empty () && (SSL_set_tlsext_host_name (this->
_tlsHandle.get (), this->_remote.hostname ().c_str ()) != 1))
1734 SSL_set_connect_state (this->
_tlsHandle.get ());
1738 SSL_set_accept_state (this->
_tlsHandle.get ());
1741 SSL_set_app_data (this->
_tlsHandle.get (),
this);
1762 if (this->
_state == State::Connecting)
1803 if ((SSL_get_shutdown (this->
_tlsHandle.get ()) & SSL_SENT_SHUTDOWN) ==
false)
1806 int result = SSL_shutdown (this->
_tlsHandle.get ());
1810 switch (SSL_get_error (this->
_tlsHandle.get (), result))
1812 case SSL_ERROR_WANT_READ:
1813 case SSL_ERROR_WANT_WRITE:
1817 case SSL_ERROR_SYSCALL:
1826 this->
_state = State::Disconnected;
1829 lastError = std::make_error_code (
static_cast <std::errc
> (errno));
1836 std::cout << ERR_reason_error_string (ERR_get_error ()) << std::endl;
1844 else if (result == 1)
1881 return (this->
wait (SSL_want_read (this->
_tlsHandle.get ()), SSL_want_write (this->
_tlsHandle.get ()), timeout) == 0);
1895 return SSL_pending (this->
_tlsHandle.get ());
1907 virtual int read (
char *data,
unsigned long maxSize)
noexcept override
1912 int result = SSL_read (this->
_tlsHandle.get (), data, int (maxSize));
1915 switch (SSL_get_error (this->
_tlsHandle.get (), result))
1917 case SSL_ERROR_WANT_READ:
1918 case SSL_ERROR_WANT_WRITE:
1919 case SSL_ERROR_WANT_X509_LOOKUP:
1923 case SSL_ERROR_ZERO_RETURN:
1927 if (SSL_get_shutdown (this->
_tlsHandle.get ()) & SSL_SENT_SHUTDOWN)
1932 case SSL_ERROR_SYSCALL:
1941 this->
_state = State::Disconnected;
1944 lastError = std::make_error_code (
static_cast <std::errc
> (errno));
1951 std::cout << ERR_reason_error_string (ERR_get_error ()) << std::endl;
1975 return (this->
wait (SSL_want_read (this->
_tlsHandle.get ()), SSL_want_write (this->
_tlsHandle.get ()), timeout) == 0);
1987 virtual int write (
const char *data,
unsigned long maxSize)
noexcept override
1992 int result = SSL_write (this->
_tlsHandle.get (), data, int (maxSize));
1995 switch (SSL_get_error (this->
_tlsHandle.get (), result))
1997 case SSL_ERROR_WANT_READ:
1998 case SSL_ERROR_WANT_WRITE:
1999 case SSL_ERROR_WANT_X509_LOOKUP:
2003 case SSL_ERROR_ZERO_RETURN:
2007 if (SSL_get_shutdown (this->
_tlsHandle.get ()) & SSL_SENT_SHUTDOWN)
2012 case SSL_ERROR_SYSCALL:
2021 this->
_state = State::Disconnected;
2024 lastError = std::make_error_code (
static_cast <std::errc
> (errno));
2031 std::cout << ERR_reason_error_string (ERR_get_error ()) << std::endl;
2063 if (((this->
_tlsHandle) ? SSL_use_certificate_file (this->
_tlsHandle.get (), cert.c_str (), SSL_FILETYPE_PEM)
2064 : SSL_CTX_use_certificate_file (this->
_tlsContext.get (), cert.c_str (), SSL_FILETYPE_PEM)) == 0)
2073 : SSL_CTX_use_PrivateKey_file (this->
_tlsContext.get (),
key.c_str (), SSL_FILETYPE_PEM)) == 0)
2081 : SSL_CTX_check_private_key (this->
_tlsContext.get ())) == 0)
2098 if (stat (caPath.c_str (), &st) != 0 || !S_ISDIR (st.st_mode) ||
2099 SSL_CTX_load_verify_locations (this->
_tlsContext.get (),
nullptr, caPath.c_str ()) == 0)
2116 if (stat (caFile.c_str (), &st) != 0 || !S_ISREG (st.st_mode) ||
2117 SSL_CTX_load_verify_locations (this->
_tlsContext.get (), caFile.c_str (),
nullptr) == 0)
2136 SSL_CTX_set_verify_depth (this->
_tlsContext.get (), depth);
2140 SSL_CTX_set_verify (this->
_tlsContext.get (), SSL_VERIFY_NONE,
nullptr);
2152 : SSL_CTX_set_cipher_list (this->
_tlsContext.get (), cipher.c_str ())) == 0)
2169 : SSL_CTX_set_ciphersuites (this->
_tlsContext.get (), cipher.c_str ())) == 0)
2195 int result = SSL_do_handshake (this->
_tlsHandle.get ());
2198 switch (SSL_get_error (this->
_tlsHandle.get (), result))
2200 case SSL_ERROR_WANT_READ:
2201 case SSL_ERROR_WANT_WRITE:
2202 case SSL_ERROR_WANT_X509_LOOKUP:
2206 case SSL_ERROR_ZERO_RETURN:
2211 case SSL_ERROR_SYSCALL:
2219 this->
_state = State::Disconnected;
2222 lastError = std::make_error_code (
static_cast <std::errc
> (errno));
2229 std::cout << ERR_reason_error_string (ERR_get_error ()) << std::endl;
2262 if (where & SSL_CB_ALERT)
2264 std::cout <<
"SSL/TLS Alert ";
2265 (where & SSL_CB_READ) ? std::cout <<
"[read] " : std::cout <<
"[write] ";
2266 std::cout << SSL_alert_type_string_long (ret) <<
":";
2267 std::cout << SSL_alert_desc_string_long (ret);
2268 std::cout << std::endl;
2270 else if (where & SSL_CB_LOOP)
2272 std::cout <<
"SSL/TLS State ";
2273 (SSL_in_connect_init (this->
_tlsHandle.get ())) ? std::cout <<
"[connect] " : (SSL_in_accept_init (this->
_tlsHandle.get ())) ? std::cout <<
"[accept] " : std::cout <<
"[undefined] ";
2274 std::cout << SSL_state_string_long (this->
_tlsHandle.get ());
2275 std::cout << std::endl;
2277 else if (where & SSL_CB_HANDSHAKE_START)
2279 std::cout <<
"SSL/TLS Handshake [Start] "<< SSL_state_string_long (this->
_tlsHandle.get ()) << std::endl;
2281 else if (where & SSL_CB_HANDSHAKE_DONE)
2283 std::cout <<
"SSL/TLS Handshake [Done] "<< SSL_state_string_long (this->
_tlsHandle.get ()) << std::endl;
2284 std::cout << SSL_CTX_sess_number (this->
_tlsContext.get ()) <<
" items in the session cache"<< std::endl;
2285 std::cout << SSL_CTX_sess_connect (this->
_tlsContext.get ()) <<
" client connects"<< std::endl;
2286 std::cout << SSL_CTX_sess_connect_good (this->
_tlsContext.get ()) <<
" client connects that finished"<< std::endl;
2287 std::cout << SSL_CTX_sess_connect_renegotiate (this->
_tlsContext.get ()) <<
" client renegotiations requested"<< std::endl;
2288 std::cout << SSL_CTX_sess_accept (this->
_tlsContext.get ()) <<
" server connects"<< std::endl;
2289 std::cout << SSL_CTX_sess_accept_good (this->
_tlsContext.get ()) <<
" server connects that finished"<< std::endl;
2290 std::cout << SSL_CTX_sess_accept_renegotiate (this->
_tlsContext.get ()) <<
" server renegotiations requested"<< std::endl;
2291 std::cout << SSL_CTX_sess_hits (this->
_tlsContext.get ()) <<
" session cache hits"<< std::endl;
2292 std::cout << SSL_CTX_sess_cb_hits (this->
_tlsContext.get ()) <<
" external session cache hits"<< std::endl;
2293 std::cout << SSL_CTX_sess_misses (this->
_tlsContext.get ()) <<
" session cache misses"<< std::endl;
2294 std::cout << SSL_CTX_sess_timeouts (this->
_tlsContext.get ()) <<
" session cache timeouts"<< std::endl;
2295 std::cout <<
"negotiated " << SSL_get_cipher (this->
_tlsHandle.get ()) <<
" cipher suite" << std::endl;
2307 SSL* ssl =
static_cast <SSL*
> (X509_STORE_CTX_get_ex_data (context, SSL_get_ex_data_X509_STORE_CTX_idx ()));
2321 int maxDepth = SSL_get_verify_depth (this->
_tlsHandle.get ());
2322 int dpth = X509_STORE_CTX_get_error_depth (context);
2325 std::cout <<
"verification started at depth="<< dpth << std::endl;
2329 if ((maxDepth >= 0) && (dpth > maxDepth))
2332 X509_STORE_CTX_set_error (context, X509_V_ERR_CERT_CHAIN_TOO_LONG);
2338 std::cout <<
"verification failed at depth=" << dpth <<
" - " << X509_verify_cert_error_string (X509_STORE_CTX_get_error (context)) << std::endl;
2347 std::cout <<
"rejected by CERT at depth=" << dpth << std::endl;
2371 std::cout <<
"certificate accepted at depth=" << dpth << std::endl;
2384 int depth = X509_STORE_CTX_get_error_depth (context);
2385 X509* cert = X509_STORE_CTX_get_current_cert (context);
2388 X509_NAME_oneline (X509_get_subject_name (cert), buf,
sizeof (buf));
2390 std::cout <<
"subject=" << buf << std::endl;
2400 std::cout <<
"no match for hostname in the certificate" << std::endl;
2419 join::StackOfGeneralNamePtr altnames (
reinterpret_cast <STACK_OF (GENERAL_NAME)*
> (X509_get_ext_d2i (certificate, NID_subject_alt_name, 0, 0)));
2422 for (
int i = 0; (i < sk_GENERAL_NAME_num (altnames.get ())) && !match; ++i)
2425 GENERAL_NAME *current_name = sk_GENERAL_NAME_value (altnames.get (), i);
2427 if (current_name->type == GEN_DNS)
2430 const char *host =
reinterpret_cast <const char *
> (ASN1_STRING_get0_data (current_name->d.ia5));
2431 size_t len = size_t (ASN1_STRING_length (current_name->d.ia5));
2432 std::string pattern (host, host + len), serverName (this->
_remote.hostname ());
2435 if (pattern.back () ==
'.')
2437 pattern.pop_back ();
2440 if (serverName.back () ==
'.')
2442 serverName.pop_back ();
2446 if (fnmatch (pattern.c_str (), serverName.c_str (), 0) == 0)
2497 template <
class Protocol>
2498 constexpr bool operator< (
const BasicTlsSocket <Protocol>& a,
const BasicTlsSocket <Protocol>& b)
noexcept
2500 return a.handle () < b.handle ();
2507 template <>
struct is_error_condition_enum <
join::TlsErrc> :
public true_type {};
basic datagram socket class.
Definition socket.hpp:645
virtual ~BasicDatagramSocket()=default
Destroy the instance.
typename BasicSocket< Protocol >::Mode Mode
Definition socket.hpp:648
BasicDatagramSocket(const BasicDatagramSocket &other)=delete
Copy constructor.
BasicDatagramSocket(Mode mode, int ttl=60)
Create instance specifying the mode.
Definition socket.hpp:665
virtual int connect(const Endpoint &endpoint)
make a connection to the given endpoint.
Definition socket.hpp:798
std::unique_ptr< BasicDatagramSocket< Protocol > > Ptr
Definition socket.hpp:647
virtual int bindToDevice(const std::string &device) noexcept
assigns the specified device to the socket.
Definition socket.hpp:764
virtual bool connected() noexcept
check if the socket is connected.
Definition socket.hpp:1062
virtual int setOption(Option option, int value) noexcept override
set the given option to the given value.
Definition socket.hpp:958
Endpoint _remote
remote endpoint.
Definition socket.hpp:1116
virtual int read(char *data, unsigned long maxSize) noexcept override
read data.
Definition socket.hpp:876
int _ttl
packet time to live.
Definition socket.hpp:1119
virtual int write(const char *data, unsigned long maxSize) noexcept override
write data.
Definition socket.hpp:923
virtual void close() noexcept override
close the socket handle.
Definition socket.hpp:864
typename Protocol::Endpoint Endpoint
Definition socket.hpp:651
int ttl() const
returns the Time-To-Live value.
Definition socket.hpp:1109
BasicDatagramSocket(int ttl=60)
Default constructor.
Definition socket.hpp:656
int mtu() const
get socket mtu.
Definition socket.hpp:1071
BasicDatagramSocket & operator=(const BasicDatagramSocket &other)=delete
Copy assignment operator.
virtual int readFrom(char *data, unsigned long maxSize, Endpoint *endpoint=nullptr) noexcept
read data on the socket.
Definition socket.hpp:888
virtual int writeTo(const char *data, unsigned long maxSize, const Endpoint &endpoint) noexcept
write data on the socket.
Definition socket.hpp:935
typename BasicSocket< Protocol >::Option Option
Definition socket.hpp:649
virtual int disconnect()
shutdown the connection.
Definition socket.hpp:835
virtual int open(const Protocol &protocol=Protocol()) noexcept override
open socket using the given protocol.
Definition socket.hpp:723
BasicDatagramSocket(BasicDatagramSocket &&other)
Move constructor.
Definition socket.hpp:688
typename BasicSocket< Protocol >::State State
Definition socket.hpp:650
const Endpoint & remoteEndpoint() const
determine the remote endpoint associated with this socket.
Definition socket.hpp:1053
basic socket class.
Definition socket.hpp:60
bool opened() const noexcept
check if the socket is opened.
Definition socket.hpp:489
BasicSocket & operator=(const BasicSocket &other)=delete
copy assignment operator.
virtual int open(const Protocol &protocol=Protocol()) noexcept
open socket using the given protocol.
Definition socket.hpp:194
static uint16_t checksum(const uint16_t *data, size_t len, uint16_t current=0)
get standard 1s complement checksum.
Definition socket.hpp:546
void setMode(Mode mode) noexcept
set the socket to the non-blocking or blocking mode.
Definition socket.hpp:380
State
socket states.
Definition socket.hpp:102
@ Disconnected
Definition socket.hpp:106
@ Connecting
Definition socket.hpp:103
@ Disconnecting
Definition socket.hpp:105
@ Closed
Definition socket.hpp:107
@ Connected
Definition socket.hpp:104
Protocol _protocol
protocol.
Definition socket.hpp:625
virtual int setOption(Option option, int value) noexcept
set the given option to the given value.
Definition socket.hpp:407
int handle() const noexcept override
get socket native handle.
Definition socket.hpp:534
std::unique_ptr< BasicSocket< Protocol > > Ptr
Definition socket.hpp:62
Mode _mode
socket mode.
Definition socket.hpp:619
virtual void close() noexcept
close the socket.
Definition socket.hpp:223
int family() const noexcept
get socket address family.
Definition socket.hpp:507
Mode
socket modes.
Definition socket.hpp:69
@ Blocking
Definition socket.hpp:70
@ NonBlocking
Definition socket.hpp:71
virtual bool waitReadyRead(int timeout=0) const noexcept
block until new data is available for reading.
Definition socket.hpp:294
virtual ~BasicSocket()
destroy the socket instance.
Definition socket.hpp:181
virtual int bind(const Endpoint &endpoint) noexcept
assigns the specified endpoint to the socket.
Definition socket.hpp:238
Endpoint localEndpoint() const
determine the local endpoint associated with this socket.
Definition socket.hpp:472
BasicSocket()
default constructor.
Definition socket.hpp:113
int type() const noexcept
get the protocol communication semantic.
Definition socket.hpp:516
State _state
socket state.
Definition socket.hpp:616
typename Protocol::Endpoint Endpoint
Definition socket.hpp:63
virtual bool encrypted() const noexcept
check if the socket is secure.
Definition socket.hpp:498
Option
socket options.
Definition socket.hpp:78
@ MulticastTtl
Definition socket.hpp:92
@ SndBuffer
Definition socket.hpp:84
@ Ttl
Definition socket.hpp:90
@ Broadcast
Definition socket.hpp:89
@ RcvError
Definition socket.hpp:94
@ ReusePort
Definition socket.hpp:88
@ MulticastLoop
Definition socket.hpp:91
@ KeepAlive
Definition socket.hpp:80
@ ReuseAddr
Definition socket.hpp:87
@ KeepCount
Definition socket.hpp:83
@ KeepIntvl
Definition socket.hpp:82
@ AuxData
Definition socket.hpp:95
@ PathMtuDiscover
Definition socket.hpp:93
@ NoDelay
Definition socket.hpp:79
@ TimeStamp
Definition socket.hpp:86
@ KeepIdle
Definition socket.hpp:81
@ RcvBuffer
Definition socket.hpp:85
virtual bool waitReadyWrite(int timeout=0) const noexcept
block until at least one byte can be written.
Definition socket.hpp:341
BasicSocket(BasicSocket &&other)
move constructor.
Definition socket.hpp:144
virtual int read(char *data, unsigned long maxSize) noexcept
read data.
Definition socket.hpp:305
virtual int write(const char *data, unsigned long maxSize) noexcept
write data.
Definition socket.hpp:352
BasicSocket(Mode mode)
create socket instance specifying the mode.
Definition socket.hpp:122
int wait(bool wantRead, bool wantWrite, int timeout) const noexcept
wait for the socket handle to become ready.
Definition socket.hpp:579
int protocol() const noexcept
get socket protocol.
Definition socket.hpp:525
int _handle
socket handle.
Definition socket.hpp:622
virtual int canRead() const noexcept
get the number of readable bytes.
Definition socket.hpp:275
BasicSocket(const BasicSocket &other)=delete
copy constructor.
basic stream acceptor class.
Definition protocol.hpp:45
basic stream socket class.
Definition socket.hpp:1139
std::unique_ptr< BasicStreamSocket< Protocol > > Ptr
Definition socket.hpp:1141
virtual ~BasicStreamSocket()=default
destroy the instance.
typename BasicDatagramSocket< Protocol >::Option Option
Definition socket.hpp:1143
typename BasicDatagramSocket< Protocol >::Mode Mode
Definition socket.hpp:1142
typename BasicDatagramSocket< Protocol >::State State
Definition socket.hpp:1144
virtual int setOption(Option option, int value) noexcept override
set the given option to the given value.
Definition socket.hpp:1393
virtual bool connecting() const noexcept
check if the socket is connecting.
Definition socket.hpp:1443
BasicStreamSocket(const BasicStreamSocket &other)=delete
copy constructor.
BasicStreamSocket(BasicStreamSocket &&other)
move constructor.
Definition socket.hpp:1181
virtual bool waitConnected(int timeout=0)
block until connected.
Definition socket.hpp:1208
int readExactly(std::string &data, unsigned long size, int timeout=0)
read data until size is reached or an error occurred.
Definition socket.hpp:1350
int writeExactly(const char *data, unsigned long size, int timeout=0)
write data until size is reached or an error occurred.
Definition socket.hpp:1363
BasicStreamSocket(Mode mode)
create instance specifying the mode.
Definition socket.hpp:1159
typename Protocol::Endpoint Endpoint
Definition socket.hpp:1145
BasicStreamSocket & operator=(const BasicStreamSocket &other)=delete
copy assignment operator.
virtual bool connected() noexcept override
check if the socket is connected.
Definition socket.hpp:1452
virtual bool waitDisconnected(int timeout=0)
wait until the connection as been shut down.
Definition socket.hpp:1275
virtual int disconnect() override
shutdown the connection.
Definition socket.hpp:1233
BasicStreamSocket()
default constructor.
Definition socket.hpp:1150
int readExactly(char *data, unsigned long size, int timeout=0)
read data until size is reached or an error occurred.
Definition socket.hpp:1319
basic TLS acceptor class.
Definition protocol.hpp:46
basic TLS socket class.
Definition socket.hpp:1547
BasicTlsSocket()
default constructor.
Definition socket.hpp:1558
BasicTlsSocket & operator=(const BasicTlsSocket &other)=delete
copy assignment operator.
int setCaFile(const std::string &caFile)
set the location of the trusted CA certificate file.
Definition socket.hpp:2113
std::unique_ptr< BasicTlsSocket< Protocol > > Ptr
Definition socket.hpp:1549
virtual int canRead() const noexcept override
get the number of readable bytes.
Definition socket.hpp:1891
int startEncryption()
start socket encryption (perform TLS handshake).
Definition socket.hpp:1707
bool waitEncrypted(int timeout=0)
wait until TLS handshake is performed or timeout occur (non blocking socket).
Definition socket.hpp:1758
virtual bool encrypted() const noexcept override
check if the socket is secure.
Definition socket.hpp:2050
BasicTlsSocket(Mode mode, join::SslCtxPtr tlsContext)
Create socket instance specifying the socket mode and TLS context.
Definition socket.hpp:1613
join::SslCtxPtr _tlsContext
verify certificate revocation using CRL.
Definition socket.hpp:2479
virtual int read(char *data, unsigned long maxSize) noexcept override
read data on the socket.
Definition socket.hpp:1907
void setVerify(bool verify, int depth=-1)
Enable/Disable the verification of the peer certificate.
Definition socket.hpp:2131
join::SslPtr _tlsHandle
TLS handle.
Definition socket.hpp:2482
int verifyCallback(int preverified, X509_STORE_CTX *context) const
trusted CA certificates verification callback.
Definition socket.hpp:2319
virtual bool waitReadyRead(int timeout=0) const noexcept override
block until new data is available for reading.
Definition socket.hpp:1877
int verifyCert(X509_STORE_CTX *context) const
verify certificate validity.
Definition socket.hpp:2382
void infoCallback(int where, int ret) const
state information callback.
Definition socket.hpp:2260
BasicTlsSocket(Mode mode)
create instance specifying the mode.
Definition socket.hpp:1567
TlsState
TLS state.
Definition socket.hpp:2183
@ Encrypted
Definition socket.hpp:2184
@ NonEncrypted
Definition socket.hpp:2185
TlsState _tlsState
TLS state.
Definition socket.hpp:2485
bool checkHostName(X509 *certificate) const
confirm a match between the hostname contacted and the hostnames listed in the certificate.
Definition socket.hpp:2414
typename BasicStreamSocket< Protocol >::Mode Mode
Definition socket.hpp:1550
virtual int disconnect() override
shutdown the connection.
Definition socket.hpp:1798
int setCertificate(const std::string &cert, const std::string &key="")
set the certificate and the private key.
Definition socket.hpp:2061
virtual bool waitReadyWrite(int timeout=0) const noexcept override
block until until at least one byte can be written on the socket.
Definition socket.hpp:1971
int setCipher(const std::string &cipher)
set the cipher list (TLSv1.2 and below).
Definition socket.hpp:2149
typename Protocol::Endpoint Endpoint
Definition socket.hpp:1553
virtual void close() noexcept override
close the socket handle.
Definition socket.hpp:1865
int setCipher_1_3(const std::string &cipher)
set the cipher list (TLSv1.3).
Definition socket.hpp:2166
virtual ~BasicTlsSocket()=default
destroy the instance.
int setCaPath(const std::string &caPath)
set the location of the trusted CA certificates.
Definition socket.hpp:2095
typename BasicStreamSocket< Protocol >::State State
Definition socket.hpp:1552
BasicTlsSocket(const BasicTlsSocket &other)=delete
copy constructor.
int startHandshake()
Start SSL handshake.
Definition socket.hpp:2192
typename BasicStreamSocket< Protocol >::Option Option
Definition socket.hpp:1551
static void infoWrapper(const SSL *ssl, int where, int ret)
c style callback wrapper for the state information callback.
Definition socket.hpp:2249
virtual int write(const char *data, unsigned long maxSize) noexcept override
write data on the socket.
Definition socket.hpp:1987
BasicTlsSocket(join::SslCtxPtr tlsContext)
create instance specifying TLS context.
Definition socket.hpp:1603
static int verifyWrapper(int preverified, X509_STORE_CTX *context)
c style callback wrapper for the Trusted CA certificates verification callback.
Definition socket.hpp:2305
BasicTlsSocket(BasicTlsSocket &&other)
move constructor.
Definition socket.hpp:1640
int connectEncrypted(const Endpoint &endpoint)
make an encrypted connection to the given endpoint.
Definition socket.hpp:1687
Event handler interface class.
Definition reactor.hpp:44
TLS error category.
Definition socket.hpp:1506
virtual std::string message(int code) const
translate digest error code to human readable error string.
Definition socket.cpp:44
virtual const char * name() const noexcept
get digest error category name.
Definition socket.cpp:35
const std::string key(65, 'a')
key.
Definition acceptor.hpp:32
bool operator<(const BasicUnixEndpoint< Protocol > &a, const BasicUnixEndpoint< Protocol > &b) noexcept
compare if endpoint is lower.
Definition endpoint.hpp:207
std::error_code make_error_code(join::Errc code)
Create an std::error_code object.
Definition error.cpp:154
std::unique_ptr< SSL, SslDelete > SslPtr
Definition openssl.hpp:225
const std::string defaultCipher_1_3
Definition openssl.cpp:39
std::unique_ptr< SSL_CTX, SslCtxDelete > SslCtxPtr
Definition openssl.hpp:240
TlsErrc
TLS error codes.
Definition socket.hpp:1497
const std::error_category & getTlsCategory()
get error category.
Definition socket.cpp:61
std::unique_ptr< STACK_OF(GENERAL_NAME), StackOfGeneralNameDelete > StackOfGeneralNamePtr
Definition openssl.hpp:210
const std::string defaultCipher
Definition openssl.cpp:36
std::error_condition make_error_condition(join::Errc code)
Create an std::error_condition object.
Definition error.cpp:163