introduce strong type for socket type index

This commit is contained in:
arvidn
2019-11-03 17:21:53 +01:00
committed by Arvid Norberg
parent 7053743d7a
commit 614d10e34a
15 changed files with 217 additions and 180 deletions

View File

@ -127,6 +127,7 @@ set(libtorrent_include_files
sliding_average
socket
socket_io
socket_type
socks5_stream
span
ssl_stream

View File

@ -527,6 +527,7 @@ HEADERS = \
sliding_average.hpp \
socket.hpp \
socket_io.hpp \
socket_type.hpp \
socks5_stream.hpp \
span.hpp \
ssl_stream.hpp \

View File

@ -606,10 +606,16 @@ void bind_alert()
enum_<socket_type_t>("socket_type_t")
.value("tcp", socket_type_t::tcp)
.value("tcp_ssl", socket_type_t::tcp_ssl)
.value("udp", socket_type_t::udp)
.value("i2p", socket_type_t::i2p)
.value("socks5", socket_type_t::socks5)
.value("http", socket_type_t::http)
.value("utp", socket_type_t::utp)
#if TORRENT_ABI_VERSION <= 2
.value("udp", socket_type_t::udp)
#endif
.value("i2p", socket_type_t::i2p)
.value("tcp_ssl", socket_type_t::tcp_ssl)
.value("socks5_ssl", socket_type_t::socks5_ssl)
.value("http_ssl", socket_type_t::http_ssl)
.value("utp_ssl", socket_type_t::utp_ssl)
;

View File

@ -122,6 +122,24 @@ on_unknown_torrent() plugin API
Since hybrid torrents have two info-hashes, the on_unknown_torrent() function
on the plugin class now takes an info_hash_t instead of a sha1_hash.
socket_type_t
-------------
There is a new ``enum class`` called ``socket_type_t`` used to identify different
kinds of sockets. In previous versions of libtorrent this was exposed as plain
``int`` with subtly different sets of meanings.
Previously there was an enum value ``udp``, which has been deprecated in favour of ``utp``.
The socket type is exposed in the following alerts, which now use the ``socket_type_t``
enum instead of ``int``:
* ``peer_connect_alert``
* ``peer_disconnected_alert``
* ``incoming_connection_alert``
* ``listen_failed_alert``
* ``listen_succeeded_alert``
DHT settings
============

View File

@ -62,6 +62,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/aux_/noexcept_movable.hpp"
#include "libtorrent/portmap.hpp" // for portmap_transport
#include "libtorrent/tracker_manager.hpp" // for event_t
#include "libtorrent/socket_type.hpp"
#include "libtorrent/aux_/disable_warnings_push.hpp"
#include <boost/shared_array.hpp>
@ -770,14 +771,14 @@ TORRENT_VERSION_NAMESPACE_2
{
// internal
TORRENT_UNEXPORT peer_connect_alert(aux::stack_allocator& alloc, torrent_handle h
, tcp::endpoint const& ep, peer_id const& peer_id, int type);
, tcp::endpoint const& ep, peer_id const& peer_id, socket_type_t type);
TORRENT_DEFINE_ALERT(peer_connect_alert, 23)
static constexpr alert_category_t static_category = alert::connect_notification;
std::string message() const override;
int const socket_type;
socket_type_t const socket_type;
};
// This alert is generated when a peer is disconnected for any reason (other than the ones
@ -787,7 +788,7 @@ TORRENT_VERSION_NAMESPACE_2
// internal
TORRENT_UNEXPORT peer_disconnected_alert(aux::stack_allocator& alloc
, torrent_handle const& h, tcp::endpoint const& ep
, peer_id const& peer_id, operation_t op, int type, error_code const& e
, peer_id const& peer_id, operation_t op, socket_type_t type, error_code const& e
, close_reason_t r);
TORRENT_DEFINE_ALERT(peer_disconnected_alert, 24)
@ -796,7 +797,7 @@ TORRENT_VERSION_NAMESPACE_2
std::string message() const override;
// the kind of socket this peer was connected over
int const socket_type;
socket_type_t const socket_type;
// the operation or level where the error occurred. Specified as an
// value from the operation_t enum. Defined in operations.hpp.
@ -1392,11 +1393,6 @@ TORRENT_VERSION_NAMESPACE_2
aux::noexcept_movable<address> external_address;
};
enum class socket_type_t : std::uint8_t
{
tcp, tcp_ssl, udp, i2p, socks5, utp_ssl
};
// This alert is generated when none of the ports, given in the port range, to
// session can be opened for listening. The ``listen_interface`` member is the
// interface that failed, ``error`` is the error code describing the failure.
@ -1968,8 +1964,8 @@ TORRENT_VERSION_NAMESPACE_2
struct TORRENT_EXPORT incoming_connection_alert final : alert
{
// internal
TORRENT_UNEXPORT incoming_connection_alert(aux::stack_allocator& alloc, int t
, tcp::endpoint const& i);
TORRENT_UNEXPORT incoming_connection_alert(aux::stack_allocator& alloc
, socket_type_t t, tcp::endpoint const& i);
TORRENT_DEFINE_ALERT(incoming_connection_alert, 66)
@ -1977,20 +1973,7 @@ TORRENT_VERSION_NAMESPACE_2
std::string message() const override;
// tells you what kind of socket the connection was accepted
// as:
//
// 0. none (no socket instantiated)
// 1. TCP
// 2. Socks5
// 3. HTTP
// 4. uTP
// 5. i2p
// 6. SSL/TCP
// 7. SSL/Socks5
// 8. HTTPS (SSL/HTTP)
// 9. SSL/uTP
//
int const socket_type;
socket_type_t socket_type;
// is the IP address and port the connection came from.
aux::noexcept_movable<tcp::endpoint> endpoint;

View File

@ -499,7 +499,7 @@ namespace aux {
// ==== peer class operations ====
// implements session_interface
void set_peer_classes(peer_class_set* s, address const& a, int st) override;
void set_peer_classes(peer_class_set* s, address const& a, socket_type_t st) override;
peer_class_pool const& peer_classes() const override { return m_classes; }
peer_class_pool& peer_classes() override { return m_classes; }
bool ignore_unchoke_slots_set(peer_class_set const& set) const override;

View File

@ -236,7 +236,7 @@ namespace aux {
, std::weak_ptr<request_callback> c) = 0;
// peer-classes
virtual void set_peer_classes(peer_class_set* s, address const& a, int st) = 0;
virtual void set_peer_classes(peer_class_set* s, address const& a, socket_type_t st) = 0;
virtual peer_class_pool const& peer_classes() const = 0;
virtual peer_class_pool& peer_classes() = 0;
virtual bool ignore_unchoke_slots_set(peer_class_set const& set) const = 0;

View File

@ -40,6 +40,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/i2p_stream.hpp"
#include "libtorrent/aux_/utp_stream.hpp"
#include "libtorrent/aux_/polymorphic_socket.hpp"
#include "libtorrent/socket_type.hpp"
#ifdef TORRENT_USE_OPENSSL
#include "libtorrent/ssl_stream.hpp"
@ -50,50 +51,6 @@ POSSIBILITY OF SUCH DAMAGE.
namespace libtorrent {
namespace aux {
template <class S>
struct socket_type_int_impl
{ static constexpr int value = 0; };
template <>
struct socket_type_int_impl<tcp::socket>
{ static constexpr int value = 1; };
template <>
struct socket_type_int_impl<socks5_stream>
{ static constexpr int value = 2; };
template <>
struct socket_type_int_impl<http_stream>
{ static constexpr int value = 3; };
template <>
struct socket_type_int_impl<utp_stream>
{ static constexpr int value = 4; };
#if TORRENT_USE_I2P
template <>
struct socket_type_int_impl<i2p_stream>
{ static constexpr int value = 5; };
#endif
#ifdef TORRENT_USE_OPENSSL
template <>
struct socket_type_int_impl<ssl_stream<tcp::socket>>
{ static constexpr int value = 6; };
template <>
struct socket_type_int_impl<ssl_stream<socks5_stream>>
{ static constexpr int value = 7; };
template <>
struct socket_type_int_impl<ssl_stream<http_stream>>
{ static constexpr int value = 8; };
template <>
struct socket_type_int_impl<ssl_stream<utp_stream>>
{ static constexpr int value = 9; };
#endif
using socket_type = polymorphic_socket<
tcp::socket
, socks5_stream
@ -116,8 +73,7 @@ namespace aux {
// returns true if this is a uTP socket
bool is_utp(socket_type const& s);
// TODO: this should return a special enum class type?
int socket_type_idx(socket_type const& s);
socket_type_t socket_type_idx(socket_type const& s);
char const* socket_type_name(socket_type const& s);

View File

@ -0,0 +1,64 @@
/*
Copyright (c) 2019, Arvid Norberg
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TORRENT_SOCKET_TYPE_HPP
#define TORRENT_SOCKET_TYPE_HPP
#include "libtorrent/config.hpp"
#include <cstdint>
namespace libtorrent {
// A type describing kinds of sockets involved in various operations or events.
enum class socket_type_t : std::uint8_t {
tcp,
socks5,
http,
utp,
i2p,
tcp_ssl,
socks5_ssl,
http_ssl,
utp_ssl,
#if TORRENT_ABI_VERSION <= 2
udp TORRENT_DEPRECATED_ENUM = utp,
#endif
};
// return a short human readable name for types of socket
char const* socket_type_name(socket_type_t);
}
#endif

View File

@ -119,7 +119,7 @@ TORRENT_TEST(socks5_tcp_announce)
[&alert_port](lt::session&, lt::alert const* alert) {
if (auto* a = lt::alert_cast<lt::listen_succeeded_alert>(alert))
{
if (a->socket_type == socket_type_t::udp)
if (a->socket_type == socket_type_t::utp)
{
alert_port = a->port;
}

View File

@ -54,6 +54,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/piece_block.hpp"
#include "libtorrent/hex.hpp" // to_hex
#include "libtorrent/session_stats.hpp"
#include "libtorrent/socket_type.hpp"
#if TORRENT_ABI_VERSION == 1
#include "libtorrent/write_resume_data.hpp"
@ -827,40 +828,28 @@ namespace libtorrent {
namespace {
int sock_type_idx(socket_type_t type)
{
int idx =
static_cast<std::underlying_type<socket_type_t>::type>(type);
TORRENT_ASSERT(0 <= idx && idx < 6);
return idx;
}
char const* sock_type_str(socket_type_t type)
{
static char const* const type_str[] =
{ "TCP", "TCP/SSL", "UDP", "I2P", "Socks5", "uTP/SSL" };
return type_str[sock_type_idx(type)];
}
char const* const nat_type_str[] = {"NAT-PMP", "UPnP"};
char const* const protocol_str[] = {"none", "TCP", "UDP"};
char const* const socket_type_str[] = {
"null",
"TCP",
"Socks5/TCP",
"HTTP",
"uTP",
"i2p",
"SSL/TCP",
"SSL/Socks5",
"HTTPS",
"SSL/uTP"
};
#if TORRENT_ABI_VERSION == 1
int sock_type_idx(socket_type_t type)
{
// these numbers are the deprecated enum values in
// listen_succeeded_alert and listen_failed_alert
static aux::array<int, 9, socket_type_t> const mapping{{
0, // tcp
4, // socks5,
0, // http,
2, // utp,
3, // i2p,
1, // tcp_ssl
4, // socks5_ssl,
1, // http_ssl,
5 // utp_ssl,
}};
return mapping[type];
}
int to_op_t(operation_t op)
{
@ -1015,7 +1004,7 @@ namespace {
, print_endpoint(address, port).c_str()
, listen_interface()
, operation_name(op)
, sock_type_str(socket_type)
, socket_type_name(socket_type)
, convert_from_native(error.message()).c_str());
return ret;
}
@ -1103,7 +1092,7 @@ namespace {
{
char ret[200];
std::snprintf(ret, sizeof(ret), "successfully listening on [%s] %s"
, sock_type_str(socket_type), print_endpoint(address, port).c_str());
, socket_type_name(socket_type), print_endpoint(address, port).c_str());
return ret;
}
@ -1451,8 +1440,8 @@ namespace {
return torrent_alert::message() + " needs SSL certificate";
}
incoming_connection_alert::incoming_connection_alert(aux::stack_allocator&, int t
, tcp::endpoint const& i)
incoming_connection_alert::incoming_connection_alert(aux::stack_allocator&
, socket_type_t t, tcp::endpoint const& i)
: socket_type(t)
, endpoint(i)
#if TORRENT_ABI_VERSION == 1
@ -1464,12 +1453,12 @@ namespace {
{
char msg[600];
std::snprintf(msg, sizeof(msg), "incoming connection from %s (%s)"
, print_endpoint(endpoint).c_str(), socket_type_str[socket_type]);
, print_endpoint(endpoint).c_str(), socket_type_name(socket_type));
return msg;
}
peer_connect_alert::peer_connect_alert(aux::stack_allocator& alloc, torrent_handle h
, tcp::endpoint const& ep, peer_id const& peer_id, int type)
, tcp::endpoint const& ep, peer_id const& peer_id, socket_type_t const type)
: peer_alert(alloc, h, ep, peer_id)
, socket_type(type)
{}
@ -1478,7 +1467,7 @@ namespace {
{
char msg[600];
std::snprintf(msg, sizeof(msg), "%s connecting to peer (%s)"
, peer_alert::message().c_str(), socket_type_str[socket_type]);
, peer_alert::message().c_str(), socket_type_name(socket_type));
return msg;
}
@ -1624,7 +1613,7 @@ namespace {
peer_disconnected_alert::peer_disconnected_alert(aux::stack_allocator& alloc
, torrent_handle const& h, tcp::endpoint const& ep
, peer_id const& peer_id, operation_t op_, int type, error_code const& e
, peer_id const& peer_id, operation_t op_, socket_type_t const type, error_code const& e
, close_reason_t r)
: peer_alert(alloc, h, ep, peer_id)
, socket_type(type)
@ -1642,7 +1631,7 @@ namespace {
char buf[600];
std::snprintf(buf, sizeof(buf), "%s disconnecting (%s) [%s] [%s]: %s (reason: %d)"
, peer_alert::message().c_str()
, socket_type_str[socket_type]
, socket_type_name(socket_type)
, operation_name(op), error.category().name()
, convert_from_native(error.message()).c_str()
, int(reason));

View File

@ -168,7 +168,8 @@ namespace libtorrent {
, m_exceeded_limit(false)
, m_slow_start(true)
{
m_counters.inc_stats_counter(counters::num_tcp_peers + socket_type_idx(*m_socket) - 1);
m_counters.inc_stats_counter(counters::num_tcp_peers
+ static_cast<std::uint8_t>(socket_type_idx(*m_socket)));
std::shared_ptr<torrent> t = m_torrent.lock();
if (m_connected)
@ -841,7 +842,8 @@ namespace libtorrent {
peer_connection::~peer_connection()
{
m_counters.inc_stats_counter(counters::num_tcp_peers + socket_type_idx(*m_socket) - 1, -1);
m_counters.inc_stats_counter(counters::num_tcp_peers
+ static_cast<std::uint8_t>(socket_type_idx(*m_socket)), -1);
// INVARIANT_CHECK;
TORRENT_ASSERT(!m_in_constructor);

View File

@ -103,6 +103,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/aux_/set_socket_buffer.hpp"
#include "libtorrent/aux_/generate_peer_id.hpp"
#include "libtorrent/aux_/ffs.hpp"
#include "libtorrent/aux_/array.hpp"
#ifndef TORRENT_DISABLE_LOGGING
@ -1205,19 +1206,23 @@ void apply_deprecated_dht_settings(settings_pack& sett, bdecode_node const& s)
return m_peer_class_type_filter;
}
void session_impl::set_peer_classes(peer_class_set* s, address const& a, int const st)
void session_impl::set_peer_classes(peer_class_set* s, address const& a, socket_type_t const st)
{
std::uint32_t peer_class_mask = m_peer_class_filter.access(a);
using sock_t = peer_class_type_filter::socket_type_t;
// assign peer class based on socket type
static const sock_t mapping[] = {
sock_t::tcp_socket, sock_t::tcp_socket
, sock_t::tcp_socket, sock_t::tcp_socket
, sock_t::utp_socket, sock_t::i2p_socket
, sock_t::ssl_tcp_socket, sock_t::ssl_tcp_socket
, sock_t::ssl_tcp_socket, sock_t::ssl_utp_socket
};
static aux::array<sock_t, 9, socket_type_t> const mapping{{
sock_t::tcp_socket
, sock_t::tcp_socket
, sock_t::tcp_socket
, sock_t::utp_socket
, sock_t::i2p_socket
, sock_t::ssl_tcp_socket
, sock_t::ssl_tcp_socket
, sock_t::ssl_tcp_socket
, sock_t::ssl_utp_socket
}};
sock_t const socket_type = mapping[st];
// filter peer classes based on type
peer_class_mask = m_peer_class_type_filter.apply(socket_type, peer_class_mask);
@ -1631,7 +1636,7 @@ void apply_deprecated_dht_settings(settings_pack& sett, bdecode_node const& s)
socket_type_t const udp_sock_type
= (lep.ssl == transport::ssl)
? socket_type_t::utp_ssl
: socket_type_t::udp;
: socket_type_t::utp;
udp::endpoint udp_bind_ep(bind_ep.address(), bind_ep.port());
ret->udp_sock = std::make_shared<session_udp_socket>(m_io_context);
@ -2022,7 +2027,7 @@ void apply_deprecated_dht_settings(settings_pack& sett, bdecode_node const& s)
socket_type_t const socket_type
= l->ssl == transport::ssl
? socket_type_t::utp_ssl
: socket_type_t::udp;
: socket_type_t::utp;
m_alerts.emplace_alert<listen_succeeded_alert>(
udp_ep, socket_type);

View File

@ -35,6 +35,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/config.hpp"
#include "libtorrent/aux_/socket_type.hpp"
#include "libtorrent/aux_/openssl.hpp"
#include "libtorrent/aux_/array.hpp"
#ifdef TORRENT_USE_OPENSSL
#include <boost/asio/ssl/context.hpp>
@ -45,6 +46,31 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/debug.hpp"
namespace libtorrent {
char const* socket_type_name(socket_type_t const s)
{
static aux::array<char const*, 9, socket_type_t> const names{{
"TCP",
"Socks5",
"HTTP",
"uTP",
#if TORRENT_USE_I2P
"I2P",
#else
"",
#endif
#ifdef TORRENT_USE_OPENSSL
"SSL/TCP",
"SSL/Socks5",
"SSL/HTTP",
"SSL/uTP"
#else
"","","",""
#endif
}};
return names[s];
}
namespace aux {
struct is_ssl_visitor {
@ -78,39 +104,29 @@ namespace aux {
#endif
struct idx_visitor {
template <typename T>
int operator()(T const&) const { return socket_type_int_impl<T>::value; }
socket_type_t operator()(tcp::socket const&) { return socket_type_t::tcp; }
socket_type_t operator()(socks5_stream const&) { return socket_type_t::socks5; }
socket_type_t operator()(http_stream const&) { return socket_type_t::http; }
socket_type_t operator()(utp_stream const&) { return socket_type_t::utp; }
#if TORRENT_USE_I2P
socket_type_t operator()(i2p_stream const&) { return socket_type_t::i2p; }
#endif
#ifdef TORRENT_USE_OPENSSL
socket_type_t operator()(ssl_stream<tcp::socket> const&) { return socket_type_t::tcp_ssl; }
socket_type_t operator()(ssl_stream<socks5_stream> const&) { return socket_type_t::socks5_ssl; }
socket_type_t operator()(ssl_stream<http_stream> const&) { return socket_type_t::http_ssl; }
socket_type_t operator()(ssl_stream<utp_stream> const&) { return socket_type_t::utp_ssl; }
#endif
};
int socket_type_idx(socket_type const& s)
socket_type_t socket_type_idx(socket_type const& s)
{
return boost::apply_visitor(idx_visitor{}, s);
}
char const* socket_type_name(socket_type const& s)
{
static char const* const names[] =
{
"uninitialized",
"TCP",
"Socks5",
"HTTP",
"uTP",
#if TORRENT_USE_I2P
"I2P",
#else
"",
#endif
#ifdef TORRENT_USE_OPENSSL
"SSL/TCP",
"SSL/Socks5",
"SSL/HTTP",
"SSL/uTP"
#else
"","","",""
#endif
};
return names[socket_type_idx(s)];
return socket_type_name(socket_type_idx(s));
}
struct set_close_reason_visitor {

View File

@ -6757,6 +6757,26 @@ bool is_downloading_state(int const st)
}
#if defined TORRENT_USE_OPENSSL
struct hostname_visitor
{
explicit hostname_visitor(std::string const& h) : hostname_(h) {}
template <typename T>
void operator()(T&) {}
template <typename T>
void operator()(ssl_stream<T>& s) { s.set_host_name(hostname_); }
std::string const& hostname_;
};
struct ssl_native_handle_visitor
{
template <typename T>
SSL* operator()(T&) { return nullptr; }
template <typename T>
SSL* operator()(ssl_stream<T>& s) { return s.native_handle(); }
};
#endif
bool torrent::connect_to_peer(torrent_peer* peerinfo, bool const ignore_limit)
{
TORRENT_ASSERT(is_single_thread());
@ -6870,21 +6890,11 @@ bool is_downloading_state(int const st)
if (is_ssl_torrent())
{
// for ssl sockets, set the hostname
std::string host_name = aux::to_hex(m_torrent_file->info_hash().get(peerinfo->protocol()));
std::string const host_name = aux::to_hex(
m_torrent_file->info_hash().get(peerinfo->protocol()));
#define CASE(t) case aux::socket_type_int_impl<ssl_stream<t>>::value: \
boost::get<ssl_stream<t>>(*s).set_host_name(host_name); break;
switch (socket_type_idx(*s))
{
CASE(tcp::socket)
CASE(socks5_stream)
CASE(http_stream)
CASE(aux::utp_stream)
default: break;
}
boost::apply_visitor(hostname_visitor{host_name}, *s);
}
#undef CASE
#endif
}
@ -7110,22 +7120,8 @@ bool is_downloading_state(int const st)
// if this is an SSL torrent, don't allow non SSL peers on it
std::shared_ptr<aux::socket_type> s = p->get_socket();
//
#define SSL(t) aux::socket_type_int_impl<ssl_stream<t>>::value: \
ssl_conn = boost::get<ssl_stream<t>>(*s).native_handle(); \
break;
SSL* ssl_conn = nullptr;
switch (socket_type_idx(*s))
{
case SSL(tcp::socket)
case SSL(socks5_stream)
case SSL(http_stream)
case SSL(aux::utp_stream)
}
#undef SSL
SSL* const ssl_conn = boost::apply_visitor(ssl_native_handle_visitor{}, *s);
if (ssl_conn == nullptr)
{