*** empty log message ***
This commit is contained in:
parent
7fe3323ced
commit
a1b50fb1e3
2
Jamfile
2
Jamfile
|
@ -26,7 +26,6 @@ REQUIREMENTS =
|
|||
|
||||
<toolset>msvc-7:<cxxflags>/Zc:wchar_t
|
||||
<toolset>msvc-7.1:<cxxflags>/Zc:wchar_t
|
||||
<toolset>msvc:<define>WIN32
|
||||
|
||||
;
|
||||
|
||||
|
@ -106,7 +105,6 @@ lib torrent
|
|||
<threading>multi
|
||||
<link>static
|
||||
# <variant>debug:<define>TORRENT_VERBOSE_LOGGING
|
||||
<define>TORRENT_ENABLE_EXTENSIONS
|
||||
: debug release
|
||||
;
|
||||
|
||||
|
|
|
@ -1112,6 +1112,9 @@ struct torrent_status
|
|||
|
||||
const std::vector<bool>* pieces;
|
||||
size_type total_done;
|
||||
|
||||
int num_seeds;
|
||||
float distributed_copies;
|
||||
};
|
||||
</pre>
|
||||
<p><tt class="literal"><span class="pre">progress</span></tt> is a value in the range [0, 1], that represents the progress of the
|
||||
|
@ -1176,6 +1179,15 @@ be slightly smaller than the other rates, but if projected over a long time
|
|||
<p><tt class="literal"><span class="pre">total_done</span></tt> is the total number of bytes of the file(s) that we have. All
|
||||
this does not necessarily has to be downloaded during this session (that's
|
||||
<tt class="literal"><span class="pre">total_download_payload</span></tt>).</p>
|
||||
<p><tt class="literal"><span class="pre">num_seeds</span></tt> is the number of peers that are seeding that this client is
|
||||
currently connected to.</p>
|
||||
<p><tt class="literal"><span class="pre">distributed_copies</span></tt> is the number of distributed copies of the torrent.
|
||||
Note that one copy may be spread out among many peers. The integer part
|
||||
tells how many copies there are currently of the rarest piece(s) among the
|
||||
peers this client is connected to. The fractional part tells the share of
|
||||
pieces that have more copies than the rarest piece(s). For example: 2.5 would
|
||||
mean that the rarest pieces have only 2 copies among the peers this torrent is
|
||||
connected to, and that 50% of all the pieces have more than two copies.</p>
|
||||
</div>
|
||||
<div class="section" id="peer-info">
|
||||
<h1><a name="peer-info">peer_info</a></h1>
|
||||
|
|
|
@ -155,29 +155,28 @@ want to disable such checks (you want to do that in a release build) you can see
|
|||
table below for which defines you can use to control the build. The ``Jamfile`` will define
|
||||
``NDEBUG`` when it's building a release build.
|
||||
|
||||
+-------------------------------+-------------------------------------------------+
|
||||
+--------------------------------+-------------------------------------------------+
|
||||
| macro | description |
|
||||
+===============================+=================================================+
|
||||
+================================+=================================================+
|
||||
| ``NDEBUG`` | If you define this macro, all asserts, |
|
||||
| | invariant checks and general debug code will be |
|
||||
| | removed. This option takes precedence over |
|
||||
| | other debug settings. |
|
||||
+-------------------------------+-------------------------------------------------+
|
||||
+--------------------------------+-------------------------------------------------+
|
||||
| ``TORRENT_VERBOSE_LOGGING`` | If you define this macro, every peer connection |
|
||||
| | will log its traffic to a log file. |
|
||||
| | This setting requires a debug build, i.e. |
|
||||
| | if you set ``NDEBUG`` aswell, no logs will be |
|
||||
| | written. |
|
||||
+-------------------------------+-------------------------------------------------+
|
||||
+--------------------------------+-------------------------------------------------+
|
||||
| ``TORRENT_STORAGE_DEBUG`` | This will enable extra expensive invariant |
|
||||
| | checks in the storage, including logging of |
|
||||
| | piece sorting. |
|
||||
+-------------------------------+-------------------------------------------------+
|
||||
| ``TORRENT_ENABLE_EXTENSIONS`` | If you want extensions to be enabled, you must |
|
||||
| | build with this define. For more information on |
|
||||
| | which extensions are currently implemented, see |
|
||||
| | extensions_. |
|
||||
+-------------------------------+-------------------------------------------------+
|
||||
+--------------------------------+-------------------------------------------------+
|
||||
| ``TORRENT_DISABLE_EXTENSIONS`` | This will disble the support for extensions. |
|
||||
| | For more information on which extensions are |
|
||||
| | currently implemented, see extensions_. |
|
||||
+--------------------------------+-------------------------------------------------+
|
||||
|
||||
|
||||
If you experience that libtorrent uses unreasonable amounts of cpu, it will definately help to
|
||||
|
@ -1154,18 +1153,16 @@ be slightly smaller than the other rates, but if projected over a long time
|
|||
this does not necessarily has to be downloaded during this session (that's
|
||||
``total_download_payload``).
|
||||
|
||||
``num_seeds`` is the number of peers that are seeding that this torrent
|
||||
currently is connected to.
|
||||
``num_seeds`` is the number of peers that are seeding that this client is
|
||||
currently connected to.
|
||||
|
||||
``distributed_copies`` is the number of distributed copies of the torrent.
|
||||
Note that one copy may be spread out among many peers. The whole number part
|
||||
Note that one copy may be spread out among many peers. The integer part
|
||||
tells how many copies there are currently of the rarest piece(s) among the
|
||||
peers this torrent is connected to. The fractional part tells the share of
|
||||
peers this client is connected to. The fractional part tells the share of
|
||||
pieces that have more copies than the rarest piece(s). For example: 2.5 would
|
||||
mean that the rarest pieces have only 2 copies among the peers this torrent is
|
||||
connected to, and that there are as many pieces that have 2 copies as there are
|
||||
pieces that have more than two copies.
|
||||
|
||||
connected to, and that 50% of all the pieces have more than two copies.
|
||||
|
||||
|
||||
peer_info
|
||||
|
|
|
@ -233,14 +233,15 @@ void print_peer_info(std::ostream& out, std::vector<libtorrent::peer_info> const
|
|||
// << "ul:" << add_suffix(i->upload_limit) << "/s "
|
||||
// << "uc:" << add_suffix(i->upload_ceiling) << "/s "
|
||||
// << "df:" << ratio(i->total_download, i->total_upload) << " "
|
||||
<< i->download_queue_length << " "
|
||||
<< i->upload_queue_length << " "
|
||||
<< to_string(i->download_queue_length, 2) << " "
|
||||
<< to_string(i->upload_queue_length, 2) << " "
|
||||
<< static_cast<const char*>((i->flags & peer_info::interesting)?"I":"_")
|
||||
<< static_cast<const char*>((i->flags & peer_info::choked)?"C":"_")
|
||||
<< static_cast<const char*>((i->flags & peer_info::remote_interested)?"i":"_")
|
||||
<< static_cast<const char*>((i->flags & peer_info::remote_choked)?"c":"_")
|
||||
<< static_cast<const char*>((i->flags & peer_info::supports_extensions)?"e":"_")
|
||||
<< static_cast<const char*>((i->flags & peer_info::local_connection)?"l":"r");
|
||||
<< static_cast<const char*>((i->flags & peer_info::local_connection)?"l":"r") << " "
|
||||
<< identify_client(i->id);
|
||||
|
||||
if (i->downloading_piece_index >= 0)
|
||||
{
|
||||
|
@ -279,7 +280,7 @@ int main(int argc, char* argv[])
|
|||
try
|
||||
{
|
||||
std::vector<torrent_handle> handles;
|
||||
session ses(fingerprint("LT", 0, 1, 0, 0));
|
||||
session ses;
|
||||
|
||||
ses.listen_on(std::make_pair(6881, 6889));
|
||||
ses.set_upload_rate_limit(512 * 1024);
|
||||
|
|
|
@ -109,6 +109,9 @@ namespace libtorrent
|
|||
tracker_request m_req;
|
||||
std::string m_password;
|
||||
int m_code;
|
||||
|
||||
// server string in http-reply
|
||||
std::string m_server;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -90,16 +90,17 @@ namespace libtorrent
|
|||
friend class invariant_access;
|
||||
public:
|
||||
|
||||
// this is the constructor where the we are teh active part. The peer_conenction
|
||||
// should handshake and verify that the other end has the correct id
|
||||
// this is the constructor where the we are teh active part.
|
||||
// The peer_conenction should handshake and verify that the
|
||||
// other end has the correct id
|
||||
peer_connection(
|
||||
detail::session_impl& ses
|
||||
, selector& sel
|
||||
, torrent* t
|
||||
, boost::shared_ptr<libtorrent::socket> s);
|
||||
|
||||
// with this constructor we have been contacted and we still don't know which torrent the
|
||||
// connection belongs to
|
||||
// with this constructor we have been contacted and we still don't
|
||||
// know which torrent the connection belongs to
|
||||
peer_connection(
|
||||
detail::session_impl& ses
|
||||
, selector& sel
|
||||
|
@ -501,6 +502,15 @@ namespace libtorrent
|
|||
// this is set to the current time each time we get a
|
||||
// "I don't have metadata" message.
|
||||
boost::posix_time::ptime m_no_metadata;
|
||||
|
||||
// this is set to the time when we last sent
|
||||
// a request for metadata to this peer
|
||||
boost::posix_time::ptime m_metadata_request;
|
||||
|
||||
// this is set to true when we send a metadata
|
||||
// request to this peer, and reset to false when
|
||||
// we receive a reply to our request.
|
||||
bool m_waiting_metadata_request;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,14 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifndef TORRENT_RESOURCE_REQUEST_HPP_INCLUDED
|
||||
#define TORRENT_RESOURCE_REQUEST_HPP_INCLUDED
|
||||
|
||||
#ifdef min
|
||||
#undef min
|
||||
#endif
|
||||
|
||||
#ifdef max
|
||||
#undef max
|
||||
#endif
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
struct resource_request
|
||||
|
|
|
@ -330,7 +330,15 @@ namespace libtorrent
|
|||
bool valid_metadata() const { return m_storage.get() != 0; }
|
||||
std::vector<char> const& metadata() const { return m_metadata; }
|
||||
|
||||
bool received_metadata(char const* buf, int size, int offset, int total_size);
|
||||
bool received_metadata(
|
||||
char const* buf
|
||||
, int size
|
||||
, int offset
|
||||
, int total_size);
|
||||
|
||||
// returns a range of the metadata that
|
||||
// we should request.
|
||||
std::pair<int, int> metadata_request();
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -336,7 +336,8 @@ namespace libtorrent
|
|||
{
|
||||
std::string error_msg = boost::lexical_cast<std::string>(m_code)
|
||||
+ " " + m_server_message;
|
||||
if (requester()) requester()->tracker_request_error(m_code, error_msg.c_str());
|
||||
if (requester()) requester()->tracker_request_error(
|
||||
m_code, error_msg.c_str());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -346,12 +347,14 @@ namespace libtorrent
|
|||
if (received <= 0)
|
||||
{
|
||||
if (requester())
|
||||
requester()->tracker_request_error(-1, "invalid tracker response, connection closed while reading header");
|
||||
requester()->tracker_request_error(-1, "invalid tracker "
|
||||
"response, connection closed while reading header");
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<char>::iterator end = m_buffer.begin()+m_recv_pos;
|
||||
std::vector<char>::iterator newline = std::find(m_buffer.begin(), end, '\n');
|
||||
std::vector<char>::iterator newline
|
||||
= std::find(m_buffer.begin(), end, '\n');
|
||||
std::string line;
|
||||
|
||||
while (newline != end && m_state == read_header)
|
||||
|
@ -366,7 +369,8 @@ namespace libtorrent
|
|||
{
|
||||
try
|
||||
{
|
||||
m_content_length = boost::lexical_cast<int>(line.substr(16));
|
||||
m_content_length = boost::lexical_cast<int>(
|
||||
line.substr(16));
|
||||
}
|
||||
catch(boost::bad_lexical_cast&)
|
||||
{
|
||||
|
@ -420,6 +424,10 @@ namespace libtorrent
|
|||
{
|
||||
m_location.assign(line.begin() + 10, line.end());
|
||||
}
|
||||
else if (line.substr(0, 7) == "Server: ")
|
||||
{
|
||||
m_server.assign(line.begin() + 7, line.end());
|
||||
}
|
||||
else if (line.size() < 3)
|
||||
{
|
||||
m_state = read_body;
|
||||
|
|
|
@ -71,35 +71,19 @@ namespace
|
|||
boost::optional<fingerprint> parse_az_style(const peer_id& id)
|
||||
{
|
||||
fingerprint ret("..", 0, 0, 0, 0);
|
||||
peer_id::const_iterator i = id.begin();
|
||||
|
||||
if (*i != '-') return boost::optional<fingerprint>();
|
||||
++i;
|
||||
if (id[0] != '-' || !std::isprint(id[1]) || !std::isprint(id[2])
|
||||
|| !std::isalnum(id[3]) || !std::isalnum(id[4])
|
||||
|| !std::isalnum(id[5]) || !std::isalnum(id[6])
|
||||
|| id[7] != '-')
|
||||
return boost::optional<fingerprint>();
|
||||
|
||||
for (int j = 0; j < 2; ++j)
|
||||
{
|
||||
if (!std::isprint(*i)) return boost::optional<fingerprint>();
|
||||
ret.id[j] = *i;
|
||||
++i;
|
||||
}
|
||||
|
||||
if (!std::isalnum(*i)) return boost::optional<fingerprint>();
|
||||
ret.major_version = decode_digit(*i);
|
||||
++i;
|
||||
|
||||
if (!std::isalnum(*i)) return boost::optional<fingerprint>();
|
||||
ret.minor_version = decode_digit(*i);
|
||||
++i;
|
||||
|
||||
if (!std::isalnum(*i)) return boost::optional<fingerprint>();
|
||||
ret.revision_version = decode_digit(*i);
|
||||
++i;
|
||||
|
||||
if (!std::isalnum(*i)) return boost::optional<fingerprint>();
|
||||
ret.tag_version = decode_digit(*i);
|
||||
++i;
|
||||
|
||||
if (*i != '-') return boost::optional<fingerprint>();
|
||||
ret.id[0] = id[1];
|
||||
ret.id[1] = id[2];
|
||||
ret.major_version = decode_digit(id[3]);
|
||||
ret.minor_version = decode_digit(id[4]);
|
||||
ret.revision_version = decode_digit(id[5]);
|
||||
ret.tag_version = decode_digit(id[6]);
|
||||
|
||||
return boost::optional<fingerprint>(ret);
|
||||
}
|
||||
|
@ -109,41 +93,30 @@ namespace
|
|||
boost::optional<fingerprint> parse_shadow_style(const peer_id& id)
|
||||
{
|
||||
fingerprint ret("..", 0, 0, 0, 0);
|
||||
peer_id::const_iterator i = id.begin();
|
||||
|
||||
if (!std::isalnum(*i)) return boost::optional<fingerprint>();
|
||||
ret.id[0] = *i;
|
||||
ret.id[1] = 0;
|
||||
++i;
|
||||
if (!std::isalnum(id[0]))
|
||||
return boost::optional<fingerprint>();
|
||||
|
||||
if (std::equal(id.begin()+4, id.begin()+8, "----"))
|
||||
{
|
||||
if (!std::isalnum(*i)) return boost::optional<fingerprint>();
|
||||
ret.major_version = decode_digit(*i);
|
||||
++i;
|
||||
|
||||
if (!std::isalnum(*i)) return boost::optional<fingerprint>();
|
||||
ret.minor_version = decode_digit(*i);
|
||||
++i;
|
||||
|
||||
if (!std::isalnum(*i)) return boost::optional<fingerprint>();
|
||||
ret.revision_version = decode_digit(*i);
|
||||
}
|
||||
else if (id[8] == 0)
|
||||
{
|
||||
if (*i > 127) return boost::optional<fingerprint>();
|
||||
ret.major_version = *i;
|
||||
++i;
|
||||
|
||||
if (*i > 127) return boost::optional<fingerprint>();
|
||||
ret.minor_version = *i;
|
||||
++i;
|
||||
|
||||
if (*i > 127) return boost::optional<fingerprint>();
|
||||
ret.revision_version = *i;
|
||||
if (!std::isalnum(id[1]) || !std::isalnum(id[2])
|
||||
|| !std::isalnum(id[3]))
|
||||
return boost::optional<fingerprint>();
|
||||
ret.major_version = decode_digit(id[1]);
|
||||
ret.minor_version = decode_digit(id[2]);
|
||||
ret.revision_version = decode_digit(id[3]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (id[8] != 0 || id[1] > 127 || id[2] > 127 || id[3] > 127)
|
||||
return boost::optional<fingerprint>();
|
||||
ret.major_version = id[1];
|
||||
ret.minor_version = id[2];
|
||||
ret.revision_version = id[3];
|
||||
}
|
||||
|
||||
ret.id[0] = id[0];
|
||||
ret.id[1] = 0;
|
||||
|
||||
ret.tag_version = 0;
|
||||
return boost::optional<fingerprint>(ret);
|
||||
|
@ -153,39 +126,79 @@ namespace
|
|||
// identification
|
||||
boost::optional<fingerprint> parse_mainline_style(const peer_id& id)
|
||||
{
|
||||
if (!std::isprint(id[0])
|
||||
|| !std::isalnum(id[1])
|
||||
|| id[2] != '-'
|
||||
|| !std::isalnum(id[3])
|
||||
|| id[4] != '-'
|
||||
|| !std::isalnum(id[5])
|
||||
|| !std::equal(id.begin() + 6, id.begin() + 8, "--"))
|
||||
return boost::optional<fingerprint>();
|
||||
|
||||
fingerprint ret("..", 0, 0, 0, 0);
|
||||
peer_id::const_iterator i = id.begin();
|
||||
|
||||
if (!std::isprint(*i)) return boost::optional<fingerprint>();
|
||||
ret.id[0] = *i;
|
||||
ret.id[0] = id[0];
|
||||
ret.id[1] = 0;
|
||||
++i;
|
||||
|
||||
if (!std::isalnum(*i)) return boost::optional<fingerprint>();
|
||||
ret.major_version = decode_digit(*i);
|
||||
++i;
|
||||
|
||||
if (*i != '-') return boost::optional<fingerprint>();
|
||||
++i;
|
||||
|
||||
if (!std::isalnum(*i)) return boost::optional<fingerprint>();
|
||||
ret.minor_version = decode_digit(*i);
|
||||
++i;
|
||||
|
||||
if (*i != '-') return boost::optional<fingerprint>();
|
||||
++i;
|
||||
|
||||
if (!std::isalnum(*i)) return boost::optional<fingerprint>();
|
||||
ret.revision_version = decode_digit(*i);
|
||||
++i;
|
||||
|
||||
if (!std::equal(i, i+1, "--")) return boost::optional<fingerprint>();
|
||||
|
||||
ret.major_version = decode_digit(id[1]);
|
||||
ret.minor_version = decode_digit(id[3]);
|
||||
ret.revision_version = decode_digit(id[5]);
|
||||
ret.tag_version = 0;
|
||||
return boost::optional<fingerprint>(ret);
|
||||
}
|
||||
|
||||
} // namespace unnamed
|
||||
typedef std::pair<char const*, char const*> map_entry;
|
||||
|
||||
// must be ordered alphabetically
|
||||
map_entry name_map[] =
|
||||
{
|
||||
map_entry("A", "ABC")
|
||||
, map_entry("AZ", "Azureus")
|
||||
, map_entry("BX", "BittorrentX")
|
||||
, map_entry("LT", "libtorrent")
|
||||
, map_entry("M", "Mainline")
|
||||
, map_entry("MT", "Moonlight Torrent")
|
||||
, map_entry("S", "Shadow")
|
||||
, map_entry("SS", "SwarmScope")
|
||||
, map_entry("T", "BitTornado")
|
||||
, map_entry("TN", "TorrentDonNet")
|
||||
, map_entry("TS", "TorrentStorm")
|
||||
, map_entry("U", "UPnP")
|
||||
, map_entry("XT", "XanTorrent")
|
||||
};
|
||||
|
||||
bool compare_first_string(map_entry const& e, char const* str)
|
||||
{
|
||||
return e.first[0] < str[0]
|
||||
|| ((e.first[0] == str[0]) && (e.first[1] < str[1]));
|
||||
}
|
||||
|
||||
std::string lookup(fingerprint const& f)
|
||||
{
|
||||
std::stringstream identity;
|
||||
|
||||
const int size = sizeof(name_map)/sizeof(name_map[0]);
|
||||
map_entry* i =
|
||||
std::lower_bound(name_map, name_map + size
|
||||
, f.id, &compare_first_string);
|
||||
|
||||
if (i < name_map + size && std::equal(f.id, f.id + 2, i->first))
|
||||
identity << i->second;
|
||||
else
|
||||
identity << std::string(f.id, f.id + 2);
|
||||
|
||||
identity << " " << (int)f.major_version
|
||||
<< "." << (int)f.minor_version
|
||||
<< "." << (int)f.revision_version
|
||||
<< "." << (int)f.tag_version;
|
||||
|
||||
return identity.str();
|
||||
}
|
||||
|
||||
bool find_string(unsigned char const* id, char const* search)
|
||||
{
|
||||
return std::equal(search, search + std::strlen(search), id);
|
||||
}
|
||||
}
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
@ -199,178 +212,48 @@ namespace libtorrent
|
|||
|
||||
// look for azureus style id
|
||||
f = parse_az_style(p);
|
||||
if (f)
|
||||
{
|
||||
std::stringstream identity;
|
||||
|
||||
// azureus
|
||||
if (std::equal(f->id, f->id+2, "AZ"))
|
||||
identity << "Azureus ";
|
||||
|
||||
// BittorrentX
|
||||
else if (std::equal(f->id, f->id+2, "BX"))
|
||||
identity << "BittorrentX ";
|
||||
|
||||
// libtorrent
|
||||
else if (std::equal(f->id, f->id+2, "LT"))
|
||||
identity << "libtorrent ";
|
||||
|
||||
// Moonlight Torrent
|
||||
else if (std::equal(f->id, f->id+2, "MT"))
|
||||
identity << "Moonlight Torrent ";
|
||||
|
||||
// Torrent Storm
|
||||
else if (std::equal(f->id, f->id+2, "TS"))
|
||||
identity << "TorrentStorm ";
|
||||
|
||||
// SwarmScope
|
||||
else if (std::equal(f->id, f->id+2, "SS"))
|
||||
identity << "SwarmScope ";
|
||||
|
||||
// XanTorrent
|
||||
else if (std::equal(f->id, f->id+2, "XT"))
|
||||
identity << "XanTorrent ";
|
||||
|
||||
// TorrentDotNet
|
||||
else if (std::equal(f->id, f->id+2, "TN"))
|
||||
identity << "TorrentDotNET ";
|
||||
|
||||
// unknown client
|
||||
else
|
||||
identity << std::string(f->id, f->id+2) << " ";
|
||||
|
||||
identity << (int)f->major_version
|
||||
<< "." << (int)f->minor_version
|
||||
<< "." << (int)f->revision_version
|
||||
<< "." << (int)f->tag_version;
|
||||
|
||||
return identity.str();
|
||||
}
|
||||
|
||||
if (f) return lookup(*f);
|
||||
|
||||
// look for shadow style id
|
||||
f = parse_shadow_style(p);
|
||||
if (f)
|
||||
{
|
||||
std::stringstream identity;
|
||||
|
||||
// Shadow
|
||||
if (std::equal(f->id, f->id+1, "S"))
|
||||
identity << "Shadow ";
|
||||
|
||||
// ABC
|
||||
else if (std::equal(f->id, f->id+1, "A"))
|
||||
identity << "ABC ";
|
||||
|
||||
// UPnP
|
||||
else if (std::equal(f->id, f->id+1, "U"))
|
||||
identity << "UPnP ";
|
||||
|
||||
// BitTornado
|
||||
else if (std::equal(f->id, f->id+1, "T"))
|
||||
identity << "BitTornado ";
|
||||
|
||||
// unknown client
|
||||
else
|
||||
identity << std::string(f->id, f->id+1) << " ";
|
||||
|
||||
identity << (int)f->major_version
|
||||
<< "." << (int)f->minor_version
|
||||
<< "." << (int)f->revision_version;
|
||||
|
||||
return identity.str();
|
||||
}
|
||||
if (f) return lookup(*f);
|
||||
|
||||
// look for mainline style id
|
||||
f = parse_mainline_style(p);
|
||||
if (f)
|
||||
{
|
||||
std::stringstream identity;
|
||||
|
||||
// Mainline
|
||||
if (std::equal(f->id, f->id+1, "M"))
|
||||
identity << "Mainline ";
|
||||
|
||||
// unknown client
|
||||
else
|
||||
identity << std::string(f->id, f->id+1) << " ";
|
||||
|
||||
identity << (int)f->major_version
|
||||
<< "." << (int)f->minor_version
|
||||
<< "." << (int)f->revision_version;
|
||||
|
||||
return identity.str();
|
||||
}
|
||||
if (f) return lookup(*f);
|
||||
|
||||
// ----------------------
|
||||
// non standard encodings
|
||||
// ----------------------
|
||||
|
||||
if (std::equal(PID, PID + 12, "-G3g3rmz "))
|
||||
{
|
||||
return "G3 Torrent";
|
||||
}
|
||||
|
||||
if (std::equal(PID, PID + 4, "exbc"))
|
||||
{
|
||||
std::stringstream s;
|
||||
s << "BitComet " << (int)PID[4] << "." << (int)PID[5]/10 << (int)PID[5]%10;
|
||||
return s.str();
|
||||
}
|
||||
|
||||
if (std::equal(PID + 5, PID + 5 + 8, "Azureus"))
|
||||
{
|
||||
return "Azureus 2.0.3.2";
|
||||
}
|
||||
|
||||
if (std::equal(PID, PID + 11, "DansClient"))
|
||||
{
|
||||
return "XanTorrent";
|
||||
}
|
||||
|
||||
if (std::equal(PID, PID + 7, "Plus---"))
|
||||
{
|
||||
return "Bittorrent Plus";
|
||||
}
|
||||
|
||||
if (std::equal(PID, PID + 16, "Deadman Walking-"))
|
||||
{
|
||||
return "Deadman";
|
||||
}
|
||||
|
||||
if (std::equal(PID, PID + 7, "btuga"))
|
||||
{
|
||||
return "BTugaXP";
|
||||
}
|
||||
|
||||
if (std::equal(PID, PID + 7, "btfans"))
|
||||
{
|
||||
return "SimpleBT";
|
||||
}
|
||||
|
||||
if (std::equal(PID, PID + 7, "turbobt")
|
||||
&& std::isalnum(PID[8])
|
||||
&& std::isalnum(PID[10])
|
||||
&& std::isalnum(PID[12]))
|
||||
{
|
||||
std::stringstream s;
|
||||
s << "TurboBT " << PID[8] << "." << PID[10] << "." << PID[12];
|
||||
return s.str();
|
||||
}
|
||||
if (find_string(PID, "Deadman Walking-")) return "Deadman";
|
||||
if (find_string(PID + 5, "Azureus")) return "Azureus 2.0.3.2";
|
||||
if (find_string(PID, "DansClient")) return "XanTorrent";
|
||||
if (find_string(PID + 4, "btfans")) return "SimpleBT";
|
||||
if (find_string(PID, "PRC.P---")) return "Bittorrent Plus! II";
|
||||
if (find_string(PID, "P87.P---")) return "Bittorrent Plus!";
|
||||
if (find_string(PID, "S587Plus")) return "Bittorrent Plus!";
|
||||
if (find_string(PID, "martini")) return "Martini Man";
|
||||
if (find_string(PID, "Plus---")) return "Bittorrent Plus";
|
||||
if (find_string(PID, "turbobt")) return "TurboBT";
|
||||
if (find_string(PID, "BTDWV-")) return "Deadman Walking";
|
||||
if (find_string(PID + 2, "BS")) return "BitSpirit";
|
||||
if (find_string(PID, "btuga")) return "BTugaXP";
|
||||
if (find_string(PID, "oernu")) return "BTugaXP";
|
||||
if (find_string(PID, "Mbrst")) return "Burst!";
|
||||
if (find_string(PID, "Plus")) return "Plus!";
|
||||
if (find_string(PID, "exbc")) return "BitComet";
|
||||
if (find_string(PID, "-G3")) return "G3 Torrent";
|
||||
if (find_string(PID, "XBT")) return "XBT";
|
||||
|
||||
if (std::equal(PID, PID + 13, "\0\0\0\0\0\0\0\0\0\0\0\0\x97"))
|
||||
{
|
||||
return "Experimental 3.2.1b2";
|
||||
}
|
||||
|
||||
if (std::equal(PID, PID + 13, "\0\0\0\0\0\0\0\0\0\0\0\0\0"))
|
||||
{
|
||||
return "Experimental 3.1";
|
||||
}
|
||||
|
||||
if (std::equal(PID, PID + 12, "\0\0\0\0\0\0\0\0\0\0\0\0"))
|
||||
{
|
||||
return "Generic";
|
||||
}
|
||||
|
||||
std::string unknown("Unknown [");
|
||||
for (peer_id::const_iterator i = p.begin(); i != p.end(); ++i)
|
||||
|
|
|
@ -117,6 +117,10 @@ namespace libtorrent
|
|||
, m_no_metadata(
|
||||
boost::gregorian::date(1970, boost::date_time::Jan, 1)
|
||||
, boost::posix_time::seconds(0))
|
||||
, m_metadata_request(
|
||||
boost::gregorian::date(1970, boost::date_time::Jan, 1)
|
||||
, boost::posix_time::seconds(0))
|
||||
, m_waiting_metadata_request(false)
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
|
@ -190,6 +194,10 @@ namespace libtorrent
|
|||
, m_no_metadata(
|
||||
boost::gregorian::date(1970, boost::date_time::Jan, 1)
|
||||
, boost::posix_time::seconds(0))
|
||||
, m_metadata_request(
|
||||
boost::gregorian::date(1970, boost::date_time::Jan, 1)
|
||||
, boost::posix_time::seconds(0))
|
||||
, m_waiting_metadata_request(false)
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
|
@ -402,7 +410,7 @@ namespace libtorrent
|
|||
, m_send_buffer.begin() + pos + 8
|
||||
, 0);
|
||||
// indicate that we support the extension protocol
|
||||
#ifdef TORRENT_ENABLE_EXTENSIONS
|
||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||
m_send_buffer[pos+7] = 0x01;
|
||||
#endif
|
||||
pos += 8;
|
||||
|
@ -1059,6 +1067,9 @@ namespace libtorrent
|
|||
entry e = bdecode(m_recv_buffer.begin()+1, m_recv_buffer.end());
|
||||
#ifndef NDEBUG
|
||||
entry::dictionary_type& extensions = e.dict();
|
||||
std::stringstream ext;
|
||||
e.print(ext);
|
||||
(*m_logger) << ext.str();
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < num_supported_extensions; ++i)
|
||||
|
@ -1078,13 +1089,6 @@ namespace libtorrent
|
|||
(*m_logger) << i->first << "\n";
|
||||
}
|
||||
#endif
|
||||
// TODO: move the requesting into second-tick
|
||||
// of the torrent.
|
||||
if (!m_torrent->valid_metadata()
|
||||
&& supports_extension(extended_metadata_message))
|
||||
{
|
||||
send_metadata_request(0, 256);
|
||||
}
|
||||
}
|
||||
catch(invalid_encoding&)
|
||||
{
|
||||
|
@ -1216,11 +1220,13 @@ namespace libtorrent
|
|||
if (offset + data_size > total_size)
|
||||
throw protocol_error("invalid metadata message");
|
||||
|
||||
m_waiting_metadata_request = false;
|
||||
m_torrent->received_metadata(&m_recv_buffer[5+9], data_size, offset, total_size);
|
||||
}
|
||||
break;
|
||||
case 2: // have no data
|
||||
m_no_metadata = boost::posix_time::second_clock::local_time();
|
||||
m_waiting_metadata_request = false;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1680,6 +1686,22 @@ namespace libtorrent
|
|||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
// if we don't have any metadata, and this peer
|
||||
// supports the request metadata extension
|
||||
// and we aren't currently waiting for a request
|
||||
// reply.
|
||||
if (!m_torrent->valid_metadata()
|
||||
&& supports_extension(extended_metadata_message)
|
||||
&& !m_waiting_metadata_request)
|
||||
{
|
||||
assert(m_torrent);
|
||||
std::pair<int, int> req = m_torrent->metadata_request();
|
||||
send_metadata_request(req.first, req.second);
|
||||
m_waiting_metadata_request = true;
|
||||
m_metadata_request = boost::posix_time::second_clock::local_time();
|
||||
}
|
||||
|
||||
|
||||
m_statistics.second_tick();
|
||||
m_ul_bandwidth_quota.used = std::min(
|
||||
(int)ceil(statistics().upload_rate())
|
||||
|
@ -1694,7 +1716,7 @@ namespace libtorrent
|
|||
// maintain the share ratio given by m_ratio
|
||||
// with all peers.
|
||||
|
||||
if (m_torrent->is_seed() || is_choked() || m_torrent->ratio()==0.0f)
|
||||
if (m_torrent->is_seed() || is_choked() || m_torrent->ratio() == 0.0f)
|
||||
{
|
||||
// if we have downloaded more than one piece more
|
||||
// than we have uploaded OR if we are a seed
|
||||
|
@ -1901,7 +1923,7 @@ namespace libtorrent
|
|||
// these 8 bytes would be used to describe the
|
||||
// extensions available on the other side
|
||||
// currently disabled
|
||||
#ifdef TORRENT_ENABLE_EXTENSIONS
|
||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||
if (m_recv_buffer[7] & 0x01)
|
||||
m_supports_extensions = true;
|
||||
#endif
|
||||
|
|
|
@ -237,6 +237,7 @@ namespace libtorrent { namespace detail
|
|||
try
|
||||
{
|
||||
// create listener socket
|
||||
m_selector.remove(m_listen_socket);
|
||||
m_listen_socket = boost::shared_ptr<socket>(new socket(socket::tcp, false));
|
||||
|
||||
for(;;)
|
||||
|
@ -872,7 +873,7 @@ namespace libtorrent
|
|||
return torrent_handle(&m_impl, &m_checker_impl, ti.info_hash());
|
||||
}
|
||||
|
||||
#ifdef TORRENT_ENABLE_EXTENSIONS
|
||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||
torrent_handle session::add_torrent(
|
||||
char const* tracker_url
|
||||
, sha1_hash const& info_hash
|
||||
|
|
|
@ -980,7 +980,11 @@ namespace libtorrent
|
|||
, m_have_metadata.begin() + start + block_size
|
||||
, true);
|
||||
|
||||
bool have_all = std::count(m_have_metadata.begin(), m_have_metadata.end(), true) == 255;
|
||||
bool have_all = std::count(
|
||||
m_have_metadata.begin()
|
||||
, m_have_metadata.end()
|
||||
, true) == 255;
|
||||
|
||||
if (!have_all) return false;
|
||||
|
||||
hasher h;
|
||||
|
@ -993,8 +997,6 @@ namespace libtorrent
|
|||
m_have_metadata.begin()
|
||||
, m_have_metadata.end() + start + block_size
|
||||
, false);
|
||||
// TODO: rerequest
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1020,18 +1022,26 @@ namespace libtorrent
|
|||
m_picker->integrity_check(this);
|
||||
#endif
|
||||
|
||||
|
||||
// clear the storage for the bitfield
|
||||
{
|
||||
std::vector<bool> t1;
|
||||
m_have_metadata.swap(t1);
|
||||
std::vector<int> t2;
|
||||
m_requested_metadata.swap(t2);
|
||||
}
|
||||
std::vector<bool>().swap(m_have_metadata);
|
||||
std::vector<int>().swap(m_requested_metadata);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::pair<int, int> torrent::metadata_request()
|
||||
{
|
||||
// TODO: count the peers that supports the
|
||||
// metadata extension
|
||||
// check to see if we know how big the metadata
|
||||
// is (if m_metadata.size() > 0)
|
||||
std::pair<int, int> ret(0, 256);
|
||||
|
||||
for (int i = ret.first; i < ret.first + ret.second; ++i)
|
||||
m_requested_metadata[i]++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void torrent::tracker_request_timed_out()
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
|
|
Loading…
Reference in New Issue