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