improved support for multi-homed clients

This commit is contained in:
Arvid Norberg 2010-07-17 07:13:14 +00:00
parent 9a9c121ec0
commit 1e70456f58
7 changed files with 61 additions and 15 deletions

View File

@ -1,3 +1,4 @@
* improved support for multi-homed clients
* added feature to not count downloaded bytes from web seeds in stats
* added alert for incoming local service discovery messages
* added option to set file priorities when adding torrents

View File

@ -2744,8 +2744,10 @@ use_interface()
``use_interface()`` sets the network interface this torrent will use when it opens outgoing
connections. By default, it uses the same interface as the session_ uses to listen on. The
parameter must be a string containing an ip-address (either an IPv4 or IPv6 address). If
the string does not conform to this format and exception is thrown.
parameter must be a string containing one or more, comma separated, ip-address (either an
IPv4 or IPv6 address). When specifying multiple interfaces, the torrent will round-robin
which interface to use for each outgoing conneciton. This is useful for clients that are
multi-homed.
info_hash()
@ -3485,6 +3487,8 @@ It contains the following fields::
float progress;
int progress_ppm;
tcp::endpoint local_endpoint;
};
The ``flags`` attribute tells you in which state the peer is. It is set to
@ -3710,6 +3714,11 @@ floating point operations are diabled, instead use ``progress_ppm``.
``progress_ppm`` indicates the download progress of the peer in the range [0, 1000000]
(parts per million).
``local_endpoint`` is the IP and port pair the socket is bound to locally. i.e. the IP
address of the interface it's going out over. This may be useful for multi-homed
clients with multiple interfaces to the internet.
session customization
=====================

View File

@ -329,7 +329,7 @@ int peer_index(libtorrent::tcp::endpoint addr, std::vector<libtorrent::peer_info
void print_peer_info(std::string& out, std::vector<libtorrent::peer_info> const& peers)
{
using namespace libtorrent;
if (print_ip) out += "IP ";
if (print_ip) out += "IP ";
#ifndef TORRENT_DISABLE_GEO_IP
if (print_as) out += "AS ";
#endif
@ -355,7 +355,8 @@ void print_peer_info(std::string& out, std::vector<libtorrent::peer_info> const&
if (print_ip)
{
error_code ec;
snprintf(str, sizeof(str), "%-22s:%-5d ", i->ip.address().to_string(ec).c_str(), i->ip.port());
snprintf(str, sizeof(str), "%-22s %22s ", print_endpoint(i->ip).c_str()
, print_endpoint(i->local_endpoint).c_str());
out += str;
}
@ -511,6 +512,7 @@ int torrent_upload_limit = 0;
int torrent_download_limit = 0;
std::string monitor_dir;
std::string bind_to_interface = "";
std::string outgoing_interface = "";
int poll_interval = 5;
int max_connections_per_torrent = 50;
@ -573,6 +575,7 @@ void add_torrent(libtorrent::session& ses
h.set_ratio(preferred_ratio);
h.set_upload_limit(torrent_upload_limit);
h.set_download_limit(torrent_download_limit);
h.use_interface(outgoing_interface.c_str());
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
h.resolve_countries(true);
#endif
@ -752,6 +755,8 @@ int main(int argc, char* argv[])
" -m <path> sets the .torrent monitor directory\n"
" -b <IP> sets IP of the interface to bind the\n"
" listen socket to\n"
" -I <IP> sets the IP of the interface to bind\n"
" outgoing peer connections to\n"
" -w <seconds> sets the retry time for failed web seeds\n"
" -t <seconds> sets the scan interval of the monitor dir\n"
" -x <file> loads an emule IP-filter file\n"
@ -956,6 +961,7 @@ int main(int argc, char* argv[])
#endif
}
break;
case 'I': outgoing_interface = arg; break;
}
++i; // skip the argument
}
@ -999,6 +1005,7 @@ int main(int argc, char* argv[])
h.set_ratio(preferred_ratio);
h.set_upload_limit(torrent_upload_limit);
h.set_download_limit(torrent_download_limit);
h.use_interface(outgoing_interface.c_str());
}
for (std::vector<std::string>::iterator i = torrents.begin()
@ -1026,6 +1033,7 @@ int main(int argc, char* argv[])
h.set_ratio(preferred_ratio);
h.set_upload_limit(torrent_upload_limit);
h.set_download_limit(torrent_download_limit);
h.use_interface(outgoing_interface.c_str());
continue;
}

View File

@ -216,6 +216,8 @@ namespace libtorrent
int progress_ppm; // [0, 1000000]
int estimated_reciprocation_rate;
tcp::endpoint local_endpoint;
};
struct TORRENT_EXPORT peer_list_entry

View File

@ -309,7 +309,7 @@ namespace libtorrent
void file_progress(std::vector<size_type>& fp, int flags = 0) const;
void use_interface(std::string net_interface);
tcp::endpoint get_interface() const { return m_net_interface; }
tcp::endpoint get_interface() const;
void connect_to_url_seed(std::list<web_seed_entry>::iterator url);
bool connect_to_peer(policy::peer* peerinfo);
@ -939,9 +939,10 @@ namespace libtorrent
std::string m_username;
std::string m_password;
// the network interface all outgoing connections
// are opened through
union_endpoint m_net_interface;
// the network interfaces outgoing connections
// are opened through. If there is more then one,
// they are used in a round-robin fasion
std::vector<union_endpoint> m_net_interfaces;
std::string m_save_path;
@ -1208,6 +1209,9 @@ namespace libtorrent
// the number of seconds since the last byte was uploaded
// from this torrent
boost::uint16_t m_last_upload;
// round-robin index into m_interfaces
mutable boost::uint8_t m_interface_index;
};
}

View File

@ -3471,6 +3471,9 @@ namespace libtorrent
int upload_capacity = m_ses.upload_rate_limit();
if (upload_capacity == 0)
upload_capacity = (std::max)(20000, m_ses.m_peak_up_rate + 10000);
error_code ec;
p.local_endpoint = get_socket()->local_endpoint(ec);
}
// allocates a disk buffer of size 'disk_buffer_size' and replaces the

View File

@ -77,6 +77,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/broadcast_socket.hpp"
#include "libtorrent/kademlia/dht_tracker.hpp"
#include "libtorrent/peer_info.hpp"
#include "libtorrent/enum_net.hpp"
#if TORRENT_USE_IOSTREAM
#include <iostream>
@ -226,7 +227,7 @@ namespace libtorrent
PRINT_OFFSETOF(torrent, m_time_critical_pieces)
PRINT_OFFSETOF(torrent, m_username)
PRINT_OFFSETOF(torrent, m_password)
PRINT_OFFSETOF(torrent, m_net_interface)
PRINT_OFFSETOF(torrent, m_net_interfaces)
PRINT_OFFSETOF(torrent, m_save_path)
PRINT_OFFSETOF(torrent, m_verified)
PRINT_OFFSETOF(torrent, m_error)
@ -323,7 +324,6 @@ namespace libtorrent
, m_tracker_timer(ses.m_io_service)
, m_ses(ses)
, m_trackers(m_torrent_file->trackers())
, m_net_interface(tcp::endpoint(net_interface.address(), 0))
, m_save_path(complete(p.save_path))
, m_storage_constructor(p.storage)
, m_ratio(0.f)
@ -381,7 +381,10 @@ namespace libtorrent
, m_last_scrape(0)
, m_last_download(0)
, m_last_upload(0)
, m_interface_index(0)
{
m_net_interfaces.push_back(net_interface);
if (p.file_priorities)
m_file_priority = *p.file_priorities;
@ -1269,14 +1272,30 @@ namespace libtorrent
files_checked();
}
void torrent::use_interface(std::string net_interface)
void torrent::use_interface(std::string net_interfaces)
{
INVARIANT_CHECK;
m_net_interfaces.clear();
error_code ec;
address a(address::from_string(net_interface.c_str(), ec));
if (ec) return;
m_net_interface = tcp::endpoint(a, 0);
char* str = &net_interfaces[0];
while (str)
{
char* space = strchr(str, ',');
if (space) *space++ = 0;
error_code ec;
address a(address::from_string(str, ec));
str = space;
if (ec) continue;
m_net_interfaces.push_back(tcp::endpoint(a, 0));
}
}
tcp::endpoint torrent::get_interface() const
{
if (m_net_interfaces.empty()) return tcp::endpoint(address_v4(), 0);
if (m_interface_index >= m_net_interfaces.size()) m_interface_index = 0;
return m_net_interfaces[m_interface_index++];
}
void torrent::on_tracker_announce_disp(boost::weak_ptr<torrent> p