add local endpoint selection for tls client connections
This commit is contained in:
parent
ef41583614
commit
90071f8318
|
@ -78,6 +78,16 @@ session::session(boost::asio::io_service &io_service,
|
||||||
impl_->start_resolve(host, service);
|
impl_->start_resolve(host, service);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
session::session(boost::asio::io_service &io_service,
|
||||||
|
boost::asio::ssl::context &tls_ctx,
|
||||||
|
const boost::asio::ip::tcp::endpoint &local_endpoint,
|
||||||
|
const std::string &host,
|
||||||
|
const std::string &service)
|
||||||
|
: impl_(std::make_shared<session_tls_impl>(
|
||||||
|
io_service, tls_ctx, local_endpoint, host, service, boost::posix_time::seconds(60))) {
|
||||||
|
impl_->start_resolve(host, service);
|
||||||
|
}
|
||||||
|
|
||||||
session::session(boost::asio::io_service &io_service,
|
session::session(boost::asio::io_service &io_service,
|
||||||
boost::asio::ssl::context &tls_ctx, const std::string &host,
|
boost::asio::ssl::context &tls_ctx, const std::string &host,
|
||||||
const std::string &service,
|
const std::string &service,
|
||||||
|
@ -87,6 +97,17 @@ session::session(boost::asio::io_service &io_service,
|
||||||
impl_->start_resolve(host, service);
|
impl_->start_resolve(host, service);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
session::session(boost::asio::io_service &io_service,
|
||||||
|
boost::asio::ssl::context &tls_ctx,
|
||||||
|
const boost::asio::ip::tcp::endpoint &local_endpoint,
|
||||||
|
const std::string &host,
|
||||||
|
const std::string &service,
|
||||||
|
const boost::posix_time::time_duration &connect_timeout)
|
||||||
|
: impl_(std::make_shared<session_tls_impl>(io_service, tls_ctx, local_endpoint, host,
|
||||||
|
service, connect_timeout)) {
|
||||||
|
impl_->start_resolve(host, service);
|
||||||
|
}
|
||||||
|
|
||||||
session::~session() {}
|
session::~session() {}
|
||||||
|
|
||||||
session::session(session &&other) noexcept : impl_(std::move(other.impl_)) {}
|
session::session(session &&other) noexcept : impl_(std::move(other.impl_)) {}
|
||||||
|
|
|
@ -33,7 +33,7 @@ session_tls_impl::session_tls_impl(
|
||||||
boost::asio::io_service &io_service, boost::asio::ssl::context &tls_ctx,
|
boost::asio::io_service &io_service, boost::asio::ssl::context &tls_ctx,
|
||||||
const std::string &host, const std::string &service,
|
const std::string &host, const std::string &service,
|
||||||
const boost::posix_time::time_duration &connect_timeout)
|
const boost::posix_time::time_duration &connect_timeout)
|
||||||
: session_impl(io_service, connect_timeout), socket_(io_service, tls_ctx) {
|
: session_impl(io_service, connect_timeout), tcp_socket_(io_service), socket_(tcp_socket_, tls_ctx) {
|
||||||
// this callback setting is no effect is
|
// this callback setting is no effect is
|
||||||
// ssl::context::set_verify_mode(boost::asio::ssl::verify_peer) is
|
// ssl::context::set_verify_mode(boost::asio::ssl::verify_peer) is
|
||||||
// not used, which is what we want.
|
// not used, which is what we want.
|
||||||
|
@ -44,6 +44,27 @@ session_tls_impl::session_tls_impl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
session_tls_impl::session_tls_impl(
|
||||||
|
boost::asio::io_service &io_service, boost::asio::ssl::context &tls_ctx,
|
||||||
|
const boost::asio::ip::tcp::endpoint &local_endpoint,
|
||||||
|
const std::string &host, const std::string &service,
|
||||||
|
const boost::posix_time::time_duration &connect_timeout)
|
||||||
|
: session_impl(io_service, connect_timeout), tcp_socket_(io_service), socket_(tcp_socket_, tls_ctx) {
|
||||||
|
// this callback setting is no effect is
|
||||||
|
// ssl::context::set_verify_mode(boost::asio::ssl::verify_peer) is
|
||||||
|
// not used, which is what we want.
|
||||||
|
tcp_socket_.open(local_endpoint.protocol());
|
||||||
|
boost::asio::socket_base::reuse_address option(true);
|
||||||
|
tcp_socket_.set_option(option);
|
||||||
|
tcp_socket_.bind(local_endpoint);
|
||||||
|
|
||||||
|
socket_.set_verify_callback(boost::asio::ssl::rfc2818_verification(host));
|
||||||
|
auto ssl = socket_.native_handle();
|
||||||
|
if (!util::numeric_host(host.c_str())) {
|
||||||
|
SSL_set_tlsext_host_name(ssl, host.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
session_tls_impl::~session_tls_impl() {}
|
session_tls_impl::~session_tls_impl() {}
|
||||||
|
|
||||||
void session_tls_impl::start_connect(tcp::resolver::iterator endpoint_it) {
|
void session_tls_impl::start_connect(tcp::resolver::iterator endpoint_it) {
|
||||||
|
|
|
@ -35,7 +35,7 @@ namespace client {
|
||||||
|
|
||||||
using boost::asio::ip::tcp;
|
using boost::asio::ip::tcp;
|
||||||
|
|
||||||
using ssl_socket = boost::asio::ssl::stream<tcp::socket>;
|
using ssl_socket = boost::asio::ssl::stream<tcp::socket&>;
|
||||||
|
|
||||||
class session_tls_impl : public session_impl {
|
class session_tls_impl : public session_impl {
|
||||||
public:
|
public:
|
||||||
|
@ -43,6 +43,12 @@ public:
|
||||||
boost::asio::ssl::context &tls_ctx, const std::string &host,
|
boost::asio::ssl::context &tls_ctx, const std::string &host,
|
||||||
const std::string &service,
|
const std::string &service,
|
||||||
const boost::posix_time::time_duration &connect_timeout);
|
const boost::posix_time::time_duration &connect_timeout);
|
||||||
|
session_tls_impl(boost::asio::io_service &io_service,
|
||||||
|
boost::asio::ssl::context &tls_ctx,
|
||||||
|
const boost::asio::ip::tcp::endpoint & local_endpoint,
|
||||||
|
const std::string &host,
|
||||||
|
const std::string &service,
|
||||||
|
const boost::posix_time::time_duration &connect_timeout);
|
||||||
virtual ~session_tls_impl();
|
virtual ~session_tls_impl();
|
||||||
|
|
||||||
virtual void start_connect(tcp::resolver::iterator endpoint_it);
|
virtual void start_connect(tcp::resolver::iterator endpoint_it);
|
||||||
|
@ -56,6 +62,7 @@ public:
|
||||||
virtual void shutdown_socket();
|
virtual void shutdown_socket();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
tcp::socket tcp_socket_;
|
||||||
ssl_socket socket_;
|
ssl_socket socket_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -193,5 +193,27 @@ bool tls_h2_negotiated(ssl_socket &socket) {
|
||||||
return util::check_h2_is_selected(StringRef{next_proto, next_proto_len});
|
return util::check_h2_is_selected(StringRef{next_proto, next_proto_len});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool tls_h2_negotiated(ssl_tcp_socket &socket) {
|
||||||
|
auto ssl = socket.native_handle();
|
||||||
|
|
||||||
|
const unsigned char *next_proto = nullptr;
|
||||||
|
unsigned int next_proto_len = 0;
|
||||||
|
|
||||||
|
#ifndef OPENSSL_NO_NEXTPROTONEG
|
||||||
|
SSL_get0_next_proto_negotiated(ssl, &next_proto, &next_proto_len);
|
||||||
|
#endif // !OPENSSL_NO_NEXTPROTONEG
|
||||||
|
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||||
|
if (next_proto == nullptr) {
|
||||||
|
SSL_get0_alpn_selected(ssl, &next_proto, &next_proto_len);
|
||||||
|
}
|
||||||
|
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||||
|
|
||||||
|
if (next_proto == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return util::check_h2_is_selected(StringRef{next_proto, next_proto_len});
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace asio_http2
|
} // namespace asio_http2
|
||||||
} // namespace nghttp2
|
} // namespace nghttp2
|
||||||
|
|
|
@ -62,9 +62,11 @@ void split_path(uri_ref &dst, InputIt first, InputIt last) {
|
||||||
|
|
||||||
using boost::asio::ip::tcp;
|
using boost::asio::ip::tcp;
|
||||||
|
|
||||||
using ssl_socket = boost::asio::ssl::stream<tcp::socket>;
|
using ssl_socket = boost::asio::ssl::stream<tcp::socket&>;
|
||||||
|
using ssl_tcp_socket = boost::asio::ssl::stream<tcp::socket>;
|
||||||
|
|
||||||
bool tls_h2_negotiated(ssl_socket &socket);
|
bool tls_h2_negotiated(ssl_socket &socket);
|
||||||
|
bool tls_h2_negotiated(ssl_tcp_socket &socket);
|
||||||
|
|
||||||
} // namespace asio_http2
|
} // namespace asio_http2
|
||||||
|
|
||||||
|
|
|
@ -175,6 +175,13 @@ public:
|
||||||
boost::asio::ssl::context &tls_context, const std::string &host,
|
boost::asio::ssl::context &tls_context, const std::string &host,
|
||||||
const std::string &service);
|
const std::string &service);
|
||||||
|
|
||||||
|
// save as previous with pegged local endpoint
|
||||||
|
session(boost::asio::io_service &io_service,
|
||||||
|
boost::asio::ssl::context &tls_context,
|
||||||
|
const boost::asio::ip::tcp::endpoint &local_endpoint,
|
||||||
|
const std::string &host,
|
||||||
|
const std::string &service);
|
||||||
|
|
||||||
// Starts HTTP/2 session by connecting to |host| and |service|
|
// Starts HTTP/2 session by connecting to |host| and |service|
|
||||||
// (e.g., "443") using encrypted SSL/TLS connection with given
|
// (e.g., "443") using encrypted SSL/TLS connection with given
|
||||||
// connect timeout.
|
// connect timeout.
|
||||||
|
@ -183,6 +190,14 @@ public:
|
||||||
const std::string &service,
|
const std::string &service,
|
||||||
const boost::posix_time::time_duration &connect_timeout);
|
const boost::posix_time::time_duration &connect_timeout);
|
||||||
|
|
||||||
|
// same as previous with pegged local endpoint
|
||||||
|
session(boost::asio::io_service &io_service,
|
||||||
|
boost::asio::ssl::context &tls_context,
|
||||||
|
const boost::asio::ip::tcp::endpoint &local_endpoint,
|
||||||
|
const std::string &host,
|
||||||
|
const std::string &service,
|
||||||
|
const boost::posix_time::time_duration &connect_timeout);
|
||||||
|
|
||||||
~session();
|
~session();
|
||||||
|
|
||||||
session(session &&other) noexcept;
|
session(session &&other) noexcept;
|
||||||
|
|
Loading…
Reference in New Issue