diff --git a/examples/client_test.cpp b/examples/client_test.cpp index f400677d2..898560c8c 100755 --- a/examples/client_test.cpp +++ b/examples/client_test.cpp @@ -226,7 +226,7 @@ int main(int argc, char* argv[]) return 1; } - boost::filesystem::path::default_name_check(boost::filesystem::native); +// boost::filesystem::path::default_name_check(boost::filesystem::native); http_settings settings; // settings.proxy_ip = "192.168.0.1"; @@ -388,21 +388,21 @@ int main(int argc, char* argv[]) ++i) { out << "d:" << add_suffix(i->down_speed) << "/s " - << "(" << add_suffix(i->total_download) << ") " +// << "(" << add_suffix(i->total_download) << ") " << "u:" << add_suffix(i->up_speed) << "/s " - << "(" << add_suffix(i->total_upload) << ") " - << "ul:" << add_suffix(i->upload_limit) << "/s " - << "uc:" << add_suffix(i->upload_ceiling) << "/s " +// << "(" << add_suffix(i->total_upload) << ") " +// << "ul:" << add_suffix(i->upload_limit) << "/s " +// << "uc:" << add_suffix(i->upload_ceiling) << "/s " // << "df:" << ratio(i->total_download, i->total_upload) << " " -// << "q:" << i->download_queue_length << " " -// << "r:" << i->upload_queue_length << " " -// << "f:" -// << static_cast((i->flags & peer_info::interesting)?"I":"_") -// << static_cast((i->flags & peer_info::choked)?"C":"_") -// << static_cast((i->flags & peer_info::remote_interested)?"i":"_") -// << static_cast((i->flags & peer_info::remote_choked)?"c":"_") -// << static_cast((i->flags & peer_info::supports_extensions)?"e":"_") -// << static_cast((i->flags & peer_info::local_connection)?"l":"r") + << "q:" << i->download_queue_length << " " + << "r:" << i->upload_queue_length << " " + << "f:" + << static_cast((i->flags & peer_info::interesting)?"I":"_") + << static_cast((i->flags & peer_info::choked)?"C":"_") + << static_cast((i->flags & peer_info::remote_interested)?"i":"_") + << static_cast((i->flags & peer_info::remote_choked)?"c":"_") + << static_cast((i->flags & peer_info::supports_extensions)?"e":"_") + << static_cast((i->flags & peer_info::local_connection)?"l":"r") << "\n"; if (i->downloading_piece_index >= 0) diff --git a/include/libtorrent/policy.hpp b/include/libtorrent/policy.hpp index 4cbf827ce..50a481d79 100755 --- a/include/libtorrent/policy.hpp +++ b/include/libtorrent/policy.hpp @@ -169,17 +169,18 @@ namespace libtorrent peer* find_choke_candidate(); peer* find_unchoke_candidate(); + // the seed prefix means that the + // function is used while seeding. + bool seed_unchoke_one_peer(); + peer* find_seed_choke_candidate(); + peer* find_seed_unchoke_candidate(); bool connect_peer(peer *); - - bool connect_one_peer(); bool disconnect_one_peer(); peer* find_disconnect_candidate(); peer* find_connect_candidate(); - - // a functor that identifies peers that have disconnected and that // are too old for still being saved. struct old_disconnected_peer diff --git a/include/libtorrent/session.hpp b/include/libtorrent/session.hpp index 88d07df52..7ef1438a4 100755 --- a/include/libtorrent/session.hpp +++ b/include/libtorrent/session.hpp @@ -276,7 +276,7 @@ namespace libtorrent // the error. It will return true on success. bool listen_on( std::pair const& port_range - , const char* interface = 0); + , const char* net_interface = 0); // returns the port we ended up listening on unsigned short listen_port() const; diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp index 3ea3bf610..fffe365b7 100755 --- a/src/peer_connection.cpp +++ b/src/peer_connection.cpp @@ -1391,7 +1391,7 @@ namespace libtorrent #ifndef NDEBUG (*m_logger) << "sending libtorrent version\n"; #endif - int ret = m_socket->send("libtorrent version 0.1.0.0\n"); + int ret = m_socket->send("libtorrent version 0.1.0.0\n", 27); throw protocol_error("closing"); } #ifndef NDEBUG diff --git a/src/policy.cpp b/src/policy.cpp index b267524a6..91a3649c5 100755 --- a/src/policy.cpp +++ b/src/policy.cpp @@ -483,6 +483,61 @@ namespace libtorrent return candidate; } + policy::peer* policy::find_seed_choke_candidate() + { + peer* candidate = 0; + boost::posix_time::ptime last_unchoke + = boost::posix_time::ptime(boost::posix_time::ptime(boost::gregorian::date(1970, boost::gregorian::Jan, 1))); + + for (std::vector::iterator i = m_peers.begin(); + i != m_peers.end(); + ++i) + { + peer_connection* c = i->connection; + if (c == 0) continue; + if (c->is_choked()) continue; + if (last_unchoke > i->last_optimistically_unchoked) continue; + last_unchoke = i->last_optimistically_unchoked; + candidate = &(*i); + } + return candidate; + } + + policy::peer* policy::find_seed_unchoke_candidate() + { + peer* candidate = 0; + boost::posix_time::ptime last_unchoke + = boost::posix_time::second_clock::local_time(); + + for (std::vector::iterator i = m_peers.begin(); + i != m_peers.end(); + ++i) + { + peer_connection* c = i->connection; + if (c == 0) continue; + if (!c->is_choked()) continue; + if (!c->is_peer_interested()) continue; + if (c->is_disconnecting()) continue; + if (last_unchoke < i->last_optimistically_unchoked) continue; + last_unchoke = i->last_optimistically_unchoked; + candidate = &(*i); + } + return candidate; + } + + bool policy::seed_unchoke_one_peer() + { + peer* p = find_seed_unchoke_candidate(); + if (p != 0) + { + p->connection->send_unchoke(); + p->last_optimistically_unchoked + = boost::posix_time::second_clock::local_time(); + ++m_num_unchoked; + } + return p != 0; + } + void policy::pulse() { using namespace boost::posix_time; @@ -497,52 +552,70 @@ namespace libtorrent , old_disconnected_peer()) , m_peers.end()); - if(m_max_connections != std::numeric_limits::max()) + // ------------------------------------- + // maintain the number of connections + // ------------------------------------- + + // count the number of connected peers except for peers + // that are currently in the process of disconnecting + int num_connected_peers = 0; + + for (std::vector::iterator i = m_peers.begin(); + i != m_peers.end(); + ++i) { - // count the number of connected peers except for peers - // that are currently in the process of disconnecting - int num_connected_peers=0; + if (i->connection && !i->connection->is_disconnecting()) + ++num_connected_peers; + } - for (std::vector::iterator i = m_peers.begin(); - i != m_peers.end(); - ++i) - { - if(i->connection && !i->connection->is_disconnecting()) - ++num_connected_peers; - } + if (m_max_connections != std::numeric_limits::max()) + { - int max_connections=m_max_connections; + int max_connections = m_max_connections; - if(num_connected_peers >= max_connections) + if (num_connected_peers >= max_connections) { // every minute, disconnect the worst peer in hope of finding a better peer - boost::posix_time::ptime local_time=boost::posix_time::second_clock::local_time(); - if(m_last_optimistic_disconnect+boost::posix_time::seconds(120) <= local_time) + boost::posix_time::ptime local_time = boost::posix_time::second_clock::local_time(); + if(m_last_optimistic_disconnect + boost::posix_time::seconds(120) <= local_time) { - m_last_optimistic_disconnect=local_time; + m_last_optimistic_disconnect = local_time; --max_connections; // this will have the effect of disconnecting the worst peer } } else { // don't do a disconnect earlier than 1 minute after some peer was connected - m_last_optimistic_disconnect=boost::posix_time::second_clock::local_time(); + m_last_optimistic_disconnect = boost::posix_time::second_clock::local_time(); } - while(num_connected_peers > max_connections) + while (num_connected_peers > max_connections) { assert(disconnect_one_peer()); --num_connected_peers; } } - while(m_torrent->num_peers() < m_max_connections) + while (m_torrent->num_peers() < m_max_connections) { - if(!connect_one_peer()) + if (!connect_one_peer()) break; } + + // ------------------------ + // upload shift + // ------------------------ + + // this part will shift downloads + // from peers that are seeds and peers + // that don't want to download from us + // to peers that cannot upload anything + // to us. The shifting will make sure + // that the torrent's share ratio + // will be maintained + // if the share ratio is 0 (infinite) // m_available_free_upload isn't used // because it isn't necessary @@ -563,25 +636,23 @@ namespace libtorrent } // ------------------------ - // seed policy + // seed choking policy // ------------------------ if (m_torrent->is_seed()) { + if (num_connected_peers > m_max_uploads) + { + // this means there are some peers that + // are choked. To have the choked peers + // rotate, unchoke one peer here + // and let the next condiional block + // make sure another peer is choked. + seed_unchoke_one_peer(); + } + while (m_num_unchoked > m_max_uploads) { - peer* p = 0; - for (std::vector::iterator i = m_peers.begin(); - i != m_peers.end(); - ++i) - { - peer_connection* c = i->connection; - if (c == 0) continue; - if (c->is_choked()) continue; -// TODO: add some more criterions here. Maybe the peers -// that have less should be promoted? (to allow them to trade) - p = &(*i); - break; - } + peer* p = find_seed_choke_candidate(); if (p == 0) break; @@ -593,33 +664,13 @@ namespace libtorrent // unchoked peers while (m_num_unchoked < m_max_uploads) { - peer* p = 0; - for (std::vector::iterator i = m_peers.begin(); - i != m_peers.end(); - ++i) - { - peer_connection* c = i->connection; - if (c == 0) continue; - if (!c->is_choked()) continue; - if (!c->is_peer_interested()) continue; - if (c->is_disconnecting()) continue; -// TODO: add some more criterions here. Maybe the peers -// that have less should be promoted? (to allow them to trade) - p = &(*i); - break; - } - - if (p == 0) break; - - p->connection->send_unchoke(); - p->last_optimistically_unchoked = boost::posix_time::second_clock::local_time(); - ++m_num_unchoked; + if (!seed_unchoke_one_peer()) break; } } - // ------------------------ - // downloading policy - // ------------------------ + // ---------------------------- + // downloading choking policy + // ---------------------------- else { // choke peers that have leeched too much without giving anything back