[Libtorrent-devel] relay mode again

Howard Chu hyc at highlandsun.com
Mon Jun 29 22:38:17 UTC 2009


I'm still trying to get my master/slave patches working against .4. I've 
gotten quite lost in the new choke manager, and have no idea how the objects 
are connected back to either the choke_manager_node or the peerInfo. Can you 
give me some tips on how to proceed?

As a refresher: configuring a slave opens a connection to the specified 
address:port, regardless of any other tracker information.

configuring a master is supposed to give high priority to any connection from 
that address - no bandwidth limits, and never choked. I have the bandwidth 
limit removed, but still haven't figured out the new choke manager.

"blessing" a connection was my second attempt at figuring out the choke 
manager; that attempt has also been rather useless. Any help here would be 
much appreciated.

-- 
    -- Howard Chu
    CTO, Symas Corp.           http://www.symas.com
    Director, Highland Sun     http://highlandsun.com/hyc/
    Chief Architect, OpenLDAP  http://www.openldap.org/project/

-------------- next part --------------
diff -wur libtorrent-0.12.4/src/download/choke_manager.cc ../libtorrent-0.12.4/src/download/choke_manager.cc
--- libtorrent-0.12.4/src/download/choke_manager.cc	2008-05-07 05:19:13.000000000 -0700
+++ ../libtorrent-0.12.4/src/download/choke_manager.cc	2009-06-16 22:00:51.000000000 -0700
@@ -145,8 +145,8 @@
   if (base->snubbed())
     return;
 
-  if ((m_flags & flag_unchoke_all_new || (!is_full() && m_slotCanUnchoke())) &&
-      base->time_last_choke() + rak::timer::from_seconds(10) < cachedTime) {
+  if (base->blessed() || ((m_flags & flag_unchoke_all_new || (!is_full() && m_slotCanUnchoke())) &&
+      base->time_last_choke() + rak::timer::from_seconds(10) < cachedTime)) {
     m_unchoked.push_back(value_type(pc, 0));
     m_slotConnection(pc, false);
 
@@ -221,6 +221,24 @@
   }
 }
 
+void
+ChokeManager::set_blessed(PeerConnectionBase* pc, ChokeManagerNode* base, bool v) {
+  if (base->blessed() == v)
+    return;
+
+  base->set_blessed(v);
+
+  if (base->choked()) {
+    m_unchoked.push_back(value_type(pc, 0));
+    m_slotConnection(pc, false);
+
+    m_slotUnchoke(1);
+
+  } else if (base->queued()) {
+    m_queued.push_back(value_type(pc, 0));
+  }
+}
+
 // We are no longer in m_connectionList.
 void
 ChokeManager::disconnected(PeerConnectionBase* pc, ChokeManagerNode* base) {
diff -wur libtorrent-0.12.4/src/download/choke_manager.h ../libtorrent-0.12.4/src/download/choke_manager.h
--- libtorrent-0.12.4/src/download/choke_manager.h	2008-05-07 05:19:13.000000000 -0700
+++ ../libtorrent-0.12.4/src/download/choke_manager.h	2009-06-16 21:22:50.000000000 -0700
@@ -103,6 +103,8 @@
   void                set_snubbed(PeerConnectionBase* pc, ChokeManagerNode* base);
   void                set_not_snubbed(PeerConnectionBase* pc, ChokeManagerNode* base);
 
+  void                set_blessed(PeerConnectionBase* pc, ChokeManagerNode* base, bool v);
+
   void                disconnected(PeerConnectionBase* pc, ChokeManagerNode* base);
 
   uint32_t*           choke_weight()                           { return m_chokeWeight; }
diff -wur libtorrent-0.12.4/src/download/choke_manager_node.h ../libtorrent-0.12.4/src/download/choke_manager_node.h
--- libtorrent-0.12.4/src/download/choke_manager_node.h	2008-05-07 05:19:13.000000000 -0700
+++ ../libtorrent-0.12.4/src/download/choke_manager_node.h	2009-06-16 21:25:04.000000000 -0700
@@ -46,7 +46,8 @@
   ChokeManagerNode() :
     m_queued(false),
     m_unchoked(false),
-    m_snubbed(false) {}
+    m_snubbed(false),
+	m_blessed(false) {}
 
   bool                queued() const                          { return m_queued; }
   void                set_queued(bool s)                      { m_queued = s; }
@@ -58,6 +59,9 @@
   bool                snubbed() const                         { return m_snubbed; }
   void                set_snubbed(bool s)                     { m_snubbed = s; }
 
+  bool                blessed() const                         { return m_blessed; }
+  void                set_blessed(bool s)                     { m_blessed = s; }
+
   rak::timer          time_last_choke() const                 { return m_timeLastChoke; }
   void                set_time_last_choke(rak::timer t)       { m_timeLastChoke = t; }
 
@@ -65,6 +69,7 @@
   bool                m_queued;
   bool                m_unchoked;
   bool                m_snubbed;
+  bool                m_blessed;
 
   rak::timer          m_timeLastChoke;
 };
diff -wur libtorrent-0.12.4/src/download/download_main.cc ../libtorrent-0.12.4/src/download/download_main.cc
--- libtorrent-0.12.4/src/download/download_main.cc	2008-10-22 06:03:59.000000000 -0700
+++ ../libtorrent-0.12.4/src/download/download_main.cc	2009-04-26 16:02:46.000000000 -0700
@@ -184,6 +184,12 @@
   m_delegator.set_aggressive(false);
   update_endgame();  
 
+  {
+    const rak::socket_address rsa = *rak::socket_address::cast_from(manager->connection_manager()->slave_address());
+	if (!rsa.is_address_any())
+	  add_peer(rsa);
+  }
+
   receive_connect_peers();
 }  
 
diff -wur libtorrent-0.12.4/src/protocol/handshake.cc ../libtorrent-0.12.4/src/protocol/handshake.cc
--- libtorrent-0.12.4/src/protocol/handshake.cc	2008-11-10 18:39:23.000000000 -0800
+++ ../libtorrent-0.12.4/src/protocol/handshake.cc	2009-04-26 16:33:59.000000000 -0700
@@ -1022,6 +1022,14 @@
     m_peerInfo->set_flags(PeerInfo::flag_handshake);
   }
 
+  {
+    const rak::socket_address* msa = rak::socket_address::cast_from(manager->connection_manager()->master_address());
+	rak::socket_address sa = m_address;
+	sa.set_port(0);
+    if (sa == *msa)
+	  m_peerInfo->set_flags(PeerInfo::flag_master);
+  }
+
   std::memcpy(m_peerInfo->set_options(), m_options, 8);
   m_peerInfo->mutable_id().assign((const char*)m_readBuffer.position());
   m_readBuffer.consume(20);
diff -wur libtorrent-0.12.4/src/protocol/peer_connection_base.cc ../libtorrent-0.12.4/src/protocol/peer_connection_base.cc
--- libtorrent-0.12.4/src/protocol/peer_connection_base.cc	2008-08-26 13:15:15.000000000 -0700
+++ ../libtorrent-0.12.4/src/protocol/peer_connection_base.cc	2009-06-16 22:11:21.000000000 -0700
@@ -196,6 +196,11 @@
     m_download->upload_choke_manager()->set_not_snubbed(this, &m_upChoke);
 }
 
+void
+PeerConnectionBase::set_upload_blessed(bool v) {
+  m_download->upload_choke_manager()->set_blessed(this, &m_upChoke, v);
+}
+
 bool
 PeerConnectionBase::receive_upload_choke(bool choke) {
   if (choke == m_upChoke.choked())
@@ -621,6 +626,9 @@
 
   uint32_t quota = m_download->upload_throttle()->node_quota(m_peerChunks.upload_throttle());
 
+  if (m_peerInfo->is_master())
+  	quota = std::numeric_limits<uint32_t>::max();
+
   if (quota == 0) {
     manager->poll()->remove_write(this);
     m_download->upload_throttle()->node_deactivate(m_peerChunks.upload_throttle());
diff -wur libtorrent-0.12.4/src/protocol/peer_connection_base.h ../libtorrent-0.12.4/src/protocol/peer_connection_base.h
--- libtorrent-0.12.4/src/protocol/peer_connection_base.h	2008-05-07 05:19:12.000000000 -0700
+++ ../libtorrent-0.12.4/src/protocol/peer_connection_base.h	2009-06-16 21:20:53.000000000 -0700
@@ -93,6 +93,7 @@
   bool                is_up_choked() const            { return m_upChoke.choked(); }
   bool                is_up_interested() const        { return m_upChoke.queued(); }
   bool                is_up_snubbed() const           { return m_upChoke.snubbed(); }
+  bool                is_up_blessed() const           { return m_upChoke.blessed(); }
 
   bool                is_down_queued() const          { return m_downChoke.queued(); }
   bool                is_down_local_unchoked() const  { return m_downChoke.unchoked(); }
@@ -100,9 +101,11 @@
   bool                is_down_interested() const      { return m_downInterested; }
 
   void                set_upload_snubbed(bool v);
+  void                set_upload_blessed(bool v);
 
   bool                is_seeder() const               { return m_peerChunks.is_seeder(); }
   bool                is_not_seeder() const           { return !m_peerChunks.is_seeder(); }
+  bool                is_master() const               { return m_peerInfo->is_master(); }
 
   bool                is_encrypted() const            { return m_encryption.is_encrypted(); }
   bool                is_obfuscated() const           { return m_encryption.is_obfuscated(); }
diff -wur libtorrent-0.12.4/src/torrent/connection_manager.cc ../libtorrent-0.12.4/src/torrent/connection_manager.cc
--- libtorrent-0.12.4/src/torrent/connection_manager.cc	2008-11-16 06:51:48.000000000 -0800
+++ ../libtorrent-0.12.4/src/torrent/connection_manager.cc	2009-04-26 15:57:37.000000000 -0700
@@ -83,6 +83,12 @@
   m_localAddress = (new rak::socket_address())->c_sockaddr();
   rak::socket_address::cast_from(m_localAddress)->sa_inet()->clear();
 
+  m_masterAddress = (new rak::socket_address())->c_sockaddr();
+  rak::socket_address::cast_from(m_masterAddress)->sa_inet()->clear();
+
+  m_slaveAddress = (new rak::socket_address())->c_sockaddr();
+  rak::socket_address::cast_from(m_slaveAddress)->sa_inet()->clear();
+
   m_proxyAddress = (new rak::socket_address())->c_sockaddr();
   rak::socket_address::cast_from(m_proxyAddress)->sa_inet()->clear();
 }
@@ -92,6 +98,8 @@
 
   delete m_bindAddress;
   delete m_localAddress;
+  delete m_masterAddress;
+  delete m_slaveAddress;
   delete m_proxyAddress;
 }
 
@@ -140,6 +148,26 @@
 }
 
 void
+ConnectionManager::set_master_address(const sockaddr* sa) {
+  const rak::socket_address* rsa = rak::socket_address::cast_from(sa);
+
+  if (rsa->family() != rak::socket_address::af_inet)
+    throw input_error("Tried to set a master address that is not an af_inet address.");
+
+  rak::socket_address::cast_from(m_masterAddress)->copy(*rsa, rsa->length());
+}
+
+void
+ConnectionManager::set_slave_address(const sockaddr* sa) {
+  const rak::socket_address* rsa = rak::socket_address::cast_from(sa);
+
+  if (rsa->family() != rak::socket_address::af_inet)
+    throw input_error("Tried to set a slave address that is not an af_inet address.");
+
+  rak::socket_address::cast_from(m_slaveAddress)->copy(*rsa, rsa->length());
+}
+
+void
 ConnectionManager::set_proxy_address(const sockaddr* sa) {
   const rak::socket_address* rsa = rak::socket_address::cast_from(sa);
 
diff -wur libtorrent-0.12.4/src/torrent/connection_manager.h ../libtorrent-0.12.4/src/torrent/connection_manager.h
--- libtorrent-0.12.4/src/torrent/connection_manager.h	2008-05-07 05:19:13.000000000 -0700
+++ ../libtorrent-0.12.4/src/torrent/connection_manager.h	2009-04-26 15:34:04.000000000 -0700
@@ -145,6 +145,12 @@
   const sockaddr*     local_address() const                   { return m_localAddress; }
   void                set_local_address(const sockaddr* sa);
 
+  const sockaddr*     master_address() const                   { return m_masterAddress; }
+  void                set_master_address(const sockaddr* sa);
+
+  const sockaddr*     slave_address() const                   { return m_slaveAddress; }
+  void                set_slave_address(const sockaddr* sa);
+
   const sockaddr*     proxy_address() const                   { return m_proxyAddress; }
   void                set_proxy_address(const sockaddr* sa);
 
@@ -193,6 +199,8 @@
 
   sockaddr*           m_bindAddress;
   sockaddr*           m_localAddress;
+  sockaddr*           m_masterAddress;
+  sockaddr*           m_slaveAddress;
   sockaddr*           m_proxyAddress;
 
   Listen*             m_listen;
diff -wur libtorrent-0.12.4/src/torrent/peer/peer.cc ../libtorrent-0.12.4/src/torrent/peer/peer.cc
--- libtorrent-0.12.4/src/torrent/peer/peer.cc	2008-10-22 06:10:28.000000000 -0700
+++ ../libtorrent-0.12.4/src/torrent/peer/peer.cc	2009-06-16 21:20:15.000000000 -0700
@@ -65,6 +65,9 @@
 void Peer::set_snubbed(bool v)             { m_ptr()->set_upload_snubbed(v); }
 void Peer::set_banned()                    { m_peerInfo->set_failed_counter(64); }
 
+bool Peer::is_blessed() const              { return c_ptr()->is_up_blessed(); }
+void Peer::set_blessed(bool v)             { m_ptr()->set_upload_blessed(v); }
+
 const Rate*       Peer::down_rate() const  { return c_ptr()->c_peer_chunks()->download_throttle()->rate(); } 
 const Rate*       Peer::up_rate() const    { return c_ptr()->c_peer_chunks()->upload_throttle()->rate(); } 
 const Rate*       Peer::peer_rate() const  { return c_ptr()->c_peer_chunks()->peer_rate(); } 
diff -wur libtorrent-0.12.4/src/torrent/peer/peer.h ../libtorrent-0.12.4/src/torrent/peer/peer.h
--- libtorrent-0.12.4/src/torrent/peer/peer.h	2008-10-22 06:07:23.000000000 -0700
+++ ../libtorrent-0.12.4/src/torrent/peer/peer.h	2009-06-16 21:18:01.000000000 -0700
@@ -71,6 +71,9 @@
   void                 set_snubbed(bool v);
   void                 set_banned();
 
+  bool                 is_blessed() const;
+  void                 set_blessed(bool v);
+
   const HashString&    id() const                         { return peer_info()->id(); }
   const char*          options() const                    { return peer_info()->options(); }
   const sockaddr*      address() const                    { return peer_info()->socket_address(); }
diff -wur libtorrent-0.12.4/src/torrent/peer/peer_info.h ../libtorrent-0.12.4/src/torrent/peer/peer_info.h
--- libtorrent-0.12.4/src/torrent/peer/peer_info.h	2008-05-07 05:19:13.000000000 -0700
+++ ../libtorrent-0.12.4/src/torrent/peer/peer_info.h	2009-04-26 16:34:40.000000000 -0700
@@ -56,6 +56,7 @@
   static const int flag_handshake = (1 << 2);
   static const int flag_blocked   = (1 << 3);   // For initial seeding.
   static const int flag_restart   = (1 << 4);
+  static const int flag_master    = (1 << 5);
 
   PeerInfo(const sockaddr* address);
   ~PeerInfo();
@@ -65,6 +66,7 @@
   bool                is_handshake() const                  { return m_flags & flag_handshake; }
   bool                is_blocked() const                    { return m_flags & flag_blocked; }
   bool                is_restart() const                    { return m_flags & flag_restart; }
+  bool                is_master() const                     { return m_flags & flag_master; }
 
   int                 flags() const                         { return m_flags; }
 

-------------- next part --------------
diff -wur rtorrent-0.8.4/src/command_network.cc ../rtorrent-0.8.4/src/command_network.cc
--- rtorrent-0.8.4/src/command_network.cc	2008-08-27 01:25:01.000000000 -0700
+++ ../rtorrent-0.8.4/src/command_network.cc	2009-04-26 15:25:40.000000000 -0700
@@ -334,6 +334,8 @@
 
   ADD_COMMAND_STRING_TRI("bind",          rak::make_mem_fun(control->core(), &core::Manager::set_bind_address), rak::make_mem_fun(control->core(), &core::Manager::bind_address));
   ADD_COMMAND_STRING_TRI("ip",            rak::make_mem_fun(control->core(), &core::Manager::set_local_address), rak::make_mem_fun(control->core(), &core::Manager::local_address));
+  ADD_COMMAND_STRING_TRI("master",        rak::make_mem_fun(control->core(), &core::Manager::set_master_address), rak::make_mem_fun(control->core(), &core::Manager::master_address));
+  ADD_COMMAND_STRING_TRI("slave",         rak::make_mem_fun(control->core(), &core::Manager::set_slave_address), rak::make_mem_fun(control->core(), &core::Manager::slave_address));
   ADD_COMMAND_STRING_TRI("proxy_address", rak::make_mem_fun(control->core(), &core::Manager::set_proxy_address), rak::make_mem_fun(control->core(), &core::Manager::proxy_address));
   ADD_COMMAND_STRING_TRI("http_proxy",    rak::make_mem_fun(httpStack, &core::CurlStack::set_http_proxy), rak::make_mem_fun(httpStack, &core::CurlStack::http_proxy));
   ADD_COMMAND_STRING_TRI("http_capath",   rak::make_mem_fun(httpStack, &core::CurlStack::set_http_capath), rak::make_mem_fun(httpStack, &core::CurlStack::http_capath));
diff -wur rtorrent-0.8.4/src/command_peer.cc ../rtorrent-0.8.4/src/command_peer.cc
--- rtorrent-0.8.4/src/command_peer.cc	2008-05-07 05:19:11.000000000 -0700
+++ ../rtorrent-0.8.4/src/command_peer.cc	2009-06-16 22:02:59.000000000 -0700
@@ -133,6 +133,7 @@
   ADD_CP_VALUE("is_incoming",             std::mem_fun(&torrent::Peer::is_incoming));
   ADD_CP_VALUE("is_obfuscated",           std::mem_fun(&torrent::Peer::is_obfuscated));
   ADD_CP_VALUE("is_snubbed",              std::mem_fun(&torrent::Peer::is_snubbed));
+  ADD_CP_VALUE("is_blessed",              std::mem_fun(&torrent::Peer::is_blessed));
 
   ADD_CP_STRING_UNI("address",            std::ptr_fun(&retrieve_p_address));
   ADD_CP_VALUE_UNI("port",                std::ptr_fun(&retrieve_p_port));
diff -wur rtorrent-0.8.4/src/core/manager.cc ../rtorrent-0.8.4/src/core/manager.cc
--- rtorrent-0.8.4/src/core/manager.cc	2008-11-18 07:06:32.000000000 -0800
+++ ../rtorrent-0.8.4/src/core/manager.cc	2009-04-26 15:30:34.000000000 -0700
@@ -337,6 +337,66 @@
 }
 
 std::string
+Manager::master_address() const {
+  return rak::socket_address::cast_from(torrent::connection_manager()->master_address())->address_str();
+}
+
+void
+Manager::set_master_address(const std::string& addr) {
+  int err;
+  rak::address_info* ai;
+
+  if ((err = rak::address_info::get_address_info(addr.c_str(), PF_INET, SOCK_STREAM, &ai)) != 0)
+    throw torrent::input_error("Could not set master address: " + std::string(rak::address_info::strerror(err)) + ".");
+  
+  try {
+
+    torrent::connection_manager()->set_master_address(ai->address()->c_sockaddr());
+    rak::address_info::free_address_info(ai);
+
+  } catch (torrent::input_error& e) {
+    rak::address_info::free_address_info(ai);
+    throw e;
+  }
+}
+
+std::string
+Manager::slave_address() const {
+  return rak::socket_address::cast_from(torrent::connection_manager()->slave_address())->address_str();
+}
+
+void
+Manager::set_slave_address(const std::string& addr) {
+  int port;
+  rak::address_info* ai;
+
+  char buf[addr.length() + 1];
+
+  int err = std::sscanf(addr.c_str(), "%[^:]:%i", buf, &port);
+
+  if (err <= 0)
+    throw torrent::input_error("Could not parse slave address.");
+
+  if (err == 1)
+    port = 80;
+
+  if ((err = rak::address_info::get_address_info(buf, PF_INET, SOCK_STREAM, &ai)) != 0)
+    throw torrent::input_error("Could not set slave address: " + std::string(rak::address_info::strerror(err)) + ".");
+  
+  try {
+
+    ai->address()->set_port(port);
+    torrent::connection_manager()->set_slave_address(ai->address()->c_sockaddr());
+    
+    rak::address_info::free_address_info(ai);
+
+  } catch (torrent::input_error& e) {
+    rak::address_info::free_address_info(ai);
+    throw e;
+  }
+}
+
+std::string
 Manager::proxy_address() const {
   return rak::socket_address::cast_from(torrent::connection_manager()->proxy_address())->address_str();
 }
diff -wur rtorrent-0.8.4/src/core/manager.h ../rtorrent-0.8.4/src/core/manager.h
--- rtorrent-0.8.4/src/core/manager.h	2008-08-27 01:25:01.000000000 -0700
+++ ../rtorrent-0.8.4/src/core/manager.h	2009-04-26 15:26:30.000000000 -0700
@@ -97,6 +97,12 @@
   std::string         local_address() const;
   void                set_local_address(const std::string& addr);
 
+  std::string         master_address() const;
+  void                set_master_address(const std::string& addr);
+
+  std::string         slave_address() const;
+  void                set_slave_address(const std::string& addr);
+
   std::string         proxy_address() const;
   void                set_proxy_address(const std::string& addr);
 
diff -wur rtorrent-0.8.4/src/display/window_peer_list.cc ../rtorrent-0.8.4/src/display/window_peer_list.cc
--- rtorrent-0.8.4/src/display/window_peer_list.cc	2008-05-07 05:19:11.000000000 -0700
+++ ../rtorrent-0.8.4/src/display/window_peer_list.cc	2009-06-16 22:04:21.000000000 -0700
@@ -142,6 +142,9 @@
     if (p->is_snubbed())
       m_canvas->print(x, y, "*");
 
+    if (p->is_blessed())
+      m_canvas->print(x+1, y, "+");
+
     x += 6;
 
     if (p->failed_counter() != 0)
diff -wur rtorrent-0.8.4/src/ui/element_peer_list.cc ../rtorrent-0.8.4/src/ui/element_peer_list.cc
--- rtorrent-0.8.4/src/ui/element_peer_list.cc	2008-10-22 06:17:34.000000000 -0700
+++ ../rtorrent-0.8.4/src/ui/element_peer_list.cc	2009-06-16 22:06:38.000000000 -0700
@@ -75,6 +75,7 @@
 
   m_bindings['k']       = sigc::mem_fun(this, &ElementPeerList::receive_disconnect_peer);
   m_bindings['*']       = sigc::mem_fun(this, &ElementPeerList::receive_snub_peer);
+  m_bindings['+']       = sigc::mem_fun(this, &ElementPeerList::receive_bless_peer);
   m_bindings['B']       = sigc::mem_fun(this, &ElementPeerList::receive_ban_peer);
   m_bindings[KEY_LEFT] = m_bindings['B' - '@']  = sigc::mem_fun(&m_slotExit, &slot_type::operator());  
   m_bindings[KEY_RIGHT] = m_bindings['F' - '@'] = sigc::bind(sigc::mem_fun(this, &ElementPeerList::activate_display), DISPLAY_INFO);
@@ -246,6 +247,16 @@
 }
 
 void
+ElementPeerList::receive_bless_peer() {
+  if (m_listItr == m_list.end())
+    return;
+
+  (*m_listItr)->set_blessed(!(*m_listItr)->is_blessed());
+
+  update_itr();
+}
+
+void
 ElementPeerList::receive_ban_peer() {
   if (m_listItr == m_list.end())
     return;
diff -wur rtorrent-0.8.4/src/ui/element_peer_list.h ../rtorrent-0.8.4/src/ui/element_peer_list.h
--- rtorrent-0.8.4/src/ui/element_peer_list.h	2008-10-22 06:04:56.000000000 -0700
+++ ../rtorrent-0.8.4/src/ui/element_peer_list.h	2009-06-16 22:07:34.000000000 -0700
@@ -75,6 +75,7 @@
   void                receive_peer_disconnected(torrent::Peer* p);
 
   void                receive_snub_peer();
+  void                receive_bless_peer();
   void                receive_ban_peer();
 
   void                update_itr();



More information about the Libtorrent-devel mailing list