Browse Source

keep track of rt and dm messages and filter dm from get_pieces (getposts rpc)

miguelfreitas
Miguel Freitas 11 years ago
parent
commit
dc3b1b2c47
  1. 3
      libtorrent/include/libtorrent/disk_io_thread.hpp
  2. 13
      libtorrent/include/libtorrent/piece_picker.hpp
  3. 8
      libtorrent/include/libtorrent/storage.hpp
  4. 12
      libtorrent/include/libtorrent/torrent.hpp
  5. 2
      libtorrent/include/libtorrent/torrent_handle.hpp
  6. 6
      libtorrent/src/disk_io_thread.cpp
  7. 2
      libtorrent/src/peer_connection.cpp
  8. 4
      libtorrent/src/piece_picker.cpp
  9. 16
      libtorrent/src/storage.cpp
  10. 48
      libtorrent/src/torrent.cpp
  11. 8
      libtorrent/src/torrent_handle.cpp
  12. 17
      src/twister.cpp
  13. 6
      src/twister.h

3
libtorrent/include/libtorrent/disk_io_thread.hpp

@ -157,6 +157,9 @@ namespace libtorrent
// the time when this job was issued. This is used to // the time when this job was issued. This is used to
// keep track of disk I/O congestion // keep track of disk I/O congestion
ptime start_time; ptime start_time;
// post flags after hash checking
boost::uint32_t post_flags;
}; };
// returns true if the fundamental operation // returns true if the fundamental operation

13
libtorrent/include/libtorrent/piece_picker.hpp

@ -203,7 +203,7 @@ namespace libtorrent
// it means that the refcounter will indicate that // it means that the refcounter will indicate that
// we are not interested in this piece anymore // we are not interested in this piece anymore
// (i.e. we don't have to maintain a refcount) // (i.e. we don't have to maintain a refcount)
void we_have(int index); void we_have(int index, boost::uint32_t flags);
void we_dont_have(int index); void we_dont_have(int index);
int cursor() const { return m_cursor; } int cursor() const { return m_cursor; }
@ -222,6 +222,13 @@ namespace libtorrent
return m_piece_map[index].index == piece_pos::we_have_index; return m_piece_map[index].index == piece_pos::we_have_index;
} }
boost::uint32_t post_flags(int index) const
{
TORRENT_ASSERT(index >= 0);
TORRENT_ASSERT(index < int(m_piece_map.size()));
return m_piece_map[index].post_flags;
}
bool is_downloading(int index) const bool is_downloading(int index) const
{ {
TORRENT_ASSERT(index >= 0); TORRENT_ASSERT(index >= 0);
@ -421,6 +428,8 @@ namespace libtorrent
#else #else
boost::uint32_t peer_count : 16; boost::uint32_t peer_count : 16;
#endif #endif
// post flags (1 = rt, 2 = dm)
boost::uint32_t post_flags : 2;
// is 1 if the piece is marked as being downloaded // is 1 if the piece is marked as being downloaded
boost::uint32_t downloading : 1; boost::uint32_t downloading : 1;
// set when downloading, but no free blocks to request left // set when downloading, but no free blocks to request left
@ -465,7 +474,7 @@ namespace libtorrent
}; };
bool have() const { return index == we_have_index; } bool have() const { return index == we_have_index; }
void set_have() { index = we_have_index; TORRENT_ASSERT(have()); } void set_have(boost::uint32_t flags) { index = we_have_index; post_flags = flags; TORRENT_ASSERT(have()); }
void set_not_have() { index = 0; TORRENT_ASSERT(!have()); } void set_not_have() { index = 0; TORRENT_ASSERT(!have()); }
bool filtered() const { return piece_priority == filter_priority; } bool filtered() const { return piece_priority == filter_priority; }

8
libtorrent/include/libtorrent/storage.hpp

@ -415,7 +415,7 @@ namespace libtorrent
int check_fastresume(lazy_entry const& rd, error_code& error); int check_fastresume(lazy_entry const& rd, error_code& error);
// this function returns true if the checking is complete // this function returns true if the checking is complete
int check_files(int& current_slot, int& have_piece, error_code& error); int check_files(int& current_slot, int& have_piece, error_code& error, boost::uint32_t *post_flags);
#ifndef TORRENT_NO_DEPRECATE #ifndef TORRENT_NO_DEPRECATE
bool compact_allocation() const bool compact_allocation() const
@ -428,7 +428,7 @@ namespace libtorrent
bool allocate_slots_impl(int num_slots, mutex::scoped_lock& l, bool abort_on_disk = false); bool allocate_slots_impl(int num_slots, mutex::scoped_lock& l, bool abort_on_disk = false);
int hash_for_slot(int slot, bool *hash_ok, int piece_size); int hash_for_slot(int slot, bool *hash_ok, boost::uint32_t *post_flags, int piece_size);
void hint_read_impl(int piece_index, int offset, int size); void hint_read_impl(int piece_index, int offset, int size);
@ -447,10 +447,10 @@ namespace libtorrent
size_type physical_offset(int piece_index, int offset); size_type physical_offset(int piece_index, int offset);
// -1=error 0=ok >0=skip this many pieces // -1=error 0=ok >0=skip this many pieces
int check_one_piece(int& have_piece); int check_one_piece(int& have_piece, boost::uint32_t *post_flags);
void switch_to_full_mode(); void switch_to_full_mode();
bool hash_for_piece_impl(int piece, int* readback = 0); bool hash_for_piece_impl(int piece, int* readback = 0, boost::uint32_t *post_flags = NULL);
int release_files_impl() { return m_storage->release_files(); } int release_files_impl() { return m_storage->release_files(); }
int delete_files_impl() { return m_storage->delete_files(); } int delete_files_impl() { return m_storage->delete_files(); }

12
libtorrent/include/libtorrent/torrent.hpp

@ -200,7 +200,7 @@ namespace libtorrent
void read_piece(int piece); void read_piece(int piece);
void on_disk_read_complete(int ret, disk_io_job const& j, peer_request r, read_piece_struct* rp); void on_disk_read_complete(int ret, disk_io_job const& j, peer_request r, read_piece_struct* rp);
void get_pieces(std::vector<std::string> *pieces, int count, int max_id, int since_id, void get_pieces(std::vector<std::string> *pieces, int count, int max_id, int since_id, uint32_t filter_flags,
mutex *mut, condition_variable *cond, int *reqs); mutex *mut, condition_variable *cond, int *reqs);
void on_disk_read_get_piece_complete(int ret, disk_io_job const& j, void on_disk_read_get_piece_complete(int ret, disk_io_job const& j,
std::vector<std::string> *pieces, mutex *mut, condition_variable *cond, int *reqs); std::vector<std::string> *pieces, mutex *mut, condition_variable *cond, int *reqs);
@ -525,7 +525,7 @@ namespace libtorrent
// called when we learn that we have a piece // called when we learn that we have a piece
// only once per piece // only once per piece
void we_have(int index); void we_have(int index, boost::uint32_t post_flags);
int num_have() const int num_have() const
{ {
@ -666,18 +666,18 @@ namespace libtorrent
// we wasn't finished anymore. // we wasn't finished anymore.
void resume_download(); void resume_download();
void async_verify_piece(int piece_index, boost::function<void(int)> const&); void async_verify_piece(int piece_index, boost::function<void(int, boost::uint32_t)> const&);
// this is called from the peer_connection // this is called from the peer_connection
// each time a piece has failed the hash // each time a piece has failed the hash
// test // test
void piece_finished(int index, int passed_hash_check, int piece_size); void piece_finished(int index, int passed_hash_check, boost::uint32_t post_flags, int piece_size);
// piece_passed is called when a piece passes the hash check // piece_passed is called when a piece passes the hash check
// this will tell all peers that we just got his piece // this will tell all peers that we just got his piece
// and also let the piece picker know that we have this piece // and also let the piece picker know that we have this piece
// so it wont pick it for download // so it wont pick it for download
void piece_passed(int index); void piece_passed(int index, boost::uint32_t post_flags);
// piece_failed is called when a piece fails the hash check // piece_failed is called when a piece fails the hash check
void piece_failed(int index); void piece_failed(int index);
@ -897,7 +897,7 @@ namespace libtorrent
void on_cache_flushed(int ret, disk_io_job const& j); void on_cache_flushed(int ret, disk_io_job const& j);
void on_piece_verified(int ret, disk_io_job const& j void on_piece_verified(int ret, disk_io_job const& j
, boost::function<void(int)> f); , boost::function<void(int, boost::uint32_t)> f);
int prioritize_tracker(int tracker_index); int prioritize_tracker(int tracker_index);
int deprioritize_tracker(int tracker_index); int deprioritize_tracker(int tracker_index);

2
libtorrent/include/libtorrent/torrent_handle.hpp

@ -168,7 +168,7 @@ namespace libtorrent
enum flags_t { overwrite_existing = 1 }; enum flags_t { overwrite_existing = 1 };
void add_piece(int piece, char const* data, int size, int flags = 0) const; void add_piece(int piece, char const* data, int size, int flags = 0) const;
void read_piece(int piece) const; void read_piece(int piece) const;
void get_pieces(std::vector<std::string> &pieces, int count, int max_id, int since_id) const; void get_pieces(std::vector<std::string> &pieces, int count, int max_id, int since_id, uint32_t filter_flags) const;
bool have_piece(int piece) const; bool have_piece(int piece) const;
void get_full_peer_list(std::vector<peer_list_entry>& v) const; void get_full_peer_list(std::vector<peer_list_entry>& v) const;

6
libtorrent/src/disk_io_thread.cpp

@ -1079,7 +1079,7 @@ namespace libtorrent
{ {
std::string errmsg; std::string errmsg;
*hash_ok = acceptSignedPost((char const*)p->blocks[0].buf, piece_size, *hash_ok = acceptSignedPost((char const*)p->blocks[0].buf, piece_size,
j.storage->info()->name(), j.piece, errmsg); j.storage->info()->name(), j.piece, errmsg, &j.post_flags);
} }
ret = copy_from_piece(const_cast<cached_piece_entry&>(*p), hit, j, l); ret = copy_from_piece(const_cast<cached_piece_entry&>(*p), hit, j, l);
@ -2232,7 +2232,7 @@ namespace libtorrent
ptime hash_start = time_now_hires(); ptime hash_start = time_now_hires();
int readback = 0; int readback = 0;
bool hash_ok = j.storage->hash_for_piece_impl(j.piece, &readback); bool hash_ok = j.storage->hash_for_piece_impl(j.piece, &readback, &j.post_flags);
if (test_error(j)) if (test_error(j))
{ {
ret = -1; ret = -1;
@ -2413,7 +2413,7 @@ namespace libtorrent
ptime hash_start = time_now_hires(); ptime hash_start = time_now_hires();
if (m_waiting_to_shutdown) break; if (m_waiting_to_shutdown) break;
ret = j.storage->check_files(j.piece, j.offset, j.error); ret = j.storage->check_files(j.piece, j.offset, j.error, &j.post_flags);
ptime done = time_now_hires(); ptime done = time_now_hires();
m_hash_time.add_sample(total_microseconds(done - hash_start)); m_hash_time.add_sample(total_microseconds(done - hash_start));

2
libtorrent/src/peer_connection.cpp

@ -2520,7 +2520,7 @@ namespace libtorrent
check_postcondition post_checker2_(t, false); check_postcondition post_checker2_(t, false);
#endif #endif
t->async_verify_piece(p.piece, boost::bind(&torrent::piece_finished, t t->async_verify_piece(p.piece, boost::bind(&torrent::piece_finished, t
, p.piece, _1, p.length)); , p.piece, _1, _2, p.length));
} }
if (is_disconnecting()) return; if (is_disconnecting()) return;

4
libtorrent/src/piece_picker.cpp

@ -1239,7 +1239,7 @@ namespace libtorrent
// downloaded a piece, and that no further attempts // downloaded a piece, and that no further attempts
// to pick that piece should be made. The piece will // to pick that piece should be made. The piece will
// be removed from the available piece list. // be removed from the available piece list.
void piece_picker::we_have(int index) void piece_picker::we_have(int index, boost::uint32_t flags)
{ {
#ifdef TORRENT_EXPENSIVE_INVARIANT_CHECKS #ifdef TORRENT_EXPENSIVE_INVARIANT_CHECKS
TORRENT_PIECE_PICKER_INVARIANT_CHECK; TORRENT_PIECE_PICKER_INVARIANT_CHECK;
@ -1294,7 +1294,7 @@ namespace libtorrent
++m_num_have_filtered; ++m_num_have_filtered;
} }
++m_num_have; ++m_num_have;
p.set_have(); p.set_have(flags);
if (index > m_last_have) if (index > m_last_have)
m_last_have = index; m_last_have = index;
if (m_cursor == m_reverse_cursor - 1 && if (m_cursor == m_reverse_cursor - 1 &&

16
libtorrent/src/storage.cpp

@ -210,7 +210,7 @@ namespace libtorrent
} }
#endif #endif
int piece_manager::hash_for_slot(int slot, bool *hash_ok, int piece_size) int piece_manager::hash_for_slot(int slot, bool *hash_ok, boost::uint32_t *post_flags, int piece_size)
{ {
TORRENT_ASSERT_VAL(!error(), error()); TORRENT_ASSERT_VAL(!error(), error());
*hash_ok = false; *hash_ok = false;
@ -233,7 +233,7 @@ namespace libtorrent
{ {
std::string errmsg; std::string errmsg;
*hash_ok = acceptSignedPost((char const*)buf.iov_base, ret, *hash_ok = acceptSignedPost((char const*)buf.iov_base, ret,
m_info->name(), slot, errmsg); m_info->name(), slot, errmsg, post_flags);
} }
if (error()) return 0; if (error()) return 0;
@ -900,14 +900,14 @@ namespace libtorrent
return m_save_path; return m_save_path;
} }
bool piece_manager::hash_for_piece_impl(int piece, int* readback) bool piece_manager::hash_for_piece_impl(int piece, int* readback, boost::uint32_t *post_flags)
{ {
TORRENT_ASSERT(!m_storage->error()); TORRENT_ASSERT(!m_storage->error());
bool hash_ok = false; bool hash_ok = false;
int slot = slot_for(piece); int slot = slot_for(piece);
int read = hash_for_slot(slot, &hash_ok, m_files.piece_size(piece)); int read = hash_for_slot(slot, &hash_ok, post_flags, m_files.piece_size(piece));
if (readback) *readback = read; if (readback) *readback = read;
if (m_storage->error()) return false; if (m_storage->error()) return false;
return hash_ok; return hash_ok;
@ -1100,7 +1100,7 @@ namespace libtorrent
// the second return value is the progress the // the second return value is the progress the
// file check is at. 0 is nothing done, and 1 // file check is at. 0 is nothing done, and 1
// is finished // is finished
int piece_manager::check_files(int& current_slot, int& have_piece, error_code& error) int piece_manager::check_files(int& current_slot, int& have_piece, error_code& error, boost::uint32_t *post_flags)
{ {
if (m_state == state_none) return check_no_fastresume(error); if (m_state == state_none) return check_no_fastresume(error);
@ -1110,7 +1110,7 @@ namespace libtorrent
TORRENT_ASSERT(m_state == state_full_check); TORRENT_ASSERT(m_state == state_full_check);
if (m_state == state_finished) return 0; if (m_state == state_finished) return 0;
int skip = check_one_piece(have_piece); int skip = check_one_piece(have_piece, post_flags);
TORRENT_ASSERT(m_current_slot <= m_files.num_pieces()); TORRENT_ASSERT(m_current_slot <= m_files.num_pieces());
if (skip == -1) if (skip == -1)
@ -1147,7 +1147,7 @@ namespace libtorrent
} }
// -1 = error, 0 = ok, >0 = skip this many pieces // -1 = error, 0 = ok, >0 = skip this many pieces
int piece_manager::check_one_piece(int& have_piece) int piece_manager::check_one_piece(int& have_piece, boost::uint32_t *post_flags)
{ {
// ------------------------ // ------------------------
// DO THE FULL CHECK // DO THE FULL CHECK
@ -1161,7 +1161,7 @@ namespace libtorrent
int num_read = 0; int num_read = 0;
int piece_size = m_files.piece_size(m_current_slot); int piece_size = m_files.piece_size(m_current_slot);
num_read = hash_for_slot(m_current_slot, &hash_ok, piece_size); num_read = hash_for_slot(m_current_slot, &hash_ok, post_flags, piece_size);
if (!hash_ok) if (!hash_ok)
{ {

48
libtorrent/src/torrent.cpp

@ -908,7 +908,7 @@ namespace libtorrent
} }
} }
void torrent::get_pieces(std::vector<std::string> *pieces, int count, int max_id, int since_id, void torrent::get_pieces(std::vector<std::string> *pieces, int count, int max_id, int since_id, uint32_t filter_flags,
mutex *mut, condition_variable *cond, int *reqs) mutex *mut, condition_variable *cond, int *reqs)
{ {
if( !m_picker ) return; if( !m_picker ) return;
@ -919,7 +919,8 @@ namespace libtorrent
int piece_size = m_torrent_file->piece_size(0); int piece_size = m_torrent_file->piece_size(0);
for( int i = max_id; i >= 0 && i > since_id && (*reqs) < count; i--) { for( int i = max_id; i >= 0 && i > since_id && (*reqs) < count; i--) {
if( m_picker->have_piece(i) ) { if( m_picker->have_piece(i) &&
(m_picker->post_flags(i) & filter_flags) == m_picker->post_flags(i) ) {
(*reqs)++; (*reqs)++;
peer_request r; peer_request r;
@ -1176,7 +1177,7 @@ namespace libtorrent
picker().mark_as_writing(block, 0); picker().mark_as_writing(block, 0);
async_verify_piece(piece, boost::bind(&torrent::piece_finished async_verify_piece(piece, boost::bind(&torrent::piece_finished
, shared_from_this(), piece, _1, p.length)); , shared_from_this(), piece, _1, _2, p.length));
picker().dec_refcount(piece, 0); picker().dec_refcount(piece, 0);
} }
@ -1642,6 +1643,8 @@ namespace libtorrent
// if we marked an entire piece as finished, we actually // if we marked an entire piece as finished, we actually
// need to consider it finished // need to consider it finished
/* [MF] FIXME: not sure what to do - download queue on resume?
=> the problem is the missing (new) parameter of we_have()
std::vector<piece_picker::downloading_piece> const& dq std::vector<piece_picker::downloading_piece> const& dq
= m_picker->get_download_queue(); = m_picker->get_download_queue();
@ -1660,6 +1663,7 @@ namespace libtorrent
{ {
we_have(*i); we_have(*i);
} }
*/
} }
m_storage->async_check_fastresume(&m_resume_entry m_storage->async_check_fastresume(&m_resume_entry
@ -1838,22 +1842,10 @@ namespace libtorrent
char const* pieces_str = pieces->string_ptr(); char const* pieces_str = pieces->string_ptr();
for (int i = 0, end(pieces->string_length()); i < end; ++i) for (int i = 0, end(pieces->string_length()); i < end; ++i)
{ {
if (pieces_str[i] & 1) we_have(i); if (pieces_str[i] & 1) we_have(i, pieces_str[i]>>1);
if (m_seed_mode && (pieces_str[i] & 2)) m_verified.set_bit(i); if (m_seed_mode && (pieces_str[i] & 2)) m_verified.set_bit(i);
} }
} }
else
{
lazy_entry const* slots = m_resume_entry.dict_find("slots");
if (slots && slots->type() == lazy_entry::list_t)
{
for (int i = 0; i < slots->list_size(); ++i)
{
int piece = slots->list_int_value_at(i, -1);
if (piece >= 0) we_have(piece);
}
}
}
// parse unfinished pieces // parse unfinished pieces
int num_blocks_per_piece = int num_blocks_per_piece =
@ -1888,7 +1880,7 @@ namespace libtorrent
m_picker->mark_as_finished(piece_block(piece, block), 0); m_picker->mark_as_finished(piece_block(piece, block), 0);
if (m_picker->is_piece_finished(piece)) if (m_picker->is_piece_finished(piece))
async_verify_piece(piece, boost::bind(&torrent::piece_finished async_verify_piece(piece, boost::bind(&torrent::piece_finished
, shared_from_this(), piece, _1, 0)); , shared_from_this(), piece, _1, _2, 0));
} }
} }
} }
@ -2038,7 +2030,7 @@ namespace libtorrent
TORRENT_ASSERT(m_picker); TORRENT_ASSERT(m_picker);
if (j.offset >= 0 && !m_picker->have_piece(j.offset)) if (j.offset >= 0 && !m_picker->have_piece(j.offset))
{ {
we_have(j.offset); we_have(j.offset, j.post_flags);
remove_time_critical_piece(j.offset); remove_time_critical_piece(j.offset);
} }
@ -3085,7 +3077,7 @@ namespace libtorrent
// 0: success, piece passed check // 0: success, piece passed check
// -1: disk failure // -1: disk failure
// -2: piece failed check // -2: piece failed check
void torrent::piece_finished(int index, int passed_hash_check, int piece_size) void torrent::piece_finished(int index, int passed_hash_check, boost::uint32_t post_flags, int piece_size)
{ {
TORRENT_ASSERT(m_ses.is_network_thread()); TORRENT_ASSERT(m_ses.is_network_thread());
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING
@ -3119,7 +3111,7 @@ namespace libtorrent
{ {
// the following call may cause picker to become invalid // the following call may cause picker to become invalid
// in case we just became a seed // in case we just became a seed
piece_passed(index); piece_passed(index, post_flags);
// if we're in seed mode, we just acquired this piece // if we're in seed mode, we just acquired this piece
// mark it as verified // mark it as verified
if (m_seed_mode) verified(index); if (m_seed_mode) verified(index);
@ -3150,7 +3142,7 @@ namespace libtorrent
m_picker->set_piece_priority(i, 6); m_picker->set_piece_priority(i, 6);
} }
void torrent::we_have(int index) void torrent::we_have(int index, boost::uint32_t post_flags)
{ {
TORRENT_ASSERT(m_ses.is_network_thread()); TORRENT_ASSERT(m_ses.is_network_thread());
// update m_file_progress // update m_file_progress
@ -3160,10 +3152,10 @@ namespace libtorrent
remove_time_critical_piece(index, true); remove_time_critical_piece(index, true);
m_picker->we_have(index); m_picker->we_have(index, post_flags);
} }
void torrent::piece_passed(int index) void torrent::piece_passed(int index, boost::uint32_t post_flags)
{ {
// INVARIANT_CHECK; // INVARIANT_CHECK;
TORRENT_ASSERT(m_ses.is_network_thread()); TORRENT_ASSERT(m_ses.is_network_thread());
@ -3235,7 +3227,7 @@ namespace libtorrent
downloaders.clear(); downloaders.clear();
peers.clear(); peers.clear();
we_have(index); we_have(index, post_flags);
for (peer_iterator i = m_connections.begin(); i != m_connections.end();) for (peer_iterator i = m_connections.begin(); i != m_connections.end();)
{ {
@ -5323,7 +5315,7 @@ namespace libtorrent
else else
{ {
for (int i = 0, end(pieces.size()); i < end; ++i) for (int i = 0, end(pieces.size()); i < end; ++i)
pieces[i] = m_picker->have_piece(i) ? 1 : 0; pieces[i] = m_picker->have_piece(i) ? 1 + (m_picker->post_flags(i)<<1) : 0;
} }
if (m_seed_mode) if (m_seed_mode)
@ -8175,7 +8167,7 @@ namespace libtorrent
state_updated(); state_updated();
} }
void torrent::async_verify_piece(int piece_index, boost::function<void(int)> const& f) void torrent::async_verify_piece(int piece_index, boost::function<void(int, boost::uint32_t)> const& f)
{ {
TORRENT_ASSERT(m_ses.is_network_thread()); TORRENT_ASSERT(m_ses.is_network_thread());
// INVARIANT_CHECK; // INVARIANT_CHECK;
@ -8205,7 +8197,7 @@ namespace libtorrent
} }
void torrent::on_piece_verified(int ret, disk_io_job const& j void torrent::on_piece_verified(int ret, disk_io_job const& j
, boost::function<void(int)> f) , boost::function<void(int, boost::uint32_t)> f)
{ {
TORRENT_ASSERT(m_ses.is_network_thread()); TORRENT_ASSERT(m_ses.is_network_thread());
@ -8217,7 +8209,7 @@ namespace libtorrent
state_updated(); state_updated();
if (ret == -1) handle_disk_error(j); if (ret == -1) handle_disk_error(j);
f(ret); f(ret, j.post_flags);
} }
tcp::endpoint torrent::current_tracker() const tcp::endpoint torrent::current_tracker() const

8
libtorrent/src/torrent_handle.cpp

@ -238,13 +238,13 @@ namespace libtorrent
t.reset(); \ t.reset(); \
do { ses.cond.wait(l); } while(!done); } do { ses.cond.wait(l); } while(!done); }
#define TORRENT_SYNC_CALL7(x, a1, a2, a3, a4, a5, a6, a7) \ #define TORRENT_SYNC_CALL8(x, a1, a2, a3, a4, a5, a6, a7, a8) \
boost::shared_ptr<torrent> t = m_torrent.lock(); \ boost::shared_ptr<torrent> t = m_torrent.lock(); \
if (t) { \ if (t) { \
bool done = false; \ bool done = false; \
session_impl& ses = t->session(); \ session_impl& ses = t->session(); \
mutex::scoped_lock l(ses.mut); \ mutex::scoped_lock l(ses.mut); \
ses.m_io_service.dispatch(boost::bind(&fun_wrap, &done, &ses.cond, &ses.mut, boost::function<void(void)>(boost::bind(&torrent:: x, t, a1, a2, a3, a4, a5, a6, a7)))); \ ses.m_io_service.dispatch(boost::bind(&fun_wrap, &done, &ses.cond, &ses.mut, boost::function<void(void)>(boost::bind(&torrent:: x, t, a1, a2, a3, a4, a5, a6, a7, a8)))); \
t.reset(); \ t.reset(); \
do { ses.cond.wait(l); } while(!done); } do { ses.cond.wait(l); } while(!done); }
@ -823,7 +823,7 @@ namespace libtorrent
TORRENT_ASYNC_CALL1(read_piece, piece); TORRENT_ASYNC_CALL1(read_piece, piece);
} }
void torrent_handle::get_pieces(std::vector<std::string> &pieces, int count, int max_id, int since_id) const void torrent_handle::get_pieces(std::vector<std::string> &pieces, int count, int max_id, int since_id, uint32_t filter_flags) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
@ -831,7 +831,7 @@ namespace libtorrent
libtorrent::condition_variable cond; libtorrent::condition_variable cond;
int reqs = 0; int reqs = 0;
TORRENT_SYNC_CALL7(get_pieces, &pieces, count, max_id, since_id, &mut, &cond, &reqs); TORRENT_SYNC_CALL8(get_pieces, &pieces, count, max_id, since_id, filter_flags, &mut, &cond, &reqs);
mutex::scoped_lock l2(mut); mutex::scoped_lock l2(mut);
while( reqs > 0 ) { while( reqs > 0 ) {

17
src/twister.cpp

@ -597,10 +597,11 @@ bool verifySignature(std::string const &strMessage, std::string const &strUserna
return (pubkeyRec.GetID() == pubkey.GetID()); return (pubkeyRec.GetID() == pubkey.GetID());
} }
bool acceptSignedPost(char const *data, int data_size, std::string username, int seq, std::string &errmsg) bool acceptSignedPost(char const *data, int data_size, std::string username, int seq, std::string &errmsg, boost::uint32_t *flags)
{ {
bool ret = false; bool ret = false;
char errbuf[200]=""; char errbuf[200]="";
if( flags ) *flags = 0;
lazy_entry v; lazy_entry v;
int pos; int pos;
@ -645,6 +646,7 @@ bool acceptSignedPost(char const *data, int data_size, std::string username, int
std::string sig_rt = post->dict_find_string_value("sig_rt"); std::string sig_rt = post->dict_find_string_value("sig_rt");
if( rt ) { if( rt ) {
if( flags ) (*flags) |= USERPOST_FLAG_RT;
std::string username_rt = rt->dict_find_string_value("n"); std::string username_rt = rt->dict_find_string_value("n");
std::pair<char const*, int> rtbuf = rt->data_section(); std::pair<char const*, int> rtbuf = rt->data_section();
@ -655,6 +657,11 @@ bool acceptSignedPost(char const *data, int data_size, std::string username, int
sprintf(errbuf,"bad RT signature"); sprintf(errbuf,"bad RT signature");
} }
} }
lazy_entry const* dm = post->dict_find_dict("dm");
if( dm && flags ) {
(*flags) |= USERPOST_FLAG_DM;
}
} }
} }
} }
@ -948,7 +955,7 @@ Value newpostmsg(const Array& params, bool fHelp)
bencode(std::back_inserter(buf), v); bencode(std::back_inserter(buf), v);
std::string errmsg; std::string errmsg;
if( !acceptSignedPost(buf.data(),buf.size(),strUsername,k,errmsg) ) if( !acceptSignedPost(buf.data(),buf.size(),strUsername,k,errmsg,NULL) )
throw JSONRPCError(RPC_INVALID_PARAMS,errmsg); throw JSONRPCError(RPC_INVALID_PARAMS,errmsg);
torrent_handle h = startTorrentUser(strUsername); torrent_handle h = startTorrentUser(strUsername);
@ -1020,7 +1027,7 @@ Value newdirectmsg(const Array& params, bool fHelp)
bencode(std::back_inserter(buf), v); bencode(std::back_inserter(buf), v);
std::string errmsg; std::string errmsg;
if( !acceptSignedPost(buf.data(),buf.size(),strFrom,k,errmsg) ) if( !acceptSignedPost(buf.data(),buf.size(),strFrom,k,errmsg,NULL) )
throw JSONRPCError(RPC_INVALID_PARAMS,errmsg); throw JSONRPCError(RPC_INVALID_PARAMS,errmsg);
torrent_handle h = startTorrentUser(strFrom); torrent_handle h = startTorrentUser(strFrom);
@ -1055,7 +1062,7 @@ Value newrtmsg(const Array& params, bool fHelp)
bencode(std::back_inserter(buf), v); bencode(std::back_inserter(buf), v);
std::string errmsg; std::string errmsg;
if( !acceptSignedPost(buf.data(),buf.size(),strUsername,k,errmsg) ) if( !acceptSignedPost(buf.data(),buf.size(),strUsername,k,errmsg,NULL) )
throw JSONRPCError(RPC_INVALID_PARAMS,errmsg); throw JSONRPCError(RPC_INVALID_PARAMS,errmsg);
torrent_handle h = startTorrentUser(strUsername); torrent_handle h = startTorrentUser(strUsername);
@ -1112,7 +1119,7 @@ Value getposts(const Array& params, bool fHelp)
m_userTorrent[strUsername].is_valid() ){ m_userTorrent[strUsername].is_valid() ){
std::vector<std::string> pieces; std::vector<std::string> pieces;
m_userTorrent[strUsername].get_pieces(pieces, count, max_id, since_id); m_userTorrent[strUsername].get_pieces(pieces, count, max_id, since_id, USERPOST_FLAG_RT);
BOOST_FOREACH(string const& piece, pieces) { BOOST_FOREACH(string const& piece, pieces) {
lazy_entry v; lazy_entry v;

6
src/twister.h

@ -6,6 +6,10 @@
#define LIBTORRENT_PORT_OFFSET 1000 #define LIBTORRENT_PORT_OFFSET 1000
#define USERPOST_FLAG_RT 0x01
#define USERPOST_FLAG_DM 0x02
class twister class twister
{ {
public: public:
@ -18,7 +22,7 @@ void stopSessionTorrent();
std::string createSignature(std::string const &strMessage, std::string const &strUsername); std::string createSignature(std::string const &strMessage, std::string const &strUsername);
bool verifySignature(std::string const &strMessage, std::string const &strUsername, std::string const &strSign); bool verifySignature(std::string const &strMessage, std::string const &strUsername, std::string const &strSign);
bool acceptSignedPost(char const *data, int data_size, std::string username, int seq, std::string &errmsg); bool acceptSignedPost(char const *data, int data_size, std::string username, int seq, std::string &errmsg, boost::uint32_t *flags);
bool validatePostNumberForUser(std::string const &username, int k); bool validatePostNumberForUser(std::string const &username, int k);
int getBestHeight(); int getBestHeight();

Loading…
Cancel
Save