diff --git a/src/bt_peer_connection.cpp b/src/bt_peer_connection.cpp index 7635de1cd..2f187091f 100644 --- a/src/bt_peer_connection.cpp +++ b/src/bt_peer_connection.cpp @@ -257,9 +257,17 @@ namespace libtorrent #ifdef TORRENT_LOGGING peer_log("*** ON_METADATA"); #endif + + disconnect_if_redundant(); + if (m_disconnecting) return; + // connections that are still in the handshake // will send their bitfield when the handshake // is done +#ifndef TORRENT_DISABLE_EXTENSIONS + write_upload_only(); +#endif + if (!m_sent_handshake) return; if (m_sent_bitfield) return; boost::shared_ptr t = associated_torrent().lock(); @@ -2253,23 +2261,26 @@ namespace libtorrent handshake["complete_ago"] = complete_ago; // if we're using lazy bitfields or if we're super seeding, don't say - // we're upload only, since it might make peers disconnect - // don't tell anyone we're upload only when in share mode - // we want to stay connected to seeds - // if we're super seeding, we don't want to make peers - // think that we only have a single piece and is upload - // only, since they might disconnect immediately when - // they have downloaded a single piece, although we'll - // make another piece available + // we're upload only, since it might make peers disconnect. don't tell + // anyone we're upload only when in share mode, we want to stay connected + // to seeds. if we're super seeding, we don't want to make peers think + // that we only have a single piece and is upload only, since they might + // disconnect immediately when they have downloaded a single piece, + // although we'll make another piece available. If we don't have + // metadata, we also need to suppress saying we're upload-only. If we do, + // we may be disconnected before we receive the metadata. if (t->is_upload_only() && !t->share_mode() + && t->valid_metadata() && !t->super_seeding() && (!m_settings.get_bool(settings_pack::lazy_bitfields) #if !defined(TORRENT_DISABLE_ENCRYPTION) && !defined(TORRENT_DISABLE_EXTENSIONS) || m_encrypted #endif )) + { handshake["upload_only"] = 1; + } if (m_settings.get_bool(settings_pack::support_share_mode) && t->share_mode()) diff --git a/test/Jamfile b/test/Jamfile index b5c924601..d914242f1 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -34,12 +34,12 @@ rule link_libtorrent ( properties * ) if shared in $(properties) { result += - /torrent//torrent/shared/shared/on ; + /torrent//torrent/shared/on/shared/on ; } else { result += - /torrent//torrent/static/static/on ; + /torrent//torrent/static/on/static/on ; } return $(result) ; } @@ -64,6 +64,7 @@ lib libtorrent_test : # default build shared + on : # user-requirements shared:TORRENT_LINK_TEST_SHARED diff --git a/test/test_metadata_extension.cpp b/test/test_metadata_extension.cpp index ade611c54..19614127a 100644 --- a/test/test_metadata_extension.cpp +++ b/test/test_metadata_extension.cpp @@ -60,7 +60,10 @@ enum flags_t reverse = 8, // only use uTP - utp = 16 + utp = 16, + + // upload-only mode + upload_only = 32 }; void test_transfer(int flags @@ -70,13 +73,14 @@ void test_transfer(int flags using namespace libtorrent; namespace lt = libtorrent; - fprintf(stderr, "\n==== test transfer: timeout=%d %s%s%s%s%s ====\n\n" + fprintf(stderr, "\n==== test transfer: timeout=%d %s%s%s%s%s%s ====\n\n" , timeout , (flags & clear_files) ? "clear-files " : "" , (flags & disconnect) ? "disconnect " : "" , (flags & full_encryption) ? "encryption " : "" , (flags & reverse) ? "reverse " : "" - , (flags & utp) ? "utp " : ""); + , (flags & utp) ? "utp " : "" + , (flags & upload_only) ? "upload_only " : ""); // these are declared before the session objects // so that they are destructed last. This enables @@ -123,6 +127,11 @@ void test_transfer(int flags boost::tie(tor1, tor2, ignore) = setup_transfer(seed, downloader, NULL , flags & clear_files, true, false, "_meta"); + if (flags & upload_only) + { + tor2.set_upload_mode(true); + } + if (flags & reverse) { error_code ec; @@ -159,6 +168,9 @@ void test_transfer(int flags if (flags & disconnect) goto done; TEST_CHECK(tor2.status().has_metadata); + + if (flags & upload_only) goto done; + std::cerr << "waiting for transfer to complete\n"; for (int i = 0; i < timeout * 10; ++i) @@ -203,6 +215,7 @@ int test_main() test_transfer(full_encryption | reverse, &create_ut_metadata_plugin, timeout); test_transfer(full_encryption | utp, &create_ut_metadata_plugin, timeout); test_transfer(reverse, &create_ut_metadata_plugin, timeout); + test_transfer(upload_only, &create_ut_metadata_plugin, timeout); #ifndef TORRENT_NO_DEPRECATE for (int f = 0; f <= (clear_files | disconnect | full_encryption); ++f)