From a655047cb0ebd541629fa9dda6e4441dc9ba145e Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Mon, 6 Oct 2014 03:03:01 +0000 Subject: [PATCH] support SSL over uTP (unit test is still failing with same errors as previously, this has not been fixed yet) --- ChangeLog | 1 + include/libtorrent/alert_types.hpp | 4 +- include/libtorrent/aux_/session_impl.hpp | 10 +- include/libtorrent/proxy_base.hpp | 5 + include/libtorrent/socket_type.hpp | 1 - include/libtorrent/ssl_stream.hpp | 2 + include/libtorrent/utp_socket_manager.hpp | 7 +- include/libtorrent/utp_stream.hpp | 5 + src/alert.cpp | 4 +- src/peer_connection.cpp | 3 +- src/session_impl.cpp | 140 +++++++++++++++++++--- src/socket_type.cpp | 1 + src/utp_socket_manager.cpp | 16 ++- src/utp_stream.cpp | 5 + test/setup_transfer.cpp | 51 ++++---- test/test_ssl.cpp | 52 ++++++-- 16 files changed, 240 insertions(+), 67 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6f4285b73..c18182465 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,4 @@ + * support SSL over uTP connections * support web seeds that resolve to multiple IPs * added auto-sequential feature. download well-seeded torrents in-order * removed built-in GeoIP support (this functionality is orthogonal to libtorrent) diff --git a/include/libtorrent/alert_types.hpp b/include/libtorrent/alert_types.hpp index b5d55353c..b272ad9a8 100644 --- a/include/libtorrent/alert_types.hpp +++ b/include/libtorrent/alert_types.hpp @@ -1325,7 +1325,7 @@ namespace libtorrent // listen on it. 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 listen_failed_alert( @@ -1368,7 +1368,7 @@ namespace libtorrent // was opened for listening. 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 listen_succeeded_alert(tcp::endpoint const& ep, socket_type_t t) diff --git a/include/libtorrent/aux_/session_impl.hpp b/include/libtorrent/aux_/session_impl.hpp index d5e173317..d24eb767e 100644 --- a/include/libtorrent/aux_/session_impl.hpp +++ b/include/libtorrent/aux_/session_impl.hpp @@ -1029,9 +1029,14 @@ namespace libtorrent int m_external_udp_port; rate_limited_udp_socket m_udp_socket; - 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 // connections that have been made this second // this is deducted from the connect speed @@ -1050,7 +1055,8 @@ namespace libtorrent int m_tcp_mapping[2]; int m_udp_mapping[2]; #ifdef TORRENT_USE_OPENSSL - int m_ssl_mapping[2]; + int m_ssl_tcp_mapping[2]; + int m_ssl_udp_mapping[2]; #endif // the timer used to fire the tick diff --git a/include/libtorrent/proxy_base.hpp b/include/libtorrent/proxy_base.hpp index 6b28a6e54..56f0fbcb7 100644 --- a/include/libtorrent/proxy_base.hpp +++ b/include/libtorrent/proxy_base.hpp @@ -154,6 +154,11 @@ public: } #endif + error_code cancel(error_code& ec) + { + return m_sock.cancel(ec); + } + void bind(endpoint_type const& /* endpoint */, error_code& /* ec */) { // the reason why we ignore binds here is because we don't diff --git a/include/libtorrent/socket_type.hpp b/include/libtorrent/socket_type.hpp index 7dc5d435b..1e51c6ac9 100644 --- a/include/libtorrent/socket_type.hpp +++ b/include/libtorrent/socket_type.hpp @@ -263,7 +263,6 @@ namespace libtorrent error_code get_option(GettableSocketOption& opt, error_code& ec) { TORRENT_SOCKTYPE_FORWARD_RET(get_option(opt, ec), ec) } - template void instantiate(io_service& ios, void* userdata = 0) { diff --git a/include/libtorrent/ssl_stream.hpp b/include/libtorrent/ssl_stream.hpp index 5c475952e..a6c9ddb6f 100644 --- a/include/libtorrent/ssl_stream.hpp +++ b/include/libtorrent/ssl_stream.hpp @@ -114,6 +114,8 @@ public: template void async_shutdown(Handler const& handler) { + error_code ec; + m_sock.next_layer().cancel(ec); m_sock.async_shutdown(handler); } diff --git a/include/libtorrent/utp_socket_manager.hpp b/include/libtorrent/utp_socket_manager.hpp index 3439ae2bc..9beca2479 100644 --- a/include/libtorrent/utp_socket_manager.hpp +++ b/include/libtorrent/utp_socket_manager.hpp @@ -51,7 +51,8 @@ namespace libtorrent 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(); void get_status(utp_status& s) const; @@ -152,6 +153,10 @@ namespace libtorrent // stats 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; }; } diff --git a/include/libtorrent/utp_stream.hpp b/include/libtorrent/utp_stream.hpp index 1928c666a..71712a2d6 100644 --- a/include/libtorrent/utp_stream.hpp +++ b/include/libtorrent/utp_stream.hpp @@ -217,6 +217,11 @@ public: template 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(error_code const& /*ec*/) { close(); } diff --git a/src/alert.cpp b/src/alert.cpp index 317aeee1a..359e87624 100644 --- a/src/alert.cpp +++ b/src/alert.cpp @@ -301,7 +301,7 @@ namespace libtorrent { }; static char const* type_str[] = { - "TCP", "TCP/SSL", "UDP", "I2P", "Socks5" + "TCP", "TCP/SSL", "UDP", "I2P", "Socks5", "uTP/SSL" }; char ret[300]; snprintf(ret, sizeof(ret), "listening on %s failed: [%s] [%s] %s" @@ -316,7 +316,7 @@ namespace libtorrent { { static char const* type_str[] = { - "TCP", "TCP/SSL", "UDP" + "TCP", "TCP/SSL", "UDP", "uTP/SSL" }; char ret[200]; snprintf(ret, sizeof(ret), "successfully listening on [%s] %s" diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp index 01a0173d2..6a06cd671 100644 --- a/src/peer_connection.cpp +++ b/src/peer_connection.cpp @@ -6083,7 +6083,8 @@ namespace libtorrent 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 TORRENT_ASSERT(m_channel_state[download_channel] & peer_info::bw_network); diff --git a/src/session_impl.cpp b/src/session_impl.cpp index 1919cc80c..5f1812974 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -479,13 +479,14 @@ namespace aux { #endif , m_external_udp_port(0) , m_udp_socket(m_io_service) - // TODO: 4 in order to support SSL over uTP, the utp_socket manager either - // 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 + , m_utp_socket_manager(m_settings, m_udp_socket, m_stats_counters, NULL , 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_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(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 char log_filename[200]; #ifdef TORRENT_WINDOWS @@ -576,8 +582,10 @@ namespace aux { m_udp_mapping[0] = -1; m_udp_mapping[1] = -1; #ifdef TORRENT_USE_OPENSSL - m_ssl_mapping[0] = -1; - m_ssl_mapping[1] = -1; + m_ssl_tcp_mapping[0] = -1; + m_ssl_tcp_mapping[1] = -1; + m_ssl_udp_mapping[0] = -1; + m_ssl_udp_mapping[1] = -1; #endif m_global_class = m_classes.new_peer_class("global"); @@ -1500,6 +1508,9 @@ namespace aux { // the uTP connections cannot be closed gracefully m_udp_socket.close(); m_external_udp_port = 0; +#ifdef TORRENT_USE_OPENSSL + m_ssl_udp_socket.close(); +#endif m_undead_peers.clear(); @@ -2185,7 +2196,8 @@ retry: listen_socket_t s; s.ssl = true; 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); if (s.sock) @@ -2215,7 +2227,8 @@ retry: listen_socket_t s; s.ssl = true; 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); if (s.sock) @@ -2243,6 +2256,8 @@ retry: } 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 // listen_interfaces list for (int i = 0; i < m_listen_interfaces.size(); ++i) @@ -2340,6 +2355,34 @@ retry: 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()) + { + 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()) + 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 m_udp_socket.bind(udp::endpoint(m_listen_interface.address(), m_listen_interface.port()), ec); if (ec) @@ -2412,8 +2455,8 @@ retry: 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); #ifdef TORRENT_USE_OPENSSL - if (m_ssl_mapping[0] != -1) m_natpmp->delete_mapping(m_ssl_mapping[0]); - if (ssl_port > 0) m_ssl_mapping[0] = m_natpmp->add_mapping(natpmp::tcp + if (m_ssl_tcp_mapping[0] != -1) m_natpmp->delete_mapping(m_ssl_tcp_mapping[0]); + if (ssl_port > 0) m_ssl_tcp_mapping[0] = m_natpmp->add_mapping(natpmp::tcp , ssl_port, ssl_port); #endif } @@ -2422,8 +2465,8 @@ retry: 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); #ifdef TORRENT_USE_OPENSSL - if (m_ssl_mapping[1] != -1) m_upnp->delete_mapping(m_ssl_mapping[1]); - if (ssl_port > 0) m_ssl_mapping[1] = m_upnp->add_mapping(upnp::tcp + if (m_ssl_tcp_mapping[1] != -1) m_upnp->delete_mapping(m_ssl_tcp_mapping[1]); + if (ssl_port > 0) m_ssl_tcp_mapping[1] = m_upnp->add_mapping(upnp::tcp , ssl_port, ssl_port); #endif } @@ -6111,6 +6154,10 @@ retry: // open the socks incoming connection if (!m_socks_listen_socket) open_new_incoming_socks_connection(); 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() @@ -6196,12 +6243,14 @@ retry: // mode. We don't want to leak our listen port since it can // potentially identify us if it is leaked elsewere if (m_settings.get_bool(settings_pack::force_proxy)) return 0; - if (m_listen_sockets.empty()) return 0; for (std::list::const_iterator i = m_listen_sockets.begin() , end(m_listen_sockets.end()); i != end; ++i) { if (i->ssl) return i->external_port; } + + if (m_ssl_udp_socket.is_open()) + return m_ssl_udp_socket.local_port(); #endif return 0; } @@ -6666,6 +6715,11 @@ retry: m_udp_socket.unsubscribe(&m_utp_socket_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_connections.empty()); @@ -6790,6 +6844,15 @@ retry: #endif 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 session_log(">>> SET_TOS [ udp_socket tos: %x e: %s ]" , m_settings.get_int(settings_pack::peer_tos) @@ -6981,6 +7044,15 @@ retry: if (m_alerts.should_post()) 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()) + m_alerts.post_alert(udp_error_alert(udp::endpoint(), ec)); + } +#endif } void session_impl::update_dht_announce_interval() @@ -7036,6 +7108,9 @@ retry: void session_impl::update_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; @@ -7283,15 +7358,24 @@ retry: m_natpmp = n; + int ssl_port = ssl_listen_port(); + 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()) { m_udp_mapping[0] = m_natpmp->add_mapping(natpmp::udp , 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; } @@ -7315,16 +7399,25 @@ retry: m_upnp = u; + int ssl_port = ssl_listen_port(); + 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()) { m_udp_mapping[1] = m_upnp->add_mapping(upnp::udp , 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; } @@ -7355,7 +7448,15 @@ retry: void session_impl::stop_natpmp() { if (m_natpmp.get()) + { 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; } @@ -7367,7 +7468,8 @@ retry: m_udp_mapping[1] = -1; m_tcp_mapping[1] = -1; #ifdef TORRENT_USE_OPENSSL - m_ssl_mapping[1] = -1; + m_ssl_tcp_mapping[1] = -1; + m_ssl_udp_mapping[1] = -1; #endif } m_upnp = 0; diff --git a/src/socket_type.cpp b/src/socket_type.cpp index 7267af6cc..0b9dc0371 100644 --- a/src/socket_type.cpp +++ b/src/socket_type.cpp @@ -142,6 +142,7 @@ namespace libtorrent #else #define MAYBE_ASIO_DEBUGGING #endif + #define CASE(t) case socket_type_int_impl >::value: \ MAYBE_ASIO_DEBUGGING \ s.get >()->async_shutdown(boost::bind(&on_close_socket, &s, holder)); \ diff --git a/src/utp_socket_manager.cpp b/src/utp_socket_manager.cpp index 3fc9357e6..44d118cb1 100644 --- a/src/utp_socket_manager.cpp +++ b/src/utp_socket_manager.cpp @@ -47,6 +47,7 @@ namespace libtorrent utp_socket_manager::utp_socket_manager(aux::session_settings const& sett , udp_socket& s , counters& cnt + , void* ssl_context , incoming_utp_callback_t cb) : m_sock(s) , m_cb(cb) @@ -57,6 +58,7 @@ namespace libtorrent , m_last_if_update(min_time()) , m_sock_buf_size(0) , m_counters(cnt) + , m_ssl_context(ssl_context) {} utp_socket_manager::~utp_socket_manager() @@ -346,8 +348,18 @@ namespace libtorrent // create the new socket with this ID m_new_connection = id; - instantiate_connection(m_sock.get_io_service(), proxy_settings(), *c, 0, this); - utp_stream* str = c->get(); + instantiate_connection(m_sock.get_io_service(), proxy_settings(), *c + , m_ssl_context, this, true); + + + utp_stream* str = NULL; +#ifdef TORRENT_USE_OPENSSL + if (is_ssl(*c)) + str = &c->get >()->next_layer(); + else +#endif + str = c->get(); + TORRENT_ASSERT(str); int link_mtu, utp_mtu; mtu_for_dest(ep.address(), link_mtu, utp_mtu); diff --git a/src/utp_stream.cpp b/src/utp_stream.cpp index 4bf8cd5db..d7bf6804f 100644 --- a/src/utp_stream.cpp +++ b/src/utp_stream.cpp @@ -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::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 // it would time-out if it was sent right now. Takes the RTT estimate // into account diff --git a/test/setup_transfer.cpp b/test/setup_transfer.cpp index 7787a5429..11901ca5f 100644 --- a/test/setup_transfer.cpp +++ b/test/setup_transfer.cpp @@ -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"); error_code ec; + int port = 0; if (use_ssl_ports) - { - 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) - , ses2->ssl_listen_port())); - } - else - { - 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) - , ses2->listen_port())); - } + 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)); if (ses3) { // give the other peers some time to get an initial // set of pieces before they start sharing with each-other + port = 0; + int port2 = 0; if (use_ssl_ports) { - fprintf(stderr, "ses3: connecting peer port: %d\n", int(ses2->ssl_listen_port())); - tor3.connect_peer(tcp::endpoint( - 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())); + port = ses2->ssl_listen_port(); + port2 = ses1->ssl_listen_port(); } - else - { - fprintf(stderr, "ses3: connecting peer port: %d\n", int(ses2->listen_port())); + + if (port == 0) port = 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( address::from_string("127.0.0.1", ec) - , ses2->listen_port())); - 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())); - } + , port2)); } } diff --git a/test/test_ssl.cpp b/test/test_ssl.cpp index e3d8a0114..38b3e5d8e 100644 --- a/test/test_ssl.cpp +++ b/test/test_ssl.cpp @@ -83,8 +83,13 @@ int ssl_peer_disconnects = 0; bool on_alert(alert* a) { - if (alert_cast(a)) + if (peer_disconnected_alert* e = alert_cast(a)) + { ++peer_disconnects; + if (e->error.category() == boost::asio::error::get_ssl_category()) + ++ssl_peer_disconnects; + } + if (peer_error_alert* e = alert_cast(a)) { ++peer_disconnects; @@ -160,7 +165,7 @@ void test_ssl(int test_idx, bool use_utp) peer_errors = 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) { @@ -180,6 +185,23 @@ void test_ssl(int test_idx, bool use_utp) , "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 const int timeout = 100; #else @@ -233,10 +255,21 @@ void test_ssl(int test_idx, bool use_utp) test_sleep(100); } - fprintf(stderr, "peer_errors: %d expected: %d\n", peer_errors, test.peer_errors); - TEST_EQUAL(peer_errors, test.peer_errors); + fprintf(stderr, "peer_errors: %d peer_disconnects: %d expected: %d\n" + , 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); - 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: RESULT: %s\n", time_now_string(), tor2.status().is_seeding ? "SUCCEESS" : "FAILURE"); TEST_CHECK(tor2.status().is_seeding == test.expected_to_complete); @@ -489,7 +522,6 @@ void test_malicious_peer() remove_all("tmp3_ssl", ec); // set up session - int ssl_port = 1024 + rand() % 50000; settings_pack sett; sett.set_int(settings_pack::alert_mask, alert_mask); @@ -544,9 +576,11 @@ int test_main() #ifdef TORRENT_USE_OPENSSL test_malicious_peer(); - // No support for SSL/uTP yet, so always pass in false - for (int i = 0; i < sizeof(test_config)/sizeof(test_config[0]); ++i) - test_ssl(i, false); + for (int utp = 0; utp < 2; ++utp) + { + for (int i = 0; i < sizeof(test_config)/sizeof(test_config[0]); ++i) + test_ssl(i, utp); + } error_code ec; remove_all("tmp1_ssl", ec);