447 lines
12 KiB
C++
Executable File
447 lines
12 KiB
C++
Executable File
/*
|
|
|
|
Copyright (c) 2003, Arvid Norberg
|
|
All rights reserved.
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
modification, are permitted provided that the following conditions
|
|
are met:
|
|
|
|
* Redistributions of source code must retain the above copyright
|
|
notice, this list of conditions and the following disclaimer.
|
|
* Redistributions in binary form must reproduce the above copyright
|
|
notice, this list of conditions and the following disclaimer in
|
|
the documentation and/or other materials provided with the distribution.
|
|
* Neither the name of the author nor the names of its
|
|
contributors may be used to endorse or promote products derived
|
|
from this software without specific prior written permission.
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
#ifndef TORRENT_TORRENT_HANDLE_HPP_INCLUDED
|
|
#define TORRENT_TORRENT_HANDLE_HPP_INCLUDED
|
|
|
|
#include <vector>
|
|
#include <set>
|
|
|
|
#ifdef _MSC_VER
|
|
#pragma warning(push, 1)
|
|
#endif
|
|
|
|
#include <boost/date_time/posix_time/posix_time_types.hpp>
|
|
|
|
#ifdef _MSC_VER
|
|
#pragma warning(pop)
|
|
#endif
|
|
|
|
#include "libtorrent/peer_id.hpp"
|
|
#include "libtorrent/peer_info.hpp"
|
|
#include "libtorrent/piece_picker.hpp"
|
|
#include "libtorrent/torrent_info.hpp"
|
|
#include "libtorrent/time.hpp"
|
|
#include "libtorrent/config.hpp"
|
|
#include "libtorrent/storage.hpp"
|
|
|
|
namespace libtorrent
|
|
{
|
|
namespace fs = boost::filesystem;
|
|
|
|
namespace aux
|
|
{
|
|
struct session_impl;
|
|
struct checker_impl;
|
|
}
|
|
|
|
struct torrent_plugin;
|
|
|
|
struct TORRENT_EXPORT duplicate_torrent: std::exception
|
|
{
|
|
virtual const char* what() const throw()
|
|
{ return "torrent already exists in session"; }
|
|
};
|
|
|
|
struct TORRENT_EXPORT invalid_handle: std::exception
|
|
{
|
|
virtual const char* what() const throw()
|
|
{ return "invalid torrent handle used"; }
|
|
};
|
|
|
|
struct TORRENT_EXPORT torrent_status
|
|
{
|
|
torrent_status()
|
|
: state(queued_for_checking)
|
|
, paused(false)
|
|
, progress(0.f)
|
|
, total_download(0)
|
|
, total_upload(0)
|
|
, total_payload_download(0)
|
|
, total_payload_upload(0)
|
|
, total_failed_bytes(0)
|
|
, total_redundant_bytes(0)
|
|
, download_rate(0)
|
|
, upload_rate(0)
|
|
, download_payload_rate(0)
|
|
, upload_payload_rate(0)
|
|
, num_seeds(0)
|
|
, num_peers(0)
|
|
, num_complete(-1)
|
|
, num_incomplete(-1)
|
|
, list_seeds(0)
|
|
, list_peers(0)
|
|
, pieces(0)
|
|
, num_pieces(0)
|
|
, total_done(0)
|
|
, total_wanted_done(0)
|
|
, total_wanted(0)
|
|
, distributed_copies(0.f)
|
|
, block_size(0)
|
|
, num_uploads(0)
|
|
, num_connections(0)
|
|
, uploads_limit(0)
|
|
, connections_limit(0)
|
|
, storage_mode(storage_mode_sparse)
|
|
, up_bandwidth_queue(0)
|
|
, down_bandwidth_queue(0)
|
|
{}
|
|
|
|
enum state_t
|
|
{
|
|
queued_for_checking,
|
|
checking_files,
|
|
connecting_to_tracker,
|
|
downloading_metadata,
|
|
downloading,
|
|
finished,
|
|
seeding,
|
|
allocating
|
|
};
|
|
|
|
state_t state;
|
|
bool paused;
|
|
float progress;
|
|
boost::posix_time::time_duration next_announce;
|
|
boost::posix_time::time_duration announce_interval;
|
|
|
|
std::string current_tracker;
|
|
|
|
// transferred this session!
|
|
// total, payload plus protocol
|
|
size_type total_download;
|
|
size_type total_upload;
|
|
|
|
// payload only
|
|
size_type total_payload_download;
|
|
size_type total_payload_upload;
|
|
|
|
// the amount of payload bytes that
|
|
// has failed their hash test
|
|
size_type total_failed_bytes;
|
|
|
|
// the number of payload bytes that
|
|
// has been received redundantly.
|
|
size_type total_redundant_bytes;
|
|
|
|
// current transfer rate
|
|
// payload plus protocol
|
|
float download_rate;
|
|
float upload_rate;
|
|
|
|
// the rate of payload that is
|
|
// sent and received
|
|
float download_payload_rate;
|
|
float upload_payload_rate;
|
|
|
|
// the number of peers this torrent is connected to
|
|
// that are seeding.
|
|
int num_seeds;
|
|
|
|
// the number of peers this torrent
|
|
// is connected to (including seeds).
|
|
int num_peers;
|
|
|
|
// if the tracker sends scrape info in its
|
|
// announce reply, these fields will be
|
|
// set to the total number of peers that
|
|
// have the whole file and the total number
|
|
// of peers that are still downloading
|
|
int num_complete;
|
|
int num_incomplete;
|
|
|
|
// this is the number of seeds whose IP we know
|
|
// but are not necessarily connected to
|
|
int list_seeds;
|
|
|
|
// this is the number of peers whose IP we know
|
|
// (including seeds), but are not necessarily
|
|
// connected to
|
|
int list_peers;
|
|
|
|
const std::vector<bool>* pieces;
|
|
|
|
// this is the number of pieces the client has
|
|
// downloaded. it is equal to:
|
|
// std::accumulate(pieces->begin(), pieces->end());
|
|
int num_pieces;
|
|
|
|
// the number of bytes of the file we have
|
|
// including pieces that may have been filtered
|
|
// after we downloaded them
|
|
size_type total_done;
|
|
|
|
// the number of bytes we have of those that we
|
|
// want. i.e. not counting bytes from pieces that
|
|
// are filtered as not wanted.
|
|
size_type total_wanted_done;
|
|
|
|
// the total number of bytes we want to download
|
|
// this may be smaller than the total torrent size
|
|
// in case any pieces are filtered as not wanted
|
|
size_type total_wanted;
|
|
|
|
// the number of distributed copies of the file.
|
|
// note that one copy may be spread out among many peers.
|
|
//
|
|
// the integer part tells how many copies
|
|
// there are of the rarest piece(s)
|
|
//
|
|
// the fractional part tells the fraction of pieces that
|
|
// have more copies than the rarest piece(s).
|
|
float distributed_copies;
|
|
|
|
// the block size that is used in this torrent. i.e.
|
|
// the number of bytes each piece request asks for
|
|
// and each bit in the download queue bitfield represents
|
|
int block_size;
|
|
|
|
int num_uploads;
|
|
int num_connections;
|
|
int uploads_limit;
|
|
int connections_limit;
|
|
|
|
// true if the torrent is saved in compact mode
|
|
// false if it is saved in full allocation mode
|
|
storage_mode_t storage_mode;
|
|
|
|
int up_bandwidth_queue;
|
|
int down_bandwidth_queue;
|
|
};
|
|
|
|
struct TORRENT_EXPORT block_info
|
|
{
|
|
enum block_state_t
|
|
{ none, requested, writing, finished };
|
|
|
|
tcp::endpoint peer;
|
|
// number of bytes downloaded in this block
|
|
unsigned bytes_progress:16;
|
|
// the total number of bytes in this block
|
|
unsigned block_size:16;
|
|
// the state this block is in (see block_state_t)
|
|
unsigned state:2;
|
|
// the number of peers that has requested this block
|
|
// typically 0 or 1. If > 1, this block is in
|
|
// end game mode
|
|
unsigned num_peers:14;
|
|
};
|
|
|
|
struct TORRENT_EXPORT partial_piece_info
|
|
{
|
|
enum { max_blocks_per_piece = 256 };
|
|
int piece_index;
|
|
int blocks_in_piece;
|
|
// the number of blocks in the finished state
|
|
int finished;
|
|
// the number of blocks in the writing state
|
|
int writing;
|
|
// the number of blocks in the requested state
|
|
int requested;
|
|
block_info blocks[max_blocks_per_piece];
|
|
enum state_t { none, slow, medium, fast };
|
|
state_t piece_state;
|
|
};
|
|
|
|
struct TORRENT_EXPORT torrent_handle
|
|
{
|
|
friend class invariant_access;
|
|
friend struct aux::session_impl;
|
|
friend class torrent;
|
|
|
|
torrent_handle(): m_ses(0), m_chk(0), m_info_hash(0) {}
|
|
|
|
void get_peer_info(std::vector<peer_info>& v) const;
|
|
bool send_chat_message(tcp::endpoint ip, std::string message) const;
|
|
torrent_status status() const;
|
|
void get_download_queue(std::vector<partial_piece_info>& queue) const;
|
|
|
|
// fills the specified vector with the download progress [0, 1]
|
|
// of each file in the torrent. The files are ordered as in
|
|
// the torrent_info.
|
|
void file_progress(std::vector<float>& progress);
|
|
|
|
std::vector<announce_entry> const& trackers() const;
|
|
void replace_trackers(std::vector<announce_entry> const&) const;
|
|
|
|
void add_url_seed(std::string const& url) const;
|
|
void remove_url_seed(std::string const& url) const;
|
|
std::set<std::string> url_seeds() const;
|
|
|
|
#ifndef TORRENT_DISABLE_EXTENSIONS
|
|
void add_extension(boost::function<boost::shared_ptr<torrent_plugin>(torrent*, void*)> const& ext
|
|
, void* userdata = 0);
|
|
#endif
|
|
|
|
bool has_metadata() const;
|
|
const torrent_info& get_torrent_info() const;
|
|
bool is_valid() const;
|
|
|
|
bool is_seed() const;
|
|
bool is_paused() const;
|
|
void pause() const;
|
|
void resume() const;
|
|
|
|
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
|
|
void resolve_countries(bool r);
|
|
bool resolve_countries() const;
|
|
#endif
|
|
|
|
// all these are deprecated, use piece
|
|
// priority functions instead
|
|
|
|
// ================ start deprecation ============
|
|
|
|
// marks the piece with the given index as filtered
|
|
// it will not be downloaded
|
|
void filter_piece(int index, bool filter) const TORRENT_DEPRECATED;
|
|
void filter_pieces(std::vector<bool> const& pieces) const TORRENT_DEPRECATED;
|
|
bool is_piece_filtered(int index) const TORRENT_DEPRECATED;
|
|
std::vector<bool> filtered_pieces() const TORRENT_DEPRECATED;
|
|
// marks the file with the given index as filtered
|
|
// it will not be downloaded
|
|
void filter_files(std::vector<bool> const& files) const TORRENT_DEPRECATED;
|
|
|
|
// ================ end deprecation ============
|
|
|
|
void piece_availability(std::vector<int>& avail) const;
|
|
|
|
// priority must be within the range [0, 7]
|
|
void piece_priority(int index, int priority) const;
|
|
int piece_priority(int index) const;
|
|
|
|
void prioritize_pieces(std::vector<int> const& pieces) const;
|
|
std::vector<int> piece_priorities() const;
|
|
|
|
void prioritize_files(std::vector<int> const& files) const;
|
|
|
|
|
|
// set the interface to bind outgoing connections
|
|
// to.
|
|
void use_interface(const char* net_interface) const;
|
|
|
|
entry write_resume_data() const;
|
|
|
|
// forces this torrent to reannounce
|
|
// (make a rerequest from the tracker)
|
|
void force_reannounce() const;
|
|
|
|
// forces a reannounce in the specified amount of time.
|
|
// This overrides the default announce interval, and no
|
|
// announce will take place until the given time has
|
|
// timed out.
|
|
void force_reannounce(boost::posix_time::time_duration) const;
|
|
|
|
// performs a scrape request
|
|
void scrape_tracker() const;
|
|
|
|
// returns the name of this torrent, in case it doesn't
|
|
// have metadata it returns the name assigned to it
|
|
// when it was added.
|
|
std::string name() const;
|
|
|
|
// TODO: add a feature where the user can tell the torrent
|
|
// to finish all pieces currently in the pipeline, and then
|
|
// abort the torrent.
|
|
|
|
void set_upload_limit(int limit) const;
|
|
int upload_limit() const;
|
|
void set_download_limit(int limit) const;
|
|
int download_limit() const;
|
|
|
|
void set_sequenced_download_threshold(int threshold) const;
|
|
|
|
void set_peer_upload_limit(tcp::endpoint ip, int limit) const;
|
|
void set_peer_download_limit(tcp::endpoint ip, int limit) const;
|
|
|
|
// manually connect a peer
|
|
void connect_peer(tcp::endpoint const& adr, int source = 0) const;
|
|
|
|
// valid ratios are 0 (infinite ratio) or [ 1.0 , inf )
|
|
// the ratio is uploaded / downloaded. less than 1 is not allowed
|
|
void set_ratio(float up_down_ratio) const;
|
|
|
|
fs::path save_path() const;
|
|
|
|
// -1 means unlimited unchokes
|
|
void set_max_uploads(int max_uploads) const;
|
|
|
|
// -1 means unlimited connections
|
|
void set_max_connections(int max_connections) const;
|
|
|
|
void set_tracker_login(std::string const& name
|
|
, std::string const& password) const;
|
|
|
|
// post condition: save_path() == save_path if true is returned
|
|
void move_storage(fs::path const& save_path) const;
|
|
|
|
const sha1_hash& info_hash() const
|
|
{ return m_info_hash; }
|
|
|
|
bool operator==(const torrent_handle& h) const
|
|
{ return m_info_hash == h.m_info_hash; }
|
|
|
|
bool operator!=(const torrent_handle& h) const
|
|
{ return m_info_hash != h.m_info_hash; }
|
|
|
|
bool operator<(const torrent_handle& h) const
|
|
{ return m_info_hash < h.m_info_hash; }
|
|
|
|
private:
|
|
|
|
torrent_handle(aux::session_impl* s,
|
|
aux::checker_impl* c,
|
|
const sha1_hash& h)
|
|
: m_ses(s)
|
|
, m_chk(c)
|
|
, m_info_hash(h)
|
|
{
|
|
TORRENT_ASSERT(m_ses != 0);
|
|
TORRENT_ASSERT(m_chk != 0);
|
|
}
|
|
|
|
#ifndef NDEBUG
|
|
void check_invariant() const;
|
|
#endif
|
|
|
|
aux::session_impl* m_ses;
|
|
aux::checker_impl* m_chk;
|
|
sha1_hash m_info_hash;
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
#endif // TORRENT_TORRENT_HANDLE_HPP_INCLUDED
|
|
|