*** empty log message ***

This commit is contained in:
Arvid Norberg 2004-01-08 13:03:38 +00:00
parent 99db2c6395
commit cfe5da0588
5 changed files with 120 additions and 133 deletions

View File

@ -189,8 +189,8 @@ int main(int argc, char* argv[])
std::vector<torrent_handle> handles;
session ses(6881);
// limit upload rate to 100 kB/s
ses.set_upload_rate_limit(100 * 1024);
// limit global upload rate to 30 kB/s
ses.set_upload_rate_limit(30 * 1024);
ses.set_http_settings(settings);
ses.set_severity_level(alert::debug);
@ -216,7 +216,7 @@ int main(int argc, char* argv[])
{}
handles.push_back(ses.add_torrent(t, "", resume_data));
handles.back().set_max_uploads(40);
handles.back().set_max_uploads(7);
}
catch (std::exception& e)
{

View File

@ -59,18 +59,6 @@ POSSIBILITY OF SUCH DAMAGE.
// a chance to request another block instead.
// Where it also could become not-interested.
// TODO: maybe there should be some kind of
// per-torrent free-upload counter. All free
// download we get is put in there and increases
// the amount of free upload we give. The free upload
// could be distributed to the interest peers
// depending on amount we have downloaded from
// the peer and depending on the share ratio.
// there's no point in giving free upload to
// peers we can trade with. Maybe the free upload
// only should be given to those we are not interested
// in?
namespace libtorrent
{
class torrent;
@ -138,23 +126,6 @@ namespace libtorrent
protocol_error(const std::string& msg): std::runtime_error(msg) {};
};
struct chat_message_alert: alert
{
chat_message_alert(const torrent_handle& h
, const peer_id& send
, const std::string& msg)
: alert(alert::critical, msg)
, handle(h)
, sender(send)
{}
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new chat_message_alert(*this)); }
torrent_handle handle;
peer_id sender;
};
struct peer_request
{
int piece;
@ -179,6 +150,46 @@ namespace libtorrent
int full_block_bytes;
};
struct chat_message_alert: alert
{
chat_message_alert(
const torrent_handle& h
, const peer_id& send
, const std::string& msg)
: alert(alert::critical, msg)
, handle(h)
, sender(send)
{}
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new chat_message_alert(*this)); }
torrent_handle handle;
peer_id sender;
};
// TODO: document
struct invalid_request_alert: alert
{
invalid_request_alert(
const peer_request& r
, const torrent_handle& h
, const peer_id& send
, const std::string& msg)
: alert(alert::debug, msg)
, handle(h)
, sender(send)
, request(r)
{}
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new invalid_request_alert(*this)); }
torrent_handle handle;
peer_id sender;
peer_request request;
};
class peer_connection: public boost::noncopyable
{
public:
@ -259,6 +270,8 @@ namespace libtorrent
// which torrent it should be associated with
torrent* associated_torrent() const throw() { return m_attached_to_torrent?m_torrent:0; }
bool verify_piece(const peer_request& p) const;
const stat& statistics() const { return m_statistics; }
// is called once every second by the main loop

View File

@ -246,6 +246,22 @@ namespace libtorrent
send_buffer_updated();
}
// verifies a piece to see if it is valid (is within a valid range)
// and if it can correspond to a request generated by libtorrent.
bool peer_connection::verify_piece(const peer_request& p) const
{
return p.piece >= 0
&& p.piece < m_torrent->torrent_file().num_pieces()
&& p.length > 0
&& p.start >= 0
&& (p.length == m_torrent->block_size()
|| (p.length < m_torrent->block_size()
&& p.piece == m_torrent->torrent_file().num_pieces()-1
&& p.start + p.length == m_torrent->torrent_file().piece_size(p.piece)))
&& p.start + p.length <= m_torrent->torrent_file().piece_size(p.piece)
&& p.start % m_torrent->block_size() == 0;
}
boost::optional<piece_block_progress> peer_connection::downloading_piece() const
{
// are we currently receiving a 'piece' message?
@ -255,26 +271,21 @@ namespace libtorrent
return boost::optional<piece_block_progress>();
const char* ptr = &m_recv_buffer[1];
int piece_index = detail::read_int(ptr);
int offset = detail::read_int(ptr);
int len = m_packet_size - 9;
peer_request r;
r.piece = detail::read_int(ptr);
r.start = detail::read_int(ptr);
r.length = m_packet_size - 9;
// is any of the piece message header data invalid?
// TODO: make sure that len is == block_size or less only
// if its's the last block.
if (piece_index < 0
|| piece_index >= m_torrent->torrent_file().num_pieces()
|| offset < 0
|| offset + len > m_torrent->torrent_file().piece_size(piece_index)
|| offset % m_torrent->block_size() != 0)
if (!verify_piece(r))
return boost::optional<piece_block_progress>();
piece_block_progress p;
p.piece_index = piece_index;
p.block_index = offset / m_torrent->block_size();
p.piece_index = r.piece;
p.block_index = r.start / m_torrent->block_size();
p.bytes_downloaded = m_recv_pos - 9;
p.full_block_bytes = len;
p.full_block_bytes = r.length;
return boost::optional<piece_block_progress>(p);
}
@ -376,6 +387,7 @@ namespace libtorrent
void peer_connection::on_have(int received)
{
// TODO: if we're a seed, and this peer becomes a seed, disconnect
if (m_packet_size != 5)
throw protocol_error("'have' message size != 5");
m_statistics.received_bytes(0, received);
@ -454,11 +466,19 @@ namespace libtorrent
interesting = true;
}
if (piece_list.empty())
if (piece_list.size() == m_have_piece.size())
{
#ifndef NDEBUG
(*m_logger) << m_socket->sender().as_string() << " *** THIS IS A SEED ***\n";
(*m_logger) << " *** THIS IS A SEED ***\n";
#endif
// if we're a seed too, disconnect
if (m_torrent->is_seed())
{
#ifndef NDEBUG
(*m_logger) << " we're also a seed, disconnecting\n";
#endif
throw network_error(0);
}
}
if (interesting) m_torrent->get_policy().peer_is_interesting(*this);
@ -514,7 +534,14 @@ namespace libtorrent
"t: " << (int)m_torrent->torrent_file().piece_size(r.piece) << " | "
"n: " << m_torrent->torrent_file().num_pieces() << " ]\n";
#endif
// TODO: log this illegal request
if (m_torrent->alerts().should_post(alert::debug))
{
m_torrent->alerts().post_alert(invalid_request_alert(
r
, m_torrent->get_handle()
, m_peer_id
, "peer sent an illegal request, ignoring"));
}
}
}
@ -524,6 +551,8 @@ namespace libtorrent
void peer_connection::on_piece(int received)
{
// classify the received data as protocol chatter
// or data payload for the statistics
if (m_recv_pos <= 9)
// only received protocol data
m_statistics.received_bytes(0, received);
@ -544,66 +573,29 @@ namespace libtorrent
if (m_recv_pos < m_packet_size) return;
const char* ptr = &m_recv_buffer[1];
int index = detail::read_int(ptr);
if (index < 0 || index >= m_torrent->torrent_file().num_pieces())
{
#ifndef NDEBUG
(*m_logger) << m_socket->sender().as_string() << " piece index invalid\n";
#endif
throw protocol_error("invalid piece index in piece message");
}
int offset = detail::read_int(ptr);
int len = m_packet_size - 9;
peer_request p;
p.piece = detail::read_int(ptr);
p.start = detail::read_int(ptr);
p.length = m_packet_size - 9;
if (offset < 0)
if (!verify_piece(p))
{
#ifndef NDEBUG
(*m_logger) << m_socket->sender().as_string() << " offset < 0\n";
(*m_logger) << " <== INVALID_PIECE [ piece: " << p.piece << " | "
"start: " << p.start << " | "
"length: " << p.length << " ]\n";
#endif
throw protocol_error("offset < 0 in piece message");
throw protocol_error("invalid piece packet");
}
if (offset + len > m_torrent->torrent_file().piece_size(index))
{
#ifndef NDEBUG
(*m_logger) << m_socket->sender().as_string() << " piece packet contains more data than the piece size\n";
#endif
throw protocol_error("piece message contains more data than the piece size");
}
// TODO: make sure that len is == block_size or less only
// if its's the last block.
if (offset % m_torrent->block_size() != 0)
{
#ifndef NDEBUG
(*m_logger) << m_socket->sender().as_string() << " piece packet contains unaligned offset\n";
#endif
throw protocol_error("piece message contains unaligned offset");
}
/*
piece_block req = m_download_queue.front();
if (req.piece_index != index)
{
#ifndef NDEBUG
(*m_logger) << m_socket->sender().as_string() << " piece packet contains unrequested index\n";
#endif
return false;
}
if (req.block_index != offset / m_torrent->block_size())
{
#ifndef NDEBUG
(*m_logger) << m_socket->sender().as_string() << " piece packet contains unrequested offset\n";
#endif
return false;
}
*/
#ifndef NDEBUG
(*m_logger) << m_socket->sender().as_string() << " <== PIECE [ piece: " << index << " | s: " << offset << " | l: " << len << " ]\n";
(*m_logger) << " <== PIECE [ piece: " << p.piece << " | "
"s: " << p.start << " | "
"l: " << p.length << " ]\n";
#endif
piece_picker& picker = m_torrent->picker();
piece_block block_finished(index, offset / m_torrent->block_size());
piece_block block_finished(p.piece, p.start / m_torrent->block_size());
std::deque<piece_block>::iterator b
= std::find(
@ -626,25 +618,25 @@ namespace libtorrent
// if the block we got is already finished, then ignore it
if (picker.is_finished(block_finished)) return;
m_torrent->filesystem().write(&m_recv_buffer[9], index, offset, len);
m_torrent->filesystem().write(&m_recv_buffer[9], p.piece, p.start, p.length);
picker.mark_as_finished(block_finished, m_peer_id);
m_torrent->get_policy().block_finished(*this, block_finished);
// did we just finish the piece?
if (picker.is_piece_finished(index))
if (picker.is_piece_finished(p.piece))
{
bool verified = m_torrent->verify_piece(index);
bool verified = m_torrent->verify_piece(p.piece);
if (verified)
{
m_torrent->announce_piece(index);
m_torrent->announce_piece(p.piece);
}
else
{
m_torrent->piece_failed(index);
m_torrent->piece_failed(p.piece);
}
m_torrent->get_policy().piece_finished(index, verified);
m_torrent->get_policy().piece_finished(p.piece, verified);
}
}
@ -711,12 +703,6 @@ namespace libtorrent
m_extension_messages[i] = f->second.integer();
}
}
// TODO: temporary
// if (m_extension_messages[extended_chat_message] != -1)
// {
// send_chat_message("Hi, this is a test chat message");
// }
}
catch(invalid_encoding& e)
{
@ -869,6 +855,7 @@ namespace libtorrent
send_buffer_updated();
}
// TODO: should this be renamed to 'send_request()'?
void peer_connection::request_block(piece_block block)
{
assert(block.piece_index >= 0);
@ -905,6 +892,12 @@ namespace libtorrent
#ifndef NDEBUG
(*m_logger) << " ==> REQUEST [ piece: " << block.piece_index << " | s: " << block_offset << " | l: " << block_size << " | " << block.block_index << " ]\n";
peer_request r;
r.piece = block.piece_index;
r.start = block_offset;
r.length = block_size;
assert(verify_piece(r));
#endif
send_buffer_updated();
@ -1029,6 +1022,10 @@ namespace libtorrent
void peer_connection::send_have(int index)
{
// optimization, don't send have messages
// to peers that already have the piece
if (m_have_piece[index]) return;
const int packet_size = 9;
char msg[packet_size] = {0,0,0,5,msg_have};
char* ptr = msg+5;

View File

@ -247,24 +247,6 @@ namespace
namespace libtorrent
{
/*
TODO: make two proxy classes that filter out
all unneccesary members from torrent and peer_connection
to make it easier to use them in the policy
useful member functions:
void torrent::connect_to_peer(address, peer_id);
piece_picker& torrent::picker();
std::vector<peer_connection*>::const_iterator torrent::begin() const
std::vector<peer_connection*>::const_iterator torrent::end() const
void peer_connection::interested();
void peer_connection::not_interested();
void peer_connection::choke();
void peer_connection::unchoke();
void peer_connection::request_piece(int index);
const std::vector<int>& peer_connection::download_queue();
TODO: implement some kind of limit of the number of sockets
opened, to use for systems where a user has a limited number
of open file descriptors. and for windows which has a buggy tcp-stack.
@ -565,8 +547,6 @@ namespace libtorrent
i->connection->not_interested();
}
}
// TODO: if verification failed, mark the peers that were involved
// in some way
}
// TODO: we must be able to get interested

View File

@ -63,8 +63,6 @@ namespace std
};
#endif
// TODO: enable floating point exceptions in debug mode!
namespace
{
@ -886,7 +884,6 @@ namespace libtorrent
m_impl.m_alerts.set_severity(s);
}
// TODO: store resume data as an entry instead
void detail::piece_checker_data::parse_resume_data(
const entry& resume_data
, const torrent_info& info)