enum fixes and ipv6 update

This commit is contained in:
Marcos Pinto 2007-09-20 16:28:41 +00:00
parent f673833fe9
commit ddc1ee6295
15 changed files with 167 additions and 56 deletions

View File

@ -493,4 +493,3 @@ private:
#endif #endif

View File

@ -42,6 +42,9 @@ namespace libtorrent
{ {
bool is_local(address const& a); bool is_local(address const& a);
bool is_loopback(address const& addr);
bool is_multicast(address const& addr);
address_v4 guess_local_address(asio::io_service&); address_v4 guess_local_address(asio::io_service&);
typedef boost::function<void(udp::endpoint const& from typedef boost::function<void(udp::endpoint const& from
@ -79,4 +82,3 @@ namespace libtorrent
#endif #endif

View File

@ -363,4 +363,3 @@ namespace libtorrent
#endif // TORRENT_STORAGE_HPP_INCLUDED #endif // TORRENT_STORAGE_HPP_INCLUDED

View File

@ -417,4 +417,3 @@ namespace libtorrent
#endif // TORRENT_TORRENT_HANDLE_HPP_INCLUDED #endif // TORRENT_TORRENT_HANDLE_HPP_INCLUDED

View File

@ -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,21 +102,39 @@ 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));
s->open(udp::v4(), ec); if (i->is_v4())
if (ec) continue; {
s->set_option(datagram_socket::reuse_address(true), ec); s->open(udp::v4(), ec);
if (ec) continue; if (ec) continue;
s->bind(udp::endpoint(address_v4::any(), multicast_endpoint.port()), ec); s->set_option(datagram_socket::reuse_address(true), ec);
if (ec) continue; if (ec) continue;
s->set_option(join_group(multicast_endpoint.address()), ec); s->bind(udp::endpoint(address_v4::any(), multicast_endpoint.port()), ec);
if (ec) continue; if (ec) continue;
s->set_option(outbound_interface(i->to_v4()), ec); s->set_option(join_group(multicast_endpoint.address()), ec);
if (ec) continue; 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); 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);
@ -150,4 +184,3 @@ namespace libtorrent
} }

View File

@ -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)

View File

@ -72,8 +72,17 @@ namespace libtorrent
ifreq const& item = *reinterpret_cast<ifreq*>(ifr); ifreq const& item = *reinterpret_cast<ifreq*>(ifr);
if (item.ifr_addr.sa_family == AF_INET) if (item.ifr_addr.sa_family == AF_INET)
{ {
ret.push_back(address::from_string( typedef asio::ip::address_v4::bytes_type bytes_t;
inet_ntoa(((sockaddr_in const*)&item.ifr_addr)->sin_addr))); bytes_t b;
memcpy(&b[0], &((sockaddr_in const*)&item.ifr_addr)->sin_addr, b.size());
ret.push_back(address_v4(b));
}
else if (item.ifr_addr.sa_family == AF_INET6)
{
typedef asio::ip::address_v6::bytes_type bytes_t;
bytes_t b;
memcpy(&b[0], &((sockaddr_in6 const*)&item.ifr_addr)->sin6_addr, b.size());
ret.push_back(address_v6(b));
} }
#if defined __MACH__ || defined(__FreeBSD__) #if defined __MACH__ || defined(__FreeBSD__)

View File

@ -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;

View File

@ -3022,4 +3022,3 @@ namespace libtorrent
} }
} }

View File

@ -1551,4 +1551,3 @@ namespace libtorrent
} }
} }

View File

@ -400,20 +400,22 @@ namespace libtorrent
partial.update(&m_scratch_buffer[0], ph.offset); partial.update(&m_scratch_buffer[0], ph.offset);
whole.update(&m_scratch_buffer[0], slot_size1); whole.update(&m_scratch_buffer[0], slot_size1);
hasher partial_copy = ph.h; hasher partial_copy = ph.h;
std::cerr << partial_copy.final() << " " << partial.final() << std::endl;
assert(ph.offset == 0 || partial_copy.final() == partial.final()); assert(ph.offset == 0 || partial_copy.final() == partial.final());
#endif #endif
int slot_size = piece_size - ph.offset; int slot_size = piece_size - ph.offset;
if (slot_size == 0) if (slot_size > 0)
{ {
assert(ph.h.final() == whole.final()); m_scratch_buffer.resize(slot_size);
return ph.h.final(); read_impl(&m_scratch_buffer[0], slot, ph.offset, slot_size, true);
ph.h.update(&m_scratch_buffer[0], slot_size);
} }
m_scratch_buffer.resize(slot_size); #ifndef NDEBUG
read_impl(&m_scratch_buffer[0], slot, ph.offset, slot_size, true); sha1_hash ret = ph.h.final();
ph.h.update(&m_scratch_buffer[0], slot_size); assert(ret == whole.final());
assert(whole.final() == ph.h.final()); return ret;
#else
return ph.h.final(); return ph.h.final();
#endif
} }
void storage::initialize(bool allocate_files) void storage::initialize(bool allocate_files)
@ -2213,4 +2215,3 @@ namespace libtorrent
#endif #endif
} // namespace libtorrent } // namespace libtorrent

View File

@ -2937,4 +2937,3 @@ namespace libtorrent
} }

View File

@ -1001,4 +1001,3 @@ namespace libtorrent
} }

View File

@ -980,4 +980,3 @@ void upnp::close()
} }
} }

View File

@ -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
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; ++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
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; ++num_added;
} }
std::vector<char> pex_msg; std::vector<char> pex_msg;