*** empty log message ***

This commit is contained in:
Arvid Norberg 2004-01-17 20:04:19 +00:00
parent a75f327fee
commit 4d33080399
13 changed files with 239 additions and 101 deletions

View File

@ -12,14 +12,16 @@
<h1 class="title">libtorrent</h1>
<table border class="table">
<colgroup>
<col width="37%" />
<col width="13%" />
<col width="26%" />
<col width="19%" />
<col width="19%" />
<col width="15%" />
<col width="21%" />
<col width="29%" />
</colgroup>
<tbody valign="top">
<tr><td><a class="reference" href="http://www.sourceforge.net/projects/libtorrent">sourceforge page</a></td>
<td><a class="reference" href="manual.html">manual</a></td>
<td><a class="reference" href="manual.html">documentation</a></td>
<td><a class="reference" href="http://sourceforge.net/tracker/?group_id=79942&amp;atid=558250">report bugs</a></td>
<td><a class="reference" href="libtorrent_screen.png">screenshot</a></td>
<td><a class="reference" href="http://lists.sourceforge.net/lists/listinfo/libtorrent-discuss">mailing list</a></td>
</tr>
@ -37,9 +39,22 @@ example client.</p>
<li>to be very easy to use</li>
</ul>
</blockquote>
<div class="section" id="donate">
<h1><a name="donate">Donate</a></h1>
<p>Support the development of libtorrent</p>
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top">
<input type="hidden" name="cmd" value="_xclick">
<input type="hidden" name="business" value="c99ang@cs.umu.se">
<input type="hidden" name="item_name" value="libtorrent">
<input type="hidden" name="return" value="http://libtorrent.sf.net">
<input type="hidden" name="currency_code" value="EUR">
<input type="hidden" name="tax" value="0">
<input type="image" src="https://www.paypal.com/images/x-click-but04.gif"
border="0" name="submit" alt="Make payments with PayPal - it's fast, free and secure!">
</form></div>
<div class="section" id="feedback">
<h1><a name="feedback">Feedback</a></h1>
<p>There's a <a class="reference" href="http://lists.sourceforge.net/lists/listinfo/libtorrent-discuss">mailing list</a>.</p>
<p>There's a <a class="reference" href="http://lists.sourceforge.net/lists/listinfo/libtorrent-discuss">mailing list</a>, general libtorrent discussion.</p>
<p>You can usually find me as hydri in <tt class="literal"><span class="pre">#btports</span> <span class="pre">&#64;</span> <span class="pre">irc.freenode.net</span></tt>.</p>
</div>
<div class="section" id="aknowledgements">

View File

@ -3,12 +3,13 @@ libtorrent
==========
=================== ======= =========== ===============
`sourceforge page`_ manual_ screenshot_ `mailing list`_
=================== ======= =========== ===============
=================== ============== ============== =========== ===============
`sourceforge page`_ documentation_ `report bugs`_ screenshot_ `mailing list`_
=================== ============== ============== =========== ===============
.. _sourceforge page: http://www.sourceforge.net/projects/libtorrent
.. _manual: manual.html
.. _documentation: manual.html
.. _`report bugs`: http://sourceforge.net/tracker/?group_id=79942&atid=558250
.. _screenshot: libtorrent_screen.png
.. _mailing list: http://lists.sourceforge.net/lists/listinfo/libtorrent-discuss
@ -26,17 +27,36 @@ The main goals of libtorrent are:
* to be very easy to use
Donate
======
Support the development of libtorrent
.. raw:: html
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top">
<input type="hidden" name="cmd" value="_xclick">
<input type="hidden" name="business" value="c99ang@cs.umu.se">
<input type="hidden" name="item_name" value="libtorrent">
<input type="hidden" name="return" value="http://libtorrent.sf.net">
<input type="hidden" name="currency_code" value="EUR">
<input type="hidden" name="tax" value="0">
<input type="image" src="https://www.paypal.com/images/x-click-but04.gif"
border="0" name="submit" alt="Make payments with PayPal - it's fast, free and secure!">
</form>
Feedback
========
There's a `mailing list`__.
There's a `mailing list`__, general libtorrent discussion.
__ http://lists.sourceforge.net/lists/listinfo/libtorrent-discuss
You can usually find me as hydri in ``#btports @ irc.freenode.net``.
Aknowledgements
===============

View File

@ -101,7 +101,7 @@ party.</li>
of a resumed torrent. Saves the storage state, piece_picker state as well as all local
peers in a separate fast-resume file.</li>
<li>Supports the extension protocol <a class="reference" href="http://nolar.com/azureus/extended.htm">described by Nolar</a>. See <a class="reference" href="#extensions">extensions</a>.</li>
<li>SUpports files &gt; 2 gigabytes (currently only on windows)</li>
<li>Supports files &gt; 2 gigabytes (currently only on windows)</li>
</ul>
</blockquote>
<p>Functions that are yet to be implemented:</p>
@ -133,6 +133,9 @@ boost.filesystem, boost.date_time and various other boost libraries as well as z
</div>
<div class="section" id="building">
<h1><a class="toc-backref" href="#id10" name="building">building</a></h1>
<p>Whwn building in release mode you need to define NDEBUG in order to avoid
all asserts and invariant checks within libtorrent. Developer studio does
this by default.</p>
<p>To build libtorrent you need <a class="reference" href="http://www.boost.org">boost</a> and bjam installed.
Then you can use <tt class="literal"><span class="pre">bjam</span></tt> to build libtorrent.</p>
<p>To make bjam work, you need to set the environment variable <tt class="literal"><span class="pre">BOOST_ROOT</span></tt> to the
@ -253,7 +256,7 @@ change in the future to give more control of the listen-port.</em></p>
</div>
<div class="section" id="parsing-torrent-files">
<h1><a class="toc-backref" href="#id13" name="parsing-torrent-files">parsing torrent files</a></h1>
<p>The torrent files are <a class="reference" href="http://bitconjurer.org/BitTorrent/protocol.html">bencoded</a>. There are two functions in libtorrent that can encode and decode
<p>The torrent files are <a class="reference" href="http://wiki.theory.org/index.php/BitTorrentSpecification">bencoded</a>. There are two functions in libtorrent that can encode and decode
bencoded data. They are:</p>
<pre class="literal-block">
template&lt;class InIt&gt; entry bdecode(InIt start, InIt end);
@ -537,6 +540,7 @@ struct torrent_status
state_t state;
float progress;
boost::posix_time::time_duration next_announce;
boost::posix_time::time_duration announce_interval;
std::size_t total_download;
std::size_t total_upload;
@ -587,7 +591,9 @@ is a pure seeder.</td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">next_announce</span></tt> is the time until the torrent will announce itself to the tracker.</p>
<p><tt class="literal"><span class="pre">next_announce</span></tt> is the time until the torrent will announce itself to the tracker. And
<tt class="literal"><span class="pre">announce_interval</span></tt> is the time the tracker want us to wait until we announce ourself
again the next time.</p>
<p><tt class="literal"><span class="pre">total_download</span></tt> and <tt class="literal"><span class="pre">total_upload</span></tt> is the number of bytes downloaded and
uploaded to all peers, accumulated, <em>this session</em> only.</p>
<p><tt class="literal"><span class="pre">total_payload_download</span></tt> and <tt class="literal"><span class="pre">total_payload_upload</span></tt> counts the amount of bytes

View File

@ -73,6 +73,11 @@ libtorrent is released under the BSD-license_.
building
========
Whwn building in release mode you need to define NDEBUG in order to avoid
all asserts and invariant checks within libtorrent. Developer studio does
this by default.
To build libtorrent you need boost_ and bjam installed.
Then you can use ``bjam`` to build libtorrent.
@ -220,7 +225,7 @@ bencoded data. They are::
template<class InIt> entry bdecode(InIt start, InIt end);
template<class OutIt> void bencode(OutIt out, const entry& e);
__ http://bitconjurer.org/BitTorrent/protocol.html
__ http://wiki.theory.org/index.php/BitTorrentSpecification
The entry_ class is the internal representation of the bencoded data
@ -548,6 +553,7 @@ It contains the following fields::
state_t state;
float progress;
boost::posix_time::time_duration next_announce;
boost::posix_time::time_duration announce_interval;
std::size_t total_download;
std::size_t total_upload;
@ -593,7 +599,9 @@ current task is in the ``state`` member, it will be one of the following:
| | |
+--------------------------+----------------------------------------------------------+
``next_announce`` is the time until the torrent will announce itself to the tracker.
``next_announce`` is the time until the torrent will announce itself to the tracker. And
``announce_interval`` is the time the tracker want us to wait until we announce ourself
again the next time.
``total_download`` and ``total_upload`` is the number of bytes downloaded and
uploaded to all peers, accumulated, *this session* only.

View File

@ -38,6 +38,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include <boost/format.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/bind.hpp>
#include "libtorrent/entry.hpp"
#include "libtorrent/bencode.hpp"
@ -56,7 +57,7 @@ POSSIBILITY OF SUCH DAMAGE.
bool sleep_and_input(char* c)
{
Sleep(200);
Sleep(500);
if (kbhit())
{
*c = getch();
@ -116,7 +117,7 @@ bool sleep_and_input(char* c)
fd_set set;
FD_ZERO(&set);
FD_SET(0, &set);
timeval tv = {0, 200000};
timeval tv = {0, 500000};
if (select(1, &set, 0, 0, &tv) > 0)
{
*c = getc(stdin);
@ -220,7 +221,7 @@ int main(int argc, char* argv[])
// settings.proxy_port = 80;
// settings.proxy_login = "hyd";
// settings.proxy_password = "foobar";
settings.user_agent = "example";
settings.user_agent = "client_test";
std::deque<std::string> events;
@ -229,7 +230,6 @@ int main(int argc, char* argv[])
std::vector<torrent_handle> handles;
session ses(6881);
// // 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);
@ -293,9 +293,13 @@ int main(int argc, char* argv[])
break;
}
if(c==' ')
if(c == 'r')
{
events.pop_back();
// force reannounce on all torrents
std::for_each(
handles.begin()
, handles.end()
, boost::bind(&torrent_handle::force_reannounce, _1));
}
}

View File

@ -49,8 +49,20 @@ namespace libtorrent
{
struct piece_checker_data;
}
class session;
typedef boost::int64_t size_type;
std::vector<size_type> get_filesizes(
const torrent_info& t
, const boost::filesystem::path& p);
bool match_filesizes(
const torrent_info& t
, const boost::filesystem::path& p
, const std::vector<size_type>& sizes);
struct file_allocation_failed: std::exception
{
file_allocation_failed(const char* error_msg): m_msg(error_msg) {}

View File

@ -92,6 +92,9 @@ namespace libtorrent
state_t state;
float progress;
boost::posix_time::time_duration next_announce;
boost::posix_time::time_duration announce_interval;
// TODO: add name of tracker that is currently used
// transferred this session!
// total, payload plus protocol

View File

@ -1527,6 +1527,8 @@ namespace libtorrent
assert(m_send_quota_left != 0);
if (m_send_quota_left > 0)
amount_to_send = std::min(m_send_quota_left, amount_to_send);
// we have data that's scheduled for sending
int sent = m_socket->send(
&m_send_buffer[0]
@ -1540,6 +1542,7 @@ namespace libtorrent
m_send_quota_left -= sent;
}
// manage the payload markers
int amount_payload = 0;
if (!m_payloads.empty())
{
@ -1596,6 +1599,7 @@ namespace libtorrent
assert(m_added_to_selector);
send_buffer_updated();
/*
#ifndef NDEBUG
if (has_data())
{
@ -1605,6 +1609,7 @@ namespace libtorrent
}
}
#endif
*/
}

View File

@ -719,8 +719,19 @@ namespace libtorrent
// called when a peer is no longer interested in us
void policy::not_interested(peer_connection& c)
{
// TODO: return the diff() of this peer to the
// pool of undistributed free upload
if (m_torrent->ratio() != 0.f)
{
assert(c.share_diff() < std::numeric_limits<int>::max());
int diff = c.share_diff();
if (diff > 0 && c.is_seed())
{
// the peer is a seed and has sent
// us more than we have sent it back.
// consider the download as free download
m_available_free_upload += diff;
c.add_free_upload(-diff);
}
}
}
bool policy::unchoke_one_peer()

View File

@ -44,6 +44,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include <boost/filesystem/convenience.hpp>
#include <boost/filesystem/exception.hpp>
#include <boost/limits.hpp>
#include <boost/bind.hpp>
#include "libtorrent/peer_id.hpp"
#include "libtorrent/torrent_info.hpp"
@ -935,6 +936,24 @@ namespace libtorrent
if (hash != real_hash)
return;
// the peers
entry::list_type& peer_list = rd.dict()["peers"].list();
std::vector<address> tmp_peers;
tmp_peers.reserve(peer_list.size());
for (entry::list_type::iterator i = peer_list.begin();
i != peer_list.end();
++i)
{
address a(i->dict()["ip"].string(), i->dict()["port"].integer());
tmp_peers.push_back(a);
}
peers.swap(tmp_peers);
// read piece map
const entry::list_type& slots = rd.dict()["slots"].list();
if (slots.size() > info.num_pieces())
@ -990,21 +1009,19 @@ namespace libtorrent
tmp_unfinished.push_back(p);
}
// the peers
// verify file sizes
entry::list_type& peer_list = rd.dict()["peers"].list();
std::vector<size_type> file_sizes;
entry::list_type& l = rd.dict()["file sizes"].list();
std::transform(
l.begin()
, l.end()
, std::back_inserter(file_sizes)
, boost::bind(&entry::integer, _1));
std::vector<address> tmp_peers;
tmp_peers.reserve(peer_list.size());
for (entry::list_type::iterator i = peer_list.begin();
i != peer_list.end();
++i)
{
address a(i->dict()["ip"].string(), i->dict()["port"].integer());
tmp_peers.push_back(a);
}
if (!match_filesizes(info, save_path, file_sizes))
return;
peers.swap(tmp_peers);
piece_map.swap(tmp_pieces);
unfinished_pieces.swap(tmp_unfinished);
}

View File

@ -81,14 +81,6 @@ namespace {
}
};
void print_bitmask(const std::vector<bool>& x)
{
for (std::size_t i = 0; i < x.size(); ++i)
{
std::cout << x[i];
}
}
} // namespace unnamed
namespace fs = boost::filesystem;
@ -104,7 +96,43 @@ namespace {
}
namespace libtorrent {
namespace libtorrent
{
std::vector<size_type> get_filesizes(
const torrent_info& t
, const boost::filesystem::path& p)
{
std::vector<size_type> sizes;
for (torrent_info::file_iterator i = t.begin_files();
i != t.end_files();
++i)
{
file f(p / i->path / i->filename, file::in);
f.seek(0, file::end);
sizes.push_back(f.tell());
}
return sizes;
}
bool match_filesizes(
const torrent_info& t
, const boost::filesystem::path& p
, const std::vector<size_type>& sizes)
{
if (sizes.size() != t.num_files()) return false;
std::vector<size_type>::const_iterator s = sizes.begin();
for (torrent_info::file_iterator i = t.begin_files();
i != t.end_files();
++i, ++s)
{
file f(p / i->path / i->filename, file::in);
f.seek(0, file::end);
if (f.tell() != *s) return false;
}
return true;
}
struct thread_safe_storage
{
@ -394,10 +422,10 @@ namespace libtorrent {
// returns the slot currently associated with the given
// piece or assigns the given piece_index to a free slot
int slot_for_piece(int piece_index);
#ifndef NDEBUG
void check_invariant() const;
void debug_log() const;
#endif
storage m_storage;
// total number of bytes left to be downloaded
@ -464,9 +492,9 @@ namespace libtorrent {
// synchronization ------------------------------------------------------
boost::recursive_mutex::scoped_lock lock(m_mutex);
// ----------------------------------------------------------------------
#ifndef NDEBUG
check_invariant();
#endif
p.clear();
std::vector<int>::const_reverse_iterator last;
for (last = m_slot_to_piece.rbegin();
@ -484,8 +512,9 @@ namespace libtorrent {
p.push_back(*i);
}
#ifndef NDEBUG
check_invariant();
#endif
}
void piece_manager::export_piece_map(
@ -586,8 +615,10 @@ namespace libtorrent {
const std::size_t last_piece_size = m_info.piece_size(
m_info.num_pieces() - 1);
// if we have fast-resume info
// use it instead of doingthe actual checking
// use it instead of doing the actual checking
if (!data.piece_map.empty()
&& data.piece_map.size() <= m_slot_to_piece.size())
{
@ -630,6 +661,9 @@ namespace libtorrent {
return;
}
// do the real check (we didn't have valid resume data)
bool changed_file = true;
// fs::ifstream in;
file in;
@ -675,26 +709,6 @@ namespace libtorrent {
if (changed_file)
{
/*
in.close();
in.clear();
in.open(path, std::ios_base::binary);
changed_file = false;
bytes_current_read = seek_into_next;
if (!in)
{
filesize = 0;
}
else
{
in.seekg(0, std::ios_base::end);
filesize = in.tellg();
in.seekg(seek_into_next, std::ios_base::beg);
}
*/
try
{
changed_file = false;
@ -709,7 +723,6 @@ namespace libtorrent {
{
filesize = 0;
}
}
// we are at the start of a new piece
@ -721,8 +734,6 @@ namespace libtorrent {
if (filesize > 0)
{
// in.read(&piece_data[piece_offset], bytes_to_read);
// bytes_read = in.gcount();
bytes_read = in.read(&piece_data[piece_offset], bytes_to_read);
}
@ -832,16 +843,28 @@ namespace libtorrent {
bytes_to_read = m_info.piece_size(current_slot);
}
std::cout << " m_free_slots: " << m_free_slots.size() << "\n";
std::cout << " m_unallocated_slots: " << m_unallocated_slots.size() << "\n";
std::cout << " num pieces: " << m_info.num_pieces() << "\n";
#ifndef NDEBUG
std::stringstream s;
std::cout << " have_pieces: ";
print_bitmask(pieces);
std::cout << "\n";
std::cout << std::count(pieces.begin(), pieces.end(), true) << "\n";
s << " m_free_slots: " << m_free_slots.size() << "\n"
" m_unallocated_slots: " << m_unallocated_slots.size() << "\n"
" num pieces: " << m_info.num_pieces() << "\n"
" have_pieces:\n";
for (std::vector<bool>::iterator i = pieces.begin();
i != pieces.end();
++i)
{
if (((i - pieces.begin()) % 60) == 0) s << "\n";
if (*i) s << "1"; else s << "0";
}
s << "\n";
s << std::count(pieces.begin(), pieces.end(), true) << "\n";
data.torrent_ptr->debug_log(s.str());
#endif
#ifndef NDEBUG
check_invariant();
#endif
}
void piece_manager::check_pieces(
@ -858,7 +881,9 @@ namespace libtorrent {
boost::recursive_mutex::scoped_lock lock(m_mutex);
// ----------------------------------------------------------------------
#ifndef NDEBUG
check_invariant();
#endif
assert(piece_index >= 0 && piece_index < m_piece_to_slot.size());
assert(m_piece_to_slot.size() == m_slot_to_piece.size());
@ -870,7 +895,9 @@ namespace libtorrent {
assert(slot_index >= 0);
assert(slot_index < m_slot_to_piece.size());
#ifndef NDEBUG
check_invariant();
#endif
return slot_index;
}
@ -918,6 +945,7 @@ namespace libtorrent {
if (slot_index != piece_index
&& m_slot_to_piece[piece_index] >= 0)
{
#ifndef NDEBUG
std::stringstream s;
s << "there is another piece at our slot, swapping..";
@ -929,18 +957,13 @@ namespace libtorrent {
s << "\n piece at our slot: ";
s << m_slot_to_piece[piece_index];
s << "\n";
#endif
int piece_at_our_slot = m_slot_to_piece[piece_index];
assert(m_piece_to_slot[piece_at_our_slot] == piece_index);
#ifndef NDEBUG
print_to_log(s.str());
debug_log();
std::vector<char> buf(m_info.piece_length());
m_storage.read(&buf[0], piece_index, 0, m_info.piece_length());
m_storage.write(&buf[0], slot_index, 0, m_info.piece_length());
#endif
std::swap(
m_slot_to_piece[piece_index]
, m_slot_to_piece[slot_index]);
@ -949,16 +972,22 @@ namespace libtorrent {
m_piece_to_slot[piece_index]
, m_piece_to_slot[piece_at_our_slot]);
std::vector<char> buf(m_info.piece_length());
m_storage.read(&buf[0], piece_index, 0, m_info.piece_length());
m_storage.write(&buf[0], slot_index, 0, m_info.piece_length());
assert(m_slot_to_piece[piece_index] == piece_index);
assert(m_piece_to_slot[piece_index] == piece_index);
slot_index = piece_index;
#ifndef NDEBUG
debug_log();
#endif
}
#ifndef NDEBUG
check_invariant();
#endif
return slot_index;
}
@ -977,7 +1006,9 @@ namespace libtorrent {
boost::recursive_mutex::scoped_lock lock(m_mutex);
// ----------------------------------------------------------------------
#ifndef NDEBUG
check_invariant();
#endif
namespace fs = boost::filesystem;
@ -1019,7 +1050,9 @@ namespace libtorrent {
m_allocating = false;
#ifndef NDEBUG
check_invariant();
#endif
}
void piece_manager::allocate_slots(int num_slots)
@ -1031,7 +1064,8 @@ namespace libtorrent {
{
return m_pimpl->save_path();
}
#ifndef NDEBUG
void piece_manager::impl::check_invariant() const
{
// synchronization ------------------------------------------------------
@ -1101,6 +1135,6 @@ namespace libtorrent {
print_to_log(s.str());
}
#endif
} // namespace libtorrent

View File

@ -426,11 +426,6 @@ namespace libtorrent
std::vector<address> downloaders;
m_picker.get_downloaders(downloaders, index);
#ifndef NDEBUG
// std::cout << "hash-test failed. Some of these peers sent invalid data:\n";
// std::copy(downloaders.begin(), downloaders.end(), std::ostream_iterator<peer_id>(std::cout, "\n"));
#endif
// decrease the trust point of all peers that sent
// parts of this piece.
for (std::vector<address>::iterator i = downloaders.begin();
@ -587,8 +582,6 @@ namespace libtorrent
peer_lost(*i);
}
// std::cout << p->get_socket()->sender().as_string() << " *** DISCONNECT\n";
m_policy->connection_closed(*p);
m_connections.erase(i);
@ -623,7 +616,6 @@ namespace libtorrent
m_ses.m_selector.monitor_readability(s);
m_ses.m_selector.monitor_errors(s);
// std::cout << "connecting to: " << a.as_string() << ":" << a.port() << "\n";
return *c;
}
@ -792,6 +784,8 @@ namespace libtorrent
st.next_announce = next_announce()
- boost::posix_time::second_clock::local_time();
st.announce_interval = boost::posix_time::seconds(m_duration);
st.num_peers = m_connections.size();

View File

@ -252,6 +252,15 @@ namespace libtorrent
peer_list.push_back(peer);
}
std::vector<size_type> file_sizes
= get_filesizes(t->torrent_file(), t->save_path());
ret.dict()["file sizes"] = entry::list_type();
std::copy(
file_sizes.begin()
, file_sizes.end()
, std::back_inserter(ret.dict()["file sizes"].list()));
return ret;
}