forked from premiere/premiere-libtorrent
some more IPv6 support
This commit is contained in:
parent
338eedf961
commit
ba437cf72e
|
@ -43,7 +43,7 @@ namespace libtorrent
|
|||
{
|
||||
bool is_local(address const& a)
|
||||
{
|
||||
if (a.is_v6()) return false;
|
||||
if (a.is_v6()) return a.to_v6().is_link_local();
|
||||
address_v4 a4 = a.to_v4();
|
||||
unsigned long ip = a4.to_ulong();
|
||||
return ((ip & 0xff000000) == 0x0a000000
|
||||
|
@ -58,15 +58,32 @@ namespace libtorrent
|
|||
udp::resolver::iterator i = r.resolve(udp::resolver::query(asio::ip::host_name(), "0"));
|
||||
for (;i != udp::resolver_iterator(); ++i)
|
||||
{
|
||||
// ignore the loopback
|
||||
if (i->endpoint().address() == address_v4((127 << 24) + 1)) continue;
|
||||
address const& a = i->endpoint().address();
|
||||
// ignore non-IPv4 addresses
|
||||
if (i->endpoint().address().is_v4()) break;
|
||||
if (!a.is_v4()) break;
|
||||
// ignore the loopback
|
||||
if (a.to_v4() == address_v4::loopback()) continue;
|
||||
}
|
||||
if (i == udp::resolver_iterator()) return address_v4::any();
|
||||
return i->endpoint().address().to_v4();
|
||||
}
|
||||
|
||||
bool is_loopback(address const& addr)
|
||||
{
|
||||
if (addr.is_v4())
|
||||
return addr.to_v4() == address_v4::loopback();
|
||||
else
|
||||
return addr.to_v6() == address_v6::loopback();
|
||||
}
|
||||
|
||||
bool is_multicast(address const& addr)
|
||||
{
|
||||
if (addr.is_v4())
|
||||
return addr.to_v4().is_multicast();
|
||||
else
|
||||
return addr.to_v6().is_multicast();
|
||||
}
|
||||
|
||||
broadcast_socket::broadcast_socket(asio::io_service& ios
|
||||
, udp::endpoint const& multicast_endpoint
|
||||
, receive_handler_t const& handler
|
||||
|
@ -74,8 +91,7 @@ namespace libtorrent
|
|||
: m_multicast_endpoint(multicast_endpoint)
|
||||
, m_on_receive(handler)
|
||||
{
|
||||
assert(m_multicast_endpoint.address().is_v4());
|
||||
assert(m_multicast_endpoint.address().to_v4().is_multicast());
|
||||
assert(is_multicast(m_multicast_endpoint.address()));
|
||||
|
||||
using namespace asio::ip::multicast;
|
||||
|
||||
|
@ -86,21 +102,39 @@ namespace libtorrent
|
|||
, end(interfaces.end()); i != end; ++i)
|
||||
{
|
||||
// only broadcast to IPv4 addresses that are not local
|
||||
if (!i->is_v4() || !is_local(*i)) continue;
|
||||
// ignore the loopback interface
|
||||
if (i->to_v4() == address_v4((127 << 24) + 1)) continue;
|
||||
if (!is_local(*i)) continue;
|
||||
// only multicast on compatible networks
|
||||
if (i->is_v4() != multicast_endpoint.address().is_v4()) continue;
|
||||
// ignore any loopback interface
|
||||
if (is_loopback(*i)) continue;
|
||||
|
||||
boost::shared_ptr<datagram_socket> s(new datagram_socket(ios));
|
||||
s->open(udp::v4(), ec);
|
||||
if (ec) continue;
|
||||
s->set_option(datagram_socket::reuse_address(true), ec);
|
||||
if (ec) continue;
|
||||
s->bind(udp::endpoint(address_v4::any(), multicast_endpoint.port()), ec);
|
||||
if (ec) continue;
|
||||
s->set_option(join_group(multicast_endpoint.address()), ec);
|
||||
if (ec) continue;
|
||||
s->set_option(outbound_interface(i->to_v4()), ec);
|
||||
if (ec) continue;
|
||||
if (i->is_v4())
|
||||
{
|
||||
s->open(udp::v4(), ec);
|
||||
if (ec) continue;
|
||||
s->set_option(datagram_socket::reuse_address(true), ec);
|
||||
if (ec) continue;
|
||||
s->bind(udp::endpoint(address_v4::any(), multicast_endpoint.port()), ec);
|
||||
if (ec) continue;
|
||||
s->set_option(join_group(multicast_endpoint.address()), ec);
|
||||
if (ec) continue;
|
||||
s->set_option(outbound_interface(i->to_v4()), ec);
|
||||
if (ec) continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
s->open(udp::v6(), ec);
|
||||
if (ec) continue;
|
||||
s->set_option(datagram_socket::reuse_address(true), ec);
|
||||
if (ec) continue;
|
||||
s->bind(udp::endpoint(address_v6::any(), multicast_endpoint.port()), ec);
|
||||
if (ec) continue;
|
||||
s->set_option(join_group(multicast_endpoint.address()), ec);
|
||||
if (ec) continue;
|
||||
// s->set_option(outbound_interface(i->to_v6()), ec);
|
||||
// if (ec) continue;
|
||||
}
|
||||
s->set_option(hops(255), ec);
|
||||
if (ec) continue;
|
||||
s->set_option(enable_loopback(loopback), ec);
|
||||
|
|
|
@ -50,6 +50,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/version.hpp"
|
||||
#include "libtorrent/extensions.hpp"
|
||||
#include "libtorrent/aux_/session_impl.hpp"
|
||||
#include "libtorrent/enum_net.hpp"
|
||||
|
||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
#include "libtorrent/pe_crypto.hpp"
|
||||
|
@ -1474,6 +1475,19 @@ namespace libtorrent
|
|||
detail::write_address(remote().address(), out);
|
||||
handshake["yourip"] = remote_address;
|
||||
handshake["reqq"] = m_ses.settings().max_allowed_in_request_queue;
|
||||
asio::error_code ec;
|
||||
std::vector<address> const& interfaces = enum_net_interfaces(get_socket()->io_service(), ec);
|
||||
for (std::vector<address>::const_iterator i = interfaces.begin()
|
||||
, end(interfaces.end()); i != end; ++i)
|
||||
{
|
||||
// TODO: only use global IPv6 addresses
|
||||
if (!i->is_v6() || i->to_v6().is_link_local()) continue;
|
||||
std::string ipv6_address;
|
||||
std::back_insert_iterator<std::string> out(ipv6_address);
|
||||
detail::write_address(*i, out);
|
||||
handshake["ipv6"] = ipv6_address;
|
||||
break;
|
||||
}
|
||||
|
||||
// loop backwards, to make the first extension be the last
|
||||
// to fill in the handshake (i.e. give the first extensions priority)
|
||||
|
|
|
@ -890,12 +890,7 @@ namespace libtorrent
|
|||
|
||||
peer_entry p;
|
||||
p.pid.clear();
|
||||
std::stringstream ip_str;
|
||||
ip_str << (int)detail::read_uint8(i) << ".";
|
||||
ip_str << (int)detail::read_uint8(i) << ".";
|
||||
ip_str << (int)detail::read_uint8(i) << ".";
|
||||
ip_str << (int)detail::read_uint8(i);
|
||||
p.ip = ip_str.str();
|
||||
p.ip = detail::read_v4_address(i).to_string();
|
||||
p.port = detail::read_uint16(i);
|
||||
peer_list.push_back(p);
|
||||
}
|
||||
|
@ -910,6 +905,22 @@ namespace libtorrent
|
|||
}
|
||||
}
|
||||
|
||||
if (entry const* ipv6_peers = e.find_key("peers6"))
|
||||
{
|
||||
std::string const& peers = ipv6_peers->string();
|
||||
for (std::string::const_iterator i = peers.begin();
|
||||
i != peers.end();)
|
||||
{
|
||||
if (std::distance(i, peers.end()) < 18) break;
|
||||
|
||||
peer_entry p;
|
||||
p.pid.clear();
|
||||
p.ip = detail::read_v6_address(i).to_string();
|
||||
p.port = detail::read_uint16(i);
|
||||
peer_list.push_back(p);
|
||||
}
|
||||
}
|
||||
|
||||
// look for optional scrape info
|
||||
int complete = -1;
|
||||
int incomplete = -1;
|
||||
|
|
|
@ -67,8 +67,6 @@ namespace libtorrent { namespace
|
|||
if (!p.is_local()) return false;
|
||||
// don't send out peers that we haven't successfully connected to
|
||||
if (p.is_connecting()) return false;
|
||||
// ut pex does not support IPv6
|
||||
if (!p.remote().address().is_v4()) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -98,9 +96,15 @@ namespace libtorrent { namespace
|
|||
std::string& pla = pex["added"].string();
|
||||
std::string& pld = pex["dropped"].string();
|
||||
std::string& plf = pex["added.f"].string();
|
||||
std::string& pla6 = pex["added6"].string();
|
||||
std::string& pld6 = pex["dropped6"].string();
|
||||
std::string& plf6 = pex["added6.f"].string();
|
||||
std::back_insert_iterator<std::string> pla_out(pla);
|
||||
std::back_insert_iterator<std::string> pld_out(pld);
|
||||
std::back_insert_iterator<std::string> plf_out(plf);
|
||||
std::back_insert_iterator<std::string> pla6_out(pla6);
|
||||
std::back_insert_iterator<std::string> pld6_out(pld6);
|
||||
std::back_insert_iterator<std::string> plf6_out(plf6);
|
||||
|
||||
std::set<tcp::endpoint> dropped;
|
||||
m_old_peers.swap(dropped);
|
||||
|
@ -123,8 +127,6 @@ namespace libtorrent { namespace
|
|||
bt_peer_connection* p = dynamic_cast<bt_peer_connection*>(i->second);
|
||||
if (!p) continue;
|
||||
|
||||
// i->first was added since the last time
|
||||
detail::write_endpoint(i->first, pla_out);
|
||||
// no supported flags to set yet
|
||||
// 0x01 - peer supports encryption
|
||||
// 0x02 - peer is a seed
|
||||
|
@ -132,7 +134,17 @@ namespace libtorrent { namespace
|
|||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
flags |= p->supports_encryption() ? 1 : 0;
|
||||
#endif
|
||||
detail::write_uint8(flags, plf_out);
|
||||
// i->first was added since the last time
|
||||
if (i->first.address().is_v4())
|
||||
{
|
||||
detail::write_endpoint(i->first, pla_out);
|
||||
detail::write_uint8(flags, plf_out);
|
||||
}
|
||||
else
|
||||
{
|
||||
detail::write_endpoint(i->first, pla6_out);
|
||||
detail::write_uint8(flags, plf6_out);
|
||||
}
|
||||
++num_added;
|
||||
}
|
||||
else
|
||||
|
@ -146,8 +158,10 @@ namespace libtorrent { namespace
|
|||
for (std::set<tcp::endpoint>::const_iterator i = dropped.begin()
|
||||
, end(dropped.end());i != end; ++i)
|
||||
{
|
||||
if (!i->address().is_v4()) continue;
|
||||
detail::write_endpoint(*i, pld_out);
|
||||
if (i->address().is_v4())
|
||||
detail::write_endpoint(*i, pld_out);
|
||||
else
|
||||
detail::write_endpoint(*i, pld6_out);
|
||||
}
|
||||
|
||||
m_ut_pex_msg.clear();
|
||||
|
@ -227,6 +241,28 @@ namespace libtorrent { namespace
|
|||
char flags = detail::read_uint8(fin);
|
||||
p.peer_from_tracker(adr, pid, peer_info::pex, flags);
|
||||
}
|
||||
|
||||
if (entry const* p6 = pex_msg.find_key("added6"))
|
||||
{
|
||||
std::string const& peers6 = p6->string();
|
||||
std::string const& peer6_flags = pex_msg["added6.f"].string();
|
||||
|
||||
int num_peers = peers6.length() / 18;
|
||||
char const* in = peers6.c_str();
|
||||
char const* fin = peer6_flags.c_str();
|
||||
|
||||
if (int(peer6_flags.size()) != num_peers)
|
||||
return true;
|
||||
|
||||
peer_id pid(0);
|
||||
policy& p = m_torrent.get_policy();
|
||||
for (int i = 0; i < num_peers; ++i)
|
||||
{
|
||||
tcp::endpoint adr = detail::read_v6_endpoint<tcp::endpoint>(in);
|
||||
char flags = detail::read_uint8(fin);
|
||||
p.peer_from_tracker(adr, pid, peer_info::pex, flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (std::exception&)
|
||||
{
|
||||
|
@ -279,8 +315,13 @@ namespace libtorrent { namespace
|
|||
pex["dropped"].string();
|
||||
std::string& pla = pex["added"].string();
|
||||
std::string& plf = pex["added.f"].string();
|
||||
pex["dropped6"].string();
|
||||
std::string& pla6 = pex["added6"].string();
|
||||
std::string& plf6 = pex["added6.f"].string();
|
||||
std::back_insert_iterator<std::string> pla_out(pla);
|
||||
std::back_insert_iterator<std::string> plf_out(plf);
|
||||
std::back_insert_iterator<std::string> pla6_out(pla6);
|
||||
std::back_insert_iterator<std::string> plf6_out(plf6);
|
||||
|
||||
int num_added = 0;
|
||||
for (torrent::peer_iterator i = m_torrent.begin()
|
||||
|
@ -295,8 +336,6 @@ namespace libtorrent { namespace
|
|||
bt_peer_connection* p = dynamic_cast<bt_peer_connection*>(i->second);
|
||||
if (!p) continue;
|
||||
|
||||
// i->first was added since the last time
|
||||
detail::write_endpoint(i->first, pla_out);
|
||||
// no supported flags to set yet
|
||||
// 0x01 - peer supports encryption
|
||||
// 0x02 - peer is a seed
|
||||
|
@ -304,7 +343,17 @@ namespace libtorrent { namespace
|
|||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
flags |= p->supports_encryption() ? 1 : 0;
|
||||
#endif
|
||||
detail::write_uint8(flags, plf_out);
|
||||
// i->first was added since the last time
|
||||
if (i->first.address().is_v4())
|
||||
{
|
||||
detail::write_endpoint(i->first, pla_out);
|
||||
detail::write_uint8(flags, plf_out);
|
||||
}
|
||||
else
|
||||
{
|
||||
detail::write_endpoint(i->first, pla6_out);
|
||||
detail::write_uint8(flags, plf6_out);
|
||||
}
|
||||
++num_added;
|
||||
}
|
||||
std::vector<char> pex_msg;
|
||||
|
|
Loading…
Reference in New Issue