support SSL over uTP (unit test is still failing with same errors as previously, this has not been fixed yet)

This commit is contained in:
Arvid Norberg 2014-10-06 03:03:01 +00:00
parent 8168c8520a
commit a655047cb0
16 changed files with 240 additions and 67 deletions

View File

@ -1,3 +1,4 @@
* support SSL over uTP connections
* support web seeds that resolve to multiple IPs * support web seeds that resolve to multiple IPs
* added auto-sequential feature. download well-seeded torrents in-order * added auto-sequential feature. download well-seeded torrents in-order
* removed built-in GeoIP support (this functionality is orthogonal to libtorrent) * removed built-in GeoIP support (this functionality is orthogonal to libtorrent)

View File

@ -1325,7 +1325,7 @@ namespace libtorrent
// listen on it. // listen on it.
struct TORRENT_EXPORT listen_failed_alert: alert struct TORRENT_EXPORT listen_failed_alert: alert
{ {
enum socket_type_t { tcp, tcp_ssl, udp, i2p, socks5 }; enum socket_type_t { tcp, tcp_ssl, udp, i2p, socks5, utp_ssl };
// internal // internal
listen_failed_alert( listen_failed_alert(
@ -1368,7 +1368,7 @@ namespace libtorrent
// was opened for listening. // was opened for listening.
struct TORRENT_EXPORT listen_succeeded_alert: alert struct TORRENT_EXPORT listen_succeeded_alert: alert
{ {
enum socket_type_t { tcp, tcp_ssl, udp }; enum socket_type_t { tcp, tcp_ssl, udp, utp_ssl };
// internal // internal
listen_succeeded_alert(tcp::endpoint const& ep, socket_type_t t) listen_succeeded_alert(tcp::endpoint const& ep, socket_type_t t)

View File

@ -1029,9 +1029,14 @@ namespace libtorrent
int m_external_udp_port; int m_external_udp_port;
rate_limited_udp_socket m_udp_socket; rate_limited_udp_socket m_udp_socket;
libtorrent::utp_socket_manager m_utp_socket_manager; libtorrent::utp_socket_manager m_utp_socket_manager;
#ifdef TORRENT_USE_OPENSSL
// used for uTP connectons over SSL
udp_socket m_ssl_udp_socket;
libtorrent::utp_socket_manager m_ssl_utp_socket_manager;
#endif
// the number of torrent connection boosts // the number of torrent connection boosts
// connections that have been made this second // connections that have been made this second
// this is deducted from the connect speed // this is deducted from the connect speed
@ -1050,7 +1055,8 @@ namespace libtorrent
int m_tcp_mapping[2]; int m_tcp_mapping[2];
int m_udp_mapping[2]; int m_udp_mapping[2];
#ifdef TORRENT_USE_OPENSSL #ifdef TORRENT_USE_OPENSSL
int m_ssl_mapping[2]; int m_ssl_tcp_mapping[2];
int m_ssl_udp_mapping[2];
#endif #endif
// the timer used to fire the tick // the timer used to fire the tick

View File

@ -154,6 +154,11 @@ public:
} }
#endif #endif
error_code cancel(error_code& ec)
{
return m_sock.cancel(ec);
}
void bind(endpoint_type const& /* endpoint */, error_code& /* ec */) void bind(endpoint_type const& /* endpoint */, error_code& /* ec */)
{ {
// the reason why we ignore binds here is because we don't // the reason why we ignore binds here is because we don't

View File

@ -263,7 +263,6 @@ namespace libtorrent
error_code get_option(GettableSocketOption& opt, error_code& ec) error_code get_option(GettableSocketOption& opt, error_code& ec)
{ TORRENT_SOCKTYPE_FORWARD_RET(get_option(opt, ec), ec) } { TORRENT_SOCKTYPE_FORWARD_RET(get_option(opt, ec), ec) }
template <class S> template <class S>
void instantiate(io_service& ios, void* userdata = 0) void instantiate(io_service& ios, void* userdata = 0)
{ {

View File

@ -114,6 +114,8 @@ public:
template <class Handler> template <class Handler>
void async_shutdown(Handler const& handler) void async_shutdown(Handler const& handler)
{ {
error_code ec;
m_sock.next_layer().cancel(ec);
m_sock.async_shutdown(handler); m_sock.async_shutdown(handler);
} }

View File

@ -51,7 +51,8 @@ namespace libtorrent
struct utp_socket_manager : udp_socket_observer struct utp_socket_manager : udp_socket_observer
{ {
utp_socket_manager(aux::session_settings const& sett, udp_socket& s, counters& cnt, incoming_utp_callback_t cb); utp_socket_manager(aux::session_settings const& sett, udp_socket& s
, counters& cnt, void* ssl_context, incoming_utp_callback_t cb);
~utp_socket_manager(); ~utp_socket_manager();
void get_status(utp_status& s) const; void get_status(utp_status& s) const;
@ -152,6 +153,10 @@ namespace libtorrent
// stats counters // stats counters
counters& m_counters; counters& m_counters;
// this is passed on to the instantiate connection
// if this is non-null it will create SSL connections over uTP
void* m_ssl_context;
}; };
} }

View File

@ -217,6 +217,11 @@ public:
template <class GettableSocketOption> template <class GettableSocketOption>
error_code get_option(GettableSocketOption&, error_code& ec) { return ec; } error_code get_option(GettableSocketOption&, error_code& ec) { return ec; }
error_code cancel(error_code& ec)
{
cancel_handlers(asio::error::operation_aborted);
return error_code();
}
void close(); void close();
void close(error_code const& /*ec*/) { close(); } void close(error_code const& /*ec*/) { close(); }

View File

@ -301,7 +301,7 @@ namespace libtorrent {
}; };
static char const* type_str[] = static char const* type_str[] =
{ {
"TCP", "TCP/SSL", "UDP", "I2P", "Socks5" "TCP", "TCP/SSL", "UDP", "I2P", "Socks5", "uTP/SSL"
}; };
char ret[300]; char ret[300];
snprintf(ret, sizeof(ret), "listening on %s failed: [%s] [%s] %s" snprintf(ret, sizeof(ret), "listening on %s failed: [%s] [%s] %s"
@ -316,7 +316,7 @@ namespace libtorrent {
{ {
static char const* type_str[] = static char const* type_str[] =
{ {
"TCP", "TCP/SSL", "UDP" "TCP", "TCP/SSL", "UDP", "uTP/SSL"
}; };
char ret[200]; char ret[200];
snprintf(ret, sizeof(ret), "successfully listening on [%s] %s" snprintf(ret, sizeof(ret), "successfully listening on [%s] %s"

View File

@ -6083,7 +6083,8 @@ namespace libtorrent
if (ec) if (ec)
{ {
if (ec == boost::asio::error::try_again || ec == boost::asio::error::would_block) if (ec == boost::asio::error::try_again
|| ec == boost::asio::error::would_block)
{ {
// allow reading from the socket again // allow reading from the socket again
TORRENT_ASSERT(m_channel_state[download_channel] & peer_info::bw_network); TORRENT_ASSERT(m_channel_state[download_channel] & peer_info::bw_network);

View File

@ -479,13 +479,14 @@ namespace aux {
#endif #endif
, m_external_udp_port(0) , m_external_udp_port(0)
, m_udp_socket(m_io_service) , m_udp_socket(m_io_service)
// TODO: 4 in order to support SSL over uTP, the utp_socket manager either , m_utp_socket_manager(m_settings, m_udp_socket, m_stats_counters, NULL
// needs to be able to receive packets on multiple ports, or we need to
// peek into the first few bytes the payload stream of a socket to determine
// whether or not it's an SSL connection. (The former is simpler but won't
// do as well with NATs)
, m_utp_socket_manager(m_settings, m_udp_socket, m_stats_counters
, boost::bind(&session_impl::incoming_connection, this, _1)) , boost::bind(&session_impl::incoming_connection, this, _1))
#ifdef TORRENT_USE_OPENSSL
, m_ssl_udp_socket(m_io_service)
, m_ssl_utp_socket_manager(m_settings, m_ssl_udp_socket, m_stats_counters
, &m_ssl_ctx
, boost::bind(&session_impl::incoming_connection, this, _1))
#endif
, m_boost_connections(0) , m_boost_connections(0)
, m_timer(m_io_service) , m_timer(m_io_service)
, m_lsd_announce_timer(m_io_service) , m_lsd_announce_timer(m_io_service)
@ -513,6 +514,11 @@ namespace aux {
m_udp_socket.subscribe(&m_utp_socket_manager); m_udp_socket.subscribe(&m_utp_socket_manager);
m_udp_socket.subscribe(this); m_udp_socket.subscribe(this);
#ifdef TORRENT_USE_OPENSSL
m_ssl_udp_socket.subscribe(&m_ssl_utp_socket_manager);
m_ssl_udp_socket.subscribe(this);
#endif
#ifdef TORRENT_REQUEST_LOGGING #ifdef TORRENT_REQUEST_LOGGING
char log_filename[200]; char log_filename[200];
#ifdef TORRENT_WINDOWS #ifdef TORRENT_WINDOWS
@ -576,8 +582,10 @@ namespace aux {
m_udp_mapping[0] = -1; m_udp_mapping[0] = -1;
m_udp_mapping[1] = -1; m_udp_mapping[1] = -1;
#ifdef TORRENT_USE_OPENSSL #ifdef TORRENT_USE_OPENSSL
m_ssl_mapping[0] = -1; m_ssl_tcp_mapping[0] = -1;
m_ssl_mapping[1] = -1; m_ssl_tcp_mapping[1] = -1;
m_ssl_udp_mapping[0] = -1;
m_ssl_udp_mapping[1] = -1;
#endif #endif
m_global_class = m_classes.new_peer_class("global"); m_global_class = m_classes.new_peer_class("global");
@ -1500,6 +1508,9 @@ namespace aux {
// the uTP connections cannot be closed gracefully // the uTP connections cannot be closed gracefully
m_udp_socket.close(); m_udp_socket.close();
m_external_udp_port = 0; m_external_udp_port = 0;
#ifdef TORRENT_USE_OPENSSL
m_ssl_udp_socket.close();
#endif
m_undead_peers.clear(); m_undead_peers.clear();
@ -2185,7 +2196,8 @@ retry:
listen_socket_t s; listen_socket_t s;
s.ssl = true; s.ssl = true;
int retries = 10; int retries = 10;
setup_listener(&s, "0.0.0.0", true, m_settings.get_int(settings_pack::ssl_listen) setup_listener(&s, "0.0.0.0", true
, m_settings.get_int(settings_pack::ssl_listen)
, retries, flags, ec); , retries, flags, ec);
if (s.sock) if (s.sock)
@ -2215,7 +2227,8 @@ retry:
listen_socket_t s; listen_socket_t s;
s.ssl = true; s.ssl = true;
int retries = 10; int retries = 10;
setup_listener(&s, "::1", false, m_settings.get_int(settings_pack::ssl_listen) setup_listener(&s, "::1", false
, m_settings.get_int(settings_pack::ssl_listen)
, retries, flags, ec); , retries, flags, ec);
if (s.sock) if (s.sock)
@ -2243,6 +2256,8 @@ retry:
} }
else else
{ {
// TODO: 2 the udp socket(s) should be using the same generic
// mechanism and not be restricted to a single one
// we should open a one listen socket for each entry in the // we should open a one listen socket for each entry in the
// listen_interfaces list // listen_interfaces list
for (int i = 0; i < m_listen_interfaces.size(); ++i) for (int i = 0; i < m_listen_interfaces.size(); ++i)
@ -2340,6 +2355,34 @@ retry:
return; return;
} }
#ifdef TORRENT_USE_OPENSSL
// TODO: 2 use bind_to_device in udp_socket
int ssl_port = m_settings.get_int(settings_pack::ssl_listen);
udp::endpoint ssl_bind_if(m_listen_interface.address(), ssl_port);
m_ssl_udp_socket.bind(ssl_bind_if, ec);
if (ec)
{
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
session_log("SSL: cannot bind to UDP interface \"%s\": %s"
, print_endpoint(m_listen_interface).c_str(), ec.message().c_str());
#endif
#endif
if (m_alerts.should_post<listen_failed_alert>())
{
error_code err;
m_alerts.post_alert(listen_failed_alert(print_endpoint(ssl_bind_if)
, listen_failed_alert::bind, ec, listen_failed_alert::utp_ssl));
}
ec.clear();
}
else
{
if (m_alerts.should_post<listen_succeeded_alert>())
m_alerts.post_alert(listen_succeeded_alert(
tcp::endpoint(ssl_bind_if.address(), ssl_bind_if.port())
, listen_succeeded_alert::utp_ssl));
}
// TODO: 2 use bind_to_device in udp_socket // TODO: 2 use bind_to_device in udp_socket
m_udp_socket.bind(udp::endpoint(m_listen_interface.address(), m_listen_interface.port()), ec); m_udp_socket.bind(udp::endpoint(m_listen_interface.address(), m_listen_interface.port()), ec);
if (ec) if (ec)
@ -2412,8 +2455,8 @@ retry:
if (m_tcp_mapping[0] != -1) m_natpmp->delete_mapping(m_tcp_mapping[0]); if (m_tcp_mapping[0] != -1) m_natpmp->delete_mapping(m_tcp_mapping[0]);
m_tcp_mapping[0] = m_natpmp->add_mapping(natpmp::tcp, tcp_port, tcp_port); m_tcp_mapping[0] = m_natpmp->add_mapping(natpmp::tcp, tcp_port, tcp_port);
#ifdef TORRENT_USE_OPENSSL #ifdef TORRENT_USE_OPENSSL
if (m_ssl_mapping[0] != -1) m_natpmp->delete_mapping(m_ssl_mapping[0]); if (m_ssl_tcp_mapping[0] != -1) m_natpmp->delete_mapping(m_ssl_tcp_mapping[0]);
if (ssl_port > 0) m_ssl_mapping[0] = m_natpmp->add_mapping(natpmp::tcp if (ssl_port > 0) m_ssl_tcp_mapping[0] = m_natpmp->add_mapping(natpmp::tcp
, ssl_port, ssl_port); , ssl_port, ssl_port);
#endif #endif
} }
@ -2422,8 +2465,8 @@ retry:
if (m_tcp_mapping[1] != -1) m_upnp->delete_mapping(m_tcp_mapping[1]); if (m_tcp_mapping[1] != -1) m_upnp->delete_mapping(m_tcp_mapping[1]);
m_tcp_mapping[1] = m_upnp->add_mapping(upnp::tcp, tcp_port, tcp_port); m_tcp_mapping[1] = m_upnp->add_mapping(upnp::tcp, tcp_port, tcp_port);
#ifdef TORRENT_USE_OPENSSL #ifdef TORRENT_USE_OPENSSL
if (m_ssl_mapping[1] != -1) m_upnp->delete_mapping(m_ssl_mapping[1]); if (m_ssl_tcp_mapping[1] != -1) m_upnp->delete_mapping(m_ssl_tcp_mapping[1]);
if (ssl_port > 0) m_ssl_mapping[1] = m_upnp->add_mapping(upnp::tcp if (ssl_port > 0) m_ssl_tcp_mapping[1] = m_upnp->add_mapping(upnp::tcp
, ssl_port, ssl_port); , ssl_port, ssl_port);
#endif #endif
} }
@ -6111,6 +6154,10 @@ retry:
// open the socks incoming connection // open the socks incoming connection
if (!m_socks_listen_socket) open_new_incoming_socks_connection(); if (!m_socks_listen_socket) open_new_incoming_socks_connection();
m_udp_socket.set_proxy_settings(proxy()); m_udp_socket.set_proxy_settings(proxy());
#ifdef TORRENT_USE_OPENSSL
m_ssl_udp_socket.set_proxy_settings(proxy());
#endif
} }
void session_impl::update_upnp() void session_impl::update_upnp()
@ -6196,12 +6243,14 @@ retry:
// mode. We don't want to leak our listen port since it can // mode. We don't want to leak our listen port since it can
// potentially identify us if it is leaked elsewere // potentially identify us if it is leaked elsewere
if (m_settings.get_bool(settings_pack::force_proxy)) return 0; if (m_settings.get_bool(settings_pack::force_proxy)) return 0;
if (m_listen_sockets.empty()) return 0;
for (std::list<listen_socket_t>::const_iterator i = m_listen_sockets.begin() for (std::list<listen_socket_t>::const_iterator i = m_listen_sockets.begin()
, end(m_listen_sockets.end()); i != end; ++i) , end(m_listen_sockets.end()); i != end; ++i)
{ {
if (i->ssl) return i->external_port; if (i->ssl) return i->external_port;
} }
if (m_ssl_udp_socket.is_open())
return m_ssl_udp_socket.local_port();
#endif #endif
return 0; return 0;
} }
@ -6666,6 +6715,11 @@ retry:
m_udp_socket.unsubscribe(&m_utp_socket_manager); m_udp_socket.unsubscribe(&m_utp_socket_manager);
m_udp_socket.unsubscribe(&m_tracker_manager); m_udp_socket.unsubscribe(&m_tracker_manager);
#ifdef TORRENT_USE_OPENSSL
m_ssl_udp_socket.unsubscribe(this);
m_ssl_udp_socket.unsubscribe(&m_utp_socket_manager);
#endif
TORRENT_ASSERT(m_torrents.empty()); TORRENT_ASSERT(m_torrents.empty());
TORRENT_ASSERT(m_connections.empty()); TORRENT_ASSERT(m_connections.empty());
@ -6790,6 +6844,15 @@ retry:
#endif #endif
m_udp_socket.set_option(type_of_service(m_settings.get_int(settings_pack::peer_tos)), ec); m_udp_socket.set_option(type_of_service(m_settings.get_int(settings_pack::peer_tos)), ec);
#ifdef TORRENT_USE_OPENSSL
#if TORRENT_USE_IPV6 && defined IPV6_TCLASS
if (m_ssl_udp_socket.local_endpoint(ec).address().is_v6())
m_ssl_udp_socket.set_option(traffic_class(m_settings.get_int(settings_pack::peer_tos)), ec);
else
#endif
m_ssl_udp_socket.set_option(type_of_service(m_settings.get_int(settings_pack::peer_tos)), ec);
#endif
#if defined TORRENT_VERBOSE_LOGGING #if defined TORRENT_VERBOSE_LOGGING
session_log(">>> SET_TOS [ udp_socket tos: %x e: %s ]" session_log(">>> SET_TOS [ udp_socket tos: %x e: %s ]"
, m_settings.get_int(settings_pack::peer_tos) , m_settings.get_int(settings_pack::peer_tos)
@ -6981,6 +7044,15 @@ retry:
if (m_alerts.should_post<udp_error_alert>()) if (m_alerts.should_post<udp_error_alert>())
m_alerts.post_alert(udp_error_alert(udp::endpoint(), ec)); m_alerts.post_alert(udp_error_alert(udp::endpoint(), ec));
} }
#ifdef TORRENT_USE_OPENSSL
set_socket_buffer_size(m_ssl_udp_socket, m_settings, ec);
if (ec)
{
if (m_alerts.should_post<udp_error_alert>())
m_alerts.post_alert(udp_error_alert(udp::endpoint(), ec));
}
#endif
} }
void session_impl::update_dht_announce_interval() void session_impl::update_dht_announce_interval()
@ -7036,6 +7108,9 @@ retry:
void session_impl::update_force_proxy() void session_impl::update_force_proxy()
{ {
m_udp_socket.set_force_proxy(m_settings.get_bool(settings_pack::force_proxy)); m_udp_socket.set_force_proxy(m_settings.get_bool(settings_pack::force_proxy));
#ifdef TORRENT_USE_OPENSSL
m_ssl_udp_socket.set_force_proxy(m_settings.get_bool(settings_pack::force_proxy));
#endif
if (!m_settings.get_bool(settings_pack::force_proxy)) return; if (!m_settings.get_bool(settings_pack::force_proxy)) return;
@ -7283,15 +7358,24 @@ retry:
m_natpmp = n; m_natpmp = n;
int ssl_port = ssl_listen_port();
if (m_listen_interface.port() > 0) if (m_listen_interface.port() > 0)
{ {
remap_tcp_ports(1, m_listen_interface.port(), ssl_listen_port()); remap_tcp_ports(1, m_listen_interface.port(), ssl_port);
} }
if (m_udp_socket.is_open()) if (m_udp_socket.is_open())
{ {
m_udp_mapping[0] = m_natpmp->add_mapping(natpmp::udp m_udp_mapping[0] = m_natpmp->add_mapping(natpmp::udp
, m_listen_interface.port(), m_listen_interface.port()); , m_listen_interface.port(), m_listen_interface.port());
} }
#ifdef TORRENT_USE_OPENSSL
if (m_ssl_udp_socket.is_open() && ssl_port > 0)
{
m_ssl_udp_mapping[0] = m_natpmp->add_mapping(natpmp::udp
, ssl_port, ssl_port);
}
#endif
return n; return n;
} }
@ -7315,16 +7399,25 @@ retry:
m_upnp = u; m_upnp = u;
int ssl_port = ssl_listen_port();
m_upnp->discover_device(); m_upnp->discover_device();
if (m_listen_interface.port() > 0 || ssl_listen_port() > 0) if (m_listen_interface.port() > 0 || ssl_port > 0)
{ {
remap_tcp_ports(2, m_listen_interface.port(), ssl_listen_port()); remap_tcp_ports(2, m_listen_interface.port(), ssl_port);
} }
if (m_udp_socket.is_open()) if (m_udp_socket.is_open())
{ {
m_udp_mapping[1] = m_upnp->add_mapping(upnp::udp m_udp_mapping[1] = m_upnp->add_mapping(upnp::udp
, m_listen_interface.port(), m_listen_interface.port()); , m_listen_interface.port(), m_listen_interface.port());
} }
#ifdef TORRENT_USE_OPENSSL
if (m_ssl_udp_socket.is_open() && ssl_port > 0)
{
m_ssl_udp_mapping[1] = m_upnp->add_mapping(upnp::udp
, ssl_port, ssl_port);
}
#endif
return u; return u;
} }
@ -7355,7 +7448,15 @@ retry:
void session_impl::stop_natpmp() void session_impl::stop_natpmp()
{ {
if (m_natpmp.get()) if (m_natpmp.get())
{
m_natpmp->close(); m_natpmp->close();
m_udp_mapping[0] = -1;
m_tcp_mapping[0] = -1;
#ifdef TORRENT_USE_OPENSSL
m_ssl_tcp_mapping[0] = -1;
m_ssl_udp_mapping[0] = -1;
#endif
}
m_natpmp = 0; m_natpmp = 0;
} }
@ -7367,7 +7468,8 @@ retry:
m_udp_mapping[1] = -1; m_udp_mapping[1] = -1;
m_tcp_mapping[1] = -1; m_tcp_mapping[1] = -1;
#ifdef TORRENT_USE_OPENSSL #ifdef TORRENT_USE_OPENSSL
m_ssl_mapping[1] = -1; m_ssl_tcp_mapping[1] = -1;
m_ssl_udp_mapping[1] = -1;
#endif #endif
} }
m_upnp = 0; m_upnp = 0;

View File

@ -142,6 +142,7 @@ namespace libtorrent
#else #else
#define MAYBE_ASIO_DEBUGGING #define MAYBE_ASIO_DEBUGGING
#endif #endif
#define CASE(t) case socket_type_int_impl<ssl_stream<t> >::value: \ #define CASE(t) case socket_type_int_impl<ssl_stream<t> >::value: \
MAYBE_ASIO_DEBUGGING \ MAYBE_ASIO_DEBUGGING \
s.get<ssl_stream<t> >()->async_shutdown(boost::bind(&on_close_socket, &s, holder)); \ s.get<ssl_stream<t> >()->async_shutdown(boost::bind(&on_close_socket, &s, holder)); \

View File

@ -47,6 +47,7 @@ namespace libtorrent
utp_socket_manager::utp_socket_manager(aux::session_settings const& sett utp_socket_manager::utp_socket_manager(aux::session_settings const& sett
, udp_socket& s , udp_socket& s
, counters& cnt , counters& cnt
, void* ssl_context
, incoming_utp_callback_t cb) , incoming_utp_callback_t cb)
: m_sock(s) : m_sock(s)
, m_cb(cb) , m_cb(cb)
@ -57,6 +58,7 @@ namespace libtorrent
, m_last_if_update(min_time()) , m_last_if_update(min_time())
, m_sock_buf_size(0) , m_sock_buf_size(0)
, m_counters(cnt) , m_counters(cnt)
, m_ssl_context(ssl_context)
{} {}
utp_socket_manager::~utp_socket_manager() utp_socket_manager::~utp_socket_manager()
@ -346,8 +348,18 @@ namespace libtorrent
// create the new socket with this ID // create the new socket with this ID
m_new_connection = id; m_new_connection = id;
instantiate_connection(m_sock.get_io_service(), proxy_settings(), *c, 0, this); instantiate_connection(m_sock.get_io_service(), proxy_settings(), *c
utp_stream* str = c->get<utp_stream>(); , m_ssl_context, this, true);
utp_stream* str = NULL;
#ifdef TORRENT_USE_OPENSSL
if (is_ssl(*c))
str = &c->get<ssl_stream<utp_stream> >()->next_layer();
else
#endif
str = c->get<utp_stream>();
TORRENT_ASSERT(str); TORRENT_ASSERT(str);
int link_mtu, utp_mtu; int link_mtu, utp_mtu;
mtu_for_dest(ep.address(), link_mtu, utp_mtu); mtu_for_dest(ep.address(), link_mtu, utp_mtu);

View File

@ -3328,6 +3328,11 @@ void utp_socket_impl::do_ledbat(int acked_bytes, int delay, int in_flight)
void utp_stream::bind(endpoint_type const& ep, error_code& ec) { } void utp_stream::bind(endpoint_type const& ep, error_code& ec) { }
void utp_stream::cancel_handlers(error_code const& ec)
{
if (!m_impl) return;
m_impl->cancel_handlers(ec, false);
}
// returns the number of milliseconds a packet would have before // returns the number of milliseconds a packet would have before
// it would time-out if it was sent right now. Takes the RTT estimate // it would time-out if it was sent right now. Takes the RTT estimate
// into account // into account

View File

@ -808,46 +808,41 @@ setup_transfer(lt::session* ses1, lt::session* ses2, lt::session* ses3
// wait_for_alert(*ses1, torrent_finished_alert::alert_type, "ses1"); // wait_for_alert(*ses1, torrent_finished_alert::alert_type, "ses1");
error_code ec; error_code ec;
int port = 0;
if (use_ssl_ports) if (use_ssl_ports)
{ port = ses2->ssl_listen_port();
fprintf(stderr, "%s: ses1: connecting peer port: %d\n", time_now_string(), int(ses2->ssl_listen_port()));
tor1.connect_peer(tcp::endpoint(address::from_string("127.0.0.1", ec) if (port == 0)
, ses2->ssl_listen_port())); port = ses2->listen_port();
}
else fprintf(stderr, "%s: ses1: connecting peer port: %d\n"
{ , time_now_string(), port);
fprintf(stderr, "%s: ses1: connecting peer port: %d\n", time_now_string(), int(ses2->listen_port())); tor1.connect_peer(tcp::endpoint(address::from_string("127.0.0.1", ec)
tor1.connect_peer(tcp::endpoint(address::from_string("127.0.0.1", ec) , port));
, ses2->listen_port()));
}
if (ses3) if (ses3)
{ {
// give the other peers some time to get an initial // give the other peers some time to get an initial
// set of pieces before they start sharing with each-other // set of pieces before they start sharing with each-other
port = 0;
int port2 = 0;
if (use_ssl_ports) if (use_ssl_ports)
{ {
fprintf(stderr, "ses3: connecting peer port: %d\n", int(ses2->ssl_listen_port())); port = ses2->ssl_listen_port();
tor3.connect_peer(tcp::endpoint( port2 = ses1->ssl_listen_port();
address::from_string("127.0.0.1", ec)
, ses2->ssl_listen_port()));
fprintf(stderr, "ses3: connecting peer port: %d\n", int(ses1->ssl_listen_port()));
tor3.connect_peer(tcp::endpoint(
address::from_string("127.0.0.1", ec)
, ses1->ssl_listen_port()));
} }
else
{ if (port == 0) port = ses2->listen_port();
fprintf(stderr, "ses3: connecting peer port: %d\n", int(ses2->listen_port())); if (port2 == 0) port2 = ses1->listen_port();
fprintf(stderr, "ses3: connecting peer port: %d\n", port);
tor3.connect_peer(tcp::endpoint(
address::from_string("127.0.0.1", ec), port));
fprintf(stderr, "ses3: connecting peer port: %d\n", port2);
tor3.connect_peer(tcp::endpoint( tor3.connect_peer(tcp::endpoint(
address::from_string("127.0.0.1", ec) address::from_string("127.0.0.1", ec)
, ses2->listen_port())); , port2));
fprintf(stderr, "ses3: connecting peer port: %d\n", int(ses1->listen_port()));
tor3.connect_peer(tcp::endpoint(
address::from_string("127.0.0.1", ec)
, ses1->listen_port()));
}
} }
} }

View File

@ -83,8 +83,13 @@ int ssl_peer_disconnects = 0;
bool on_alert(alert* a) bool on_alert(alert* a)
{ {
if (alert_cast<peer_disconnected_alert>(a)) if (peer_disconnected_alert* e = alert_cast<peer_disconnected_alert>(a))
{
++peer_disconnects; ++peer_disconnects;
if (e->error.category() == boost::asio::error::get_ssl_category())
++ssl_peer_disconnects;
}
if (peer_error_alert* e = alert_cast<peer_error_alert>(a)) if (peer_error_alert* e = alert_cast<peer_error_alert>(a))
{ {
++peer_disconnects; ++peer_disconnects;
@ -160,7 +165,7 @@ void test_ssl(int test_idx, bool use_utp)
peer_errors = 0; peer_errors = 0;
boost::tie(tor1, tor2, ignore) = setup_transfer(&ses1, &ses2, 0 boost::tie(tor1, tor2, ignore) = setup_transfer(&ses1, &ses2, 0
, true, false, true, "_ssl", 16 * 1024, &t, false, &addp, true, test.use_ssl_ports); , true, false, false, "_ssl", 16 * 1024, &t, false, &addp, true);
if (test.seed_has_cert) if (test.seed_has_cert)
{ {
@ -180,6 +185,23 @@ void test_ssl(int test_idx, bool use_utp)
, "test"); , "test");
} }
// make sure they've taken effect
if (test.downloader_has_cert || test.seed_has_cert)
test_sleep(500);
// connect the peers after setting the certificates
int port = 0;
if (test.use_ssl_ports)
port = ses2.ssl_listen_port();
if (port == 0)
port = ses2.listen_port();
fprintf(stderr, "%s: ses1: connecting peer port: %d\n"
, time_now_string(), port);
tor1.connect_peer(tcp::endpoint(address::from_string("127.0.0.1", ec)
, port));
#ifdef TORRENT_USE_VALGRIND #ifdef TORRENT_USE_VALGRIND
const int timeout = 100; const int timeout = 100;
#else #else
@ -233,10 +255,21 @@ void test_ssl(int test_idx, bool use_utp)
test_sleep(100); test_sleep(100);
} }
fprintf(stderr, "peer_errors: %d expected: %d\n", peer_errors, test.peer_errors); fprintf(stderr, "peer_errors: %d peer_disconnects: %d expected: %d\n"
TEST_EQUAL(peer_errors, test.peer_errors); , peer_errors, peer_disconnects, test.peer_errors);
if (test.peer_errors > 0) {
TEST_CHECK(peer_errors + peer_disconnects >= test.peer_errors);
} else {
TEST_EQUAL(peer_errors + peer_disconnects, test.peer_errors);
}
fprintf(stderr, "ssl_disconnects: %d expected: %d\n", ssl_peer_disconnects, test.ssl_disconnects); fprintf(stderr, "ssl_disconnects: %d expected: %d\n", ssl_peer_disconnects, test.ssl_disconnects);
TEST_EQUAL(ssl_peer_disconnects, test.ssl_disconnects); if (test.ssl_disconnects > 0) {
TEST_CHECK(ssl_peer_disconnects >= test.ssl_disconnects);
} else {
TEST_EQUAL(ssl_peer_disconnects, test.ssl_disconnects);
}
fprintf(stderr, "%s: EXPECT: %s\n", time_now_string(), test.expected_to_complete ? "SUCCEESS" : "FAILURE"); fprintf(stderr, "%s: EXPECT: %s\n", time_now_string(), test.expected_to_complete ? "SUCCEESS" : "FAILURE");
fprintf(stderr, "%s: RESULT: %s\n", time_now_string(), tor2.status().is_seeding ? "SUCCEESS" : "FAILURE"); fprintf(stderr, "%s: RESULT: %s\n", time_now_string(), tor2.status().is_seeding ? "SUCCEESS" : "FAILURE");
TEST_CHECK(tor2.status().is_seeding == test.expected_to_complete); TEST_CHECK(tor2.status().is_seeding == test.expected_to_complete);
@ -489,7 +522,6 @@ void test_malicious_peer()
remove_all("tmp3_ssl", ec); remove_all("tmp3_ssl", ec);
// set up session // set up session
int ssl_port = 1024 + rand() % 50000; int ssl_port = 1024 + rand() % 50000;
settings_pack sett; settings_pack sett;
sett.set_int(settings_pack::alert_mask, alert_mask); sett.set_int(settings_pack::alert_mask, alert_mask);
@ -544,9 +576,11 @@ int test_main()
#ifdef TORRENT_USE_OPENSSL #ifdef TORRENT_USE_OPENSSL
test_malicious_peer(); test_malicious_peer();
// No support for SSL/uTP yet, so always pass in false for (int utp = 0; utp < 2; ++utp)
for (int i = 0; i < sizeof(test_config)/sizeof(test_config[0]); ++i) {
test_ssl(i, false); for (int i = 0; i < sizeof(test_config)/sizeof(test_config[0]); ++i)
test_ssl(i, utp);
}
error_code ec; error_code ec;
remove_all("tmp1_ssl", ec); remove_all("tmp1_ssl", ec);