first attempt to implement SOCKS5 and proper HTTP proxy support. fixes #22

This commit is contained in:
Arvid Norberg 2007-04-25 18:26:35 +00:00
parent d9902d178f
commit 00948e9fc4
23 changed files with 278 additions and 118 deletions

View File

@ -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. * optimized the piece picker in the case where a peer is a seed.
* added support for local peer discovery * added support for local peer discovery
* removed the dependency on the compiled boost.date_time library * removed the dependency on the compiled boost.date_time library

View File

@ -41,16 +41,19 @@ SOURCES =
entry entry
escape_string escape_string
http_connection http_connection
http_stream
identify_client identify_client
ip_filter ip_filter
peer_connection peer_connection
bt_peer_connection bt_peer_connection
web_peer_connection web_peer_connection
instantiate_connection
natpmp natpmp
piece_picker piece_picker
policy policy
session session
session_impl session_impl
socks5_stream
stat stat
storage storage
torrent torrent

View File

@ -461,6 +461,7 @@ int main(int ac, char* av[])
std::string bind_to_interface; std::string bind_to_interface;
std::string proxy; std::string proxy;
std::string proxy_login; std::string proxy_login;
std::string proxy_type;
int poll_interval; int poll_interval;
namespace po = boost::program_options; namespace po = boost::program_options;
@ -514,6 +515,8 @@ int main(int ac, char* av[])
("proxy-login,n", po::value<std::string>(&proxy_login)->default_value("") ("proxy-login,n", po::value<std::string>(&proxy_login)->default_value("")
, "Sets the username and password used to authenticate with the http " , "Sets the username and password used to authenticate with the http "
"proxy. The string should be given in the form: <username>:<password>") "proxy. The string should be given in the form: <username>:<password>")
("proxy-type", po::value<std::string>(&proxy_type)->default_value("socks5")
, "Sets the type of proxy to use [socks5 | http] ")
; ;
po::positional_options_description p; po::positional_options_description p;
@ -557,16 +560,21 @@ int main(int ac, char* av[])
input = vm["input-file"].as< std::vector<std::string> >(); input = vm["input-file"].as< std::vector<std::string> >();
session_settings settings; session_settings settings;
proxy_settings ps;
if (!proxy.empty()) if (!proxy.empty())
{ {
try try
{ {
std::size_t i = proxy.find(':'); std::size_t i = proxy.find(':');
settings.proxy_ip = proxy.substr(0, i); ps.hostname = proxy.substr(0, i);
if (i == std::string::npos) settings.proxy_port = 8080; if (i == std::string::npos) ps.port = 8080;
else settings.proxy_port = boost::lexical_cast<int>( else ps.port = boost::lexical_cast<int>(
proxy.substr(i + 1)); proxy.substr(i + 1));
if (proxy_type == "socks5")
ps.type = proxy_settings::socks5;
else
ps.type = proxy_settings::http;
} }
catch (std::exception&) catch (std::exception&)
{ {
@ -584,8 +592,12 @@ int main(int ac, char* av[])
<< proxy_login << std::endl; << proxy_login << std::endl;
return 1; return 1;
} }
settings.proxy_login = proxy_login.substr(0, i); ps.username = proxy_login.substr(0, i);
settings.proxy_password = proxy_login.substr(i + 1); 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) ses.listen_on(std::make_pair(listen_port, listen_port + 10)
, bind_to_interface.c_str()); , bind_to_interface.c_str());
ses.set_settings(settings); ses.set_settings(settings);
ses.set_tracker_proxy(ps);
ses.set_peer_proxy(ps);
ses.set_web_seed_proxy(ps);
if (log_level == "debug") if (log_level == "debug")
ses.set_severity_level(alert::debug); ses.set_severity_level(alert::debug);
else if (log_level == "warning") else if (log_level == "warning")

View File

@ -14,8 +14,10 @@ libtorrent/file_pool.hpp \
libtorrent/fingerprint.hpp \ libtorrent/fingerprint.hpp \
libtorrent/hasher.hpp \ libtorrent/hasher.hpp \
libtorrent/http_connection.hpp \ libtorrent/http_connection.hpp \
libtorrent/http_stream.hpp \
libtorrent/http_tracker_connection.hpp \ libtorrent/http_tracker_connection.hpp \
libtorrent/identify_client.hpp \ libtorrent/identify_client.hpp \
libtorrent/instantiate_connection.hpp \
libtorrent/invariant_check.hpp \ libtorrent/invariant_check.hpp \
libtorrent/io.hpp \ libtorrent/io.hpp \
libtorrent/ip_filter.hpp \ libtorrent/ip_filter.hpp \
@ -39,6 +41,8 @@ libtorrent/session_settings.hpp \
libtorrent/session_status.hpp \ libtorrent/session_status.hpp \
libtorrent/size_type.hpp \ libtorrent/size_type.hpp \
libtorrent/socket.hpp \ libtorrent/socket.hpp \
libtorrent/socket_type.hpp \
libtorrent/socks5_stream.hpp \
libtorrent/stat.hpp \ libtorrent/stat.hpp \
libtorrent/storage.hpp \ libtorrent/storage.hpp \
libtorrent/torrent.hpp \ libtorrent/torrent.hpp \
@ -48,6 +52,7 @@ libtorrent/tracker_manager.hpp \
libtorrent/udp_tracker_connection.hpp \ libtorrent/udp_tracker_connection.hpp \
libtorrent/utf8.hpp \ libtorrent/utf8.hpp \
libtorrent/xml_parse.hpp \ libtorrent/xml_parse.hpp \
libtorrent/variant_stream.hpp \
libtorrent/version.hpp \ libtorrent/version.hpp \
libtorrent/aux_/allocate_resources_impl.hpp \ libtorrent/aux_/allocate_resources_impl.hpp \
libtorrent/aux_/session_impl.hpp \ libtorrent/aux_/session_impl.hpp \

View File

@ -80,6 +80,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/natpmp.hpp" #include "libtorrent/natpmp.hpp"
#include "libtorrent/upnp.hpp" #include "libtorrent/upnp.hpp"
#include "libtorrent/lsd.hpp" #include "libtorrent/lsd.hpp"
#include "libtorrent/socket_type.hpp"
namespace libtorrent namespace libtorrent
{ {
@ -166,7 +167,7 @@ namespace libtorrent
#endif #endif
friend struct checker_impl; friend struct checker_impl;
friend class invariant_access; friend class invariant_access;
typedef std::map<boost::shared_ptr<peer_connection::socket_type> typedef std::map<boost::shared_ptr<socket_type>
, boost::intrusive_ptr<peer_connection> > , boost::intrusive_ptr<peer_connection> >
connection_map; connection_map;
typedef std::map<sha1_hash, boost::shared_ptr<torrent> > torrent_map; typedef std::map<sha1_hash, boost::shared_ptr<torrent> > torrent_map;
@ -187,7 +188,7 @@ namespace libtorrent
void open_listen_port(); void open_listen_port();
void async_accept(); void async_accept();
void on_incoming_connection(boost::shared_ptr<peer_connection::socket_type> const& s void on_incoming_connection(boost::shared_ptr<socket_type> const& s
, boost::weak_ptr<socket_acceptor> const& as, asio::error_code const& e); , boost::weak_ptr<socket_acceptor> const& as, asio::error_code const& e);
// must be locked to access the data // must be locked to access the data
@ -205,7 +206,7 @@ namespace libtorrent
void close_connection(boost::intrusive_ptr<peer_connection> const& p); void close_connection(boost::intrusive_ptr<peer_connection> const& p);
void connection_completed(boost::intrusive_ptr<peer_connection> const& p); void connection_completed(boost::intrusive_ptr<peer_connection> const& p);
void connection_failed(boost::shared_ptr<peer_connection::socket_type> const& s void connection_failed(boost::shared_ptr<socket_type> const& s
, tcp::endpoint const& a, char const* message); , tcp::endpoint const& a, char const* message);
void set_settings(session_settings const& s); void set_settings(session_settings const& s);
@ -283,6 +284,27 @@ namespace libtorrent
void announce_lsd(sha1_hash const& ih); 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 // handles delayed alerts
alert_manager m_alerts; alert_manager m_alerts;
@ -355,6 +377,14 @@ namespace libtorrent
// the settings for the client // the settings for the client
session_settings m_settings; 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 // set to true when the session object
// is being destructed and the thread // is being destructed and the thread

View File

@ -59,6 +59,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/tracker_manager.hpp" #include "libtorrent/tracker_manager.hpp"
#include "libtorrent/config.hpp" #include "libtorrent/config.hpp"
#include "libtorrent/buffer.hpp" #include "libtorrent/buffer.hpp"
#include "libtorrent/socket_type.hpp"
namespace libtorrent namespace libtorrent
{ {
@ -122,6 +123,7 @@ namespace libtorrent
, address bind_infc , address bind_infc
, boost::weak_ptr<request_callback> c , boost::weak_ptr<request_callback> c
, session_settings const& stn , session_settings const& stn
, proxy_settings const& ps
, std::string const& password = ""); , std::string const& password = "");
private: private:
@ -152,12 +154,13 @@ namespace libtorrent
asio::strand& m_strand; asio::strand& m_strand;
tcp::resolver m_name_lookup; tcp::resolver m_name_lookup;
int m_port; int m_port;
boost::shared_ptr<stream_socket> m_socket; boost::shared_ptr<socket_type> m_socket;
int m_recv_pos; int m_recv_pos;
std::vector<char> m_buffer; std::vector<char> m_buffer;
std::string m_send_buffer; std::string m_send_buffer;
session_settings const& m_settings; session_settings const& m_settings;
proxy_settings const& m_proxy;
std::string m_password; std::string m_password;
bool m_timed_out; bool m_timed_out;

View File

@ -34,6 +34,7 @@ POSSIBILITY OF SUCH DAMAGE.
#define TORRENT_IO_HPP_INCLUDED #define TORRENT_IO_HPP_INCLUDED
#include <boost/cstdint.hpp> #include <boost/cstdint.hpp>
#include <string>
namespace libtorrent namespace libtorrent
{ {
@ -134,6 +135,18 @@ namespace libtorrent
void write_int8(boost::int8_t val, OutIt& start) void write_int8(boost::int8_t val, OutIt& start)
{ write_impl(val, 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 <class OutIt>
void write_string(std::string const& str, OutIt& start)
{
std::copy(str.begin(), str.end(), start);
}
} }
} }

View File

@ -72,7 +72,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/session.hpp" #include "libtorrent/session.hpp"
#include "libtorrent/bandwidth_manager.hpp" #include "libtorrent/bandwidth_manager.hpp"
#include "libtorrent/policy.hpp" #include "libtorrent/policy.hpp"
#include "libtorrent/variant_stream.hpp" #include "libtorrent/socket_type.hpp"
// TODO: each time a block is 'taken over' // TODO: each time a block is 'taken over'
// from another peer. That peer must be given // from another peer. That peer must be given
@ -104,8 +104,6 @@ namespace libtorrent
friend void intrusive_ptr_release(peer_connection const*); friend void intrusive_ptr_release(peer_connection const*);
public: public:
typedef variant_stream<stream_socket> socket_type;
enum channels enum channels
{ {
upload_channel, upload_channel,
@ -121,7 +119,6 @@ namespace libtorrent
, boost::weak_ptr<torrent> t , boost::weak_ptr<torrent> t
, boost::shared_ptr<socket_type> s , boost::shared_ptr<socket_type> s
, tcp::endpoint const& remote , tcp::endpoint const& remote
, tcp::endpoint const& proxy
, policy::peer* peerinfo); , policy::peer* peerinfo);
// with this constructor we have been contacted and we still don't // with this constructor we have been contacted and we still don't
@ -221,7 +218,6 @@ namespace libtorrent
boost::shared_ptr<socket_type> get_socket() const { return m_socket; } boost::shared_ptr<socket_type> get_socket() const { return m_socket; }
tcp::endpoint const& remote() const { return m_remote; } tcp::endpoint const& remote() const { return m_remote; }
tcp::endpoint const& proxy() const { return m_remote_proxy; }
std::vector<bool> const& get_bitfield() const; std::vector<bool> const& get_bitfield() const;
@ -499,9 +495,6 @@ namespace libtorrent
// connected to, in case we use a proxy // connected to, in case we use a proxy
tcp::endpoint m_remote; 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 // this is the torrent this connection is
// associated with. If the connection is an // associated with. If the connection is an
// incoming conncetion, this is set to zero // incoming conncetion, this is set to zero

View File

@ -219,6 +219,19 @@ namespace libtorrent
void set_settings(session_settings const& s); void set_settings(session_settings const& s);
session_settings const& settings(); 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 upload_rate_limit() const;
int download_rate_limit() const; int download_rate_limit() const;

View File

@ -34,16 +34,53 @@ POSSIBILITY OF SUCH DAMAGE.
#define TORRENT_SESSION_SETTINGS_HPP_INCLUDED #define TORRENT_SESSION_SETTINGS_HPP_INCLUDED
#include "libtorrent/version.hpp" #include "libtorrent/version.hpp"
#include "libtorrent/config.hpp"
namespace libtorrent 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 struct TORRENT_EXPORT session_settings
{ {
session_settings(std::string const& user_agent_ = "libtorrent/" session_settings(std::string const& user_agent_ = "libtorrent/"
LIBTORRENT_VERSION) LIBTORRENT_VERSION)
: proxy_port(0) : user_agent(user_agent_)
, user_agent(user_agent_)
, tracker_completion_timeout(60) , tracker_completion_timeout(60)
, tracker_receive_timeout(20) , tracker_receive_timeout(20)
, stop_tracker_timeout(10) , stop_tracker_timeout(10)
@ -65,11 +102,6 @@ namespace libtorrent
#endif #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 // this is the user agent that will be sent to the tracker
// when doing requests. It is used to identify the client. // when doing requests. It is used to identify the client.
// It cannot contain \r or \n // It cannot contain \r or \n

View File

@ -221,8 +221,9 @@ namespace libtorrent
{ {
public: public:
tracker_manager(const session_settings& s) tracker_manager(session_settings const& s, proxy_settings const& ps)
: m_settings(s) {} : m_settings(s)
, m_proxy(ps) {}
void queue_request( void queue_request(
asio::strand& str asio::strand& str
@ -245,6 +246,7 @@ namespace libtorrent
tracker_connections_t; tracker_connections_t;
tracker_connections_t m_connections; tracker_connections_t m_connections;
session_settings const& m_settings; session_settings const& m_settings;
proxy_settings const& m_proxy;
}; };
} }

View File

@ -277,7 +277,7 @@ namespace aux
struct async_read_some_visitor struct async_read_some_visitor
: boost::static_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) : buffers(buffers)
, handler(handler) , handler(handler)
{} {}
@ -291,7 +291,7 @@ namespace aux
{} {}
Mutable_Buffers const& buffers; Mutable_Buffers const& buffers;
Handler& handler; Handler const& handler;
}; };
// -------------- async_write_some ----------- // -------------- async_write_some -----------
@ -300,7 +300,7 @@ namespace aux
struct async_write_some_visitor struct async_write_some_visitor
: boost::static_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) : buffers(buffers)
, handler(handler) , handler(handler)
{} {}
@ -315,7 +315,7 @@ namespace aux
{} {}
Const_Buffers const& buffers; Const_Buffers const& buffers;
Handler& handler; Handler const& handler;
}; };
// -------------- in_avail ----------- // -------------- in_avail -----------
@ -453,7 +453,7 @@ public:
} }
template <class Mutable_Buffers, class Handler> template <class Mutable_Buffers, class Handler>
void async_read_some(Mutable_Buffers const& buffers, Handler handler) void async_read_some(Mutable_Buffers const& buffers, Handler const& handler)
{ {
assert(instantiated()); assert(instantiated());
boost::apply_visitor( boost::apply_visitor(
@ -463,7 +463,7 @@ public:
} }
template <class Const_Buffers, class Handler> template <class Const_Buffers, class Handler>
void async_write_some(Const_Buffers const& buffers, Handler handler) void async_write_some(Const_Buffers const& buffers, Handler const& handler)
{ {
assert(instantiated()); assert(instantiated());
boost::apply_visitor( boost::apply_visitor(
@ -473,7 +473,7 @@ public:
} }
template <class Handler> template <class Handler>
void async_connect(endpoint_type const& endpoint, Handler handler) void async_connect(endpoint_type const& endpoint, Handler const& handler)
{ {
assert(instantiated()); assert(instantiated());
boost::apply_visitor( boost::apply_visitor(
@ -488,7 +488,7 @@ public:
} }
template <class Error_Handler> template <class Error_Handler>
void bind(endpoint_type const& endpoint, Error_Handler error_handler) void bind(endpoint_type const& endpoint, Error_Handler const& error_handler)
{ {
assert(instantiated()); assert(instantiated());
boost::apply_visitor( boost::apply_visitor(
@ -503,7 +503,7 @@ public:
} }
template <class Error_Handler> template <class Error_Handler>
void open(protocol_type const& p, Error_Handler error_handler) void open(protocol_type const& p, Error_Handler const& error_handler)
{ {
assert(instantiated()); assert(instantiated());
boost::apply_visitor( boost::apply_visitor(
@ -518,7 +518,7 @@ public:
} }
template <class Error_Handler> template <class Error_Handler>
void close(Error_Handler error_handler) void close(Error_Handler const& error_handler)
{ {
assert(instantiated()); assert(instantiated());
boost::apply_visitor( boost::apply_visitor(
@ -533,7 +533,7 @@ public:
} }
template <class Error_Handler> template <class Error_Handler>
std::size_t in_avail(Error_Handler error_handler) std::size_t in_avail(Error_Handler const& error_handler)
{ {
assert(instantiated()); assert(instantiated());
return boost::apply_visitor( return boost::apply_visitor(
@ -548,7 +548,7 @@ public:
} }
template <class Error_Handler> template <class Error_Handler>
endpoint_type remote_endpoint(Error_Handler error_handler) endpoint_type remote_endpoint(Error_Handler const& error_handler)
{ {
assert(instantiated()); assert(instantiated());
return boost::apply_visitor( return boost::apply_visitor(
@ -563,7 +563,7 @@ public:
} }
template <class Error_Handler> template <class Error_Handler>
endpoint_type local_endpoint(Error_Handler error_handler) endpoint_type local_endpoint(Error_Handler const& error_handler)
{ {
assert(instantiated()); assert(instantiated());
return boost::apply_visitor( return boost::apply_visitor(
@ -592,7 +592,7 @@ private:
variant_type m_variant; variant_type m_variant;
}; };
} // namespace network } // namespace libtorrent
#endif // VARIANT_STREAM_070211_HPP #endif // VARIANT_STREAM_070211_HPP

View File

@ -97,7 +97,6 @@ namespace libtorrent
, boost::weak_ptr<torrent> t , boost::weak_ptr<torrent> t
, boost::shared_ptr<socket_type> s , boost::shared_ptr<socket_type> s
, tcp::endpoint const& remote , tcp::endpoint const& remote
, tcp::endpoint const& proxy
, std::string const& url , std::string const& url
, policy::peer* peerinfo); , policy::peer* peerinfo);

View File

@ -20,7 +20,8 @@ stat.cpp storage.cpp torrent.cpp torrent_handle.cpp \
torrent_info.cpp tracker_manager.cpp http_connection.cpp \ torrent_info.cpp tracker_manager.cpp http_connection.cpp \
http_tracker_connection.cpp udp_tracker_connection.cpp \ http_tracker_connection.cpp udp_tracker_connection.cpp \
alert.cpp identify_client.cpp ip_filter.cpp file.cpp metadata_transfer.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 = \ noinst_HEADERS = \
$(top_srcdir)/include/libtorrent/alert.hpp \ $(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/fingerprint.hpp \
$(top_srcdir)/include/libtorrent/hasher.hpp \ $(top_srcdir)/include/libtorrent/hasher.hpp \
$(top_srcdir)/include/libtorrent/http_connection.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/session_settings.hpp \
$(top_srcdir)/include/libtorrent/http_tracker_connection.hpp \ $(top_srcdir)/include/libtorrent/http_tracker_connection.hpp \
$(top_srcdir)/include/libtorrent/identify_client.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/invariant_check.hpp \
$(top_srcdir)/include/libtorrent/io.hpp \ $(top_srcdir)/include/libtorrent/io.hpp \
$(top_srcdir)/include/libtorrent/ip_filter.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/session.hpp \
$(top_srcdir)/include/libtorrent/size_type.hpp \ $(top_srcdir)/include/libtorrent/size_type.hpp \
$(top_srcdir)/include/libtorrent/socket.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/stat.hpp \
$(top_srcdir)/include/libtorrent/storage.hpp \ $(top_srcdir)/include/libtorrent/storage.hpp \
$(top_srcdir)/include/libtorrent/time.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/udp_tracker_connection.hpp \
$(top_srcdir)/include/libtorrent/utf8.hpp \ $(top_srcdir)/include/libtorrent/utf8.hpp \
$(top_srcdir)/include/libtorrent/xml_parse.hpp \ $(top_srcdir)/include/libtorrent/xml_parse.hpp \
$(top_srcdir)/include/libtorrent/variant_stream.hpp \
$(top_srcdir)/include/libtorrent/version.hpp $(top_srcdir)/include/libtorrent/version.hpp

View File

@ -82,7 +82,7 @@ namespace libtorrent
, tcp::endpoint const& remote , tcp::endpoint const& remote
, policy::peer* peerinfo) , policy::peer* peerinfo)
: peer_connection(ses, tor, s, remote : peer_connection(ses, tor, s, remote
, tcp::endpoint(), peerinfo) , peerinfo)
, m_state(read_protocol_length) , m_state(read_protocol_length)
#ifndef TORRENT_DISABLE_EXTENSIONS #ifndef TORRENT_DISABLE_EXTENSIONS
, m_supports_extensions(false) , m_supports_extensions(false)

View File

@ -58,6 +58,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/bencode.hpp" #include "libtorrent/bencode.hpp"
#include "libtorrent/torrent.hpp" #include "libtorrent/torrent.hpp"
#include "libtorrent/io.hpp" #include "libtorrent/io.hpp"
#include "libtorrent/instantiate_connection.hpp"
using namespace libtorrent; using namespace libtorrent;
using boost::bind; using boost::bind;
@ -285,6 +286,7 @@ namespace libtorrent
, address bind_infc , address bind_infc
, boost::weak_ptr<request_callback> c , boost::weak_ptr<request_callback> c
, session_settings const& stn , session_settings const& stn
, proxy_settings const& ps
, std::string const& auth) , std::string const& auth)
: tracker_connection(man, req, str, bind_infc, c) : tracker_connection(man, req, str, bind_infc, c)
, m_man(man) , m_man(man)
@ -294,19 +296,16 @@ namespace libtorrent
, m_recv_pos(0) , m_recv_pos(0)
, m_buffer(http_buffer_size) , m_buffer(http_buffer_size)
, m_settings(stn) , m_settings(stn)
, m_proxy(ps)
, m_password(auth) , m_password(auth)
, m_timed_out(false) , m_timed_out(false)
{ {
const std::string* connect_to_host;
bool using_proxy = false;
m_send_buffer.assign("GET "); m_send_buffer.assign("GET ");
// should we use the proxy? // 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 += "http://";
m_send_buffer += hostname; m_send_buffer += hostname;
if (port != 80) if (port != 80)
@ -314,12 +313,6 @@ namespace libtorrent
m_send_buffer += ":"; m_send_buffer += ":";
m_send_buffer += boost::lexical_cast<std::string>(port); m_send_buffer += boost::lexical_cast<std::string>(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) if (tracker_req().kind == tracker_request::scrape_request)
@ -446,12 +439,12 @@ namespace libtorrent
m_send_buffer += ':'; m_send_buffer += ':';
m_send_buffer += boost::lexical_cast<std::string>(port); m_send_buffer += boost::lexical_cast<std::string>(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 += "\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 += "\r\nAuthorization: Basic ";
m_send_buffer += base64encode(auth); m_send_buffer += base64encode(auth);
@ -466,11 +459,11 @@ namespace libtorrent
info_hash_str << req.info_hash; info_hash_str << req.info_hash;
requester().debug_log("info_hash: " requester().debug_log("info_hash: "
+ boost::lexical_cast<std::string>(req.info_hash)); + boost::lexical_cast<std::string>(req.info_hash));
requester().debug_log("name lookup: " + *connect_to_host); requester().debug_log("name lookup: " + hostname);
} }
#endif #endif
tcp::resolver::query q(*connect_to_host tcp::resolver::query q(hostname
, boost::lexical_cast<std::string>(m_port)); , boost::lexical_cast<std::string>(m_port));
m_name_lookup.async_resolve(q, m_strand.wrap( m_name_lookup.async_resolve(q, m_strand.wrap(
boost::bind(&http_tracker_connection::name_lookup, self(), _1, _2))); 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; 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<http_stream>().set_no_connect(true);
}
m_socket->open(target_address.protocol()); m_socket->open(target_address.protocol());
m_socket->bind(tcp::endpoint(bind_interface(), 0)); m_socket->bind(tcp::endpoint(bind_interface(), 0));
m_socket->async_connect(target_address, bind(&http_tracker_connection::connected, self(), _1)); m_socket->async_connect(target_address, bind(&http_tracker_connection::connected, self(), _1));
@ -712,6 +714,13 @@ namespace libtorrent
return; 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); buffer::const_interval buf(&m_buffer[0] + m_parser.body_start(), &m_buffer[0] + m_recv_pos);
std::string content_encoding = m_parser.header<std::string>("content-encoding"); std::string content_encoding = m_parser.header<std::string>("content-encoding");

View File

@ -50,6 +50,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/extensions.hpp" #include "libtorrent/extensions.hpp"
#include "libtorrent/aux_/session_impl.hpp" #include "libtorrent/aux_/session_impl.hpp"
#include "libtorrent/policy.hpp" #include "libtorrent/policy.hpp"
#include "libtorrent/socket_type.hpp"
using boost::bind; using boost::bind;
using boost::shared_ptr; using boost::shared_ptr;
@ -78,7 +79,6 @@ namespace libtorrent
, boost::weak_ptr<torrent> tor , boost::weak_ptr<torrent> tor
, shared_ptr<socket_type> s , shared_ptr<socket_type> s
, tcp::endpoint const& remote , tcp::endpoint const& remote
, tcp::endpoint const& proxy
, policy::peer* peerinfo) , policy::peer* peerinfo)
: :
#ifndef NDEBUG #ifndef NDEBUG
@ -97,7 +97,6 @@ namespace libtorrent
, m_last_sent(time_now()) , m_last_sent(time_now())
, m_socket(s) , m_socket(s)
, m_remote(remote) , m_remote(remote)
, m_remote_proxy(proxy)
, m_torrent(tor) , m_torrent(tor)
, m_active(true) , m_active(true)
, m_peer_interested(false) , m_peer_interested(false)
@ -1551,7 +1550,7 @@ namespace libtorrent
} }
void close_socket_ignore_error(boost::shared_ptr<peer_connection::socket_type> s) void close_socket_ignore_error(boost::shared_ptr<socket_type> s)
{ {
try { s->close(); } catch (std::exception& e) {} try { s->close(); } catch (std::exception& e) {}
} }
@ -2169,16 +2168,8 @@ namespace libtorrent
assert(m_connecting); assert(m_connecting);
m_socket->open(t->get_interface().protocol()); m_socket->open(t->get_interface().protocol());
m_socket->bind(t->get_interface()); 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 m_socket->async_connect(m_remote
, bind(&peer_connection::on_connection_complete, self(), _1)); , bind(&peer_connection::on_connection_complete, self(), _1));
}
if (t->alerts().should_post(alert::debug)) if (t->alerts().should_post(alert::debug))
{ {

View File

@ -198,8 +198,7 @@ namespace libtorrent
// the number of blocks we want, but it will try to make the picked // the number of blocks we want, but it will try to make the picked
// blocks be from whole pieces, possibly by returning more blocks // blocks be from whole pieces, possibly by returning more blocks
// than we requested. // than we requested.
assert((c.proxy() == tcp::endpoint() && c.remote() == c.get_socket()->remote_endpoint()) assert(c.remote() == c.get_socket()->remote_endpoint());
|| c.proxy() == c.get_socket()->remote_endpoint());
// picks the interesting pieces from this peer // picks the interesting pieces from this peer
// the integer is the number of pieces that // the integer is the number of pieces that
@ -885,8 +884,7 @@ namespace libtorrent
// TODO: only allow _one_ connection to use this // TODO: only allow _one_ connection to use this
// override at a time // override at a time
assert((c.proxy() == tcp::endpoint() && c.remote() == c.get_socket()->remote_endpoint()) assert(c.remote() == c.get_socket()->remote_endpoint());
|| c.proxy() == c.get_socket()->remote_endpoint());
if (m_torrent->num_peers() >= m_torrent->m_connections_quota.given if (m_torrent->num_peers() >= m_torrent->m_connections_quota.given
&& c.remote().address() != m_torrent->current_tracker().address()) && c.remote().address() != m_torrent->current_tracker().address())
@ -944,8 +942,7 @@ namespace libtorrent
{ {
// we don't have ny info about this peer. // we don't have ny info about this peer.
// add a new entry // add a new entry
assert((c.proxy() == tcp::endpoint() && c.remote() == c.get_socket()->remote_endpoint()) assert(c.remote() == c.get_socket()->remote_endpoint());
|| c.proxy() == c.get_socket()->remote_endpoint());
peer p(c.remote(), peer::not_connectable, 0); peer p(c.remote(), peer::not_connectable, 0);
m_peers.push_back(p); m_peers.push_back(p);
@ -1325,8 +1322,7 @@ namespace libtorrent
INVARIANT_CHECK; INVARIANT_CHECK;
assert(c); assert(c);
assert((c->proxy() == tcp::endpoint() && c->remote() == c->get_socket()->remote_endpoint()) assert(c->remote() == c->get_socket()->remote_endpoint());
|| c->proxy() == c->get_socket()->remote_endpoint());
return std::find_if( return std::find_if(
m_peers.begin() m_peers.begin()

View File

@ -262,6 +262,49 @@ namespace libtorrent
return m_impl->settings(); 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) void session::set_max_uploads(int limit)
{ {
m_impl->set_max_uploads(limit); m_impl->set_max_uploads(limit);

View File

@ -479,7 +479,7 @@ namespace libtorrent { namespace detail
: m_strand(m_io_service) : m_strand(m_io_service)
, m_dl_bandwidth_manager(m_io_service, peer_connection::download_channel) , m_dl_bandwidth_manager(m_io_service, peer_connection::download_channel)
, m_ul_bandwidth_manager(m_io_service, peer_connection::upload_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_port_range(listen_port_range)
, m_listen_interface(address::from_string(listen_interface), listen_port_range.first) , m_listen_interface(address::from_string(listen_interface), listen_port_range.first)
, m_external_listen_port(0) , m_external_listen_port(0)
@ -729,14 +729,14 @@ namespace libtorrent { namespace detail
void session_impl::async_accept() void session_impl::async_accept()
{ {
shared_ptr<peer_connection::socket_type> c(new peer_connection::socket_type(m_io_service)); shared_ptr<socket_type> c(new socket_type(m_io_service));
c->instantiate<stream_socket>(); c->instantiate<stream_socket>();
m_listen_socket->async_accept(c->get<stream_socket>() m_listen_socket->async_accept(c->get<stream_socket>()
, bind(&session_impl::on_incoming_connection, this, c , bind(&session_impl::on_incoming_connection, this, c
, weak_ptr<socket_acceptor>(m_listen_socket), _1)); , weak_ptr<socket_acceptor>(m_listen_socket), _1));
} }
void session_impl::on_incoming_connection(shared_ptr<peer_connection::socket_type> const& s void session_impl::on_incoming_connection(shared_ptr<socket_type> const& s
, weak_ptr<socket_acceptor> const& listen_socket, asio::error_code const& e) try , weak_ptr<socket_acceptor> const& listen_socket, asio::error_code const& e) try
{ {
if (listen_socket.expired()) if (listen_socket.expired())
@ -797,7 +797,7 @@ namespace libtorrent { namespace detail
#endif #endif
} }
void session_impl::connection_failed(boost::shared_ptr<peer_connection::socket_type> const& s void session_impl::connection_failed(boost::shared_ptr<socket_type> const& s
, tcp::endpoint const& a, char const* message) , tcp::endpoint const& a, char const* message)
#ifndef NDEBUG #ifndef NDEBUG
try try

View File

@ -71,6 +71,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/alert_types.hpp" #include "libtorrent/alert_types.hpp"
#include "libtorrent/extensions.hpp" #include "libtorrent/extensions.hpp"
#include "libtorrent/aux_/session_impl.hpp" #include "libtorrent/aux_/session_impl.hpp"
#include "libtorrent/instantiate_connection.hpp"
using namespace libtorrent; using namespace libtorrent;
using boost::tuples::tuple; using boost::tuples::tuple;
@ -1352,7 +1353,17 @@ namespace libtorrent
#endif #endif
m_resolving_web_seeds.insert(url); 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<std::string>(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 protocol;
std::string hostname; std::string hostname;
@ -1366,14 +1377,6 @@ namespace libtorrent
bind(&torrent::on_name_lookup, shared_from_this(), _1, _2, url bind(&torrent::on_name_lookup, shared_from_this(), _1, _2, url
, tcp::endpoint()))); , tcp::endpoint())));
} }
else
{
// use proxy
tcp::resolver::query q(m_ses.settings().proxy_ip
, boost::lexical_cast<std::string>(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; else return;
} }
boost::shared_ptr<peer_connection::socket_type> s( boost::shared_ptr<socket_type> s
new peer_connection::socket_type(m_ses.m_io_service)); = instantiate_connection(m_ses.m_io_service, m_ses.web_seed_proxy());
s->instantiate<stream_socket>(); 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<http_stream>().set_no_connect(true);
}
boost::intrusive_ptr<peer_connection> c(new web_peer_connection( boost::intrusive_ptr<peer_connection> 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 #ifndef NDEBUG
c->m_in_constructor = false; c->m_in_constructor = false;
@ -1875,9 +1884,8 @@ namespace libtorrent
if (m_connections.find(a) != m_connections.end()) if (m_connections.find(a) != m_connections.end())
throw protocol_error("already connected to peer"); throw protocol_error("already connected to peer");
boost::shared_ptr<peer_connection::socket_type> s( boost::shared_ptr<socket_type> s
new peer_connection::socket_type(m_ses.m_io_service)); = instantiate_connection(m_ses.m_io_service, m_ses.peer_proxy());
s->instantiate<stream_socket>();
boost::intrusive_ptr<peer_connection> c(new bt_peer_connection( boost::intrusive_ptr<peer_connection> c(new bt_peer_connection(
m_ses, shared_from_this(), s, a, peerinfo)); m_ses, shared_from_this(), s, a, peerinfo));
@ -2011,8 +2019,7 @@ namespace libtorrent
m_connections.erase(ci); m_connections.erase(ci);
throw; throw;
} }
assert((p->proxy() == tcp::endpoint() && p->remote() == p->get_socket()->remote_endpoint()) assert(p->remote() == p->get_socket()->remote_endpoint());
|| p->proxy() == p->get_socket()->remote_endpoint());
#ifndef NDEBUG #ifndef NDEBUG
m_policy->check_invariant(); m_policy->check_invariant();

View File

@ -515,6 +515,7 @@ namespace libtorrent
, bind_infc , bind_infc
, c , c
, m_settings , m_settings
, m_proxy
, auth); , auth);
} }
else if (protocol == "udp") else if (protocol == "udp")

View File

@ -61,10 +61,9 @@ namespace libtorrent
, boost::weak_ptr<torrent> t , boost::weak_ptr<torrent> t
, boost::shared_ptr<socket_type> s , boost::shared_ptr<socket_type> s
, tcp::endpoint const& remote , tcp::endpoint const& remote
, tcp::endpoint const& proxy
, std::string const& url , std::string const& url
, policy::peer* peerinfo) , policy::peer* peerinfo)
: peer_connection(ses, t, s, remote, proxy, peerinfo) : peer_connection(ses, t, s, remote, peerinfo)
, m_url(url) , m_url(url)
, m_first_request(true) , m_first_request(true)
{ {
@ -170,9 +169,9 @@ namespace libtorrent
size -= request_size; size -= request_size;
} }
bool using_proxy = false; proxy_settings const& ps = m_ses.web_seed_proxy();
if (!m_ses.settings().proxy_ip.empty()) bool using_proxy = ps.type == proxy_settings::http
using_proxy = true; || ps.type == proxy_settings::http_pw;
if (single_file_request) if (single_file_request)
{ {
@ -188,11 +187,10 @@ namespace libtorrent
request += "\r\nUser-Agent: "; request += "\r\nUser-Agent: ";
request += m_ses.settings().user_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 += "\r\nProxy-Authorization: Basic ";
request += base64encode(m_ses.settings().proxy_login + ":" request += base64encode(ps.username + ":" + ps.password);
+ m_ses.settings().proxy_password);
} }
if (using_proxy) if (using_proxy)
{ {
@ -241,11 +239,10 @@ namespace libtorrent
request += "\r\nUser-Agent: "; request += "\r\nUser-Agent: ";
request += m_ses.settings().user_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 += "\r\nProxy-Authorization: Basic ";
request += base64encode(m_ses.settings().proxy_login + ":" request += base64encode(ps.username + ":" + ps.password);
+ m_ses.settings().proxy_password);
} }
if (using_proxy) if (using_proxy)
{ {