Browse Source

more untested stuff: try to preserve piece_size when reading from disk.

first signature checking instead of hash.
miguelfreitas
miguel 11 years ago
parent
commit
6fb557e33c
  1. 8
      libtorrent/include/libtorrent/disk_io_thread.hpp
  2. 2
      libtorrent/include/libtorrent/torrent_info.hpp
  3. 63
      libtorrent/src/disk_io_thread.cpp
  4. 11
      libtorrent/src/session_impl.cpp
  5. 2
      libtorrent/src/storage.cpp
  6. 5
      libtorrent/src/torrent.cpp
  7. 3
      libtorrent/src/torrent_info.cpp

8
libtorrent/include/libtorrent/disk_io_thread.hpp

@ -322,6 +322,8 @@ namespace libtorrent @@ -322,6 +322,8 @@ namespace libtorrent
struct cached_piece_entry
{
int piece;
// read size
int piece_size;
// storage this piece belongs to
boost::intrusive_ptr<piece_manager> storage;
// the pointers to the block data
@ -373,7 +375,7 @@ namespace libtorrent @@ -373,7 +375,7 @@ namespace libtorrent
bool is_cache_hit(cached_piece_entry& p
, disk_io_job const& j, mutex::scoped_lock& l);
int copy_from_piece(cached_piece_entry& p, bool& hit
, disk_io_job const& j, mutex::scoped_lock& l);
, disk_io_job & j, mutex::scoped_lock& l);
struct ignore_t
{
@ -409,8 +411,8 @@ namespace libtorrent @@ -409,8 +411,8 @@ namespace libtorrent
enum cache_flags_t {
cache_only = 1
};
int try_read_from_cache(disk_io_job const& j, bool& hit, int flags = 0);
int read_piece_from_cache_and_hash(disk_io_job const& j, sha1_hash& h);
int try_read_from_cache(disk_io_job & j, bool& hit, int flags = 0);
int read_piece_from_cache_and_hash(disk_io_job & j, bool *hash_ok);
int cache_piece(disk_io_job const& j, cache_piece_index_t::iterator& p
, bool& hit, int options, mutex::scoped_lock& l);

2
libtorrent/include/libtorrent/torrent_info.hpp

@ -253,7 +253,7 @@ namespace libtorrent @@ -253,7 +253,7 @@ namespace libtorrent
#endif
torrent_info(torrent_info const& t, int flags = 0);
torrent_info(sha1_hash const& info_hash, int flags = 0);
torrent_info(sha1_hash const& info_hash, std::string const name, int flags = 0);
torrent_info(lazy_entry const& torrent_file, error_code& ec, int flags = 0);
torrent_info(char const* buffer, int size, error_code& ec, int flags = 0);
torrent_info(std::string const& filename, error_code& ec, int flags = 0);

63
libtorrent/src/disk_io_thread.cpp

@ -47,6 +47,8 @@ POSSIBILITY OF SUCH DAMAGE. @@ -47,6 +47,8 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/time.hpp"
#include "../../src/twister.h"
#if TORRENT_USE_MLOCK && !defined TORRENT_WINDOWS
#include <sys/mman.h>
#endif
@ -821,7 +823,7 @@ namespace libtorrent @@ -821,7 +823,7 @@ namespace libtorrent
return -1;
}
if (ret != buffer_size)
if (ret < 0)
{
// this means the file wasn't big enough for this read
p.storage->get_storage_impl()->set_error(""
@ -829,6 +831,7 @@ namespace libtorrent @@ -829,6 +831,7 @@ namespace libtorrent
free_piece(p, l);
return -1;
}
p.piece_size = ret;
int offset = 0;
for (int i = 0; i < iov_counter; ++i)
@ -852,7 +855,7 @@ namespace libtorrent @@ -852,7 +855,7 @@ namespace libtorrent
return -1;
}
if (ret != buffer_size)
if (ret < 0)
{
// this means the file wasn't big enough for this read
p.storage->get_storage_impl()->set_error(""
@ -860,9 +863,10 @@ namespace libtorrent @@ -860,9 +863,10 @@ namespace libtorrent
free_piece(p, l);
return -1;
}
p.piece_size = ret;
}
TORRENT_ASSERT(ret == buffer_size);
TORRENT_ASSERT(ret <= buffer_size);
return ret;
}
@ -1049,7 +1053,7 @@ namespace libtorrent @@ -1049,7 +1053,7 @@ namespace libtorrent
}
// cache the entire piece and hash it
int disk_io_thread::read_piece_from_cache_and_hash(disk_io_job const& j, sha1_hash& h)
int disk_io_thread::read_piece_from_cache_and_hash(disk_io_job & j, bool *hash_ok)
{
TORRENT_ASSERT(j.buffer);
@ -1069,18 +1073,30 @@ namespace libtorrent @@ -1069,18 +1073,30 @@ namespace libtorrent
bool hit;
int ret = cache_piece(j, p, hit, ignore_cache_size, l);
if (ret < 0) return ret;
piece_size = p->piece_size;
if (!m_settings.disable_hash_checks)
{
hasher ctx;
*hash_ok = false;
for (int i = 0; i < blocks_in_piece; ++i)
{
TORRENT_ASSERT(p->blocks[i].buf);
ctx.update((char const*)p->blocks[i].buf, (std::min)(piece_size, m_block_size));
piece_size -= m_block_size;
lazy_entry v;
int pos;
error_code ec;
if (lazy_bdecode((char const*)p->blocks[0].buf, (char const*)p->blocks[0].buf
+ piece_size, v, ec, &pos) == 0) {
if( v.type() == lazy_entry::dict_t ) {
lazy_entry const* post = v.dict_find("userpost");
std::string sig = v.dict_find_string_value("sig_userpost");
std::string username = j.storage->info()->name();
if( post && sig.size() ) {
std::pair<char const*, int> postbuf = post->data_section();
*hash_ok = verifySignature(
std::string(postbuf.first,postbuf.second),
username, sig);
}
}
}
h = ctx.final();
}
ret = copy_from_piece(const_cast<cached_piece_entry&>(*p), hit, j, l);
@ -1146,7 +1162,7 @@ namespace libtorrent @@ -1146,7 +1162,7 @@ namespace libtorrent
}
int disk_io_thread::copy_from_piece(cached_piece_entry& p, bool& hit
, disk_io_job const& j, mutex::scoped_lock& l)
, disk_io_job & j, mutex::scoped_lock& l)
{
TORRENT_ASSERT(j.buffer);
@ -1196,10 +1212,18 @@ namespace libtorrent @@ -1196,10 +1212,18 @@ namespace libtorrent
int ret = read_into_piece(p, block, 0, blocks_to_read, l);
hit = false;
if (ret < 0) return ret;
if (ret < size + block_offset) return -2;
//[MF]
TORRENT_ASSERT(ret == p.piece_size);
piece_size = ret;
//if (ret < size + block_offset) return -2;
TORRENT_ASSERT(p.blocks[block].buf);
}
//[MF]
TORRENT_ASSERT(j.buffer_size >= piece_size);
j.buffer_size = piece_size;
size = piece_size;
// build a vector of all the buffers we need to free
// and free them all in one go
std::vector<char*> buffers;
@ -1236,7 +1260,7 @@ namespace libtorrent @@ -1236,7 +1260,7 @@ namespace libtorrent
return j.buffer_size;
}
int disk_io_thread::try_read_from_cache(disk_io_job const& j, bool& hit, int flags)
int disk_io_thread::try_read_from_cache(disk_io_job & j, bool& hit, int flags)
{
TORRENT_ASSERT(j.buffer);
TORRENT_ASSERT(j.cache_min_time >= 0);
@ -1937,8 +1961,8 @@ namespace libtorrent @@ -1937,8 +1961,8 @@ namespace libtorrent
// since we need to check the hash, this function
// will ignore the cache size limit (at least for
// reading and hashing, not for keeping it around)
sha1_hash h;
ret = read_piece_from_cache_and_hash(j, h);
bool hash_ok;
ret = read_piece_from_cache_and_hash(j, &hash_ok);
// -2 means there's no space in the read cache
// or that the read cache is disabled
@ -1948,7 +1972,7 @@ namespace libtorrent @@ -1948,7 +1972,7 @@ namespace libtorrent
break;
}
if (!m_settings.disable_hash_checks)
ret = (j.storage->info()->hash_for_piece(j.piece) == h)?ret:-3;
ret = (hash_ok)?ret:-3;
if (ret == -3)
{
j.storage->mark_failed(j.piece);
@ -2026,7 +2050,9 @@ namespace libtorrent @@ -2026,7 +2050,9 @@ namespace libtorrent
test_error(j);
break;
}
if (ret != j.buffer_size)
//[MF] size is unknown beforehand
j.buffer_size = ret;
if (ret == 0)
{
// this means the file wasn't big enough for this read
j.buffer = 0;
@ -2036,6 +2062,7 @@ namespace libtorrent @@ -2036,6 +2062,7 @@ namespace libtorrent
ret = -1;
break;
}
++m_cache_stats.blocks_read;
hit = false;
}

11
libtorrent/src/session_impl.cpp

@ -5115,7 +5115,7 @@ retry: @@ -5115,7 +5115,7 @@ retry:
if (lazy_bdecode(&params.resume_data[0], &params.resume_data[0]
+ params.resume_data.size(), tmp, ec, &pos) == 0
&& tmp.type() == lazy_entry::dict_t
&& (info = tmp.dict_find_dict("info")))
/* && (info = tmp.dict_find_dict("info")) */)
{
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING
session_log("found metadata in resume data");
@ -5123,8 +5123,12 @@ retry: @@ -5123,8 +5123,12 @@ retry:
// verify the info-hash of the metadata stored in the resume file matches
// the torrent we're loading
/* [MF]
std::pair<char const*, int> buf = info->data_section();
sha1_hash resume_ih = hasher(buf.first, buf.second).final();
*/
std::string info_hash = tmp.dict_find_string_value("info-hash");
sha1_hash resume_ih = sha1_hash(info_hash);
// if url is set, the info_hash is not actually the info-hash of the
// torrent, but the hash of the URL, until we have the full torrent
@ -5136,8 +5140,8 @@ retry: @@ -5136,8 +5140,8 @@ retry:
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING
session_log("info-hash matched");
#endif
params.ti = new torrent_info(resume_ih);
params.ti = new torrent_info(resume_ih, params.name);
/*
if (params.ti->parse_info_section(*info, ec, 0))
{
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING
@ -5154,6 +5158,7 @@ retry: @@ -5154,6 +5158,7 @@ retry:
, ec.message().c_str());
#endif
}
*/
}
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
else

2
libtorrent/src/storage.cpp

@ -2511,11 +2511,13 @@ ret: @@ -2511,11 +2511,13 @@ ret:
TORRENT_ASSERT(have_piece == -1);
// initialization for the full check
/* [MF]
if (m_hash_to_piece.empty())
{
for (int i = 0; i < m_files.num_pieces(); ++i)
m_hash_to_piece.insert(std::pair<const sha1_hash, int>(m_info->hash_for_piece(i), i));
}
*/
partial_hash ph;
int num_read = 0;

5
libtorrent/src/torrent.cpp

@ -458,7 +458,7 @@ namespace libtorrent @@ -458,7 +458,7 @@ namespace libtorrent
}
if (!m_torrent_file)
m_torrent_file = (p.ti ? p.ti : new torrent_info(info_hash));
m_torrent_file = (p.ti ? p.ti : new torrent_info(info_hash, p.name));
m_trackers = m_torrent_file->trackers();
if (m_torrent_file->is_valid())
@ -5148,12 +5148,13 @@ namespace libtorrent @@ -5148,12 +5148,13 @@ namespace libtorrent
const sha1_hash& info_hash = torrent_file().info_hash();
ret["info-hash"] = std::string((char*)info_hash.begin(), (char*)info_hash.end());
/* [MF] don't save metadata
if (valid_metadata())
{
if (m_magnet_link || (m_save_resume_flags & torrent_handle::save_info_dict))
ret["info"] = bdecode(&torrent_file().metadata()[0]
, &torrent_file().metadata()[0] + torrent_file().metadata_size());
}
} */
// blocks per piece
int num_blocks_per_piece =

3
libtorrent/src/torrent_info.cpp

@ -829,7 +829,7 @@ namespace libtorrent @@ -829,7 +829,7 @@ namespace libtorrent
// will not contain any hashes, comments, creation date
// just the necessary to use it with piece manager
// used for torrents with no metadata
torrent_info::torrent_info(sha1_hash const& info_hash, int flags)
torrent_info::torrent_info(sha1_hash const& info_hash, std::string const name, int flags)
: m_merkle_first_leaf(0)
, m_piece_hashes(0)
, m_creation_date(time(0))
@ -845,6 +845,7 @@ namespace libtorrent @@ -845,6 +845,7 @@ namespace libtorrent
file_entry e;
e.size = 1;
m_files.add_file(e);
m_files.set_name(name);
}
torrent_info::~torrent_info()

Loading…
Cancel
Save