diff --git a/ChangeLog b/ChangeLog index b9deae8e8..e13609e19 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,4 @@ + * aded support for SOCKS5 proxies and HTTP CONNECT proxies. * optimized the piece picker in the case where a peer is a seed. * added support for local peer discovery * removed the dependency on the compiled boost.date_time library diff --git a/Jamfile b/Jamfile index 32feb7f02..21823445b 100755 --- a/Jamfile +++ b/Jamfile @@ -41,16 +41,19 @@ SOURCES = entry escape_string http_connection + http_stream identify_client ip_filter peer_connection bt_peer_connection web_peer_connection + instantiate_connection natpmp piece_picker policy session session_impl + socks5_stream stat storage torrent diff --git a/examples/client_test.cpp b/examples/client_test.cpp index 3213c3881..5375d4eef 100644 --- a/examples/client_test.cpp +++ b/examples/client_test.cpp @@ -461,6 +461,7 @@ int main(int ac, char* av[]) std::string bind_to_interface; std::string proxy; std::string proxy_login; + std::string proxy_type; int poll_interval; namespace po = boost::program_options; @@ -514,6 +515,8 @@ int main(int ac, char* av[]) ("proxy-login,n", po::value(&proxy_login)->default_value("") , "Sets the username and password used to authenticate with the http " "proxy. The string should be given in the form: :") + ("proxy-type", po::value(&proxy_type)->default_value("socks5") + , "Sets the type of proxy to use [socks5 | http] ") ; po::positional_options_description p; @@ -557,16 +560,21 @@ int main(int ac, char* av[]) input = vm["input-file"].as< std::vector >(); session_settings settings; + proxy_settings ps; if (!proxy.empty()) { try { std::size_t i = proxy.find(':'); - settings.proxy_ip = proxy.substr(0, i); - if (i == std::string::npos) settings.proxy_port = 8080; - else settings.proxy_port = boost::lexical_cast( + ps.hostname = proxy.substr(0, i); + if (i == std::string::npos) ps.port = 8080; + else ps.port = boost::lexical_cast( proxy.substr(i + 1)); + if (proxy_type == "socks5") + ps.type = proxy_settings::socks5; + else + ps.type = proxy_settings::http; } catch (std::exception&) { @@ -584,8 +592,12 @@ int main(int ac, char* av[]) << proxy_login << std::endl; return 1; } - settings.proxy_login = proxy_login.substr(0, i); - settings.proxy_password = proxy_login.substr(i + 1); + ps.username = proxy_login.substr(0, i); + ps.password = proxy_login.substr(i + 1); + if (proxy_type == "socks5") + ps.type = proxy_settings::socks5_pw; + else + ps.type = proxy_settings::http_pw; } } @@ -611,6 +623,10 @@ int main(int ac, char* av[]) ses.listen_on(std::make_pair(listen_port, listen_port + 10) , bind_to_interface.c_str()); ses.set_settings(settings); + ses.set_tracker_proxy(ps); + ses.set_peer_proxy(ps); + ses.set_web_seed_proxy(ps); + if (log_level == "debug") ses.set_severity_level(alert::debug); else if (log_level == "warning") diff --git a/include/Makefile.am b/include/Makefile.am index 0d27a22b6..f5cd6ff04 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -14,8 +14,10 @@ libtorrent/file_pool.hpp \ libtorrent/fingerprint.hpp \ libtorrent/hasher.hpp \ libtorrent/http_connection.hpp \ +libtorrent/http_stream.hpp \ libtorrent/http_tracker_connection.hpp \ libtorrent/identify_client.hpp \ +libtorrent/instantiate_connection.hpp \ libtorrent/invariant_check.hpp \ libtorrent/io.hpp \ libtorrent/ip_filter.hpp \ @@ -39,6 +41,8 @@ libtorrent/session_settings.hpp \ libtorrent/session_status.hpp \ libtorrent/size_type.hpp \ libtorrent/socket.hpp \ +libtorrent/socket_type.hpp \ +libtorrent/socks5_stream.hpp \ libtorrent/stat.hpp \ libtorrent/storage.hpp \ libtorrent/torrent.hpp \ @@ -48,6 +52,7 @@ libtorrent/tracker_manager.hpp \ libtorrent/udp_tracker_connection.hpp \ libtorrent/utf8.hpp \ libtorrent/xml_parse.hpp \ +libtorrent/variant_stream.hpp \ libtorrent/version.hpp \ libtorrent/aux_/allocate_resources_impl.hpp \ libtorrent/aux_/session_impl.hpp \ diff --git a/include/libtorrent/aux_/session_impl.hpp b/include/libtorrent/aux_/session_impl.hpp index 116fcc0d6..51908287a 100644 --- a/include/libtorrent/aux_/session_impl.hpp +++ b/include/libtorrent/aux_/session_impl.hpp @@ -80,6 +80,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/natpmp.hpp" #include "libtorrent/upnp.hpp" #include "libtorrent/lsd.hpp" +#include "libtorrent/socket_type.hpp" namespace libtorrent { @@ -166,7 +167,7 @@ namespace libtorrent #endif friend struct checker_impl; friend class invariant_access; - typedef std::map + typedef std::map , boost::intrusive_ptr > connection_map; typedef std::map > torrent_map; @@ -187,7 +188,7 @@ namespace libtorrent void open_listen_port(); void async_accept(); - void on_incoming_connection(boost::shared_ptr const& s + void on_incoming_connection(boost::shared_ptr const& s , boost::weak_ptr const& as, asio::error_code const& e); // must be locked to access the data @@ -205,7 +206,7 @@ namespace libtorrent void close_connection(boost::intrusive_ptr const& p); void connection_completed(boost::intrusive_ptr const& p); - void connection_failed(boost::shared_ptr const& s + void connection_failed(boost::shared_ptr const& s , tcp::endpoint const& a, char const* message); void set_settings(session_settings const& s); @@ -282,7 +283,28 @@ namespace libtorrent torrent_handle find_torrent_handle(sha1_hash const& info_hash); void announce_lsd(sha1_hash const& ih); - + + void set_peer_proxy(proxy_settings const& s) + { m_peer_proxy = s; } + void set_web_seed_proxy(proxy_settings const& s) + { m_web_seed_proxy = s; } + void set_tracker_proxy(proxy_settings const& s) + { m_tracker_proxy = s; } + + proxy_settings const& peer_proxy() const + { return m_peer_proxy; } + proxy_settings const& web_seed_proxy() const + { return m_web_seed_proxy; } + proxy_settings const& tracker_proxy() const + { return m_tracker_proxy; } + +#ifndef TORRENT_DISABLE_DHT + void set_dht_proxy(proxy_settings const& s) + { m_dht_proxy = s; } + proxy_settings const& dht_proxy() const + { return m_dht_proxy; } +#endif + // handles delayed alerts alert_manager m_alerts; @@ -355,6 +377,14 @@ namespace libtorrent // the settings for the client session_settings m_settings; + // the proxy settings for different + // kinds of connections + proxy_settings m_peer_proxy; + proxy_settings m_web_seed_proxy; + proxy_settings m_tracker_proxy; +#ifndef TORRENT_DISABLE_DHT + proxy_settings m_dht_proxy; +#endif // set to true when the session object // is being destructed and the thread diff --git a/include/libtorrent/http_tracker_connection.hpp b/include/libtorrent/http_tracker_connection.hpp index 151e12cba..dcae78e9a 100755 --- a/include/libtorrent/http_tracker_connection.hpp +++ b/include/libtorrent/http_tracker_connection.hpp @@ -59,6 +59,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/tracker_manager.hpp" #include "libtorrent/config.hpp" #include "libtorrent/buffer.hpp" +#include "libtorrent/socket_type.hpp" namespace libtorrent { @@ -122,6 +123,7 @@ namespace libtorrent , address bind_infc , boost::weak_ptr c , session_settings const& stn + , proxy_settings const& ps , std::string const& password = ""); private: @@ -152,12 +154,13 @@ namespace libtorrent asio::strand& m_strand; tcp::resolver m_name_lookup; int m_port; - boost::shared_ptr m_socket; + boost::shared_ptr m_socket; int m_recv_pos; std::vector m_buffer; std::string m_send_buffer; session_settings const& m_settings; + proxy_settings const& m_proxy; std::string m_password; bool m_timed_out; diff --git a/include/libtorrent/io.hpp b/include/libtorrent/io.hpp index 57a22cf97..f73c3e290 100755 --- a/include/libtorrent/io.hpp +++ b/include/libtorrent/io.hpp @@ -34,6 +34,7 @@ POSSIBILITY OF SUCH DAMAGE. #define TORRENT_IO_HPP_INCLUDED #include +#include namespace libtorrent { @@ -134,6 +135,18 @@ namespace libtorrent void write_int8(boost::int8_t val, OutIt& start) { write_impl(val, start); } + inline void write_string(std::string const& str, char*& start) + { + std::copy(str.begin(), str.end(), start); + start += str.size(); + } + + template + void write_string(std::string const& str, OutIt& start) + { + std::copy(str.begin(), str.end(), start); + } + } } diff --git a/include/libtorrent/peer_connection.hpp b/include/libtorrent/peer_connection.hpp index b60c718c8..42164656e 100755 --- a/include/libtorrent/peer_connection.hpp +++ b/include/libtorrent/peer_connection.hpp @@ -72,7 +72,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/session.hpp" #include "libtorrent/bandwidth_manager.hpp" #include "libtorrent/policy.hpp" -#include "libtorrent/variant_stream.hpp" +#include "libtorrent/socket_type.hpp" // TODO: each time a block is 'taken over' // from another peer. That peer must be given @@ -104,8 +104,6 @@ namespace libtorrent friend void intrusive_ptr_release(peer_connection const*); public: - typedef variant_stream socket_type; - enum channels { upload_channel, @@ -121,7 +119,6 @@ namespace libtorrent , boost::weak_ptr t , boost::shared_ptr s , tcp::endpoint const& remote - , tcp::endpoint const& proxy , policy::peer* peerinfo); // with this constructor we have been contacted and we still don't @@ -221,7 +218,6 @@ namespace libtorrent boost::shared_ptr get_socket() const { return m_socket; } tcp::endpoint const& remote() const { return m_remote; } - tcp::endpoint const& proxy() const { return m_remote_proxy; } std::vector const& get_bitfield() const; @@ -499,9 +495,6 @@ namespace libtorrent // connected to, in case we use a proxy tcp::endpoint m_remote; - // if we use a proxy, this is the address to it - tcp::endpoint m_remote_proxy; - // this is the torrent this connection is // associated with. If the connection is an // incoming conncetion, this is set to zero diff --git a/include/libtorrent/session.hpp b/include/libtorrent/session.hpp index afb15312e..e7feb7b26 100755 --- a/include/libtorrent/session.hpp +++ b/include/libtorrent/session.hpp @@ -219,6 +219,19 @@ namespace libtorrent void set_settings(session_settings const& s); session_settings const& settings(); + void set_peer_proxy(proxy_settings const& s); + void set_web_seed_proxy(proxy_settings const& s); + void set_tracker_proxy(proxy_settings const& s); + + proxy_settings const& peer_proxy() const; + proxy_settings const& web_seed_proxy() const; + proxy_settings const& tracker_proxy() const; + +#ifndef TORRENT_DISABLE_DHT + void set_dht_proxy(proxy_settings const& s); + proxy_settings const& dht_proxy() const; +#endif + int upload_rate_limit() const; int download_rate_limit() const; diff --git a/include/libtorrent/session_settings.hpp b/include/libtorrent/session_settings.hpp index 958434c6b..a933ff5f3 100644 --- a/include/libtorrent/session_settings.hpp +++ b/include/libtorrent/session_settings.hpp @@ -34,16 +34,53 @@ POSSIBILITY OF SUCH DAMAGE. #define TORRENT_SESSION_SETTINGS_HPP_INCLUDED #include "libtorrent/version.hpp" +#include "libtorrent/config.hpp" namespace libtorrent { + struct TORRENT_EXPORT proxy_settings + { + proxy_settings() : port(0), type(none) {} + + std::string hostname; + int port; + + std::string username; + std::string password; + + enum proxy_type + { + // a plain tcp socket is used, and + // the other settings are ignored. + none, + // the hostname and port settings are + // used to connect to the proxy. No + // username or password is sent. + socks5, + // the hostname and port are used to + // connect to the proxy. the username + // and password are used to authenticate + // with the proxy server. + socks5_pw, + // the http proxy is only available for + // tracker and web seed traffic + // assumes anonymous access to proxy + http, + // http proxy with basic authentication + // uses username and password + http_pw + }; + + proxy_type type; + + }; + struct TORRENT_EXPORT session_settings { session_settings(std::string const& user_agent_ = "libtorrent/" LIBTORRENT_VERSION) - : proxy_port(0) - , user_agent(user_agent_) + : user_agent(user_agent_) , tracker_completion_timeout(60) , tracker_receive_timeout(20) , stop_tracker_timeout(10) @@ -65,11 +102,6 @@ namespace libtorrent #endif {} - std::string proxy_ip; - int proxy_port; - std::string proxy_login; - std::string proxy_password; - // this is the user agent that will be sent to the tracker // when doing requests. It is used to identify the client. // It cannot contain \r or \n diff --git a/include/libtorrent/tracker_manager.hpp b/include/libtorrent/tracker_manager.hpp index 3c8514179..b51e07c49 100755 --- a/include/libtorrent/tracker_manager.hpp +++ b/include/libtorrent/tracker_manager.hpp @@ -221,8 +221,9 @@ namespace libtorrent { public: - tracker_manager(const session_settings& s) - : m_settings(s) {} + tracker_manager(session_settings const& s, proxy_settings const& ps) + : m_settings(s) + , m_proxy(ps) {} void queue_request( asio::strand& str @@ -245,6 +246,7 @@ namespace libtorrent tracker_connections_t; tracker_connections_t m_connections; session_settings const& m_settings; + proxy_settings const& m_proxy; }; } diff --git a/include/libtorrent/variant_stream.hpp b/include/libtorrent/variant_stream.hpp index 1049c5749..784eefbb0 100644 --- a/include/libtorrent/variant_stream.hpp +++ b/include/libtorrent/variant_stream.hpp @@ -277,7 +277,7 @@ namespace aux struct async_read_some_visitor : boost::static_visitor<> { - async_read_some_visitor(Mutable_Buffers const& buffers, Handler& handler) + async_read_some_visitor(Mutable_Buffers const& buffers, Handler const& handler) : buffers(buffers) , handler(handler) {} @@ -291,7 +291,7 @@ namespace aux {} Mutable_Buffers const& buffers; - Handler& handler; + Handler const& handler; }; // -------------- async_write_some ----------- @@ -300,7 +300,7 @@ namespace aux struct async_write_some_visitor : boost::static_visitor<> { - async_write_some_visitor(Const_Buffers const& buffers, Handler& handler) + async_write_some_visitor(Const_Buffers const& buffers, Handler const& handler) : buffers(buffers) , handler(handler) {} @@ -315,7 +315,7 @@ namespace aux {} Const_Buffers const& buffers; - Handler& handler; + Handler const& handler; }; // -------------- in_avail ----------- @@ -419,7 +419,7 @@ public: >::type variant_type; typedef typename S0::lowest_layer_type lowest_layer_type; - typedef typename S0::endpoint_type endpoint_type; + typedef typename S0::endpoint_type endpoint_type; typedef typename S0::protocol_type protocol_type; explicit variant_stream(asio::io_service& io_service) @@ -436,7 +436,7 @@ public: owned.release(); } - template + template S& get() { return *boost::get(m_variant); @@ -453,7 +453,7 @@ public: } template - void async_read_some(Mutable_Buffers const& buffers, Handler handler) + void async_read_some(Mutable_Buffers const& buffers, Handler const& handler) { assert(instantiated()); boost::apply_visitor( @@ -463,7 +463,7 @@ public: } template - void async_write_some(Const_Buffers const& buffers, Handler handler) + void async_write_some(Const_Buffers const& buffers, Handler const& handler) { assert(instantiated()); boost::apply_visitor( @@ -473,7 +473,7 @@ public: } template - void async_connect(endpoint_type const& endpoint, Handler handler) + void async_connect(endpoint_type const& endpoint, Handler const& handler) { assert(instantiated()); boost::apply_visitor( @@ -488,7 +488,7 @@ public: } template - void bind(endpoint_type const& endpoint, Error_Handler error_handler) + void bind(endpoint_type const& endpoint, Error_Handler const& error_handler) { assert(instantiated()); boost::apply_visitor( @@ -503,7 +503,7 @@ public: } template - void open(protocol_type const& p, Error_Handler error_handler) + void open(protocol_type const& p, Error_Handler const& error_handler) { assert(instantiated()); boost::apply_visitor( @@ -518,7 +518,7 @@ public: } template - void close(Error_Handler error_handler) + void close(Error_Handler const& error_handler) { assert(instantiated()); boost::apply_visitor( @@ -533,7 +533,7 @@ public: } template - std::size_t in_avail(Error_Handler error_handler) + std::size_t in_avail(Error_Handler const& error_handler) { assert(instantiated()); return boost::apply_visitor( @@ -548,7 +548,7 @@ public: } template - endpoint_type remote_endpoint(Error_Handler error_handler) + endpoint_type remote_endpoint(Error_Handler const& error_handler) { assert(instantiated()); return boost::apply_visitor( @@ -563,7 +563,7 @@ public: } template - endpoint_type local_endpoint(Error_Handler error_handler) + endpoint_type local_endpoint(Error_Handler const& error_handler) { assert(instantiated()); return boost::apply_visitor( @@ -592,7 +592,7 @@ private: variant_type m_variant; }; -} // namespace network +} // namespace libtorrent #endif // VARIANT_STREAM_070211_HPP diff --git a/include/libtorrent/web_peer_connection.hpp b/include/libtorrent/web_peer_connection.hpp index bd1e85079..db87d7459 100755 --- a/include/libtorrent/web_peer_connection.hpp +++ b/include/libtorrent/web_peer_connection.hpp @@ -97,7 +97,6 @@ namespace libtorrent , boost::weak_ptr t , boost::shared_ptr s , tcp::endpoint const& remote - , tcp::endpoint const& proxy , std::string const& url , policy::peer* peerinfo); diff --git a/src/Makefile.am b/src/Makefile.am index a432feafc..2b0fedd2a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -20,7 +20,8 @@ stat.cpp storage.cpp torrent.cpp torrent_handle.cpp \ torrent_info.cpp tracker_manager.cpp http_connection.cpp \ http_tracker_connection.cpp udp_tracker_connection.cpp \ alert.cpp identify_client.cpp ip_filter.cpp file.cpp metadata_transfer.cpp \ -logger.cpp file_pool.cpp ut_pex.cpp lsd.cpp upnp.cpp $(kademlia_sources) +logger.cpp file_pool.cpp ut_pex.cpp lsd.cpp upnp.cpp instantiate_connection.cpp \ +socks5_stream.cpp http_stream.cpp $(kademlia_sources) noinst_HEADERS = \ $(top_srcdir)/include/libtorrent/alert.hpp \ @@ -43,9 +44,11 @@ $(top_srcdir)/include/libtorrent/file_pool.hpp \ $(top_srcdir)/include/libtorrent/fingerprint.hpp \ $(top_srcdir)/include/libtorrent/hasher.hpp \ $(top_srcdir)/include/libtorrent/http_connection.hpp \ +$(top_srcdir)/include/libtorrent/http_stream.hpp \ $(top_srcdir)/include/libtorrent/session_settings.hpp \ $(top_srcdir)/include/libtorrent/http_tracker_connection.hpp \ $(top_srcdir)/include/libtorrent/identify_client.hpp \ +$(top_srcdir)/include/libtorrent/instantiate_connection.hpp \ $(top_srcdir)/include/libtorrent/invariant_check.hpp \ $(top_srcdir)/include/libtorrent/io.hpp \ $(top_srcdir)/include/libtorrent/ip_filter.hpp \ @@ -66,6 +69,8 @@ $(top_srcdir)/include/libtorrent/resource_request.hpp \ $(top_srcdir)/include/libtorrent/session.hpp \ $(top_srcdir)/include/libtorrent/size_type.hpp \ $(top_srcdir)/include/libtorrent/socket.hpp \ +$(top_srcdir)/include/libtorrent/socket_type.hpp \ +$(top_srcdir)/include/libtorrent/socks5_stream.hpp \ $(top_srcdir)/include/libtorrent/stat.hpp \ $(top_srcdir)/include/libtorrent/storage.hpp \ $(top_srcdir)/include/libtorrent/time.hpp \ @@ -76,6 +81,7 @@ $(top_srcdir)/include/libtorrent/tracker_manager.hpp \ $(top_srcdir)/include/libtorrent/udp_tracker_connection.hpp \ $(top_srcdir)/include/libtorrent/utf8.hpp \ $(top_srcdir)/include/libtorrent/xml_parse.hpp \ +$(top_srcdir)/include/libtorrent/variant_stream.hpp \ $(top_srcdir)/include/libtorrent/version.hpp diff --git a/src/bt_peer_connection.cpp b/src/bt_peer_connection.cpp index b5deaad1f..f7f72c47a 100755 --- a/src/bt_peer_connection.cpp +++ b/src/bt_peer_connection.cpp @@ -82,7 +82,7 @@ namespace libtorrent , tcp::endpoint const& remote , policy::peer* peerinfo) : peer_connection(ses, tor, s, remote - , tcp::endpoint(), peerinfo) + , peerinfo) , m_state(read_protocol_length) #ifndef TORRENT_DISABLE_EXTENSIONS , m_supports_extensions(false) diff --git a/src/http_tracker_connection.cpp b/src/http_tracker_connection.cpp index 787a01562..c0ed90147 100755 --- a/src/http_tracker_connection.cpp +++ b/src/http_tracker_connection.cpp @@ -58,6 +58,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/bencode.hpp" #include "libtorrent/torrent.hpp" #include "libtorrent/io.hpp" +#include "libtorrent/instantiate_connection.hpp" using namespace libtorrent; using boost::bind; @@ -285,6 +286,7 @@ namespace libtorrent , address bind_infc , boost::weak_ptr c , session_settings const& stn + , proxy_settings const& ps , std::string const& auth) : tracker_connection(man, req, str, bind_infc, c) , m_man(man) @@ -294,19 +296,16 @@ namespace libtorrent , m_recv_pos(0) , m_buffer(http_buffer_size) , m_settings(stn) + , m_proxy(ps) , m_password(auth) , m_timed_out(false) { - const std::string* connect_to_host; - bool using_proxy = false; - m_send_buffer.assign("GET "); // should we use the proxy? - if (!m_settings.proxy_ip.empty()) + if (m_proxy.type == proxy_settings::http + || m_proxy.type == proxy_settings::http_pw) { - connect_to_host = &m_settings.proxy_ip; - using_proxy = true; m_send_buffer += "http://"; m_send_buffer += hostname; if (port != 80) @@ -314,12 +313,6 @@ namespace libtorrent m_send_buffer += ":"; m_send_buffer += boost::lexical_cast(port); } - m_port = m_settings.proxy_port != 0 - ? m_settings.proxy_port : 80 ; - } - else - { - connect_to_host = &hostname; } if (tracker_req().kind == tracker_request::scrape_request) @@ -446,12 +439,12 @@ namespace libtorrent m_send_buffer += ':'; m_send_buffer += boost::lexical_cast(port); } - if (using_proxy && !m_settings.proxy_login.empty()) + if (m_proxy.type == proxy_settings::http_pw) { m_send_buffer += "\r\nProxy-Authorization: Basic "; - m_send_buffer += base64encode(m_settings.proxy_login + ":" + m_settings.proxy_password); + m_send_buffer += base64encode(m_proxy.username + ":" + m_proxy.password); } - if (auth != "") + if (!auth.empty()) { m_send_buffer += "\r\nAuthorization: Basic "; m_send_buffer += base64encode(auth); @@ -466,11 +459,11 @@ namespace libtorrent info_hash_str << req.info_hash; requester().debug_log("info_hash: " + boost::lexical_cast(req.info_hash)); - requester().debug_log("name lookup: " + *connect_to_host); + requester().debug_log("name lookup: " + hostname); } #endif - tcp::resolver::query q(*connect_to_host + tcp::resolver::query q(hostname , boost::lexical_cast(m_port)); m_name_lookup.async_resolve(q, m_strand.wrap( boost::bind(&http_tracker_connection::name_lookup, self(), _1, _2))); @@ -532,7 +525,16 @@ namespace libtorrent } if (has_requester()) requester().m_tracker_address = target_address; - m_socket.reset(new stream_socket(m_name_lookup.io_service())); + m_socket = instantiate_connection(m_name_lookup.io_service(), m_proxy); + + if (m_proxy.type == proxy_settings::http + || m_proxy.type == proxy_settings::http_pw) + { + // the tracker connection will talk immediately to + // the proxy, without requiring CONNECT support + m_socket->get().set_no_connect(true); + } + m_socket->open(target_address.protocol()); m_socket->bind(tcp::endpoint(bind_interface(), 0)); m_socket->async_connect(target_address, bind(&http_tracker_connection::connected, self(), _1)); @@ -711,6 +713,13 @@ namespace libtorrent close(); return; } + + if (m_parser.status_code() != 200) + { + fail(m_parser.status_code(), m_parser.message().c_str()); + close(); + return; + } buffer::const_interval buf(&m_buffer[0] + m_parser.body_start(), &m_buffer[0] + m_recv_pos); diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp index 4f6f95183..2987fc5dc 100755 --- a/src/peer_connection.cpp +++ b/src/peer_connection.cpp @@ -50,6 +50,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/extensions.hpp" #include "libtorrent/aux_/session_impl.hpp" #include "libtorrent/policy.hpp" +#include "libtorrent/socket_type.hpp" using boost::bind; using boost::shared_ptr; @@ -78,7 +79,6 @@ namespace libtorrent , boost::weak_ptr tor , shared_ptr s , tcp::endpoint const& remote - , tcp::endpoint const& proxy , policy::peer* peerinfo) : #ifndef NDEBUG @@ -97,7 +97,6 @@ namespace libtorrent , m_last_sent(time_now()) , m_socket(s) , m_remote(remote) - , m_remote_proxy(proxy) , m_torrent(tor) , m_active(true) , m_peer_interested(false) @@ -1551,7 +1550,7 @@ namespace libtorrent } - void close_socket_ignore_error(boost::shared_ptr s) + void close_socket_ignore_error(boost::shared_ptr s) { try { s->close(); } catch (std::exception& e) {} } @@ -2169,16 +2168,8 @@ namespace libtorrent assert(m_connecting); m_socket->open(t->get_interface().protocol()); m_socket->bind(t->get_interface()); - if (m_remote_proxy != tcp::endpoint()) - { - m_socket->async_connect(m_remote_proxy - , bind(&peer_connection::on_connection_complete, self(), _1)); - } - else - { - m_socket->async_connect(m_remote - , bind(&peer_connection::on_connection_complete, self(), _1)); - } + m_socket->async_connect(m_remote + , bind(&peer_connection::on_connection_complete, self(), _1)); if (t->alerts().should_post(alert::debug)) { diff --git a/src/policy.cpp b/src/policy.cpp index a85e26582..fff6778ef 100755 --- a/src/policy.cpp +++ b/src/policy.cpp @@ -198,8 +198,7 @@ namespace libtorrent // the number of blocks we want, but it will try to make the picked // blocks be from whole pieces, possibly by returning more blocks // than we requested. - assert((c.proxy() == tcp::endpoint() && c.remote() == c.get_socket()->remote_endpoint()) - || c.proxy() == c.get_socket()->remote_endpoint()); + assert(c.remote() == c.get_socket()->remote_endpoint()); // picks the interesting pieces from this peer // the integer is the number of pieces that @@ -885,8 +884,7 @@ namespace libtorrent // TODO: only allow _one_ connection to use this // override at a time - assert((c.proxy() == tcp::endpoint() && c.remote() == c.get_socket()->remote_endpoint()) - || c.proxy() == c.get_socket()->remote_endpoint()); + assert(c.remote() == c.get_socket()->remote_endpoint()); if (m_torrent->num_peers() >= m_torrent->m_connections_quota.given && c.remote().address() != m_torrent->current_tracker().address()) @@ -944,8 +942,7 @@ namespace libtorrent { // we don't have ny info about this peer. // add a new entry - assert((c.proxy() == tcp::endpoint() && c.remote() == c.get_socket()->remote_endpoint()) - || c.proxy() == c.get_socket()->remote_endpoint()); + assert(c.remote() == c.get_socket()->remote_endpoint()); peer p(c.remote(), peer::not_connectable, 0); m_peers.push_back(p); @@ -1325,8 +1322,7 @@ namespace libtorrent INVARIANT_CHECK; assert(c); - assert((c->proxy() == tcp::endpoint() && c->remote() == c->get_socket()->remote_endpoint()) - || c->proxy() == c->get_socket()->remote_endpoint()); + assert(c->remote() == c->get_socket()->remote_endpoint()); return std::find_if( m_peers.begin() diff --git a/src/session.cpp b/src/session.cpp index 405eff859..f33e3b474 100755 --- a/src/session.cpp +++ b/src/session.cpp @@ -262,6 +262,49 @@ namespace libtorrent return m_impl->settings(); } + void session::set_peer_proxy(proxy_settings const& s) + { + m_impl->set_peer_proxy(s); + } + + void session::set_web_seed_proxy(proxy_settings const& s) + { + m_impl->set_web_seed_proxy(s); + } + + void session::set_tracker_proxy(proxy_settings const& s) + { + m_impl->set_tracker_proxy(s); + } + + proxy_settings const& session::peer_proxy() const + { + return m_impl->peer_proxy(); + } + + proxy_settings const& session::web_seed_proxy() const + { + return m_impl->web_seed_proxy(); + } + + proxy_settings const& session::tracker_proxy() const + { + return m_impl->tracker_proxy(); + } + + +#ifndef TORRENT_DISABLE_DHT + void session::set_dht_proxy(proxy_settings const& s) + { + m_impl->set_dht_proxy(s); + } + + proxy_settings const& session::dht_proxy() const + { + return m_impl->dht_proxy(); + } +#endif + void session::set_max_uploads(int limit) { m_impl->set_max_uploads(limit); diff --git a/src/session_impl.cpp b/src/session_impl.cpp index dcea29c6f..517559592 100755 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -479,7 +479,7 @@ namespace libtorrent { namespace detail : m_strand(m_io_service) , m_dl_bandwidth_manager(m_io_service, peer_connection::download_channel) , m_ul_bandwidth_manager(m_io_service, peer_connection::upload_channel) - , m_tracker_manager(m_settings) + , m_tracker_manager(m_settings, m_tracker_proxy) , m_listen_port_range(listen_port_range) , m_listen_interface(address::from_string(listen_interface), listen_port_range.first) , m_external_listen_port(0) @@ -729,14 +729,14 @@ namespace libtorrent { namespace detail void session_impl::async_accept() { - shared_ptr c(new peer_connection::socket_type(m_io_service)); + shared_ptr c(new socket_type(m_io_service)); c->instantiate(); m_listen_socket->async_accept(c->get() , bind(&session_impl::on_incoming_connection, this, c , weak_ptr(m_listen_socket), _1)); } - void session_impl::on_incoming_connection(shared_ptr const& s + void session_impl::on_incoming_connection(shared_ptr const& s , weak_ptr const& listen_socket, asio::error_code const& e) try { if (listen_socket.expired()) @@ -797,7 +797,7 @@ namespace libtorrent { namespace detail #endif } - void session_impl::connection_failed(boost::shared_ptr const& s + void session_impl::connection_failed(boost::shared_ptr const& s , tcp::endpoint const& a, char const* message) #ifndef NDEBUG try diff --git a/src/torrent.cpp b/src/torrent.cpp index ac840f3ef..1db508d22 100755 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -71,6 +71,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/alert_types.hpp" #include "libtorrent/extensions.hpp" #include "libtorrent/aux_/session_impl.hpp" +#include "libtorrent/instantiate_connection.hpp" using namespace libtorrent; using boost::tuples::tuple; @@ -1352,7 +1353,17 @@ namespace libtorrent #endif m_resolving_web_seeds.insert(url); - if (m_ses.settings().proxy_ip.empty()) + proxy_settings const& ps = m_ses.web_seed_proxy(); + if (ps.type == proxy_settings::http + || ps.type == proxy_settings::http_pw) + { + // use proxy + tcp::resolver::query q(ps.hostname + , boost::lexical_cast(ps.port)); + m_host_resolver.async_resolve(q, m_ses.m_strand.wrap( + bind(&torrent::on_proxy_name_lookup, shared_from_this(), _1, _2, url))); + } + else { std::string protocol; std::string hostname; @@ -1366,14 +1377,6 @@ namespace libtorrent bind(&torrent::on_name_lookup, shared_from_this(), _1, _2, url , tcp::endpoint()))); } - else - { - // use proxy - tcp::resolver::query q(m_ses.settings().proxy_ip - , boost::lexical_cast(m_ses.settings().proxy_port)); - m_host_resolver.async_resolve(q, m_ses.m_strand.wrap( - bind(&torrent::on_proxy_name_lookup, shared_from_this(), _1, _2, url))); - } } @@ -1488,11 +1491,17 @@ namespace libtorrent else return; } - boost::shared_ptr s( - new peer_connection::socket_type(m_ses.m_io_service)); - s->instantiate(); + boost::shared_ptr s + = instantiate_connection(m_ses.m_io_service, m_ses.web_seed_proxy()); + if (m_ses.web_seed_proxy().type == proxy_settings::http + || m_ses.web_seed_proxy().type == proxy_settings::http_pw) + { + // the web seed connection will talk immediately to + // the proxy, without requiring CONNECT support + s->get().set_no_connect(true); + } boost::intrusive_ptr c(new web_peer_connection( - m_ses, shared_from_this(), s, a, proxy, url, 0)); + m_ses, shared_from_this(), s, a, url, 0)); #ifndef NDEBUG c->m_in_constructor = false; @@ -1875,9 +1884,8 @@ namespace libtorrent if (m_connections.find(a) != m_connections.end()) throw protocol_error("already connected to peer"); - boost::shared_ptr s( - new peer_connection::socket_type(m_ses.m_io_service)); - s->instantiate(); + boost::shared_ptr s + = instantiate_connection(m_ses.m_io_service, m_ses.peer_proxy()); boost::intrusive_ptr c(new bt_peer_connection( m_ses, shared_from_this(), s, a, peerinfo)); @@ -2011,8 +2019,7 @@ namespace libtorrent m_connections.erase(ci); throw; } - assert((p->proxy() == tcp::endpoint() && p->remote() == p->get_socket()->remote_endpoint()) - || p->proxy() == p->get_socket()->remote_endpoint()); + assert(p->remote() == p->get_socket()->remote_endpoint()); #ifndef NDEBUG m_policy->check_invariant(); diff --git a/src/tracker_manager.cpp b/src/tracker_manager.cpp index aaabf99ca..da5333b89 100755 --- a/src/tracker_manager.cpp +++ b/src/tracker_manager.cpp @@ -515,6 +515,7 @@ namespace libtorrent , bind_infc , c , m_settings + , m_proxy , auth); } else if (protocol == "udp") diff --git a/src/web_peer_connection.cpp b/src/web_peer_connection.cpp index b90c4e37c..5d8dd99ef 100755 --- a/src/web_peer_connection.cpp +++ b/src/web_peer_connection.cpp @@ -61,10 +61,9 @@ namespace libtorrent , boost::weak_ptr t , boost::shared_ptr s , tcp::endpoint const& remote - , tcp::endpoint const& proxy , std::string const& url , policy::peer* peerinfo) - : peer_connection(ses, t, s, remote, proxy, peerinfo) + : peer_connection(ses, t, s, remote, peerinfo) , m_url(url) , m_first_request(true) { @@ -170,9 +169,9 @@ namespace libtorrent size -= request_size; } - bool using_proxy = false; - if (!m_ses.settings().proxy_ip.empty()) - using_proxy = true; + proxy_settings const& ps = m_ses.web_seed_proxy(); + bool using_proxy = ps.type == proxy_settings::http + || ps.type == proxy_settings::http_pw; if (single_file_request) { @@ -188,11 +187,10 @@ namespace libtorrent request += "\r\nUser-Agent: "; request += m_ses.settings().user_agent; } - if (using_proxy && !m_ses.settings().proxy_login.empty()) + if (ps.type == proxy_settings::http_pw) { request += "\r\nProxy-Authorization: Basic "; - request += base64encode(m_ses.settings().proxy_login + ":" - + m_ses.settings().proxy_password); + request += base64encode(ps.username + ":" + ps.password); } if (using_proxy) { @@ -241,11 +239,10 @@ namespace libtorrent request += "\r\nUser-Agent: "; request += m_ses.settings().user_agent; } - if (using_proxy && !m_ses.settings().proxy_login.empty()) + if (ps.type == proxy_settings::http_pw) { request += "\r\nProxy-Authorization: Basic "; - request += base64encode(m_ses.settings().proxy_login + ":" - + m_ses.settings().proxy_password); + request += base64encode(ps.username + ":" + ps.password); } if (using_proxy) {