ConvertUTF.h | ConvertUTF.h | |||
---|---|---|---|---|
skipping to change at line 100 | skipping to change at line 100 | |||
#ifdef __cplusplus | #ifdef __cplusplus | |||
#include "libtorrent/config.hpp" | #include "libtorrent/config.hpp" | |||
// these are standard C types, but they might | // these are standard C types, but they might | |||
// not be available in c++ | // not be available in c++ | |||
#include <boost/cstdint.hpp> | #include <boost/cstdint.hpp> | |||
typedef boost::uint32_t UTF32; | typedef boost::uint32_t UTF32; | |||
typedef boost::uint16_t UTF16; | typedef boost::uint16_t UTF16; | |||
typedef boost::uint8_t UTF8; | typedef boost::uint8_t UTF8; | |||
extern "C" { | extern "C" { | |||
#else | #else | |||
#define TORRENT_EXTRA_EXPORT | ||||
#ifdef _MSC_VER | #ifdef _MSC_VER | |||
// msvc doesn't seem to have stdint.h | // msvc doesn't seem to have stdint.h | |||
typedef unsigned __int32 UTF32; | typedef unsigned __int32 UTF32; | |||
typedef unsigned __int16 UTF16; | typedef unsigned __int16 UTF16; | |||
typedef unsigned __int8 UTF8; | typedef unsigned __int8 UTF8; | |||
#else | #else | |||
#include <stdint.h> | #include <stdint.h> | |||
typedef uint32_t UTF32; | typedef uint32_t UTF32; | |||
typedef uint16_t UTF16; | typedef uint16_t UTF16; | |||
typedef uint8_t UTF8; | typedef uint8_t UTF8; | |||
skipping to change at line 134 | skipping to change at line 135 | |||
sourceExhausted, /* partial character in source, but hit end */ | sourceExhausted, /* partial character in source, but hit end */ | |||
targetExhausted, /* insuff. room in target for conversion */ | targetExhausted, /* insuff. room in target for conversion */ | |||
sourceIllegal /* source sequence is illegal/malformed */ | sourceIllegal /* source sequence is illegal/malformed */ | |||
} ConversionResult; | } ConversionResult; | |||
typedef enum { | typedef enum { | |||
strictConversion = 0, | strictConversion = 0, | |||
lenientConversion | lenientConversion | |||
} ConversionFlags; | } ConversionFlags; | |||
ConversionResult ConvertUTF8toUTF16 ( | TORRENT_EXTRA_EXPORT ConversionResult ConvertUTF8toUTF16 ( | |||
const UTF8** sourceStart, const UTF8* sourceEnd, | const UTF8** sourceStart, const UTF8* sourceEnd, | |||
UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags ); | UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags ); | |||
ConversionResult ConvertUTF16toUTF8 ( | TORRENT_EXTRA_EXPORT ConversionResult ConvertUTF16toUTF8 ( | |||
const UTF16** sourceStart, const UTF16* sourceEnd, | const UTF16** sourceStart, const UTF16* sourceEnd, | |||
UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags); | UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags); | |||
ConversionResult ConvertUTF8toUTF32 ( | TORRENT_EXTRA_EXPORT ConversionResult ConvertUTF8toUTF32 ( | |||
const UTF8** sourceStart, const UTF8* sourceEnd, | const UTF8** sourceStart, const UTF8* sourceEnd, | |||
UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags ); | UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags ); | |||
ConversionResult ConvertUTF32toUTF8 ( | TORRENT_EXTRA_EXPORT ConversionResult ConvertUTF32toUTF8 ( | |||
const UTF32** sourceStart, const UTF32* sourceEnd, | const UTF32** sourceStart, const UTF32* sourceEnd, | |||
UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags); | UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags); | |||
ConversionResult ConvertUTF16toUTF32 ( | TORRENT_EXTRA_EXPORT ConversionResult ConvertUTF16toUTF32 ( | |||
const UTF16** sourceStart, const UTF16* sourceEnd, | const UTF16** sourceStart, const UTF16* sourceEnd, | |||
UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags ); | UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags ); | |||
ConversionResult ConvertUTF32toUTF16 ( | TORRENT_EXTRA_EXPORT ConversionResult ConvertUTF32toUTF16 ( | |||
const UTF32** sourceStart, const UTF32* sourceEnd, | const UTF32** sourceStart, const UTF32* sourceEnd, | |||
UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags ); | UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags ); | |||
Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd); | TORRENT_EXTRA_EXPORT Boolean isLegalUTF8Sequence(const UTF8 *source, | |||
const UTF8 *sourceEnd); | ||||
#ifdef __cplusplus | #ifdef __cplusplus | |||
} | } | |||
#endif | #endif | |||
/* --------------------------------------------------------------------- */ | /* --------------------------------------------------------------------- */ | |||
End of changes. 8 change blocks. | ||||
7 lines changed or deleted | 9 lines changed or added | |||
add_torrent_params.hpp | add_torrent_params.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2009, Arvid Norberg | Copyright (c) 2009-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 44 | skipping to change at line 44 | |||
#define TORRENT_ADD_TORRENT_PARAMS_HPP_INCLUDED | #define TORRENT_ADD_TORRENT_PARAMS_HPP_INCLUDED | |||
#include <string> | #include <string> | |||
#include <vector> | #include <vector> | |||
#include <boost/intrusive_ptr.hpp> | #include <boost/intrusive_ptr.hpp> | |||
#include "libtorrent/storage_defs.hpp" | #include "libtorrent/storage_defs.hpp" | |||
#include "libtorrent/peer_id.hpp" // sha1_hash | #include "libtorrent/peer_id.hpp" // sha1_hash | |||
#include "libtorrent/version.hpp" | #include "libtorrent/version.hpp" | |||
#ifndef TORRENT_DISABLE_EXTENSIONS | ||||
#include "libtorrent/extensions.hpp" | ||||
#endif | ||||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
class torrent_info; | class torrent_info; | |||
class torrent; | ||||
struct torrent_plugin; | ||||
struct add_torrent_params | // The add_torrent_params is a parameter pack for adding torrents to | |||
a | ||||
// session. The key fields when adding a torrent are: | ||||
// | ||||
// * ti - when you have a .torrent file | ||||
// * url - when you have a magnet link or http URL to the .torrent f | ||||
ile | ||||
// * info_hash - when all you have is an info-hash (this is similar | ||||
to a | ||||
// magnet link) | ||||
// | ||||
// one of those fields need to be set. Another mandatory field is | ||||
// ``save_path``. The add_torrent_params object is passed into one o | ||||
f the | ||||
// ``session::add_torrent()`` overloads or ``session::async_add_torr | ||||
ent()``. | ||||
// | ||||
// If you only specify the info-hash, the torrent file will be downl | ||||
oaded | ||||
// from peers, which requires them to support the metadata extension | ||||
. For | ||||
// the metadata extension to work, libtorrent must be built with ext | ||||
ensions | ||||
// enabled (``TORRENT_DISABLE_EXTENSIONS`` must not be defined). It | ||||
also | ||||
// takes an optional ``name`` argument. This may be left empty in ca | ||||
se no | ||||
// name should be assigned to the torrent. In case it's not, the nam | ||||
e is | ||||
// used for the torrent as long as it doesn't have metadata. See | ||||
// ``torrent_handle::name``. | ||||
// | ||||
struct TORRENT_EXPORT add_torrent_params | ||||
{ | { | |||
// The constructor can be used to initialize the storage con | ||||
structor, | ||||
// which determines the storage mechanism for the downloaded | ||||
or seeding | ||||
// data for the torrent. For more information, see the ``sto | ||||
rage`` field. | ||||
add_torrent_params(storage_constructor_type sc = default_sto rage_constructor) | add_torrent_params(storage_constructor_type sc = default_sto rage_constructor) | |||
: version(LIBTORRENT_VERSION_NUM) | : version(LIBTORRENT_VERSION_NUM) | |||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
, tracker_url(0) | , tracker_url(0) | |||
#endif | #endif | |||
, resume_data(0) | ||||
, storage_mode(storage_mode_sparse) | , storage_mode(storage_mode_sparse) | |||
, storage(sc) | , storage(sc) | |||
, userdata(0) | , userdata(0) | |||
, file_priorities(0) | ||||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
, flags(flag_ignore_flags | default_flags) | , flags(flag_ignore_flags | default_flags) | |||
#else | ||||
, flags(default_flags) | ||||
#endif | ||||
, max_uploads(-1) | ||||
, max_connections(-1) | ||||
, upload_limit(-1) | ||||
, download_limit(-1) | ||||
#ifndef TORRENT_NO_DEPRECATE | ||||
, seed_mode(false) | , seed_mode(false) | |||
, override_resume_data(false) | , override_resume_data(false) | |||
, upload_mode(false) | , upload_mode(false) | |||
, share_mode(false) | , share_mode(false) | |||
, apply_ip_filter(true) | , apply_ip_filter(true) | |||
, paused(true) | , paused(true) | |||
, auto_managed(true) | , auto_managed(true) | |||
, duplicate_is_error(false) | , duplicate_is_error(false) | |||
, merge_resume_trackers(false) | , merge_resume_trackers(false) | |||
#else | ||||
, flags(default_flags) | ||||
#endif | #endif | |||
{ | { | |||
} | } | |||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
void update_flags() const | void update_flags() const | |||
{ | { | |||
if (flags != (flag_ignore_flags | default_flags)) re turn; | if (flags != (flag_ignore_flags | default_flags)) re turn; | |||
boost::uint64_t& f = const_cast<boost::uint64_t&>(fl ags); | boost::uint64_t& f = const_cast<boost::uint64_t&>(fl ags); | |||
skipping to change at line 96 | skipping to change at line 130 | |||
if (upload_mode) f |= flag_upload_mode; | if (upload_mode) f |= flag_upload_mode; | |||
if (share_mode) f |= flag_share_mode; | if (share_mode) f |= flag_share_mode; | |||
if (apply_ip_filter) f |= flag_apply_ip_filter; | if (apply_ip_filter) f |= flag_apply_ip_filter; | |||
if (paused) f |= flag_paused; | if (paused) f |= flag_paused; | |||
if (auto_managed) f |= flag_auto_managed; | if (auto_managed) f |= flag_auto_managed; | |||
if (duplicate_is_error) f |= flag_duplicate_is_error ; | if (duplicate_is_error) f |= flag_duplicate_is_error ; | |||
if (merge_resume_trackers) f |= flag_merge_resume_tr ackers; | if (merge_resume_trackers) f |= flag_merge_resume_tr ackers; | |||
} | } | |||
#endif | #endif | |||
// values for the ``flags`` field | ||||
enum flags_t | enum flags_t | |||
{ | { | |||
// If ``flag_seed_mode`` is set, libtorrent will ass | ||||
ume that all files | ||||
// are present for this torrent and that they all ma | ||||
tch the hashes in | ||||
// the torrent file. Each time a peer requests to do | ||||
wnload a block, | ||||
// the piece is verified against the hash, unless it | ||||
has been verified | ||||
// already. If a hash fails, the torrent will automa | ||||
tically leave the | ||||
// seed mode and recheck all the files. The use case | ||||
for this mode is | ||||
// if a torrent is created and seeded, or if the use | ||||
r already know | ||||
// that the files are complete, this is a way to avo | ||||
id the initial | ||||
// file checks, and significantly reduce the startup | ||||
time. | ||||
// | ||||
// Setting ``flag_seed_mode`` on a torrent without m | ||||
etadata (a | ||||
// .torrent file) is a no-op and will be ignored. | ||||
// | ||||
// If resume data is passed in with this torrent, th | ||||
e seed mode saved | ||||
// in there will override the seed mode you set here | ||||
. | ||||
flag_seed_mode = 0x001, | flag_seed_mode = 0x001, | |||
// If ``flag_override_resume_data`` is set, the ``pa | ||||
used``, | ||||
// ``auto_managed`` and ``save_path`` of the torrent | ||||
are not loaded | ||||
// from the resume data, but the states requested by | ||||
the flags in | ||||
// ``add_torrent_params`` will override them. | ||||
// | ||||
// If you pass in resume data, the paused state of t | ||||
he torrent when | ||||
// the resume data was saved will override the pause | ||||
d state you pass | ||||
// in here. You can override this by setting | ||||
// ``flag_override_resume_data``. | ||||
flag_override_resume_data = 0x002, | flag_override_resume_data = 0x002, | |||
// If ``flag_upload_mode`` is set, the torrent will | ||||
be initialized in | ||||
// upload-mode, which means it will not make any pie | ||||
ce requests. This | ||||
// state is typically entered on disk I/O errors, an | ||||
d if the torrent | ||||
// is also auto managed, it will be taken out of thi | ||||
s state | ||||
// periodically. This mode can be used to avoid race | ||||
conditions when | ||||
// adjusting priorities of pieces before allowing th | ||||
e torrent to start | ||||
// downloading. | ||||
// | ||||
// If the torrent is auto-managed (``flag_auto_manag | ||||
ed``), the torrent | ||||
// will eventually be taken out of upload-mode, rega | ||||
rdless of how it | ||||
// got there. If it's important to manually control | ||||
when the torrent | ||||
// leaves upload mode, don't make it auto managed. | ||||
flag_upload_mode = 0x004, | flag_upload_mode = 0x004, | |||
// determines if the torrent should be added in *sha | ||||
re mode* or not. | ||||
// Share mode indicates that we are not interested i | ||||
n downloading the | ||||
// torrent, but merley want to improve our share rat | ||||
io (i.e. increase | ||||
// it). A torrent started in share mode will do its | ||||
best to never | ||||
// download more than it uploads to the swarm. If th | ||||
e swarm does not | ||||
// have enough demand for upload capacity, the torre | ||||
nt will not | ||||
// download anything. This mode is intended to be sa | ||||
fe to add any | ||||
// number of torrents to, without manual screening, | ||||
without the risk | ||||
// of downloading more than is uploaded. | ||||
// | ||||
// A torrent in share mode sets the priority to all | ||||
pieces to 0, | ||||
// except for the pieces that are downloaded, when p | ||||
ieces are decided | ||||
// to be downloaded. This affects the progress bar, | ||||
which might be set | ||||
// to "100% finished" most of the time. Do not chang | ||||
e file or piece | ||||
// priorities for torrents in share mode, it will ma | ||||
ke it not work. | ||||
// | ||||
// The share mode has one setting, the share ratio t | ||||
arget, see | ||||
// ``session_settings::share_mode_target`` for more | ||||
info. | ||||
flag_share_mode = 0x008, | flag_share_mode = 0x008, | |||
// determines if the IP filter should apply to this | ||||
torrent or not. By | ||||
// default all torrents are subject to filtering by | ||||
the IP filter | ||||
// (i.e. this flag is set by default). This is usefu | ||||
l if certain | ||||
// torrents needs to be excempt for some reason, bei | ||||
ng an auto-update | ||||
// torrent for instance. | ||||
flag_apply_ip_filter = 0x010, | flag_apply_ip_filter = 0x010, | |||
// specifies whether or not the torrent is to be sta | ||||
rted in a paused | ||||
// state. I.e. it won't connect to the tracker or an | ||||
y of the peers | ||||
// until it's resumed. This is typically a good way | ||||
of avoiding race | ||||
// conditions when setting configuration options on | ||||
torrents before | ||||
// starting them. | ||||
flag_paused = 0x020, | flag_paused = 0x020, | |||
// If the torrent is auto-managed (``flag_auto_manag | ||||
ed``), the torrent | ||||
// may be resumed at any point, regardless of how it | ||||
paused. If it's | ||||
// important to manually control when the torrent is | ||||
paused and | ||||
// resumed, don't make it auto managed. | ||||
// | ||||
// If ``flag_auto_managed`` is set, the torrent will | ||||
be queued, | ||||
// started and seeded automatically by libtorrent. W | ||||
hen this is set, | ||||
// the torrent should also be started as paused. The | ||||
default queue | ||||
// order is the order the torrents were added. They | ||||
are all downloaded | ||||
// in that order. For more details, see queuing_. | ||||
// | ||||
// If you pass in resume data, the auto_managed stat | ||||
e of the torrent | ||||
// when the resume data was saved will override the | ||||
auto_managed state | ||||
// you pass in here. You can override this by settin | ||||
g | ||||
// ``override_resume_data``. | ||||
flag_auto_managed = 0x040, | flag_auto_managed = 0x040, | |||
flag_duplicate_is_error = 0x080, | flag_duplicate_is_error = 0x080, | |||
// defaults to off and specifies whether tracker URL | ||||
s loaded from | ||||
// resume data should be added to the trackers in th | ||||
e torrent or | ||||
// replace the trackers. | ||||
flag_merge_resume_trackers = 0x100, | flag_merge_resume_trackers = 0x100, | |||
// on by default and means that this torrent will be | ||||
part of state | ||||
// updates when calling post_torrent_updates(). | ||||
flag_update_subscribe = 0x200, | flag_update_subscribe = 0x200, | |||
// sets the torrent into super seeding mode. If the | ||||
torrent is not a | ||||
// seed, this flag has no effect. It has the same ef | ||||
fect as calling | ||||
// ``torrent_handle::super_seeding(true)`` on the to | ||||
rrent handle | ||||
// immediately after adding it. | ||||
flag_super_seeding = 0x400, | ||||
// sets the sequential download state for the torren | ||||
t. It has the same | ||||
// effect as calling ``torrent_handle::sequential_do | ||||
wnload(true)`` on | ||||
// the torrent handle immediately after adding it. | ||||
flag_sequential_download = 0x800, | ||||
// if this flag is set, the save path from the resum | ||||
e data file, if | ||||
// present, is honored. This defaults to not being s | ||||
et, in which | ||||
// case the save_path specified in add_torrent_param | ||||
s is always used. | ||||
flag_use_resume_save_path = 0x1000, | ||||
// internal | ||||
default_flags = flag_update_subscribe | flag_auto_ma naged | flag_paused | flag_apply_ip_filter | default_flags = flag_update_subscribe | flag_auto_ma naged | flag_paused | flag_apply_ip_filter | |||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
, flag_ignore_flags = 0x80000000 | , flag_ignore_flags = 0x80000000 | |||
#endif | #endif | |||
}; | }; | |||
// libtorrent version. Used for forward binary compatibility | // filled in by the constructor and should be left untouched | |||
. It | ||||
// is used for forward binary compatibility. | ||||
int version; | int version; | |||
// torrent_info object with the torrent to add. Unless the u | ||||
rl or | ||||
// info_hash is set, this is required to be initiazlied. | ||||
boost::intrusive_ptr<torrent_info> ti; | boost::intrusive_ptr<torrent_info> ti; | |||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
char const* tracker_url; | char const* tracker_url; | |||
#endif | #endif | |||
// If the torrent doesn't have a tracker, but relies on the | ||||
DHT to find | ||||
// peers, the ``trackers`` can specify tracker URLs for the | ||||
torrent. | ||||
std::vector<std::string> trackers; | std::vector<std::string> trackers; | |||
// url seeds to be added to the torrent (`BEP 17`_). | ||||
std::vector<std::string> url_seeds; | ||||
// a list of hostname and port pairs, representing DHT nodes | ||||
to be added | ||||
// to the session (if DHT is enabled). The hostname may be a | ||||
n IP address. | ||||
std::vector<std::pair<std::string, int> > dht_nodes; | std::vector<std::pair<std::string, int> > dht_nodes; | |||
sha1_hash info_hash; | ||||
std::string name; | std::string name; | |||
// the path where the torrent is or will be stored. Note tha | ||||
t this may | ||||
// alos be stored in resume data. If you which the save path | ||||
saved in | ||||
// the resume data to be used, you need to set the | ||||
// flag_use_resume_save_path flag. | ||||
std::string save_path; | std::string save_path; | |||
std::vector<char>* resume_data; | ||||
// The optional parameter, ``resume_data`` can be given if u | ||||
p to date | ||||
// fast-resume data is available. The fast-resume data can b | ||||
e acquired | ||||
// from a running torrent by calling save_resume_data() on | ||||
// torrent_handle. See fast-resume_. The ``vector`` that is | ||||
passed in | ||||
// will be swapped into the running torrent instance with | ||||
// ``std::vector::swap()``. | ||||
std::vector<char> resume_data; | ||||
// One of the values from storage_mode_t. For more informati | ||||
on, see | ||||
// storage-allocation_. | ||||
storage_mode_t storage_mode; | storage_mode_t storage_mode; | |||
// can be used to customize how the data is stored. The defa | ||||
ult storage | ||||
// will simply write the data to the files it belongs to, bu | ||||
t it could be | ||||
// overridden to save everything to a single file at a speci | ||||
fic location | ||||
// or encrypt the content on disk for instance. For more inf | ||||
ormation | ||||
// about the storage_interface that needs to be implemented | ||||
for a custom | ||||
// storage, see storage_interface. | ||||
storage_constructor_type storage; | storage_constructor_type storage; | |||
// The ``userdata`` parameter is optional and will be passed | ||||
on to the | ||||
// extension constructor functions, if any (see `add_extensi | ||||
on()`_). | ||||
void* userdata; | void* userdata; | |||
std::vector<boost::uint8_t> const* file_priorities; | ||||
// can be set to control the initial file priorities when ad | ||||
ding a | ||||
// torrent. The semantics are the same as for | ||||
// ``torrent_handle::prioritize_files()``. | ||||
std::vector<boost::uint8_t> file_priorities; | ||||
// torrent extension construction functions can be added to | ||||
this vector | ||||
// to have them be added immediately when the torrent is con | ||||
structed. | ||||
// This may be desired over the torrent_handle::add_extensio | ||||
n() in order | ||||
// to avoid race conditions. For instance it may be importan | ||||
t to have the | ||||
// plugin catch events that happen very early on after the t | ||||
orrent is | ||||
// created. | ||||
std::vector<boost::function<boost::shared_ptr<torrent_plugin | ||||
>(torrent*, void*)> > | ||||
extensions; | ||||
// the default tracker id to be used when announcing to trac | ||||
kers. By | ||||
// default this is empty, and no tracker ID is used, since t | ||||
his is an | ||||
// optional argument. If a tracker returns a tracker ID, tha | ||||
t ID is used | ||||
// instead of this. | ||||
std::string trackerid; | std::string trackerid; | |||
// If you specify a ``url``, the torrent will be set in | ||||
// ``downloading_metadata`` state until the .torrent file ha | ||||
s been | ||||
// downloaded. If there's any error while downloading, the t | ||||
orrent will | ||||
// be stopped and the torrent error state (``torrent_status: | ||||
:error``) | ||||
// will indicate what went wrong. The ``url`` may refer to a | ||||
magnet link | ||||
// or a regular http URL. | ||||
// | ||||
// If it refers to an HTTP URL, the info-hash for the added | ||||
torrent will | ||||
// not be the true info-hash of the .torrent. Instead a plac | ||||
eholder, | ||||
// unique, info-hash is used which is later updated once the | ||||
.torrent | ||||
// file has been downloaded. | ||||
// | ||||
// Once the info-hash change happens, a torrent_update_alert | ||||
is posted. | ||||
std::string url; | std::string url; | |||
// if ``uuid`` is specified, it is used to find duplicates. | ||||
If another | ||||
// torrent is already running with the same UUID as the one | ||||
being added, | ||||
// it will be considered a duplicate. This is mainly useful | ||||
for RSS feed | ||||
// items which has UUIDs specified. | ||||
std::string uuid; | std::string uuid; | |||
// should point to the URL of the RSS feed this torrent come | ||||
s from, | ||||
// if it comes from an RSS feed. | ||||
std::string source_feed_url; | std::string source_feed_url; | |||
// flags controlling aspects of this torrent and how it's ad | ||||
ded. See | ||||
// flags_t for details. | ||||
boost::uint64_t flags; | boost::uint64_t flags; | |||
// set this to the info hash of the torrent to add in case t | ||||
he info-hash | ||||
// is the only known property of the torrent. i.e. you don't | ||||
have a | ||||
// .torrent file nor a magnet link. | ||||
sha1_hash info_hash; | ||||
// ``max_uploads``, ``max_connections``, ``upload_limit``, | ||||
// ``download_limit`` correspond to the ``set_max_uploads()` | ||||
`, | ||||
// ``set_max_connections()``, ``set_upload_limit()`` and | ||||
// ``set_download_limit()`` functions on torrent_handle. The | ||||
se values let | ||||
// you initialize these settings when the torrent is added, | ||||
instead of | ||||
// calling these functions immediately following adding it. | ||||
// | ||||
// -1 means unlimited on these settings just like their coun | ||||
terpart | ||||
// functions on torrent_handle | ||||
int max_uploads; | ||||
int max_connections; | ||||
int upload_limit; | ||||
int download_limit; | ||||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
bool seed_mode; | bool seed_mode; | |||
bool override_resume_data; | bool override_resume_data; | |||
bool upload_mode; | bool upload_mode; | |||
bool share_mode; | bool share_mode; | |||
bool apply_ip_filter; | bool apply_ip_filter; | |||
bool paused; | bool paused; | |||
bool auto_managed; | bool auto_managed; | |||
bool duplicate_is_error; | bool duplicate_is_error; | |||
bool merge_resume_trackers; | bool merge_resume_trackers; | |||
#endif | #endif | |||
}; | }; | |||
} | } | |||
#endif | #endif | |||
End of changes. 37 change blocks. | ||||
10 lines changed or deleted | 387 lines changed or added | |||
address.hpp | address.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2009, Arvid Norberg | Copyright (c) 2009-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
alert.hpp | alert.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2003, Arvid Norberg, Daniel Wallin | Copyright (c) 2003-2014, Arvid Norberg, Daniel Wallin | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 44 | skipping to change at line 44 | |||
#define TORRENT_ALERT_HPP_INCLUDED | #define TORRENT_ALERT_HPP_INCLUDED | |||
#include <memory> | #include <memory> | |||
#include <deque> | #include <deque> | |||
#include <string> | #include <string> | |||
#ifdef _MSC_VER | #ifdef _MSC_VER | |||
#pragma warning(push, 1) | #pragma warning(push, 1) | |||
#endif | #endif | |||
#include <boost/function/function1.hpp> | ||||
#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp> | #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp> | |||
#include <boost/preprocessor/repetition/enum.hpp> | #include <boost/preprocessor/repetition/enum.hpp> | |||
#include <boost/preprocessor/repetition/enum_params.hpp> | #include <boost/preprocessor/repetition/enum_params.hpp> | |||
#include <boost/preprocessor/repetition/enum_shifted_params.hpp> | #include <boost/preprocessor/repetition/enum_shifted_params.hpp> | |||
#include <boost/preprocessor/repetition/enum_shifted_binary_params.hpp> | #include <boost/preprocessor/repetition/enum_shifted_binary_params.hpp> | |||
#ifndef TORRENT_DISABLE_EXTENSIONS | // OVERVIEW | |||
#include <boost/shared_ptr.hpp> | // | |||
#include <list> | // The pop_alerts() function on session is the main interface for retrievin | |||
#endif | g | |||
// alerts (warnings, messages and errors from libtorrent). If no alerts hav | ||||
e | ||||
// been posted by libtorrent pop_alert() will return an empty list. | ||||
// | ||||
// By default, only errors are reported. set_alert_mask() can be used to | ||||
// specify which kinds of events should be reported. The alert mask is | ||||
// comprised by bits from the category_t enum. | ||||
// | ||||
// Every alert belongs to one or more category. There is a small cost invol | ||||
ved | ||||
// in posting alerts. Only alerts that belong to an enabled category are | ||||
// posted. Setting the alert bitmask to 0 will disable all alerts (except t | ||||
hose | ||||
// that are non-discardable). | ||||
// | ||||
// There are other alert base classes that some alerts derive from, all the | ||||
// alerts that are generated for a specific torrent are derived from | ||||
// torrent_alert, and tracker events derive from tracker_alert. | ||||
// | ||||
#ifdef _MSC_VER | #ifdef _MSC_VER | |||
#pragma warning(pop) | #pragma warning(pop) | |||
#endif | #endif | |||
#include "libtorrent/ptime.hpp" | #include "libtorrent/ptime.hpp" | |||
#include "libtorrent/config.hpp" | #include "libtorrent/config.hpp" | |||
#include "libtorrent/assert.hpp" | ||||
#include "libtorrent/thread.hpp" | #ifndef TORRENT_NO_DEPRECATE | |||
#include "libtorrent/io_service_fwd.hpp" | #ifndef BOOST_NO_TYPEID | |||
#include <typeinfo> | ||||
#endif | ||||
#endif // TORRENT_NO_DEPRECATE | ||||
#ifndef TORRENT_MAX_ALERT_TYPES | #ifndef TORRENT_MAX_ALERT_TYPES | |||
#define TORRENT_MAX_ALERT_TYPES 15 | #define TORRENT_MAX_ALERT_TYPES 15 | |||
#endif | #endif | |||
namespace libtorrent { | namespace libtorrent { | |||
#ifndef TORRENT_DISABLE_EXTENSIONS | // The ``alert`` class is the base class that specific messages are | |||
struct plugin; | derived from. | |||
#endif | ||||
class TORRENT_EXPORT alert | class TORRENT_EXPORT alert | |||
{ | { | |||
public: | public: | |||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
// only here for backwards compatibility | // only here for backwards compatibility | |||
enum severity_t { debug, info, warning, critical, fatal, non e }; | enum severity_t { debug, info, warning, critical, fatal, non e }; | |||
#endif | #endif | |||
// these are bits for the alert_mask used by the session. Se e set_alert_mask(). | ||||
enum category_t | enum category_t | |||
{ | { | |||
// Enables alerts that report an error. This include | ||||
s: | ||||
// | ||||
// * tracker errors | ||||
// * tracker warnings | ||||
// * file errors | ||||
// * resume data failures | ||||
// * web seed errors | ||||
// * .torrent files errors | ||||
// * listen socket errors | ||||
// * port mapping errors | ||||
error_notification = 0x1, | error_notification = 0x1, | |||
// Enables alerts when peers send invalid requests, | ||||
get banned or | ||||
// snubbed. | ||||
peer_notification = 0x2, | peer_notification = 0x2, | |||
// Enables alerts for port mapping events. For NAT-P | ||||
MP and UPnP. | ||||
port_mapping_notification = 0x4, | port_mapping_notification = 0x4, | |||
// Enables alerts for events related to the storage. | ||||
File errors and | ||||
// synchronization events for moving the storage, re | ||||
naming files etc. | ||||
storage_notification = 0x8, | storage_notification = 0x8, | |||
// Enables all tracker events. Includes announcing t | ||||
o trackers, | ||||
// receiving responses, warnings and errors. | ||||
tracker_notification = 0x10, | tracker_notification = 0x10, | |||
// Low level alerts for when peers are connected and | ||||
disconnected. | ||||
debug_notification = 0x20, | debug_notification = 0x20, | |||
// Enables alerts for when a torrent or the session | ||||
changes state. | ||||
status_notification = 0x40, | status_notification = 0x40, | |||
// Alerts for when blocks are requested and complete | ||||
d. Also when | ||||
// pieces are completed. | ||||
progress_notification = 0x80, | progress_notification = 0x80, | |||
// Alerts when a peer is blocked by the ip blocker o | ||||
r port blocker. | ||||
ip_block_notification = 0x100, | ip_block_notification = 0x100, | |||
// Alerts when some limit is reached that might limi | ||||
t the download | ||||
// or upload rate. | ||||
performance_warning = 0x200, | performance_warning = 0x200, | |||
// Alerts on events in the DHT node. For incoming se | ||||
arches or | ||||
// bootstrapping being done etc. | ||||
dht_notification = 0x400, | dht_notification = 0x400, | |||
// If you enable these alerts, you will receive a st | ||||
ats_alert | ||||
// approximately once every second, for every active | ||||
torrent. | ||||
// These alerts contain all statistics counters for | ||||
the interval since | ||||
// the lasts stats alert. | ||||
stats_notification = 0x800, | stats_notification = 0x800, | |||
// Alerts on RSS related events, like feeds being up | ||||
dated, feed error | ||||
// conditions and successful RSS feed updates. Enabl | ||||
ing this categoty | ||||
// will make you receive rss_alert alerts. | ||||
rss_notification = 0x1000, | rss_notification = 0x1000, | |||
// The full bitmask, representing all available cate | ||||
gories. | ||||
// | ||||
// since the enum is signed, make sure this isn't | // since the enum is signed, make sure this isn't | |||
// interpreted as -1. For instance, boost.python | // interpreted as -1. For instance, boost.python | |||
// does that and fails when assigning it to an | // does that and fails when assigning it to an | |||
// unsigned parameter. | // unsigned parameter. | |||
all_categories = 0x7fffffff | all_categories = 0x7fffffff | |||
}; | }; | |||
// hidden | ||||
alert(); | alert(); | |||
// hidden | ||||
virtual ~alert(); | virtual ~alert(); | |||
// a timestamp is automatically created in the constructor | // a timestamp is automatically created in the constructor | |||
ptime timestamp() const; | ptime timestamp() const; | |||
// returns an integer that is unique to this alert type. It | ||||
can be | ||||
// compared against a specific alert by querying a static co | ||||
nstant called ``alert_type`` | ||||
// in the alert. It can be used to determine the run-time ty | ||||
pe of an alert* in | ||||
// order to cast to that alert type and access specific memb | ||||
ers. | ||||
// | ||||
// e.g:: | ||||
// | ||||
// std::auto_ptr<alert> a = ses.pop_alert(); | ||||
// switch (a->type()) | ||||
// { | ||||
// case read_piece_alert::alert_type: | ||||
// { | ||||
// read_piece_alert* p = (read_piece_al | ||||
ert*)a.get(); | ||||
// if (p->ec) { | ||||
// // read_piece failed | ||||
// break; | ||||
// } | ||||
// // use p | ||||
// break; | ||||
// } | ||||
// case file_renamed_alert::alert_type: | ||||
// { | ||||
// // etc... | ||||
// } | ||||
// } | ||||
virtual int type() const = 0; | virtual int type() const = 0; | |||
// returns a string literal describing the type of the alert | ||||
. It does | ||||
// not include any information that might be bundled with th | ||||
e alert. | ||||
virtual char const* what() const = 0; | virtual char const* what() const = 0; | |||
// generate a string describing the alert and the informatio | ||||
n bundled | ||||
// with it. This is mainly intended for debug and developmen | ||||
t use. It is not suitable | ||||
// to use this for applications that may be localized. Inste | ||||
ad, handle each alert | ||||
// type individually and extract and render the information | ||||
from the alert depending | ||||
// on the locale. | ||||
virtual std::string message() const = 0; | virtual std::string message() const = 0; | |||
// returns a bitmask specifying which categories this alert | ||||
belong to. | ||||
virtual int category() const = 0; | virtual int category() const = 0; | |||
// determines whether or not an alert is allowed to be disca | ||||
rded | ||||
// when the alert queue is full. There are a few alerts whic | ||||
h may not be discared, | ||||
// since they would break the user contract, such as save_re | ||||
sume_data_alert. | ||||
virtual bool discardable() const { return true; } | virtual bool discardable() const { return true; } | |||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
severity_t severity() const TORRENT_DEPRECATED { return warn ing; } | severity_t severity() const TORRENT_DEPRECATED { return warn ing; } | |||
#endif | #endif | |||
// returns a pointer to a copy of the alert. | ||||
virtual std::auto_ptr<alert> clone() const = 0; | virtual std::auto_ptr<alert> clone() const = 0; | |||
private: | private: | |||
ptime m_timestamp; | ptime m_timestamp; | |||
}; | }; | |||
class TORRENT_EXTRA_EXPORT alert_manager | #ifndef TORRENT_NO_DEPRECATE | |||
{ | ||||
public: | ||||
alert_manager(io_service& ios, int queue_limit | ||||
, boost::uint32_t alert_mask = alert::error_notifica | ||||
tion); | ||||
~alert_manager(); | ||||
void post_alert(const alert& alert_); | ||||
void post_alert_ptr(alert* alert_); | ||||
bool pending() const; | ||||
std::auto_ptr<alert> get(); | ||||
void get_all(std::deque<alert*>* alerts); | ||||
template <class T> | ||||
bool should_post() const | ||||
{ | ||||
mutex::scoped_lock lock(m_mutex); | ||||
if (m_alerts.size() >= m_queue_size_limit) return fa | ||||
lse; | ||||
return (m_alert_mask & T::static_category) != 0; | ||||
} | ||||
alert const* wait_for_alert(time_duration max_wait); | ||||
void set_alert_mask(boost::uint32_t m) | ||||
{ | ||||
mutex::scoped_lock lock(m_mutex); | ||||
m_alert_mask = m; | ||||
} | ||||
int alert_mask() const { return m_alert_mask; } | ||||
size_t alert_queue_size_limit() const { return m_queue_size_ | ||||
limit; } | ||||
size_t set_alert_queue_size_limit(size_t queue_size_limit_); | ||||
void set_dispatch_function(boost::function<void(std::auto_pt | ||||
r<alert>)> const&); | ||||
#ifndef TORRENT_DISABLE_EXTENSIONS | ||||
void add_extension(boost::shared_ptr<plugin> ext); | ||||
#endif | ||||
private: | ||||
void post_impl(std::auto_ptr<alert>& alert_); | ||||
std::deque<alert*> m_alerts; | ||||
mutable mutex m_mutex; | ||||
// event m_condition; | ||||
boost::uint32_t m_alert_mask; | ||||
size_t m_queue_size_limit; | ||||
boost::function<void(std::auto_ptr<alert>)> m_dispatch; | ||||
io_service& m_ios; | ||||
#ifndef TORRENT_DISABLE_EXTENSIONS | ||||
typedef std::list<boost::shared_ptr<plugin> > ses_extension_ | ||||
list_t; | ||||
ses_extension_list_t m_ses_extensions; | ||||
#endif | ||||
}; | ||||
struct TORRENT_EXPORT unhandled_alert : std::exception | struct TORRENT_EXPORT unhandled_alert : std::exception | |||
{ | { | |||
unhandled_alert() {} | unhandled_alert() {} | |||
}; | }; | |||
#ifndef BOOST_NO_TYPEID | #ifndef BOOST_NO_TYPEID | |||
namespace detail { | namespace detail { | |||
struct void_; | struct void_; | |||
skipping to change at line 245 | skipping to change at line 293 | |||
#define ALERT_POINTER_TYPE(z, n, text) (BOOST_PP_CAT (T, n)*)0 | #define ALERT_POINTER_TYPE(z, n, text) (BOOST_PP_CAT (T, n)*)0 | |||
detail::handle_alert_dispatch(alert_, handler, typei d(*alert_) | detail::handle_alert_dispatch(alert_, handler, typei d(*alert_) | |||
, BOOST_PP_ENUM(TORRENT_MAX_ALERT_TYPES, ALE RT_POINTER_TYPE, _)); | , BOOST_PP_ENUM(TORRENT_MAX_ALERT_TYPES, ALE RT_POINTER_TYPE, _)); | |||
#undef ALERT_POINTER_TYPE | #undef ALERT_POINTER_TYPE | |||
} | } | |||
}; | }; | |||
#endif // BOOST_NO_TYPEID | #endif // BOOST_NO_TYPEID | |||
#endif // TORRENT_NO_DEPRECATE | ||||
// When you get an alert, you can use ``alert_cast<>`` to attempt to cast t | ||||
he pointer to a | ||||
// more specific alert type, in order to query it for more information. | ||||
template <class T> | template <class T> | |||
T* alert_cast(alert* a) | T* alert_cast(alert* a) | |||
{ | { | |||
if (a == 0) return 0; | if (a == 0) return 0; | |||
if (a->type() == T::alert_type) return static_cast<T*>(a); | if (a->type() == T::alert_type) return static_cast<T*>(a); | |||
return 0; | return 0; | |||
} | } | |||
template <class T> | template <class T> | |||
T const* alert_cast(alert const* a) | T const* alert_cast(alert const* a) | |||
{ | { | |||
if (a == 0) return 0; | if (a == 0) return 0; | |||
if (a->type() == T::alert_type) return static_cast<T const*>(a); | if (a->type() == T::alert_type) return static_cast<T const*>(a); | |||
return 0; | return 0; | |||
} | } | |||
} // namespace libtorrent | } // namespace libtorrent | |||
End of changes. 32 change blocks. | ||||
77 lines changed or deleted | 161 lines changed or added | |||
alert_types.hpp | alert_types.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2003, Arvid Norberg | Copyright (c) 2003-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 57 | skipping to change at line 57 | |||
// the type-ids of the alert types | // the type-ids of the alert types | |||
// are derived from the line on which | // are derived from the line on which | |||
// they are declared | // they are declared | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
// user defined alerts should use IDs greater than this | // user defined alerts should use IDs greater than this | |||
const static int user_alert_id = 10000; | const static int user_alert_id = 10000; | |||
// This is a base class for alerts that are associated with a | ||||
// specific torrent. It contains a handle to the torrent. | ||||
struct TORRENT_EXPORT torrent_alert: alert | struct TORRENT_EXPORT torrent_alert: alert | |||
{ | { | |||
// internal | ||||
torrent_alert(torrent_handle const& h) | torrent_alert(torrent_handle const& h) | |||
: handle(h) | : handle(h) | |||
{} | {} | |||
// internal | ||||
const static int alert_type = 1; | const static int alert_type = 1; | |||
virtual std::string message() const; | virtual std::string message() const; | |||
// The torrent_handle pointing to the torrent this | ||||
// alert is associated with. | ||||
torrent_handle handle; | torrent_handle handle; | |||
}; | }; | |||
// The peer alert is a base class for alerts that refer to a specifi | ||||
c peer. It includes all | ||||
// the information to identify the peer. i.e. ``ip`` and ``peer-id`` | ||||
. | ||||
struct TORRENT_EXPORT peer_alert: torrent_alert | struct TORRENT_EXPORT peer_alert: torrent_alert | |||
{ | { | |||
peer_alert(torrent_handle const& h, tcp::endpoint const& ip_ | // internal | |||
, peer_id const& pid_) | peer_alert(torrent_handle const& h, tcp::endpoint const& i | |||
, peer_id const& pi) | ||||
: torrent_alert(h) | : torrent_alert(h) | |||
, ip(ip_) | , ip(i) | |||
, pid(pid_) | , pid(pi) | |||
{} | {} | |||
const static int alert_type = 2; | const static int alert_type = 2; | |||
const static int static_category = alert::peer_notification; | const static int static_category = alert::peer_notification; | |||
virtual int category() const { return static_category; } | virtual int category() const { return static_category; } | |||
virtual std::string message() const; | virtual std::string message() const; | |||
// The peer's IP address and port. | ||||
tcp::endpoint ip; | tcp::endpoint ip; | |||
// the peer ID, if known. | ||||
peer_id pid; | peer_id pid; | |||
}; | }; | |||
// This is a base class used for alerts that are associated with a | ||||
// specific tracker. It derives from torrent_alert since a tracker | ||||
// is also associated with a specific torrent. | ||||
struct TORRENT_EXPORT tracker_alert: torrent_alert | struct TORRENT_EXPORT tracker_alert: torrent_alert | |||
{ | { | |||
// internal | ||||
tracker_alert(torrent_handle const& h | tracker_alert(torrent_handle const& h | |||
, std::string const& url_) | , std::string const& u) | |||
: torrent_alert(h) | : torrent_alert(h) | |||
, url(url_) | , url(u) | |||
{} | {} | |||
const static int alert_type = 3; | const static int alert_type = 3; | |||
const static int static_category = alert::tracker_notificati on; | const static int static_category = alert::tracker_notificati on; | |||
virtual int category() const { return static_category; } | virtual int category() const { return static_category; } | |||
virtual std::string message() const; | virtual std::string message() const; | |||
// The tracker URL | ||||
std::string url; | std::string url; | |||
}; | }; | |||
#define TORRENT_DEFINE_ALERT(name) \ | #define TORRENT_DEFINE_ALERT(name) \ | |||
const static int alert_type = __LINE__; \ | const static int alert_type = __LINE__; \ | |||
virtual int type() const { return alert_type; } \ | virtual int type() const { return alert_type; } \ | |||
virtual std::auto_ptr<alert> clone() const \ | virtual std::auto_ptr<alert> clone() const \ | |||
{ return std::auto_ptr<alert>(new name(*this)); } \ | { return std::auto_ptr<alert>(new name(*this)); } \ | |||
virtual int category() const { return static_category; } \ | virtual int category() const { return static_category; } \ | |||
virtual char const* what() const { return #name; } | virtual char const* what() const { return #name; } | |||
// The ``torrent_added_alert`` is posted once every time a torrent i | ||||
s successfully | ||||
// added. It doesn't contain any members of its own, but inherits th | ||||
e torrent handle | ||||
// from its base class. | ||||
// It's posted when the ``status_notification`` bit is set in the al | ||||
ert_mask. | ||||
struct TORRENT_EXPORT torrent_added_alert: torrent_alert | struct TORRENT_EXPORT torrent_added_alert: torrent_alert | |||
{ | { | |||
// internal | ||||
torrent_added_alert(torrent_handle const& h) | torrent_added_alert(torrent_handle const& h) | |||
: torrent_alert(h) | : torrent_alert(h) | |||
{} | {} | |||
TORRENT_DEFINE_ALERT(torrent_added_alert); | TORRENT_DEFINE_ALERT(torrent_added_alert); | |||
const static int static_category = alert::status_notificatio n; | const static int static_category = alert::status_notificatio n; | |||
virtual std::string message() const; | virtual std::string message() const; | |||
}; | }; | |||
// The ``torrent_removed_alert`` is posted whenever a torrent is rem | ||||
oved. Since | ||||
// the torrent handle in its baseclass will always be invalid (since | ||||
the torrent | ||||
// is already removed) it has the info hash as a member, to identify | ||||
it. | ||||
// It's posted when the ``status_notification`` bit is set in the al | ||||
ert_mask. | ||||
// | ||||
// Even though the ``handle`` member doesn't point to an existing to | ||||
rrent anymore, | ||||
// it is still useful for comparing to other handles, which may also | ||||
no | ||||
// longer point to existing torrents, but to the same non-existing t | ||||
orrents. | ||||
// | ||||
// The ``torrent_handle`` acts as a ``weak_ptr``, even though its ob | ||||
ject no | ||||
// longer exists, it can still compare equal to another weak pointer | ||||
which | ||||
// points to the same non-existent object. | ||||
struct TORRENT_EXPORT torrent_removed_alert: torrent_alert | struct TORRENT_EXPORT torrent_removed_alert: torrent_alert | |||
{ | { | |||
// internal | ||||
torrent_removed_alert(torrent_handle const& h, sha1_hash con st& ih) | torrent_removed_alert(torrent_handle const& h, sha1_hash con st& ih) | |||
: torrent_alert(h) | : torrent_alert(h) | |||
, info_hash(ih) | , info_hash(ih) | |||
{} | {} | |||
TORRENT_DEFINE_ALERT(torrent_removed_alert); | TORRENT_DEFINE_ALERT(torrent_removed_alert); | |||
const static int static_category = alert::status_notificatio n; | const static int static_category = alert::status_notificatio n; | |||
virtual std::string message() const; | virtual std::string message() const; | |||
sha1_hash info_hash; | sha1_hash info_hash; | |||
}; | }; | |||
struct TORRENT_EXPORT read_piece_alert: torrent_alert | // This alert is posted when the asynchronous read operation initiat | |||
ed by | ||||
// a call to torrent_handle::read_piece() is completed. If the read | ||||
failed, the torrent | ||||
// is paused and an error state is set and the buffer member of the | ||||
alert | ||||
// is 0. If successful, ``buffer`` points to a buffer containing all | ||||
the data | ||||
// of the piece. ``piece`` is the piece index that was read. ``size` | ||||
` is the | ||||
// number of bytes that was read. | ||||
// | ||||
// If the operation fails, ec will indicat what went wrong. | ||||
struct TORRENT_EXPORT read_piece_alert: torrent_alert | ||||
{ | { | |||
// internal | ||||
read_piece_alert(torrent_handle const& h | read_piece_alert(torrent_handle const& h | |||
, int p, boost::shared_array<char> d, int s) | , int p, boost::shared_array<char> d, int s) | |||
: torrent_alert(h) | : torrent_alert(h) | |||
, buffer(d) | , buffer(d) | |||
, piece(p) | , piece(p) | |||
, size(s) | , size(s) | |||
{} | {} | |||
read_piece_alert(torrent_handle h, int p, error_code e) | ||||
: torrent_alert(h) | ||||
, ec(e) | ||||
, piece(p) | ||||
, size(0) | ||||
{} | ||||
TORRENT_DEFINE_ALERT(read_piece_alert); | TORRENT_DEFINE_ALERT(read_piece_alert); | |||
const static int static_category = alert::storage_notificati on; | const static int static_category = alert::storage_notificati on; | |||
virtual std::string message() const; | virtual std::string message() const; | |||
virtual bool discardable() const { return false; } | virtual bool discardable() const { return false; } | |||
error_code ec; | ||||
boost::shared_array<char> buffer; | boost::shared_array<char> buffer; | |||
int piece; | int piece; | |||
int size; | int size; | |||
}; | }; | |||
// This is posted whenever an individual file completes its download | ||||
. i.e. | ||||
// All pieces overlapping this file have passed their hash check. | ||||
struct TORRENT_EXPORT file_completed_alert: torrent_alert | struct TORRENT_EXPORT file_completed_alert: torrent_alert | |||
{ | { | |||
// internal | ||||
file_completed_alert(torrent_handle const& h | file_completed_alert(torrent_handle const& h | |||
, int index_) | , int idx) | |||
: torrent_alert(h) | : torrent_alert(h) | |||
, index(index_) | , index(idx) | |||
{} | {} | |||
TORRENT_DEFINE_ALERT(file_completed_alert); | TORRENT_DEFINE_ALERT(file_completed_alert); | |||
const static int static_category = alert::progress_notificat ion; | const static int static_category = alert::progress_notificat ion; | |||
virtual std::string message() const; | virtual std::string message() const; | |||
// refers to the index of the file that completed. | ||||
int index; | int index; | |||
}; | }; | |||
// This is posted as a response to a torrent_handle::rename_file() c | ||||
all, if the rename | ||||
// operation succeeds. | ||||
struct TORRENT_EXPORT file_renamed_alert: torrent_alert | struct TORRENT_EXPORT file_renamed_alert: torrent_alert | |||
{ | { | |||
// internal | ||||
file_renamed_alert(torrent_handle const& h | file_renamed_alert(torrent_handle const& h | |||
, std::string const& name_ | , std::string const& n | |||
, int index_) | , int idx) | |||
: torrent_alert(h) | : torrent_alert(h) | |||
, name(name_) | , name(n) | |||
, index(index_) | , index(idx) | |||
{} | {} | |||
TORRENT_DEFINE_ALERT(file_renamed_alert); | TORRENT_DEFINE_ALERT(file_renamed_alert); | |||
const static int static_category = alert::storage_notificati on; | const static int static_category = alert::storage_notificati on; | |||
virtual std::string message() const; | virtual std::string message() const; | |||
virtual bool discardable() const { return false; } | virtual bool discardable() const { return false; } | |||
std::string name; | std::string name; | |||
// refers to the index of the file that was renamed, | ||||
// ``name`` is the new name of the file. | ||||
int index; | int index; | |||
}; | }; | |||
// This is posted as a response to a torrent_handle::rename_file() c | ||||
all, if the rename | ||||
// operation failed. | ||||
struct TORRENT_EXPORT file_rename_failed_alert: torrent_alert | struct TORRENT_EXPORT file_rename_failed_alert: torrent_alert | |||
{ | { | |||
// internal | ||||
file_rename_failed_alert(torrent_handle const& h | file_rename_failed_alert(torrent_handle const& h | |||
, int index_ | , int idx | |||
, error_code ec_) | , error_code ec) | |||
: torrent_alert(h) | : torrent_alert(h) | |||
, index(index_) | , index(idx) | |||
, error(ec_) | , error(ec) | |||
{} | {} | |||
TORRENT_DEFINE_ALERT(file_rename_failed_alert); | TORRENT_DEFINE_ALERT(file_rename_failed_alert); | |||
const static int static_category = alert::storage_notificati on; | const static int static_category = alert::storage_notificati on; | |||
virtual std::string message() const; | virtual std::string message() const; | |||
virtual bool discardable() const { return false; } | virtual bool discardable() const { return false; } | |||
// refers to the index of the file that was supposed to be r | ||||
enamed, | ||||
// ``error`` is the error code returned from the filesystem. | ||||
int index; | int index; | |||
error_code error; | error_code error; | |||
}; | }; | |||
// This alert is generated when a limit is reached that might have a | ||||
negative impact on | ||||
// upload or download rate performance. | ||||
struct TORRENT_EXPORT performance_alert: torrent_alert | struct TORRENT_EXPORT performance_alert: torrent_alert | |||
{ | { | |||
enum performance_warning_t | enum performance_warning_t | |||
{ | { | |||
// This warning means that the number of bytes queue | ||||
d to be written to disk | ||||
// exceeds the max disk byte queue setting (``sessio | ||||
n_settings::max_queued_disk_bytes``). | ||||
// This might restrict the download rate, by not que | ||||
uing up enough write jobs | ||||
// to the disk I/O thread. When this alert is posted | ||||
, peer connections are | ||||
// temporarily stopped from downloading, until the q | ||||
ueued disk bytes have fallen | ||||
// below the limit again. Unless your ``max_queued_d | ||||
isk_bytes`` setting is already | ||||
// high, you might want to increase it to get better | ||||
performance. | ||||
outstanding_disk_buffer_limit_reached, | outstanding_disk_buffer_limit_reached, | |||
outstanding_request_limit_reached, | ||||
// This is posted when libtorrent would like to send | ||||
more requests to a peer, | ||||
// but it's limited by ``session_settings::max_out_r | ||||
equest_queue``. The queue length | ||||
// libtorrent is trying to achieve is determined by | ||||
the download rate and the | ||||
// assumed round-trip-time (``session_settings::requ | ||||
est_queue_time``). The assumed | ||||
// rount-trip-time is not limited to just the networ | ||||
k RTT, but also the remote disk | ||||
// access time and message handling time. It default | ||||
s to 3 seconds. The target number | ||||
// of outstanding requests is set to fill the bandwi | ||||
dth-delay product (assumed RTT | ||||
// times download rate divided by number of bytes pe | ||||
r request). When this alert | ||||
// is posted, there is a risk that the number of out | ||||
standing requests is too low | ||||
// and limits the download rate. You might want to i | ||||
ncrease the ``max_out_request_queue`` | ||||
// setting. | ||||
outstanding_request_limit_reached, | ||||
// This warning is posted when the amount of TCP/IP | ||||
overhead is greater than the | ||||
// upload rate limit. When this happens, the TCP/IP | ||||
overhead is caused by a much | ||||
// faster download rate, triggering TCP ACK packets. | ||||
These packets eat into the | ||||
// rate limit specified to libtorrent. When the over | ||||
head traffic is greater than | ||||
// the rate limit, libtorrent will not be able to se | ||||
nd any actual payload, such | ||||
// as piece requests. This means the download rate w | ||||
ill suffer, and new requests | ||||
// can be sent again. There will be an equilibrium w | ||||
here the download rate, on | ||||
// average, is about 20 times the upload rate limit. | ||||
If you want to maximize the | ||||
// download rate, increase the upload rate limit abo | ||||
ve 5% of your download capacity. | ||||
upload_limit_too_low, | upload_limit_too_low, | |||
// This is the same warning as ``upload_limit_too_lo | ||||
w`` but referring to the download | ||||
// limit instead of upload. This suggests that your | ||||
download rate limit is mcuh lower | ||||
// than your upload capacity. Your upload rate will | ||||
suffer. To maximize upload rate, | ||||
// make sure your download rate limit is above 5% of | ||||
your upload capacity. | ||||
download_limit_too_low, | download_limit_too_low, | |||
// We're stalled on the disk. We want to write to th | ||||
e socket, and we can write | ||||
// but our send buffer is empty, waiting to be refil | ||||
led from the disk. | ||||
// This either means the disk is slower than the net | ||||
work connection | ||||
// or that our send buffer watermark is too small, b | ||||
ecause we can | ||||
// send it all before the disk gets back to us. | ||||
// The number of bytes that we keep outstanding, req | ||||
uested from the disk, is calculated | ||||
// as follows:: | ||||
// | ||||
// min(512, max(upload_rate * send_buffer_watermar | ||||
k_factor / 100, send_buffer_watermark)) | ||||
// | ||||
// If you receive this alert, you migth want to eith | ||||
er increase your ``send_buffer_watermark`` | ||||
// or ``send_buffer_watermark_factor``. | ||||
send_buffer_watermark_too_low, | send_buffer_watermark_too_low, | |||
// If the half (or more) of all upload slots are set | ||||
as optimistic unchoke slots, this | ||||
// warning is issued. You probably want more regular | ||||
(rate based) unchoke slots. | ||||
too_many_optimistic_unchoke_slots, | too_many_optimistic_unchoke_slots, | |||
bittyrant_with_no_uplimit, | ||||
// If the disk write queue ever grows larger than ha | ||||
lf of the cache size, this warning | ||||
// is posted. The disk write queue eats into the tot | ||||
al disk cache and leaves very little | ||||
// left for the actual cache. This causes the disk c | ||||
ache to oscillate in evicting large | ||||
// portions of the cache before allowing peers to do | ||||
wnload any more, onto the disk write | ||||
// queue. Either lower ``max_queued_disk_bytes`` or | ||||
increase ``cache_size``. | ||||
too_high_disk_queue_limit, | too_high_disk_queue_limit, | |||
bittyrant_with_no_uplimit, | ||||
// This is generated if outgoing peer connections ar | ||||
e failing because of *address in use* | ||||
// errors, indicating that ``session_settings::outgo | ||||
ing_ports`` is set and is too small of | ||||
// a range. Consider not using the ``outgoing_ports` | ||||
` setting at all, or widen the range to | ||||
// include more ports. | ||||
too_few_outgoing_ports, | too_few_outgoing_ports, | |||
too_few_file_descriptors, | too_few_file_descriptors, | |||
num_warnings | num_warnings | |||
}; | }; | |||
// internal | ||||
performance_alert(torrent_handle const& h | performance_alert(torrent_handle const& h | |||
, performance_warning_t w) | , performance_warning_t w) | |||
: torrent_alert(h) | : torrent_alert(h) | |||
, warning_code(w) | , warning_code(w) | |||
{} | {} | |||
TORRENT_DEFINE_ALERT(performance_alert); | TORRENT_DEFINE_ALERT(performance_alert); | |||
const static int static_category = alert::performance_warnin g; | const static int static_category = alert::performance_warnin g; | |||
virtual std::string message() const; | virtual std::string message() const; | |||
performance_warning_t warning_code; | performance_warning_t warning_code; | |||
}; | }; | |||
// Generated whenever a torrent changes its state. | ||||
struct TORRENT_EXPORT state_changed_alert: torrent_alert | struct TORRENT_EXPORT state_changed_alert: torrent_alert | |||
{ | { | |||
// internal | ||||
state_changed_alert(torrent_handle const& h | state_changed_alert(torrent_handle const& h | |||
, torrent_status::state_t state_ | , torrent_status::state_t st | |||
, torrent_status::state_t prev_state_) | , torrent_status::state_t prev_st) | |||
: torrent_alert(h) | : torrent_alert(h) | |||
, state(state_) | , state(st) | |||
, prev_state(prev_state_) | , prev_state(prev_st) | |||
{} | {} | |||
TORRENT_DEFINE_ALERT(state_changed_alert); | TORRENT_DEFINE_ALERT(state_changed_alert); | |||
const static int static_category = alert::status_notificatio n; | const static int static_category = alert::status_notificatio n; | |||
virtual std::string message() const; | virtual std::string message() const; | |||
// the new state of the torrent. | ||||
torrent_status::state_t state; | torrent_status::state_t state; | |||
// the previous state. | ||||
torrent_status::state_t prev_state; | torrent_status::state_t prev_state; | |||
}; | }; | |||
// This alert is generated on tracker time outs, premature disconnec | ||||
ts, invalid response or | ||||
// a HTTP response other than "200 OK". From the alert you can get t | ||||
he handle to the torrent | ||||
// the tracker belongs to. | ||||
// | ||||
// The ``times_in_row`` member says how many times in a row this tra | ||||
cker has failed. | ||||
// ``status_code`` is the code returned from the HTTP server. 401 me | ||||
ans the tracker needs | ||||
// authentication, 404 means not found etc. If the tracker timed out | ||||
, the code will be set | ||||
// to 0. | ||||
struct TORRENT_EXPORT tracker_error_alert: tracker_alert | struct TORRENT_EXPORT tracker_error_alert: tracker_alert | |||
{ | { | |||
// internal | ||||
tracker_error_alert(torrent_handle const& h | tracker_error_alert(torrent_handle const& h | |||
, int times | , int times | |||
, int status | , int status | |||
, std::string const& url_ | , std::string const& u | |||
, error_code const& e | , error_code const& e | |||
, std::string const& m) | , std::string const& m) | |||
: tracker_alert(h, url_) | : tracker_alert(h, u) | |||
, times_in_row(times) | , times_in_row(times) | |||
, status_code(status) | , status_code(status) | |||
, error(e) | , error(e) | |||
, msg(m) | , msg(m) | |||
{ | { | |||
TORRENT_ASSERT(!url.empty()); | TORRENT_ASSERT(!url.empty()); | |||
} | } | |||
TORRENT_DEFINE_ALERT(tracker_error_alert); | TORRENT_DEFINE_ALERT(tracker_error_alert); | |||
const static int static_category = alert::tracker_notificati on | alert::error_notification; | const static int static_category = alert::tracker_notificati on | alert::error_notification; | |||
virtual std::string message() const; | virtual std::string message() const; | |||
int times_in_row; | int times_in_row; | |||
int status_code; | int status_code; | |||
error_code error; | error_code error; | |||
std::string msg; | std::string msg; | |||
}; | }; | |||
// This alert is triggered if the tracker reply contains a warning f | ||||
ield. Usually this | ||||
// means that the tracker announce was successful, but the tracker h | ||||
as a message to | ||||
// the client. | ||||
struct TORRENT_EXPORT tracker_warning_alert: tracker_alert | struct TORRENT_EXPORT tracker_warning_alert: tracker_alert | |||
{ | { | |||
// internal | ||||
tracker_warning_alert(torrent_handle const& h | tracker_warning_alert(torrent_handle const& h | |||
, std::string const& url_ | , std::string const& u | |||
, std::string const& msg_) | , std::string const& m) | |||
: tracker_alert(h, url_) | : tracker_alert(h, u) | |||
, msg(msg_) | , msg(m) | |||
{ TORRENT_ASSERT(!url.empty()); } | { TORRENT_ASSERT(!url.empty()); } | |||
TORRENT_DEFINE_ALERT(tracker_warning_alert); | TORRENT_DEFINE_ALERT(tracker_warning_alert); | |||
const static int static_category = alert::tracker_notificati on | alert::error_notification; | const static int static_category = alert::tracker_notificati on | alert::error_notification; | |||
virtual std::string message() const; | virtual std::string message() const; | |||
// contains the warning message from the tracker. | ||||
std::string msg; | std::string msg; | |||
}; | }; | |||
// This alert is generated when a scrape request succeeds. | ||||
struct TORRENT_EXPORT scrape_reply_alert: tracker_alert | struct TORRENT_EXPORT scrape_reply_alert: tracker_alert | |||
{ | { | |||
// internal | ||||
scrape_reply_alert(torrent_handle const& h | scrape_reply_alert(torrent_handle const& h | |||
, int incomplete_ | , int incomp | |||
, int complete_ | , int comp | |||
, std::string const& url_) | , std::string const& u) | |||
: tracker_alert(h, url_) | : tracker_alert(h, u) | |||
, incomplete(incomplete_) | , incomplete(incomp) | |||
, complete(complete_) | , complete(comp) | |||
{ TORRENT_ASSERT(!url.empty()); } | { TORRENT_ASSERT(!url.empty()); } | |||
TORRENT_DEFINE_ALERT(scrape_reply_alert); | TORRENT_DEFINE_ALERT(scrape_reply_alert); | |||
virtual std::string message() const; | virtual std::string message() const; | |||
// the data returned in the scrape response. These numbers | ||||
// may be -1 if the reponse was malformed. | ||||
int incomplete; | int incomplete; | |||
int complete; | int complete; | |||
}; | }; | |||
// If a scrape request fails, this alert is generated. This might be | ||||
due | ||||
// to the tracker timing out, refusing connection or returning an ht | ||||
tp response | ||||
// code indicating an error. | ||||
struct TORRENT_EXPORT scrape_failed_alert: tracker_alert | struct TORRENT_EXPORT scrape_failed_alert: tracker_alert | |||
{ | { | |||
// internal | ||||
scrape_failed_alert(torrent_handle const& h | scrape_failed_alert(torrent_handle const& h | |||
, std::string const& url_ | , std::string const& u | |||
, error_code const& e) | , error_code const& e) | |||
: tracker_alert(h, url_) | : tracker_alert(h, u) | |||
, msg(convert_from_native(e.message())) | , msg(convert_from_native(e.message())) | |||
{ TORRENT_ASSERT(!url.empty()); } | { TORRENT_ASSERT(!url.empty()); } | |||
scrape_failed_alert(torrent_handle const& h | scrape_failed_alert(torrent_handle const& h | |||
, std::string const& url_ | , std::string const& u | |||
, std::string const& msg_) | , std::string const& m) | |||
: tracker_alert(h, url_) | : tracker_alert(h, u) | |||
, msg(msg_) | , msg(m) | |||
{ TORRENT_ASSERT(!url.empty()); } | { TORRENT_ASSERT(!url.empty()); } | |||
TORRENT_DEFINE_ALERT(scrape_failed_alert); | TORRENT_DEFINE_ALERT(scrape_failed_alert); | |||
const static int static_category = alert::tracker_notificati on | alert::error_notification; | const static int static_category = alert::tracker_notificati on | alert::error_notification; | |||
virtual std::string message() const; | virtual std::string message() const; | |||
// contains a message describing the error. | ||||
std::string msg; | std::string msg; | |||
}; | }; | |||
// This alert is only for informational purpose. It is generated whe | ||||
n a tracker announce | ||||
// succeeds. It is generated regardless what kind of tracker was use | ||||
d, be it UDP, HTTP or | ||||
// the DHT. | ||||
struct TORRENT_EXPORT tracker_reply_alert: tracker_alert | struct TORRENT_EXPORT tracker_reply_alert: tracker_alert | |||
{ | { | |||
// internal | ||||
tracker_reply_alert(torrent_handle const& h | tracker_reply_alert(torrent_handle const& h | |||
, int np | , int np | |||
, std::string const& url_) | , std::string const& u) | |||
: tracker_alert(h, url_) | : tracker_alert(h, u) | |||
, num_peers(np) | , num_peers(np) | |||
{ TORRENT_ASSERT(!url.empty()); } | { TORRENT_ASSERT(!url.empty()); } | |||
TORRENT_DEFINE_ALERT(tracker_reply_alert); | TORRENT_DEFINE_ALERT(tracker_reply_alert); | |||
virtual std::string message() const; | virtual std::string message() const; | |||
// tells how many peers the tracker returned in this respons | ||||
e. This is | ||||
// not expected to be more thant the ``num_want`` settings. | ||||
These are not necessarily | ||||
// all new peers, some of them may already be connected. | ||||
int num_peers; | int num_peers; | |||
}; | }; | |||
// This alert is generated each time the DHT receives peers from a n | ||||
ode. ``num_peers`` | ||||
// is the number of peers we received in this packet. Typically thes | ||||
e packets are | ||||
// received from multiple DHT nodes, and so the alerts are typically | ||||
generated | ||||
// a few at a time. | ||||
struct TORRENT_EXPORT dht_reply_alert: tracker_alert | struct TORRENT_EXPORT dht_reply_alert: tracker_alert | |||
{ | { | |||
// internal | ||||
dht_reply_alert(torrent_handle const& h | dht_reply_alert(torrent_handle const& h | |||
, int np) | , int np) | |||
: tracker_alert(h, "") | : tracker_alert(h, "") | |||
, num_peers(np) | , num_peers(np) | |||
{} | {} | |||
TORRENT_DEFINE_ALERT(dht_reply_alert); | TORRENT_DEFINE_ALERT(dht_reply_alert); | |||
virtual std::string message() const; | virtual std::string message() const; | |||
int num_peers; | int num_peers; | |||
}; | }; | |||
// This alert is generated each time a tracker announce is sent (or | ||||
attempted to be sent). | ||||
// There are no extra data members in this alert. The url can be fou | ||||
nd in the base class | ||||
// however. | ||||
struct TORRENT_EXPORT tracker_announce_alert: tracker_alert | struct TORRENT_EXPORT tracker_announce_alert: tracker_alert | |||
{ | { | |||
// internal | ||||
tracker_announce_alert(torrent_handle const& h | tracker_announce_alert(torrent_handle const& h | |||
, std::string const& url_, int event_) | , std::string const& u, int e) | |||
: tracker_alert(h, url_) | : tracker_alert(h, u) | |||
, event(event_) | , event(e) | |||
{ TORRENT_ASSERT(!url.empty()); } | { TORRENT_ASSERT(!url.empty()); } | |||
TORRENT_DEFINE_ALERT(tracker_announce_alert); | TORRENT_DEFINE_ALERT(tracker_announce_alert); | |||
virtual std::string message() const; | virtual std::string message() const; | |||
// specifies what event was sent to the tracker. It is defin | ||||
ed as: | ||||
// | ||||
// 0. None | ||||
// 1. Completed | ||||
// 2. Started | ||||
// 3. Stopped | ||||
int event; | int event; | |||
}; | }; | |||
// This alert is generated when a finished piece fails its hash chec | ||||
k. You can get the handle | ||||
// to the torrent which got the failed piece and the index of the pi | ||||
ece itself from the alert. | ||||
struct TORRENT_EXPORT hash_failed_alert: torrent_alert | struct TORRENT_EXPORT hash_failed_alert: torrent_alert | |||
{ | { | |||
// internal | ||||
hash_failed_alert( | hash_failed_alert( | |||
torrent_handle const& h | torrent_handle const& h | |||
, int index) | , int index) | |||
: torrent_alert(h) | : torrent_alert(h) | |||
, piece_index(index) | , piece_index(index) | |||
{ TORRENT_ASSERT(index >= 0);} | { TORRENT_ASSERT(index >= 0);} | |||
TORRENT_DEFINE_ALERT(hash_failed_alert); | TORRENT_DEFINE_ALERT(hash_failed_alert); | |||
const static int static_category = alert::status_notificatio n; | const static int static_category = alert::status_notificatio n; | |||
virtual std::string message() const; | virtual std::string message() const; | |||
int piece_index; | int piece_index; | |||
}; | }; | |||
// This alert is generated when a peer is banned because it has sent | ||||
too many corrupt pieces | ||||
// to us. ``ip`` is the endpoint to the peer that was banned. | ||||
struct TORRENT_EXPORT peer_ban_alert: peer_alert | struct TORRENT_EXPORT peer_ban_alert: peer_alert | |||
{ | { | |||
// internal | ||||
peer_ban_alert(torrent_handle h, tcp::endpoint const& ep | peer_ban_alert(torrent_handle h, tcp::endpoint const& ep | |||
, peer_id const& peer_id) | , peer_id const& peer_id) | |||
: peer_alert(h, ep, peer_id) | : peer_alert(h, ep, peer_id) | |||
{} | {} | |||
TORRENT_DEFINE_ALERT(peer_ban_alert); | TORRENT_DEFINE_ALERT(peer_ban_alert); | |||
virtual std::string message() const; | virtual std::string message() const; | |||
}; | }; | |||
// This alert is generated when a peer is unsnubbed. Essentially whe | ||||
n it was snubbed for stalling | ||||
// sending data, and now it started sending data again. | ||||
struct TORRENT_EXPORT peer_unsnubbed_alert: peer_alert | struct TORRENT_EXPORT peer_unsnubbed_alert: peer_alert | |||
{ | { | |||
// internal | ||||
peer_unsnubbed_alert(torrent_handle h, tcp::endpoint const& ep | peer_unsnubbed_alert(torrent_handle h, tcp::endpoint const& ep | |||
, peer_id const& peer_id) | , peer_id const& peer_id) | |||
: peer_alert(h, ep, peer_id) | : peer_alert(h, ep, peer_id) | |||
{} | {} | |||
TORRENT_DEFINE_ALERT(peer_unsnubbed_alert); | TORRENT_DEFINE_ALERT(peer_unsnubbed_alert); | |||
virtual std::string message() const; | virtual std::string message() const; | |||
}; | }; | |||
// This alert is generated when a peer is snubbed, when it stops sen | ||||
ding data when we request | ||||
// it. | ||||
struct TORRENT_EXPORT peer_snubbed_alert: peer_alert | struct TORRENT_EXPORT peer_snubbed_alert: peer_alert | |||
{ | { | |||
// internal | ||||
peer_snubbed_alert(torrent_handle h, tcp::endpoint const& ep | peer_snubbed_alert(torrent_handle h, tcp::endpoint const& ep | |||
, peer_id const& peer_id) | , peer_id const& peer_id) | |||
: peer_alert(h, ep, peer_id) | : peer_alert(h, ep, peer_id) | |||
{} | {} | |||
TORRENT_DEFINE_ALERT(peer_snubbed_alert); | TORRENT_DEFINE_ALERT(peer_snubbed_alert); | |||
virtual std::string message() const; | virtual std::string message() const; | |||
}; | }; | |||
// This alert is generated when a peer sends invalid data over the p | ||||
eer-peer protocol. The peer | ||||
// will be disconnected, but you get its ip address from the alert, | ||||
to identify it. | ||||
struct TORRENT_EXPORT peer_error_alert: peer_alert | struct TORRENT_EXPORT peer_error_alert: peer_alert | |||
{ | { | |||
// internal | ||||
peer_error_alert(torrent_handle const& h, tcp::endpoint cons t& ep | peer_error_alert(torrent_handle const& h, tcp::endpoint cons t& ep | |||
, peer_id const& peer_id, error_code const& e) | , peer_id const& peer_id, error_code const& e) | |||
: peer_alert(h, ep, peer_id) | : peer_alert(h, ep, peer_id) | |||
, error(e) | , error(e) | |||
{ | { | |||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
msg = convert_from_native(error.message()); | msg = convert_from_native(error.message()); | |||
#endif | #endif | |||
} | } | |||
TORRENT_DEFINE_ALERT(peer_error_alert); | TORRENT_DEFINE_ALERT(peer_error_alert); | |||
const static int static_category = alert::peer_notification; | const static int static_category = alert::peer_notification; | |||
virtual std::string message() const | virtual std::string message() const | |||
{ | { | |||
return peer_alert::message() + " peer error: " + con vert_from_native(error.message()); | return peer_alert::message() + " peer error: " + con vert_from_native(error.message()); | |||
} | } | |||
// tells you what error caused this alert. | ||||
error_code error; | error_code error; | |||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
std::string msg; | std::string msg; | |||
#endif | #endif | |||
}; | }; | |||
// This alert is posted every time an outgoing peer connect attempts succeeds. | ||||
struct TORRENT_EXPORT peer_connect_alert: peer_alert | struct TORRENT_EXPORT peer_connect_alert: peer_alert | |||
{ | { | |||
// internal | ||||
peer_connect_alert(torrent_handle h, tcp::endpoint const& ep | peer_connect_alert(torrent_handle h, tcp::endpoint const& ep | |||
, peer_id const& peer_id) | , peer_id const& peer_id, int type) | |||
: peer_alert(h, ep, peer_id) | : peer_alert(h, ep, peer_id) | |||
, socket_type(type) | ||||
{} | {} | |||
TORRENT_DEFINE_ALERT(peer_connect_alert); | TORRENT_DEFINE_ALERT(peer_connect_alert); | |||
const static int static_category = alert::debug_notification ; | const static int static_category = alert::debug_notification ; | |||
virtual std::string message() const | virtual std::string message() const; | |||
{ return peer_alert::message() + " connecting to peer"; } | ||||
int socket_type; | ||||
}; | }; | |||
// This alert is generated when a peer is disconnected for any reaso | ||||
n (other than the ones | ||||
// covered by peer_error_alert ). | ||||
struct TORRENT_EXPORT peer_disconnected_alert: peer_alert | struct TORRENT_EXPORT peer_disconnected_alert: peer_alert | |||
{ | { | |||
// internal | ||||
peer_disconnected_alert(torrent_handle const& h, tcp::endpoi nt const& ep | peer_disconnected_alert(torrent_handle const& h, tcp::endpoi nt const& ep | |||
, peer_id const& peer_id, error_code const& e) | , peer_id const& peer_id, error_code const& e) | |||
: peer_alert(h, ep, peer_id) | : peer_alert(h, ep, peer_id) | |||
, error(e) | , error(e) | |||
{ | { | |||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
msg = convert_from_native(error.message()); | msg = convert_from_native(error.message()); | |||
#endif | #endif | |||
} | } | |||
TORRENT_DEFINE_ALERT(peer_disconnected_alert); | TORRENT_DEFINE_ALERT(peer_disconnected_alert); | |||
const static int static_category = alert::debug_notification ; | const static int static_category = alert::debug_notification ; | |||
virtual std::string message() const; | virtual std::string message() const; | |||
// tells you what error caused peer to disconnect. | ||||
error_code error; | error_code error; | |||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
std::string msg; | std::string msg; | |||
#endif | #endif | |||
}; | }; | |||
// This is a debug alert that is generated by an incoming invalid pi | ||||
ece request. | ||||
// ``ip`` is the address of the peer and the ``request`` is the actu | ||||
al incoming | ||||
// request from the peer. See peer_request for more info. | ||||
struct TORRENT_EXPORT invalid_request_alert: peer_alert | struct TORRENT_EXPORT invalid_request_alert: peer_alert | |||
{ | { | |||
// internal | ||||
invalid_request_alert(torrent_handle const& h, tcp::endpoint const& ep | invalid_request_alert(torrent_handle const& h, tcp::endpoint const& ep | |||
, peer_id const& peer_id, peer_request const& r) | , peer_id const& peer_id, peer_request const& r) | |||
: peer_alert(h, ep, peer_id) | : peer_alert(h, ep, peer_id) | |||
, request(r) | , request(r) | |||
{} | {} | |||
TORRENT_DEFINE_ALERT(invalid_request_alert); | TORRENT_DEFINE_ALERT(invalid_request_alert); | |||
virtual std::string message() const; | virtual std::string message() const; | |||
peer_request request; | peer_request request; | |||
}; | }; | |||
// This alert is generated when a torrent switches from being a down | ||||
loader to a seed. | ||||
// It will only be generated once per torrent. It contains a torrent | ||||
_handle to the | ||||
// torrent in question. | ||||
struct TORRENT_EXPORT torrent_finished_alert: torrent_alert | struct TORRENT_EXPORT torrent_finished_alert: torrent_alert | |||
{ | { | |||
// internal | ||||
torrent_finished_alert( | torrent_finished_alert( | |||
const torrent_handle& h) | const torrent_handle& h) | |||
: torrent_alert(h) | : torrent_alert(h) | |||
{} | {} | |||
TORRENT_DEFINE_ALERT(torrent_finished_alert); | TORRENT_DEFINE_ALERT(torrent_finished_alert); | |||
const static int static_category = alert::status_notificatio n; | const static int static_category = alert::status_notificatio n; | |||
virtual std::string message() const | virtual std::string message() const | |||
{ return torrent_alert::message() + " torrent finished downl oading"; } | { return torrent_alert::message() + " torrent finished downl oading"; } | |||
}; | }; | |||
// this alert is posted every time a piece completes downloading | ||||
// and passes the hash check. This alert derives from torrent_alert | ||||
// which contains the torrent_handle to the torrent the piece belong | ||||
s to. | ||||
struct TORRENT_EXPORT piece_finished_alert: torrent_alert | struct TORRENT_EXPORT piece_finished_alert: torrent_alert | |||
{ | { | |||
// internal | ||||
piece_finished_alert( | piece_finished_alert( | |||
const torrent_handle& h | const torrent_handle& h | |||
, int piece_num) | , int piece_num) | |||
: torrent_alert(h) | : torrent_alert(h) | |||
, piece_index(piece_num) | , piece_index(piece_num) | |||
{ TORRENT_ASSERT(piece_index >= 0);} | { TORRENT_ASSERT(piece_index >= 0);} | |||
TORRENT_DEFINE_ALERT(piece_finished_alert); | TORRENT_DEFINE_ALERT(piece_finished_alert); | |||
const static int static_category = alert::progress_notificat ion; | const static int static_category = alert::progress_notificat ion; | |||
virtual std::string message() const; | virtual std::string message() const; | |||
// the index of the piece that finished | ||||
int piece_index; | int piece_index; | |||
}; | }; | |||
// This alert is generated when a peer rejects or ignores a piece re quest. | ||||
struct TORRENT_EXPORT request_dropped_alert: peer_alert | struct TORRENT_EXPORT request_dropped_alert: peer_alert | |||
{ | { | |||
// internal | ||||
request_dropped_alert(const torrent_handle& h, tcp::endpoint const& ep | request_dropped_alert(const torrent_handle& h, tcp::endpoint const& ep | |||
, peer_id const& peer_id, int block_num, int piece_n um) | , peer_id const& peer_id, int block_num, int piece_n um) | |||
: peer_alert(h, ep, peer_id) | : peer_alert(h, ep, peer_id) | |||
, block_index(block_num) | , block_index(block_num) | |||
, piece_index(piece_num) | , piece_index(piece_num) | |||
{ TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);} | { TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);} | |||
TORRENT_DEFINE_ALERT(request_dropped_alert); | TORRENT_DEFINE_ALERT(request_dropped_alert); | |||
const static int static_category = alert::progress_notificat ion | const static int static_category = alert::progress_notificat ion | |||
| alert::peer_notification; | | alert::peer_notification; | |||
virtual std::string message() const; | virtual std::string message() const; | |||
int block_index; | int block_index; | |||
int piece_index; | int piece_index; | |||
}; | }; | |||
// This alert is generated when a block request times out. | ||||
struct TORRENT_EXPORT block_timeout_alert: peer_alert | struct TORRENT_EXPORT block_timeout_alert: peer_alert | |||
{ | { | |||
// internal | ||||
block_timeout_alert(const torrent_handle& h, tcp::endpoint c onst& ep | block_timeout_alert(const torrent_handle& h, tcp::endpoint c onst& ep | |||
, peer_id const& peer_id, int block_num, int piece_n um) | , peer_id const& peer_id, int block_num, int piece_n um) | |||
: peer_alert(h, ep, peer_id) | : peer_alert(h, ep, peer_id) | |||
, block_index(block_num) | , block_index(block_num) | |||
, piece_index(piece_num) | , piece_index(piece_num) | |||
{ TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);} | { TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);} | |||
TORRENT_DEFINE_ALERT(block_timeout_alert); | TORRENT_DEFINE_ALERT(block_timeout_alert); | |||
const static int static_category = alert::progress_notificat ion | const static int static_category = alert::progress_notificat ion | |||
| alert::peer_notification; | | alert::peer_notification; | |||
virtual std::string message() const; | virtual std::string message() const; | |||
int block_index; | int block_index; | |||
int piece_index; | int piece_index; | |||
}; | }; | |||
// This alert is generated when a block request receives a response. | ||||
struct TORRENT_EXPORT block_finished_alert: peer_alert | struct TORRENT_EXPORT block_finished_alert: peer_alert | |||
{ | { | |||
// internal | ||||
block_finished_alert(const torrent_handle& h, tcp::endpoint const& ep | block_finished_alert(const torrent_handle& h, tcp::endpoint const& ep | |||
, peer_id const& peer_id, int block_num, int piece_n um) | , peer_id const& peer_id, int block_num, int piece_n um) | |||
: peer_alert(h, ep, peer_id) | : peer_alert(h, ep, peer_id) | |||
, block_index(block_num) | , block_index(block_num) | |||
, piece_index(piece_num) | , piece_index(piece_num) | |||
{ TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);} | { TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);} | |||
TORRENT_DEFINE_ALERT(block_finished_alert); | TORRENT_DEFINE_ALERT(block_finished_alert); | |||
const static int static_category = alert::progress_notificat ion; | const static int static_category = alert::progress_notificat ion; | |||
virtual std::string message() const; | virtual std::string message() const; | |||
int block_index; | int block_index; | |||
int piece_index; | int piece_index; | |||
}; | }; | |||
// This alert is generated when a block request is sent to a peer. | ||||
struct TORRENT_EXPORT block_downloading_alert: peer_alert | struct TORRENT_EXPORT block_downloading_alert: peer_alert | |||
{ | { | |||
// internal | ||||
block_downloading_alert(const torrent_handle& h, tcp::endpoi nt const& ep | block_downloading_alert(const torrent_handle& h, tcp::endpoi nt const& ep | |||
, peer_id const& peer_id, char const* speedmsg, int block_num, int piece_num) | , peer_id const& peer_id, char const* speedmsg, int block_num, int piece_num) | |||
: peer_alert(h, ep, peer_id) | : peer_alert(h, ep, peer_id) | |||
, peer_speedmsg(speedmsg) | , peer_speedmsg(speedmsg) | |||
, block_index(block_num) | , block_index(block_num) | |||
, piece_index(piece_num) | , piece_index(piece_num) | |||
{ TORRENT_ASSERT(block_index >= 0 && piece_index >= 0); } | { TORRENT_ASSERT(block_index >= 0 && piece_index >= 0); } | |||
TORRENT_DEFINE_ALERT(block_downloading_alert); | TORRENT_DEFINE_ALERT(block_downloading_alert); | |||
const static int static_category = alert::progress_notificat ion; | const static int static_category = alert::progress_notificat ion; | |||
virtual std::string message() const; | virtual std::string message() const; | |||
char const* peer_speedmsg; | char const* peer_speedmsg; | |||
int block_index; | int block_index; | |||
int piece_index; | int piece_index; | |||
}; | }; | |||
// This alert is generated when a block is received that was not req | ||||
uested or | ||||
// whose request timed out. | ||||
struct TORRENT_EXPORT unwanted_block_alert: peer_alert | struct TORRENT_EXPORT unwanted_block_alert: peer_alert | |||
{ | { | |||
// internal | ||||
unwanted_block_alert(const torrent_handle& h, tcp::endpoint const& ep | unwanted_block_alert(const torrent_handle& h, tcp::endpoint const& ep | |||
, peer_id const& peer_id, int block_num, int piece_n um) | , peer_id const& peer_id, int block_num, int piece_n um) | |||
: peer_alert(h, ep, peer_id) | : peer_alert(h, ep, peer_id) | |||
, block_index(block_num) | , block_index(block_num) | |||
, piece_index(piece_num) | , piece_index(piece_num) | |||
{ TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);} | { TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);} | |||
TORRENT_DEFINE_ALERT(unwanted_block_alert); | TORRENT_DEFINE_ALERT(unwanted_block_alert); | |||
virtual std::string message() const; | virtual std::string message() const; | |||
int block_index; | int block_index; | |||
int piece_index; | int piece_index; | |||
}; | }; | |||
// The ``storage_moved_alert`` is generated when all the disk IO has | ||||
completed and the | ||||
// files have been moved, as an effect of a call to ``torrent_handle | ||||
::move_storage``. This | ||||
// is useful to synchronize with the actual disk. The ``path`` membe | ||||
r is the new path of | ||||
// the storage. | ||||
struct TORRENT_EXPORT storage_moved_alert: torrent_alert | struct TORRENT_EXPORT storage_moved_alert: torrent_alert | |||
{ | { | |||
storage_moved_alert(torrent_handle const& h, std::string con | // internal | |||
st& path_) | storage_moved_alert(torrent_handle const& h, std::string con | |||
st& p) | ||||
: torrent_alert(h) | : torrent_alert(h) | |||
, path(path_) | , path(p) | |||
{} | {} | |||
TORRENT_DEFINE_ALERT(storage_moved_alert); | TORRENT_DEFINE_ALERT(storage_moved_alert); | |||
const static int static_category = alert::storage_notificati on; | const static int static_category = alert::storage_notificati on; | |||
virtual std::string message() const | virtual std::string message() const | |||
{ | { | |||
return torrent_alert::message() + " moved storage to : " | return torrent_alert::message() + " moved storage to : " | |||
+ path; | + path; | |||
} | } | |||
std::string path; | std::string path; | |||
}; | }; | |||
// The ``storage_moved_failed_alert`` is generated when an attempt t | ||||
o move the storage, | ||||
// via torrent_handle::move_storage(), fails. | ||||
struct TORRENT_EXPORT storage_moved_failed_alert: torrent_alert | struct TORRENT_EXPORT storage_moved_failed_alert: torrent_alert | |||
{ | { | |||
storage_moved_failed_alert(torrent_handle const& h, error_co | // internal | |||
de const& ec_) | storage_moved_failed_alert(torrent_handle const& h, error_co | |||
de const& e) | ||||
: torrent_alert(h) | : torrent_alert(h) | |||
, error(ec_) | , error(e) | |||
{} | {} | |||
TORRENT_DEFINE_ALERT(storage_moved_failed_alert); | TORRENT_DEFINE_ALERT(storage_moved_failed_alert); | |||
const static int static_category = alert::storage_notificati on; | const static int static_category = alert::storage_notificati on; | |||
virtual std::string message() const | virtual std::string message() const | |||
{ | { | |||
return torrent_alert::message() + " storage move fai led: " | return torrent_alert::message() + " storage move fai led: " | |||
+ convert_from_native(error.message()); | + convert_from_native(error.message()); | |||
} | } | |||
error_code error; | error_code error; | |||
}; | }; | |||
// This alert is generated when a request to delete the files of a t | ||||
orrent complete. | ||||
// | ||||
// The ``info_hash`` is the info-hash of the torrent that was just d | ||||
eleted. Most of | ||||
// the time the torrent_handle in the ``torrent_alert`` will be inva | ||||
lid by the time | ||||
// this alert arrives, since the torrent is being deleted. The ``inf | ||||
o_hash`` member | ||||
// is hence the main way of identifying which torrent just completed | ||||
the delete. | ||||
// | ||||
// This alert is posted in the ``storage_notification`` category, an | ||||
d that bit | ||||
// needs to be set in the alert_mask. | ||||
struct TORRENT_EXPORT torrent_deleted_alert: torrent_alert | struct TORRENT_EXPORT torrent_deleted_alert: torrent_alert | |||
{ | { | |||
// internal | ||||
torrent_deleted_alert(torrent_handle const& h, sha1_hash con st& ih) | torrent_deleted_alert(torrent_handle const& h, sha1_hash con st& ih) | |||
: torrent_alert(h) | : torrent_alert(h) | |||
{ info_hash = ih; } | { info_hash = ih; } | |||
TORRENT_DEFINE_ALERT(torrent_deleted_alert); | TORRENT_DEFINE_ALERT(torrent_deleted_alert); | |||
const static int static_category = alert::storage_notificati on; | const static int static_category = alert::storage_notificati on; | |||
virtual std::string message() const | virtual std::string message() const | |||
{ return torrent_alert::message() + " deleted"; } | { return torrent_alert::message() + " deleted"; } | |||
virtual bool discardable() const { return false; } | ||||
sha1_hash info_hash; | sha1_hash info_hash; | |||
}; | }; | |||
// This alert is generated when a request to delete the files of a t | ||||
orrent fails. | ||||
// Just removing a torrent from the session cannot fail | ||||
struct TORRENT_EXPORT torrent_delete_failed_alert: torrent_alert | struct TORRENT_EXPORT torrent_delete_failed_alert: torrent_alert | |||
{ | { | |||
torrent_delete_failed_alert(torrent_handle const& h, error_c | // internal | |||
ode const& e) | torrent_delete_failed_alert(torrent_handle const& h, error_c | |||
ode const& e, sha1_hash const& ih) | ||||
: torrent_alert(h) | : torrent_alert(h) | |||
, error(e) | , error(e) | |||
, info_hash(ih) | ||||
{ | { | |||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
msg = convert_from_native(error.message()); | msg = convert_from_native(error.message()); | |||
#endif | #endif | |||
} | } | |||
TORRENT_DEFINE_ALERT(torrent_delete_failed_alert); | TORRENT_DEFINE_ALERT(torrent_delete_failed_alert); | |||
const static int static_category = alert::storage_notificati on | const static int static_category = alert::storage_notificati on | |||
| alert::error_notification; | | alert::error_notification; | |||
virtual std::string message() const | virtual std::string message() const | |||
{ | { | |||
return torrent_alert::message() + " torrent deletion failed: " | return torrent_alert::message() + " torrent deletion failed: " | |||
+convert_from_native(error.message()); | +convert_from_native(error.message()); | |||
} | } | |||
virtual bool discardable() const { return false; } | ||||
// tells you why it failed. | ||||
error_code error; | error_code error; | |||
// the info hash of the torrent whose files failed to be del | ||||
eted | ||||
sha1_hash info_hash; | ||||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
std::string msg; | std::string msg; | |||
#endif | #endif | |||
}; | }; | |||
// This alert is generated as a response to a ``torrent_handle::save | ||||
_resume_data`` request. | ||||
// It is generated once the disk IO thread is done writing the state | ||||
for this torrent. | ||||
struct TORRENT_EXPORT save_resume_data_alert: torrent_alert | struct TORRENT_EXPORT save_resume_data_alert: torrent_alert | |||
{ | { | |||
// internal | ||||
save_resume_data_alert(boost::shared_ptr<entry> const& rd | save_resume_data_alert(boost::shared_ptr<entry> const& rd | |||
, torrent_handle const& h) | , torrent_handle const& h) | |||
: torrent_alert(h) | : torrent_alert(h) | |||
, resume_data(rd) | , resume_data(rd) | |||
{} | {} | |||
TORRENT_DEFINE_ALERT(save_resume_data_alert); | TORRENT_DEFINE_ALERT(save_resume_data_alert); | |||
const static int static_category = alert::storage_notificati on; | const static int static_category = alert::storage_notificati on; | |||
virtual std::string message() const | virtual std::string message() const | |||
{ return torrent_alert::message() + " resume data generated" ; } | { return torrent_alert::message() + " resume data generated" ; } | |||
virtual bool discardable() const { return false; } | virtual bool discardable() const { return false; } | |||
// points to the resume data. | ||||
boost::shared_ptr<entry> resume_data; | boost::shared_ptr<entry> resume_data; | |||
}; | }; | |||
// This alert is generated instead of ``save_resume_data_alert`` if | ||||
there was an error | ||||
// generating the resume data. ``error`` describes what went wrong. | ||||
struct TORRENT_EXPORT save_resume_data_failed_alert: torrent_alert | struct TORRENT_EXPORT save_resume_data_failed_alert: torrent_alert | |||
{ | { | |||
// internal | ||||
save_resume_data_failed_alert(torrent_handle const& h | save_resume_data_failed_alert(torrent_handle const& h | |||
, error_code const& e) | , error_code const& e) | |||
: torrent_alert(h) | : torrent_alert(h) | |||
, error(e) | , error(e) | |||
{ | { | |||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
msg = convert_from_native(error.message()); | msg = convert_from_native(error.message()); | |||
#endif | #endif | |||
} | } | |||
skipping to change at line 786 | skipping to change at line 1052 | |||
} | } | |||
virtual bool discardable() const { return false; } | virtual bool discardable() const { return false; } | |||
error_code error; | error_code error; | |||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
std::string msg; | std::string msg; | |||
#endif | #endif | |||
}; | }; | |||
// This alert is generated as a response to a ``torrent_handle::paus | ||||
e`` request. It is | ||||
// generated once all disk IO is complete and the files in the torre | ||||
nt have been closed. | ||||
// This is useful for synchronizing with the disk. | ||||
struct TORRENT_EXPORT torrent_paused_alert: torrent_alert | struct TORRENT_EXPORT torrent_paused_alert: torrent_alert | |||
{ | { | |||
// internal | ||||
torrent_paused_alert(torrent_handle const& h) | torrent_paused_alert(torrent_handle const& h) | |||
: torrent_alert(h) | : torrent_alert(h) | |||
{} | {} | |||
TORRENT_DEFINE_ALERT(torrent_paused_alert); | TORRENT_DEFINE_ALERT(torrent_paused_alert); | |||
const static int static_category = alert::status_notificatio n; | const static int static_category = alert::status_notificatio n; | |||
virtual std::string message() const | virtual std::string message() const | |||
{ return torrent_alert::message() + " paused"; } | { return torrent_alert::message() + " paused"; } | |||
}; | }; | |||
// This alert is generated as a response to a torrent_handle::resume | ||||
() request. It is | ||||
// generated when a torrent goes from a paused state to an active st | ||||
ate. | ||||
struct TORRENT_EXPORT torrent_resumed_alert: torrent_alert | struct TORRENT_EXPORT torrent_resumed_alert: torrent_alert | |||
{ | { | |||
// internal | ||||
torrent_resumed_alert(torrent_handle const& h) | torrent_resumed_alert(torrent_handle const& h) | |||
: torrent_alert(h) {} | : torrent_alert(h) {} | |||
TORRENT_DEFINE_ALERT(torrent_resumed_alert); | TORRENT_DEFINE_ALERT(torrent_resumed_alert); | |||
const static int static_category = alert::status_notificatio n; | const static int static_category = alert::status_notificatio n; | |||
virtual std::string message() const | virtual std::string message() const | |||
{ return torrent_alert::message() + " resumed"; } | { return torrent_alert::message() + " resumed"; } | |||
}; | }; | |||
// This alert is posted when a torrent completes checking. i.e. when | ||||
it transitions | ||||
// out of the ``checking files`` state into a state where it is read | ||||
y to start downloading | ||||
struct TORRENT_EXPORT torrent_checked_alert: torrent_alert | struct TORRENT_EXPORT torrent_checked_alert: torrent_alert | |||
{ | { | |||
// internal | ||||
torrent_checked_alert(torrent_handle const& h) | torrent_checked_alert(torrent_handle const& h) | |||
: torrent_alert(h) | : torrent_alert(h) | |||
{} | {} | |||
TORRENT_DEFINE_ALERT(torrent_checked_alert); | TORRENT_DEFINE_ALERT(torrent_checked_alert); | |||
const static int static_category = alert::status_notificatio n; | const static int static_category = alert::status_notificatio n; | |||
virtual std::string message() const | virtual std::string message() const | |||
{ return torrent_alert::message() + " checked"; } | { return torrent_alert::message() + " checked"; } | |||
}; | }; | |||
// This alert is generated when a HTTP seed name lookup fails. | ||||
struct TORRENT_EXPORT url_seed_alert: torrent_alert | struct TORRENT_EXPORT url_seed_alert: torrent_alert | |||
{ | { | |||
// internal | ||||
url_seed_alert( | url_seed_alert( | |||
torrent_handle const& h | torrent_handle const& h | |||
, std::string const& url_ | , std::string const& u | |||
, error_code const& e) | , error_code const& e) | |||
: torrent_alert(h) | : torrent_alert(h) | |||
, url(url_) | , url(u) | |||
, msg(convert_from_native(e.message())) | , msg(convert_from_native(e.message())) | |||
{} | {} | |||
url_seed_alert( | url_seed_alert( | |||
torrent_handle const& h | torrent_handle const& h | |||
, std::string const& url_ | , std::string const& u | |||
, std::string const& msg_) | , std::string const& m) | |||
: torrent_alert(h) | : torrent_alert(h) | |||
, url(url_) | , url(u) | |||
, msg(msg_) | , msg(m) | |||
{} | {} | |||
TORRENT_DEFINE_ALERT(url_seed_alert); | TORRENT_DEFINE_ALERT(url_seed_alert); | |||
const static int static_category = alert::peer_notification | alert::error_notification; | const static int static_category = alert::peer_notification | alert::error_notification; | |||
virtual std::string message() const | virtual std::string message() const | |||
{ | { | |||
return torrent_alert::message() + " url seed (" | return torrent_alert::message() + " url seed (" | |||
+ url + ") failed: " + msg; | + url + ") failed: " + msg; | |||
} | } | |||
// the HTTP seed that failed | ||||
std::string url; | std::string url; | |||
// the error message, potentially from the server | ||||
std::string msg; | std::string msg; | |||
}; | }; | |||
// If the storage fails to read or write files that it needs access | ||||
to, this alert is | ||||
// generated and the torrent is paused. | ||||
struct TORRENT_EXPORT file_error_alert: torrent_alert | struct TORRENT_EXPORT file_error_alert: torrent_alert | |||
{ | { | |||
// internal | ||||
file_error_alert( | file_error_alert( | |||
std::string const& f | std::string const& f | |||
, torrent_handle const& h | , torrent_handle const& h | |||
, error_code const& e) | , error_code const& e) | |||
: torrent_alert(h) | : torrent_alert(h) | |||
, file(f) | , file(f) | |||
, error(e) | , error(e) | |||
{ | { | |||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
msg = convert_from_native(error.message()); | msg = convert_from_native(error.message()); | |||
skipping to change at line 883 | skipping to change at line 1166 | |||
const static int static_category = alert::status_notificatio n | const static int static_category = alert::status_notificatio n | |||
| alert::error_notification | | alert::error_notification | |||
| alert::storage_notification; | | alert::storage_notification; | |||
virtual std::string message() const | virtual std::string message() const | |||
{ | { | |||
return torrent_alert::message() + " file (" + file + ") error: " | return torrent_alert::message() + " file (" + file + ") error: " | |||
+ convert_from_native(error.message()); | + convert_from_native(error.message()); | |||
} | } | |||
// the path to the file that was accessed when the error occ urred. | ||||
std::string file; | std::string file; | |||
// the error code describing the error. | ||||
error_code error; | error_code error; | |||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
std::string msg; | std::string msg; | |||
#endif | #endif | |||
}; | }; | |||
// This alert is generated when the metadata has been completely rec | ||||
eived and the info-hash | ||||
// failed to match it. i.e. the metadata that was received was corru | ||||
pt. libtorrent will | ||||
// automatically retry to fetch it in this case. This is only releva | ||||
nt when running a | ||||
// torrent-less download, with the metadata extension provided by li | ||||
btorrent. | ||||
struct TORRENT_EXPORT metadata_failed_alert: torrent_alert | struct TORRENT_EXPORT metadata_failed_alert: torrent_alert | |||
{ | { | |||
metadata_failed_alert(const torrent_handle& h) | // internal | |||
metadata_failed_alert(const torrent_handle& h, error_code e) | ||||
: torrent_alert(h) | : torrent_alert(h) | |||
, error(e) | ||||
{} | {} | |||
TORRENT_DEFINE_ALERT(metadata_failed_alert); | TORRENT_DEFINE_ALERT(metadata_failed_alert); | |||
const static int static_category = alert::error_notification ; | const static int static_category = alert::error_notification ; | |||
virtual std::string message() const | virtual std::string message() const | |||
{ return torrent_alert::message() + " invalid metadata recei ved"; } | { return torrent_alert::message() + " invalid metadata recei ved"; } | |||
// the error that occurred | ||||
error_code error; | ||||
}; | }; | |||
// This alert is generated when the metadata has been completely rec | ||||
eived and the torrent | ||||
// can start downloading. It is not generated on torrents that are s | ||||
tarted with metadata, but | ||||
// only those that needs to download it from peers (when utilizing t | ||||
he libtorrent extension). | ||||
// | ||||
// There are no additional data members in this alert. | ||||
// | ||||
// Typically, when receiving this alert, you would want to save the | ||||
torrent file in order | ||||
// to load it back up again when the session is restarted. Here's an | ||||
example snippet of | ||||
// code to do that:: | ||||
// | ||||
// torrent_handle h = alert->handle(); | ||||
// if (h.is_valid()) { | ||||
// boost::intrusive_ptr<torrent_info const> ti = h.torr | ||||
ent_file(); | ||||
// create_torrent ct(*ti); | ||||
// entry te = ct.generate(); | ||||
// std::vector<char> buffer; | ||||
// bencode(std::back_inserter(buffer), te); | ||||
// FILE* f = fopen((to_hex(ti->info_hash().to_string()) | ||||
+ ".torrent").c_str(), "wb+"); | ||||
// if (f) { | ||||
// fwrite(&buffer[0], 1, buffer.size(), f); | ||||
// fclose(f); | ||||
// } | ||||
// } | ||||
// | ||||
struct TORRENT_EXPORT metadata_received_alert: torrent_alert | struct TORRENT_EXPORT metadata_received_alert: torrent_alert | |||
{ | { | |||
// internal | ||||
metadata_received_alert( | metadata_received_alert( | |||
const torrent_handle& h) | const torrent_handle& h) | |||
: torrent_alert(h) | : torrent_alert(h) | |||
{} | {} | |||
TORRENT_DEFINE_ALERT(metadata_received_alert); | TORRENT_DEFINE_ALERT(metadata_received_alert); | |||
const static int static_category = alert::status_notificatio n; | const static int static_category = alert::status_notificatio n; | |||
virtual std::string message() const | virtual std::string message() const | |||
{ return torrent_alert::message() + " metadata successfully received"; } | { return torrent_alert::message() + " metadata successfully received"; } | |||
}; | }; | |||
// This alert is posted when there is an error on the UDP socket. Th | ||||
e | ||||
// UDP socket is used for all uTP, DHT and UDP tracker traffic. It's | ||||
// global to the session. | ||||
struct TORRENT_EXPORT udp_error_alert: alert | struct TORRENT_EXPORT udp_error_alert: alert | |||
{ | { | |||
// internal | ||||
udp_error_alert( | udp_error_alert( | |||
udp::endpoint const& ep | udp::endpoint const& ep | |||
, error_code const& ec) | , error_code const& ec) | |||
: endpoint(ep) | : endpoint(ep) | |||
, error(ec) | , error(ec) | |||
{} | {} | |||
TORRENT_DEFINE_ALERT(udp_error_alert); | TORRENT_DEFINE_ALERT(udp_error_alert); | |||
const static int static_category = alert::error_notification ; | const static int static_category = alert::error_notification ; | |||
virtual std::string message() const | virtual std::string message() const | |||
{ | { | |||
error_code ec; | error_code ec; | |||
return "UDP error: " + convert_from_native(error.mes sage()) + " from: " + endpoint.address().to_string(ec); | return "UDP error: " + convert_from_native(error.mes sage()) + " from: " + endpoint.address().to_string(ec); | |||
} | } | |||
// the source address associated with the error (if any) | ||||
udp::endpoint endpoint; | udp::endpoint endpoint; | |||
// the error code describing the error | ||||
error_code error; | error_code error; | |||
}; | }; | |||
// Whenever libtorrent learns about the machines external IP, this a | ||||
lert is | ||||
// generated. The external IP address can be acquired from the track | ||||
er (if it | ||||
// supports that) or from peers that supports the extension protocol | ||||
. | ||||
// The address can be accessed through the ``external_address`` memb | ||||
er. | ||||
struct TORRENT_EXPORT external_ip_alert: alert | struct TORRENT_EXPORT external_ip_alert: alert | |||
{ | { | |||
// internal | ||||
external_ip_alert(address const& ip) | external_ip_alert(address const& ip) | |||
: external_address(ip) | : external_address(ip) | |||
{} | {} | |||
TORRENT_DEFINE_ALERT(external_ip_alert); | TORRENT_DEFINE_ALERT(external_ip_alert); | |||
const static int static_category = alert::status_notificatio n; | const static int static_category = alert::status_notificatio n; | |||
virtual std::string message() const | virtual std::string message() const | |||
{ | { | |||
error_code ec; | error_code ec; | |||
return "external IP received: " + external_address.t o_string(ec); | return "external IP received: " + external_address.t o_string(ec); | |||
} | } | |||
// the IP address that is believed to be our external IP | ||||
address external_address; | address external_address; | |||
}; | }; | |||
// This alert is generated when none of the ports, given in the port | ||||
range, to | ||||
// session can be opened for listening. The ``endpoint`` member is t | ||||
he | ||||
// interface and port that failed, ``error`` is the error code descr | ||||
ibing | ||||
// the failure. | ||||
// | ||||
// libtorrent may sometimes try to listen on port 0, if all other po | ||||
rts failed. | ||||
// Port 0 asks the operating system to pick a port that's free). If | ||||
that fails | ||||
// you may see a listen_failed_alert with port 0 even if you didn't | ||||
ask to | ||||
// listen on it. | ||||
struct TORRENT_EXPORT listen_failed_alert: alert | struct TORRENT_EXPORT listen_failed_alert: alert | |||
{ | { | |||
enum socket_type_t { tcp, tcp_ssl, udp, i2p, socks5 }; | ||||
// internal | ||||
listen_failed_alert( | listen_failed_alert( | |||
tcp::endpoint const& ep | tcp::endpoint const& ep | |||
, error_code const& ec) | , int op | |||
, error_code const& ec | ||||
, socket_type_t t) | ||||
: endpoint(ep) | : endpoint(ep) | |||
, error(ec) | , error(ec) | |||
, operation(op) | ||||
, sock_type(t) | ||||
{} | {} | |||
TORRENT_DEFINE_ALERT(listen_failed_alert); | TORRENT_DEFINE_ALERT(listen_failed_alert); | |||
const static int static_category = alert::status_notificatio n | alert::error_notification; | const static int static_category = alert::status_notificatio n | alert::error_notification; | |||
virtual std::string message() const; | virtual std::string message() const; | |||
virtual bool discardable() const { return false; } | virtual bool discardable() const { return false; } | |||
// the endpoint libtorrent attempted to listen on | ||||
tcp::endpoint endpoint; | tcp::endpoint endpoint; | |||
// the error the system returned | ||||
error_code error; | error_code error; | |||
enum op_t | ||||
{ | ||||
parse_addr, open, bind, listen, get_peer_name, accep | ||||
t | ||||
}; | ||||
// the specific low level operation that failed. See op_t. | ||||
int operation; | ||||
// the type of listen socket this alert refers to. | ||||
socket_type_t sock_type; | ||||
}; | }; | |||
// This alert is posted when the listen port succeeds to be opened o | ||||
n a | ||||
// particular interface. ``endpoint`` is the endpoint that successfu | ||||
lly | ||||
// was opened for listening. | ||||
struct TORRENT_EXPORT listen_succeeded_alert: alert | struct TORRENT_EXPORT listen_succeeded_alert: alert | |||
{ | { | |||
listen_succeeded_alert(tcp::endpoint const& ep) | enum socket_type_t { tcp, tcp_ssl, udp }; | |||
// internal | ||||
listen_succeeded_alert(tcp::endpoint const& ep, socket_type_ | ||||
t t) | ||||
: endpoint(ep) | : endpoint(ep) | |||
, sock_type(t) | ||||
{} | {} | |||
TORRENT_DEFINE_ALERT(listen_succeeded_alert); | TORRENT_DEFINE_ALERT(listen_succeeded_alert); | |||
const static int static_category = alert::status_notificatio n; | const static int static_category = alert::status_notificatio n; | |||
virtual std::string message() const; | virtual std::string message() const; | |||
virtual bool discardable() const { return false; } | virtual bool discardable() const { return false; } | |||
// the endpoint libtorrent ended up listening on. The addres | ||||
s | ||||
// refers to the local interface and the port is the listen | ||||
port. | ||||
tcp::endpoint endpoint; | tcp::endpoint endpoint; | |||
// the type of listen socket this alert refers to. | ||||
socket_type_t sock_type; | ||||
}; | }; | |||
// This alert is generated when a NAT router was successfully found | ||||
but some | ||||
// part of the port mapping request failed. It contains a text messa | ||||
ge that | ||||
// may help the user figure out what is wrong. This alert is not gen | ||||
erated in | ||||
// case it appears the client is not running on a NAT:ed network or | ||||
if it | ||||
// appears there is no NAT router that can be remote controlled to a | ||||
dd port | ||||
// mappings. | ||||
struct TORRENT_EXPORT portmap_error_alert: alert | struct TORRENT_EXPORT portmap_error_alert: alert | |||
{ | { | |||
// internal | ||||
portmap_error_alert(int i, int t, error_code const& e) | portmap_error_alert(int i, int t, error_code const& e) | |||
: mapping(i), map_type(t), error(e) | : mapping(i), map_type(t), error(e) | |||
{ | { | |||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
msg = convert_from_native(error.message()); | msg = convert_from_native(error.message()); | |||
#endif | #endif | |||
} | } | |||
TORRENT_DEFINE_ALERT(portmap_error_alert); | TORRENT_DEFINE_ALERT(portmap_error_alert); | |||
const static int static_category = alert::port_mapping_notif ication | const static int static_category = alert::port_mapping_notif ication | |||
| alert::error_notification; | | alert::error_notification; | |||
virtual std::string message() const; | virtual std::string message() const; | |||
// refers to the mapping index of the port map that failed, | ||||
i.e. | ||||
// the index returned from add_mapping(). | ||||
int mapping; | int mapping; | |||
// is 0 for NAT-PMP and 1 for UPnP. | ||||
int map_type; | int map_type; | |||
// tells you what failed. | ||||
error_code error; | error_code error; | |||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
std::string msg; | std::string msg; | |||
#endif | #endif | |||
}; | }; | |||
// This alert is generated when a NAT router was successfully found | ||||
and | ||||
// a port was successfully mapped on it. On a NAT:ed network with a | ||||
NAT-PMP | ||||
// capable router, this is typically generated once when mapping the | ||||
TCP | ||||
// port and, if DHT is enabled, when the UDP port is mapped. | ||||
struct TORRENT_EXPORT portmap_alert: alert | struct TORRENT_EXPORT portmap_alert: alert | |||
{ | { | |||
// internal | ||||
portmap_alert(int i, int port, int t) | portmap_alert(int i, int port, int t) | |||
: mapping(i), external_port(port), map_type(t) | : mapping(i), external_port(port), map_type(t) | |||
{} | {} | |||
TORRENT_DEFINE_ALERT(portmap_alert); | TORRENT_DEFINE_ALERT(portmap_alert); | |||
const static int static_category = alert::port_mapping_notif ication; | const static int static_category = alert::port_mapping_notif ication; | |||
virtual std::string message() const; | virtual std::string message() const; | |||
// refers to the mapping index of the port map that failed, | ||||
i.e. | ||||
// the index returned from add_mapping(). | ||||
int mapping; | int mapping; | |||
// the external port allocated for the mapping. | ||||
int external_port; | int external_port; | |||
// 0 for NAT-PMP and 1 for UPnP. | ||||
int map_type; | int map_type; | |||
}; | }; | |||
// This alert is generated to log informational events related to ei | ||||
ther | ||||
// UPnP or NAT-PMP. They contain a log line and the type (0 = NAT-PM | ||||
P | ||||
// and 1 = UPnP). Displaying these messages to an end user is only u | ||||
seful | ||||
// for debugging the UPnP or NAT-PMP implementation. | ||||
struct TORRENT_EXPORT portmap_log_alert: alert | struct TORRENT_EXPORT portmap_log_alert: alert | |||
{ | { | |||
// internal | ||||
portmap_log_alert(int t, std::string const& m) | portmap_log_alert(int t, std::string const& m) | |||
: map_type(t), msg(m) | : map_type(t), msg(m) | |||
{} | {} | |||
TORRENT_DEFINE_ALERT(portmap_log_alert); | TORRENT_DEFINE_ALERT(portmap_log_alert); | |||
const static int static_category = alert::port_mapping_notif ication; | const static int static_category = alert::port_mapping_notif ication; | |||
virtual std::string message() const; | virtual std::string message() const; | |||
int map_type; | int map_type; | |||
std::string msg; | std::string msg; | |||
}; | }; | |||
// This alert is generated when a fastresume file has been passed to | ||||
add_torrent() but the | ||||
// files on disk did not match the fastresume file. The error_code e | ||||
xplains the reason why the | ||||
// resume file was rejected. | ||||
struct TORRENT_EXPORT fastresume_rejected_alert: torrent_alert | struct TORRENT_EXPORT fastresume_rejected_alert: torrent_alert | |||
{ | { | |||
// internal | ||||
fastresume_rejected_alert(torrent_handle const& h | fastresume_rejected_alert(torrent_handle const& h | |||
, error_code const& e) | , error_code const& e) | |||
: torrent_alert(h) | : torrent_alert(h) | |||
, error(e) | , error(e) | |||
{ | { | |||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
msg = convert_from_native(error.message()); | msg = convert_from_native(error.message()); | |||
#endif | #endif | |||
} | } | |||
skipping to change at line 1073 | skipping to change at line 1481 | |||
virtual std::string message() const | virtual std::string message() const | |||
{ return torrent_alert::message() + " fast resume rejected: " + convert_from_native(error.message()); } | { return torrent_alert::message() + " fast resume rejected: " + convert_from_native(error.message()); } | |||
error_code error; | error_code error; | |||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
std::string msg; | std::string msg; | |||
#endif | #endif | |||
}; | }; | |||
// This alert is posted when an incoming peer connection, or a peer | ||||
that's about to be added | ||||
// to our peer list, is blocked for some reason. This could be any o | ||||
f: | ||||
// | ||||
// * the IP filter | ||||
// * i2p mixed mode restrictions (a normal peer is not allowed on an | ||||
i2p swarm) | ||||
// * the port filter | ||||
// * the peer has a low port and ``no_connect_privileged_ports`` is | ||||
enabled | ||||
// * the protocol of the peer is blocked (uTP/TCP blocking) | ||||
struct TORRENT_EXPORT peer_blocked_alert: torrent_alert | struct TORRENT_EXPORT peer_blocked_alert: torrent_alert | |||
{ | { | |||
peer_blocked_alert(torrent_handle const& h, address const& i | // internal | |||
p_) | peer_blocked_alert(torrent_handle const& h, address const& i | |||
, int r) | ||||
: torrent_alert(h) | : torrent_alert(h) | |||
, ip(ip_) | , ip(i) | |||
, reason(r) | ||||
{} | {} | |||
TORRENT_DEFINE_ALERT(peer_blocked_alert); | TORRENT_DEFINE_ALERT(peer_blocked_alert); | |||
const static int static_category = alert::ip_block_notificat ion; | const static int static_category = alert::ip_block_notificat ion; | |||
virtual std::string message() const | virtual std::string message() const; | |||
{ | ||||
error_code ec; | ||||
return torrent_alert::message() + ": blocked peer: " | ||||
+ ip.to_string(ec); | ||||
} | ||||
// the address that was blocked. | ||||
address ip; | address ip; | |||
enum reason_t | ||||
{ | ||||
ip_filter, | ||||
port_filter, | ||||
i2p_mixed, | ||||
privileged_ports, | ||||
utp_disabled, | ||||
tcp_disabled | ||||
}; | ||||
int reason; | ||||
}; | }; | |||
// This alert is generated when a DHT node announces to an info-hash | ||||
on our | ||||
// DHT node. It belongs to the ``dht_notification`` category. | ||||
struct TORRENT_EXPORT dht_announce_alert: alert | struct TORRENT_EXPORT dht_announce_alert: alert | |||
{ | { | |||
dht_announce_alert(address const& ip_, int port_ | // internal | |||
, sha1_hash const& info_hash_) | dht_announce_alert(address const& i, int p | |||
: ip(ip_) | , sha1_hash const& ih) | |||
, port(port_) | : ip(i) | |||
, info_hash(info_hash_) | , port(p) | |||
, info_hash(ih) | ||||
{} | {} | |||
TORRENT_DEFINE_ALERT(dht_announce_alert); | TORRENT_DEFINE_ALERT(dht_announce_alert); | |||
const static int static_category = alert::dht_notification; | const static int static_category = alert::dht_notification; | |||
virtual std::string message() const; | virtual std::string message() const; | |||
address ip; | address ip; | |||
int port; | int port; | |||
sha1_hash info_hash; | sha1_hash info_hash; | |||
}; | }; | |||
// This alert is generated when a DHT node sends a ``get_peers`` mes | ||||
sage to | ||||
// our DHT node. It belongs to the ``dht_notification`` category. | ||||
struct TORRENT_EXPORT dht_get_peers_alert: alert | struct TORRENT_EXPORT dht_get_peers_alert: alert | |||
{ | { | |||
dht_get_peers_alert(sha1_hash const& info_hash_) | // internal | |||
: info_hash(info_hash_) | dht_get_peers_alert(sha1_hash const& ih) | |||
: info_hash(ih) | ||||
{} | {} | |||
TORRENT_DEFINE_ALERT(dht_get_peers_alert); | TORRENT_DEFINE_ALERT(dht_get_peers_alert); | |||
const static int static_category = alert::dht_notification; | const static int static_category = alert::dht_notification; | |||
virtual std::string message() const; | virtual std::string message() const; | |||
sha1_hash info_hash; | sha1_hash info_hash; | |||
}; | }; | |||
// This alert is posted approximately once every second, and it cont | ||||
ains | ||||
// byte counters of most statistics that's tracked for torrents. Eac | ||||
h active | ||||
// torrent posts these alerts regularly. | ||||
struct TORRENT_EXPORT stats_alert: torrent_alert | struct TORRENT_EXPORT stats_alert: torrent_alert | |||
{ | { | |||
// internal | ||||
stats_alert(torrent_handle const& h, int interval | stats_alert(torrent_handle const& h, int interval | |||
, stat const& s); | , stat const& s); | |||
TORRENT_DEFINE_ALERT(stats_alert); | TORRENT_DEFINE_ALERT(stats_alert); | |||
const static int static_category = alert::stats_notification ; | const static int static_category = alert::stats_notification ; | |||
virtual std::string message() const; | virtual std::string message() const; | |||
enum stats_channel | enum stats_channel | |||
{ | { | |||
skipping to change at line 1152 | skipping to change at line 1590 | |||
upload_ip_protocol, | upload_ip_protocol, | |||
upload_dht_protocol, | upload_dht_protocol, | |||
upload_tracker_protocol, | upload_tracker_protocol, | |||
download_ip_protocol, | download_ip_protocol, | |||
download_dht_protocol, | download_dht_protocol, | |||
download_tracker_protocol, | download_tracker_protocol, | |||
#endif | #endif | |||
num_channels | num_channels | |||
}; | }; | |||
// an array of samples. The enum describes what each sample | ||||
is a | ||||
// measurement of. All of these are raw, and not smoothing i | ||||
s performed. | ||||
int transferred[num_channels]; | int transferred[num_channels]; | |||
// the number of milliseconds during which these stats were | ||||
collected. | ||||
// This is typically just above 1000, but if CPU is limited, | ||||
it may be | ||||
// higher than that. | ||||
int interval; | int interval; | |||
}; | }; | |||
// This alert is posted when the disk cache has been flushed for a s | ||||
pecific | ||||
// torrent as a result of a call to torrent_handle::flush_cache(). T | ||||
his | ||||
// alert belongs to the ``storage_notification`` category, which mus | ||||
t be | ||||
// enabled to let this alert through. The alert is also posted when | ||||
removing | ||||
// a torrent from the session, once the outstanding cache flush is c | ||||
omplete | ||||
// and the torrent does no longer have any files open. | ||||
struct TORRENT_EXPORT cache_flushed_alert: torrent_alert | struct TORRENT_EXPORT cache_flushed_alert: torrent_alert | |||
{ | { | |||
// internal | ||||
cache_flushed_alert(torrent_handle const& h); | cache_flushed_alert(torrent_handle const& h); | |||
TORRENT_DEFINE_ALERT(cache_flushed_alert); | TORRENT_DEFINE_ALERT(cache_flushed_alert); | |||
const static int static_category = alert::storage_notificati on; | const static int static_category = alert::storage_notificati on; | |||
}; | }; | |||
// This alert is posted when a bittorrent feature is blocked because | ||||
of the | ||||
// anonymous mode. For instance, if the tracker proxy is not set up, | ||||
no | ||||
// trackers will be used, because trackers can only be used through | ||||
proxies | ||||
// when in anonymous mode. | ||||
struct TORRENT_EXPORT anonymous_mode_alert: torrent_alert | struct TORRENT_EXPORT anonymous_mode_alert: torrent_alert | |||
{ | { | |||
// internal | ||||
anonymous_mode_alert(torrent_handle const& h | anonymous_mode_alert(torrent_handle const& h | |||
, int kind_, std::string const& str_) | , int k, std::string const& s) | |||
: torrent_alert(h) | : torrent_alert(h) | |||
, kind(kind_) | , kind(k) | |||
, str(str_) | , str(s) | |||
{} | {} | |||
TORRENT_DEFINE_ALERT(anonymous_mode_alert); | TORRENT_DEFINE_ALERT(anonymous_mode_alert); | |||
const static int static_category = alert::error_notification ; | const static int static_category = alert::error_notification ; | |||
virtual std::string message() const; | virtual std::string message() const; | |||
enum kind_t | enum kind_t | |||
{ | { | |||
// means that there's no proxy set up for tracker | ||||
// communication and the tracker will not be contact | ||||
ed. | ||||
// The tracker which this failed for is specified in | ||||
the ``str`` member. | ||||
tracker_not_anonymous = 0 | tracker_not_anonymous = 0 | |||
}; | }; | |||
// specifies what error this is, see kind_t. | ||||
int kind; | int kind; | |||
std::string str; | std::string str; | |||
}; | }; | |||
// This alert is generated when we receive a local service discovery | ||||
message | ||||
// from a peer for a torrent we're currently participating in. | ||||
struct TORRENT_EXPORT lsd_peer_alert: peer_alert | struct TORRENT_EXPORT lsd_peer_alert: peer_alert | |||
{ | { | |||
// internal | ||||
lsd_peer_alert(torrent_handle const& h | lsd_peer_alert(torrent_handle const& h | |||
, tcp::endpoint const& ip_) | , tcp::endpoint const& i) | |||
: peer_alert(h, ip_, peer_id(0)) | : peer_alert(h, i, peer_id(0)) | |||
{} | {} | |||
TORRENT_DEFINE_ALERT(lsd_peer_alert); | TORRENT_DEFINE_ALERT(lsd_peer_alert); | |||
const static int static_category = alert::peer_notification; | const static int static_category = alert::peer_notification; | |||
virtual std::string message() const; | virtual std::string message() const; | |||
}; | }; | |||
// This alert is posted whenever a tracker responds with a ``tracker | ||||
id``. | ||||
// The tracker ID is like a cookie. The libtorrent will store the tr | ||||
acker ID | ||||
// for this tracker and repeat it in subsequent announces. | ||||
struct TORRENT_EXPORT trackerid_alert: tracker_alert | struct TORRENT_EXPORT trackerid_alert: tracker_alert | |||
{ | { | |||
// internal | ||||
trackerid_alert(torrent_handle const& h | trackerid_alert(torrent_handle const& h | |||
, std::string const& url_ | , std::string const& u | |||
, const std::string& id) | , const std::string& id) | |||
: tracker_alert(h, url_) | : tracker_alert(h, u) | |||
, trackerid(id) | , trackerid(id) | |||
{} | {} | |||
TORRENT_DEFINE_ALERT(trackerid_alert); | TORRENT_DEFINE_ALERT(trackerid_alert); | |||
const static int static_category = alert::status_notificatio n; | const static int static_category = alert::status_notificatio n; | |||
virtual std::string message() const; | virtual std::string message() const; | |||
// The tracker ID returned by the tracker | ||||
std::string trackerid; | std::string trackerid; | |||
}; | }; | |||
// This alert is posted when the initial DHT bootstrap is done. | ||||
struct TORRENT_EXPORT dht_bootstrap_alert: alert | struct TORRENT_EXPORT dht_bootstrap_alert: alert | |||
{ | { | |||
// internal | ||||
dht_bootstrap_alert() {} | dht_bootstrap_alert() {} | |||
TORRENT_DEFINE_ALERT(dht_bootstrap_alert); | TORRENT_DEFINE_ALERT(dht_bootstrap_alert); | |||
const static int static_category = alert::dht_notification; | const static int static_category = alert::dht_notification; | |||
virtual std::string message() const; | virtual std::string message() const; | |||
}; | }; | |||
// This alert is posted on RSS feed events such as start of RSS feed | ||||
updates, | ||||
// successful completed updates and errors during updates. | ||||
// | ||||
// This alert is only posted if the ``rss_notifications`` category i | ||||
s enabled | ||||
// in the alert_mask. | ||||
struct TORRENT_EXPORT rss_alert: alert | struct TORRENT_EXPORT rss_alert: alert | |||
{ | { | |||
rss_alert(feed_handle h, std::string const& url_, int state_ | // internal | |||
, error_code const& ec) | rss_alert(feed_handle h, std::string const& u, int s, error_ | |||
: handle(h), url(url_), state(state_), error(ec) | code const& ec) | |||
: handle(h), url(u), state(s), error(ec) | ||||
{} | {} | |||
TORRENT_DEFINE_ALERT(rss_alert); | TORRENT_DEFINE_ALERT(rss_alert); | |||
const static int static_category = alert::rss_notification; | const static int static_category = alert::rss_notification; | |||
virtual std::string message() const; | virtual std::string message() const; | |||
enum state_t | enum state_t | |||
{ | { | |||
state_updating, state_updated, state_error | // An update of this feed was just initiated, it wil | |||
l either succeed | ||||
// or fail soon. | ||||
state_updating, | ||||
// The feed just completed a successful update, ther | ||||
e may be new items | ||||
// in it. If you're adding torrents manually, you ma | ||||
y want to request | ||||
// the feed status of the feed and look through the | ||||
``items`` vector. | ||||
state_updated, | ||||
// An error just occurred. See the ``error`` field f | ||||
or information on | ||||
// what went wrong. | ||||
state_error | ||||
}; | }; | |||
// the handle to the feed which generated this alert. | ||||
feed_handle handle; | feed_handle handle; | |||
// a short cut to access the url of the feed, without | ||||
// having to call feed_handle::get_settings(). | ||||
std::string url; | std::string url; | |||
// one of the values from rss_alert::state_t. | ||||
int state; | int state; | |||
// an error code used for when an error occurs on the feed. | ||||
error_code error; | error_code error; | |||
}; | }; | |||
// This is posted whenever a torrent is transitioned into the error state. | ||||
struct TORRENT_EXPORT torrent_error_alert: torrent_alert | struct TORRENT_EXPORT torrent_error_alert: torrent_alert | |||
{ | { | |||
// internal | ||||
torrent_error_alert(torrent_handle const& h | torrent_error_alert(torrent_handle const& h | |||
, error_code const& e) | , error_code const& e) | |||
: torrent_alert(h) | : torrent_alert(h) | |||
, error(e) | , error(e) | |||
{} | {} | |||
TORRENT_DEFINE_ALERT(torrent_error_alert); | TORRENT_DEFINE_ALERT(torrent_error_alert); | |||
const static int static_category = alert::error_notification | alert::status_notification; | const static int static_category = alert::error_notification | alert::status_notification; | |||
virtual std::string message() const; | virtual std::string message() const; | |||
// specifies which error the torrent encountered. | ||||
error_code error; | error_code error; | |||
}; | }; | |||
// This is always posted for SSL torrents. This is a reminder to the | ||||
client that | ||||
// the torrent won't work unless torrent_handle::set_ssl_certificate | ||||
() is called with | ||||
// a valid certificate. Valid certificates MUST be signed by the SSL | ||||
certificate | ||||
// in the .torrent file. | ||||
struct TORRENT_EXPORT torrent_need_cert_alert: torrent_alert | struct TORRENT_EXPORT torrent_need_cert_alert: torrent_alert | |||
{ | { | |||
// internal | ||||
torrent_need_cert_alert(torrent_handle const& h) | torrent_need_cert_alert(torrent_handle const& h) | |||
: torrent_alert(h) | : torrent_alert(h) | |||
{} | {} | |||
TORRENT_DEFINE_ALERT(torrent_need_cert_alert); | TORRENT_DEFINE_ALERT(torrent_need_cert_alert); | |||
const static int static_category = alert::status_notificatio n; | const static int static_category = alert::status_notificatio n; | |||
virtual std::string message() const; | virtual std::string message() const; | |||
virtual bool discardable() const { return false; } | virtual bool discardable() const { return false; } | |||
error_code error; | error_code error; | |||
}; | }; | |||
// The incoming connection alert is posted every time we successfull | ||||
y accept | ||||
// an incoming connection, through any mean. The most straigh-forwar | ||||
d ways | ||||
// of accepting incoming connections are through the TCP listen sock | ||||
et and | ||||
// the UDP listen socket for uTP sockets. However, connections may a | ||||
lso be | ||||
// accepted ofer a Socks5 or i2p listen socket, or via a torrent spe | ||||
cific | ||||
// listen socket for SSL torrents. | ||||
struct TORRENT_EXPORT incoming_connection_alert: alert | struct TORRENT_EXPORT incoming_connection_alert: alert | |||
{ | { | |||
incoming_connection_alert(int type_, tcp::endpoint const& ip | // internal | |||
_) | incoming_connection_alert(int t, tcp::endpoint const& i) | |||
: socket_type(type_) | : socket_type(t) | |||
, ip(ip_) | , ip(i) | |||
{} | {} | |||
TORRENT_DEFINE_ALERT(incoming_connection_alert); | TORRENT_DEFINE_ALERT(incoming_connection_alert); | |||
const static int static_category = alert::peer_notification; | const static int static_category = alert::peer_notification; | |||
virtual std::string message() const; | virtual std::string message() const; | |||
// tells you what kind of socket the connection was accepted | ||||
// as: | ||||
// | ||||
// 0. none (no socket instantiated) | ||||
// 1. TCP | ||||
// 2. Socks5 | ||||
// 3. HTTP | ||||
// 4. uTP | ||||
// 5. i2p | ||||
// 6. SSL/TCP | ||||
// 7. SSL/Socks5 | ||||
// 8. HTTPS (SSL/HTTP) | ||||
// 9. SSL/uTP | ||||
// | ||||
int socket_type; | int socket_type; | |||
// is the IP address and port the connection came from. | ||||
tcp::endpoint ip; | tcp::endpoint ip; | |||
}; | }; | |||
// This alert is always posted when a torrent was attempted to be ad | ||||
ded | ||||
// and contains the return status of the add operation. The torrent | ||||
handle of the new | ||||
// torrent can be found in the base class' ``handle`` member. If add | ||||
ing | ||||
// the torrent failed, ``error`` contains the error code. | ||||
struct TORRENT_EXPORT add_torrent_alert : torrent_alert | struct TORRENT_EXPORT add_torrent_alert : torrent_alert | |||
{ | { | |||
// internal | ||||
add_torrent_alert(torrent_handle h, add_torrent_params const & p, error_code ec) | add_torrent_alert(torrent_handle h, add_torrent_params const & p, error_code ec) | |||
: torrent_alert(h) | : torrent_alert(h) | |||
, params(p) | , params(p) | |||
, error(ec) | , error(ec) | |||
{} | {} | |||
TORRENT_DEFINE_ALERT(add_torrent_alert); | TORRENT_DEFINE_ALERT(add_torrent_alert); | |||
const static int static_category = alert::status_notificatio n; | const static int static_category = alert::status_notificatio n; | |||
virtual std::string message() const; | virtual std::string message() const; | |||
virtual bool discardable() const { return false; } | virtual bool discardable() const { return false; } | |||
// a copy of the parameters used when adding the torrent, it | ||||
can be used | ||||
// to identify which invocation to ``async_add_torrent()`` c | ||||
aused this alert. | ||||
add_torrent_params params; | add_torrent_params params; | |||
// set to the error, if one occurred while adding the torren | ||||
t. | ||||
error_code error; | error_code error; | |||
}; | }; | |||
// This alert is only posted when requested by the user, by calling | ||||
session::post_torrent_updates() | ||||
// on the session. It contains the torrent status of all torrents th | ||||
at changed | ||||
// since last time this message was posted. Its category is ``status | ||||
_notification``, but | ||||
// it's not subject to filtering, since it's only manually posted an | ||||
yway. | ||||
struct TORRENT_EXPORT state_update_alert : alert | struct TORRENT_EXPORT state_update_alert : alert | |||
{ | { | |||
TORRENT_DEFINE_ALERT(state_update_alert); | TORRENT_DEFINE_ALERT(state_update_alert); | |||
const static int static_category = alert::status_notificatio n; | const static int static_category = alert::status_notificatio n; | |||
virtual std::string message() const; | virtual std::string message() const; | |||
virtual bool discardable() const { return false; } | virtual bool discardable() const { return false; } | |||
// contains the torrent status of all torrents that changed | ||||
since last time | ||||
// this message was posted. Note that you can map a torrent | ||||
status to a specific torrent | ||||
// via its ``handle`` member. The receiving end is suggested | ||||
to have all torrents sorted | ||||
// by the torrent_handle or hashed by it, for efficient upda | ||||
tes. | ||||
std::vector<torrent_status> status; | std::vector<torrent_status> status; | |||
}; | }; | |||
// When a torrent changes its info-hash, this alert is posted. This | ||||
only happens in very | ||||
// specific cases. For instance, when a torrent is downloaded from a | ||||
URL, the true info | ||||
// hash is not known immediately. First the .torrent file must be do | ||||
wnloaded and parsed. | ||||
// | ||||
// Once this download completes, the ``torrent_update_alert`` is pos | ||||
ted to notify the client | ||||
// of the info-hash changing. | ||||
struct TORRENT_EXPORT torrent_update_alert : torrent_alert | ||||
{ | ||||
// internal | ||||
torrent_update_alert(torrent_handle h, sha1_hash const& old_ | ||||
hash, sha1_hash const& new_hash) | ||||
: torrent_alert(h) | ||||
, old_ih(old_hash) | ||||
, new_ih(new_hash) | ||||
{} | ||||
TORRENT_DEFINE_ALERT(torrent_update_alert); | ||||
const static int static_category = alert::status_notificatio | ||||
n; | ||||
virtual std::string message() const; | ||||
virtual bool discardable() const { return false; } | ||||
// ``old_ih`` and ``new_ih`` are the previous and new info-h | ||||
ash for the torrent, respectively. | ||||
sha1_hash old_ih; | ||||
sha1_hash new_ih; | ||||
}; | ||||
// This alert is posted every time a new RSS item (i.e. torrent) is | ||||
received | ||||
// from an RSS feed. | ||||
// | ||||
// It is only posted if the ``rss_notifications`` category is enable | ||||
d in the | ||||
// alert_mask. | ||||
struct TORRENT_EXPORT rss_item_alert : alert | ||||
{ | ||||
// internal | ||||
rss_item_alert(feed_handle h, feed_item const& item) | ||||
: handle(h) | ||||
, item(item) | ||||
{} | ||||
TORRENT_DEFINE_ALERT(rss_item_alert); | ||||
const static int static_category = alert::rss_notification; | ||||
virtual std::string message() const; | ||||
feed_handle handle; | ||||
feed_item item; | ||||
}; | ||||
// posted when something fails in the DHT. This is not necessarily a | ||||
fatal | ||||
// error, but it could prevent proper operation | ||||
struct TORRENT_EXPORT dht_error_alert: alert | ||||
{ | ||||
// internal | ||||
dht_error_alert(int op, error_code const& ec) | ||||
: error(ec), operation(op_t(op)) {} | ||||
TORRENT_DEFINE_ALERT(dht_error_alert); | ||||
const static int static_category = alert::error_notification | ||||
| alert::dht_notification; | ||||
virtual std::string message() const; | ||||
// the error code | ||||
error_code error; | ||||
enum op_t | ||||
{ | ||||
unknown, | ||||
hostname_lookup | ||||
}; | ||||
// the operation that failed | ||||
op_t operation; | ||||
}; | ||||
// this alert is posted as a response to a call to session::get_item | ||||
(), | ||||
// specifically the overload for looking up immutable items in the D | ||||
HT. | ||||
struct TORRENT_EXPORT dht_immutable_item_alert: alert | ||||
{ | ||||
dht_immutable_item_alert(sha1_hash const& t, entry const& i) | ||||
: target(t), item(i) {} | ||||
TORRENT_DEFINE_ALERT(dht_immutable_item_alert); | ||||
const static int static_category = alert::error_notification | ||||
| alert::dht_notification; | ||||
virtual std::string message() const; | ||||
virtual bool discardable() const { return false; } | ||||
// the target hash of the immutable item. This must | ||||
// match the sha-1 hash of the bencoded form of ``item``. | ||||
sha1_hash target; | ||||
// the data for this item | ||||
entry item; | ||||
}; | ||||
// this alert is posted as a response to a call to session::get_item | ||||
(), | ||||
// specifically the overload for looking up mutable items in the DHT | ||||
. | ||||
struct TORRENT_EXPORT dht_mutable_item_alert: alert | ||||
{ | ||||
dht_mutable_item_alert(boost::array<char, 32> k | ||||
, boost::array<char, 64> sig | ||||
, boost::uint64_t sequence | ||||
, std::string const& s | ||||
, entry const& i) | ||||
: key(k), signature(sig), seq(sequence), salt(s), it | ||||
em(i) {} | ||||
TORRENT_DEFINE_ALERT(dht_mutable_item_alert); | ||||
const static int static_category = alert::error_notification | ||||
| alert::dht_notification; | ||||
virtual std::string message() const; | ||||
virtual bool discardable() const { return false; } | ||||
// the public key that was looked up | ||||
boost::array<char, 32> key; | ||||
// the signature of the data. This is not the signature of t | ||||
he | ||||
// plain encoded form of the item, but it includes the seque | ||||
nce number | ||||
// and possibly the hash as well. See the dht_store document | ||||
for more | ||||
// information. This is primarily useful for echoing back in | ||||
a store | ||||
// request. | ||||
boost::array<char, 64> signature; | ||||
// the sequence number of this item | ||||
boost::uint64_t seq; | ||||
// the salf, if any, used to lookup and store this item. If | ||||
no | ||||
// salt was used, this is an empty string | ||||
std::string salt; | ||||
// the data for this item | ||||
entry item; | ||||
}; | ||||
// this is posted when a DHT put operation completes. This is useful | ||||
if the | ||||
// client is waiting for a put to complete before shutting down for | ||||
instance. | ||||
struct TORRENT_EXPORT dht_put_alert: alert | ||||
{ | ||||
// internal | ||||
dht_put_alert(sha1_hash const& t) | ||||
: target(t) | ||||
, seq(0) | ||||
{} | ||||
dht_put_alert(boost::array<char, 32> key | ||||
, boost::array<char, 64> sig | ||||
, std::string s | ||||
, boost::uint64_t sequence_number) | ||||
: target(0) | ||||
, public_key(key) | ||||
, signature(sig) | ||||
, salt(s) | ||||
, seq(sequence_number) | ||||
{} | ||||
TORRENT_DEFINE_ALERT(dht_put_alert); | ||||
const static int static_category = alert::dht_notification; | ||||
virtual std::string message() const; | ||||
// the target hash the item was stored under if this was an | ||||
*immutable* | ||||
// item. | ||||
sha1_hash target; | ||||
// if a mutable item was stored, these are the public key, s | ||||
ignature, | ||||
// salt and sequence number the item was stored under. | ||||
boost::array<char, 32> public_key; | ||||
boost::array<char, 64> signature; | ||||
std::string salt; | ||||
boost::uint64_t seq; | ||||
}; | ||||
// this alert is used to report errors in the i2p SAM connection | ||||
struct TORRENT_EXPORT i2p_alert : alert | struct TORRENT_EXPORT i2p_alert : alert | |||
{ | { | |||
i2p_alert(error_code const& ec) : error(ec) {} | i2p_alert(error_code const& ec) : error(ec) {} | |||
TORRENT_DEFINE_ALERT(i2p_alert); | TORRENT_DEFINE_ALERT(i2p_alert); | |||
const static int static_category = alert::error_notification ; | const static int static_category = alert::error_notification ; | |||
virtual std::string message() const; | virtual std::string message() const; | |||
// the error that occurred in the i2p SAM connection | ||||
error_code error; | error_code error; | |||
}; | }; | |||
#undef TORRENT_DEFINE_ALERT | #undef TORRENT_DEFINE_ALERT | |||
} | } | |||
#endif | #endif | |||
End of changes. 253 change blocks. | ||||
99 lines changed or deleted | 1062 lines changed or added | |||
alloca.hpp | alloca.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2008, Arvid Norberg | Copyright (c) 2008-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
allocator.hpp | allocator.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2009, Arvid Norberg | Copyright (c) 2009-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 50 | skipping to change at line 50 | |||
{ | { | |||
TORRENT_EXTRA_EXPORT int page_size(); | TORRENT_EXTRA_EXPORT int page_size(); | |||
struct TORRENT_EXTRA_EXPORT page_aligned_allocator | struct TORRENT_EXTRA_EXPORT page_aligned_allocator | |||
{ | { | |||
typedef std::size_t size_type; | typedef std::size_t size_type; | |||
typedef std::ptrdiff_t difference_type; | typedef std::ptrdiff_t difference_type; | |||
static char* malloc(const size_type bytes); | static char* malloc(const size_type bytes); | |||
static void free(char* const block); | static void free(char* block); | |||
}; | }; | |||
struct TORRENT_EXTRA_EXPORT aligned_holder | struct TORRENT_EXTRA_EXPORT aligned_holder | |||
{ | { | |||
aligned_holder(): m_buf(0) {} | aligned_holder(): m_buf(0) {} | |||
aligned_holder(int size): m_buf(page_aligned_allocator::mall oc(size)) {} | aligned_holder(int size): m_buf(page_aligned_allocator::mall oc(size)) {} | |||
~aligned_holder() { if (m_buf) page_aligned_allocator::free( m_buf); } | ~aligned_holder() { if (m_buf) page_aligned_allocator::free( m_buf); } | |||
char* get() const { return m_buf; } | char* get() const { return m_buf; } | |||
void reset(char* buf = 0) | void reset(char* buf = 0) | |||
{ | { | |||
End of changes. 2 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
assert.hpp | assert.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2007, Arvid Norberg | Copyright (c) 2007-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 37 | skipping to change at line 37 | |||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 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 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||
POSSIBILITY OF SUCH DAMAGE. | POSSIBILITY OF SUCH DAMAGE. | |||
*/ | */ | |||
#ifndef TORRENT_ASSERT | #ifndef TORRENT_ASSERT | |||
#include "libtorrent/config.hpp" | #include "libtorrent/config.hpp" | |||
#if (!defined TORRENT_DEBUG && !TORRENT_RELEASE_ASSERTS) \ | #if defined TORRENT_DEBUG || defined TORRENT_ASIO_DEBUGGING || TORRENT_RELE | |||
|| TORRENT_NO_ASSERTS | ASE_ASSERTS | |||
#define TORRENT_ASSERT(a) do {} while(false) | #include <string> | |||
#define TORRENT_ASSERT_VAL(a, b) do {} while(false) | std::string demangle(char const* name); | |||
#else | TORRENT_EXPORT void print_backtrace(char* out, int len, int max_depth = 0); | |||
#endif | ||||
#if TORRENT_USE_ASSERTS | ||||
#if TORRENT_PRODUCTION_ASSERTS | #if TORRENT_PRODUCTION_ASSERTS | |||
extern char const* libtorrent_assert_log; | extern char const* libtorrent_assert_log; | |||
#endif | #endif | |||
#include <string> | ||||
std::string demangle(char const* name); | ||||
void print_backtrace(char* out, int len, int max_depth = 0); | ||||
#if (defined __linux__ || defined __MACH__) && defined __GNUC__ && !TORRENT _USE_SYSTEM_ASSERT | #if (defined __linux__ || defined __MACH__) && defined __GNUC__ && !TORRENT _USE_SYSTEM_ASSERT | |||
#if TORRENT_USE_IOSTREAM | #if TORRENT_USE_IOSTREAM | |||
#include <sstream> | #include <sstream> | |||
#endif | #endif | |||
TORRENT_EXPORT void assert_fail(const char* expr, int line, char const* fil e | TORRENT_EXPORT void assert_fail(const char* expr, int line, char const* fil e | |||
, char const* function, char const* val); | , char const* function, char const* val, int kind = 0); | |||
#define TORRENT_ASSERT_PRECOND(x) \ | ||||
do { if (x) {} else assert_fail(#x, __LINE__, __FILE__, __PRETTY_FUN | ||||
CTION__, "", 1); } while (false) | ||||
#define TORRENT_ASSERT(x) \ | ||||
do { if (x) {} else assert_fail(#x, __LINE__, __FILE__, __PRETTY_FUN | ||||
CTION__, "", 0); } while (false) | ||||
#define TORRENT_ASSERT(x) do { if (x) {} else assert_fail(#x, __LINE__, __F ILE__, __PRETTY_FUNCTION__, 0); } while (false) | ||||
#if TORRENT_USE_IOSTREAM | #if TORRENT_USE_IOSTREAM | |||
#define TORRENT_ASSERT_VAL(x, y) do { if (x) {} else { std::stringstream __ | #define TORRENT_ASSERT_VAL(x, y) \ | |||
s__; __s__ << #y ": " << y; assert_fail(#x, __LINE__, __FILE__, __PRETTY_FU | do { if (x) {} else { std::stringstream __s__; __s__ << #y ": " << y | |||
NCTION__, __s__.str().c_str()); } } while (false) | ; \ | |||
assert_fail(#x, __LINE__, __FILE__, __PRETTY_FUNCTION__, __s__.str() | ||||
.c_str(), 0); } } while (false) | ||||
#else | #else | |||
#define TORRENT_ASSERT_VAL(x, y) TORRENT_ASSERT(x) | #define TORRENT_ASSERT_VAL(x, y) TORRENT_ASSERT(x) | |||
#endif | #endif | |||
#else | #else | |||
#include <cassert> | #include <cassert> | |||
#define TORRENT_ASSERT_PRECOND(x) assert(x) | ||||
#define TORRENT_ASSERT(x) assert(x) | #define TORRENT_ASSERT(x) assert(x) | |||
#define TORRENT_ASSERT_VAL(x, y) assert(x) | #define TORRENT_ASSERT_VAL(x, y) assert(x) | |||
#endif | #endif | |||
#endif | #else // TORRENT_USE_ASSERTS | |||
#define TORRENT_ASSERT_PRECOND(a) do {} while(false) | ||||
#define TORRENT_ASSERT(a) do {} while(false) | ||||
#define TORRENT_ASSERT_VAL(a, b) do {} while(false) | ||||
#endif // TORRENT_USE_ASSERTS | ||||
#endif | #endif | |||
End of changes. 8 change blocks. | ||||
17 lines changed or deleted | 31 lines changed or added | |||
bandwidth_limit.hpp | bandwidth_limit.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2007, Arvid Norberg | Copyright (c) 2007-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 67 | skipping to change at line 67 | |||
int quota_left() const; | int quota_left() const; | |||
void update_quota(int dt_milliseconds); | void update_quota(int dt_milliseconds); | |||
// this is used when connections disconnect with | // this is used when connections disconnect with | |||
// some quota left. It's returned to its bandwidth | // some quota left. It's returned to its bandwidth | |||
// channels. | // channels. | |||
void return_quota(int amount); | void return_quota(int amount); | |||
void use_quota(int amount); | void use_quota(int amount); | |||
// this is an optimization. If there is more than one second | ||||
// of quota built up in this channel, just apply it right away | ||||
// instead of introducing a delay to split it up evenly. This | ||||
// should especially help in situations where a single peer | ||||
// has a capacity under the rate limit, but would otherwise be | ||||
// held back by the latency of getting bandwidth from the limiter | ||||
bool need_queueing(int amount) | ||||
{ | ||||
if (m_quota_left - amount < m_limit) return true; | ||||
m_quota_left -= amount; | ||||
return false; | ||||
} | ||||
// used as temporary storage while distributing | // used as temporary storage while distributing | |||
// bandwidth | // bandwidth | |||
int tmp; | int tmp; | |||
// this is the number of bytes to distribute this round | // this is the number of bytes to distribute this round | |||
int distribute_quota; | int distribute_quota; | |||
private: | private: | |||
// this is the amount of bandwidth we have | // this is the amount of bandwidth we have | |||
End of changes. 2 change blocks. | ||||
1 lines changed or deleted | 14 lines changed or added | |||
bandwidth_manager.hpp | bandwidth_manager.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2007, Arvid Norberg | Copyright (c) 2007-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 66 | skipping to change at line 66 | |||
struct TORRENT_EXTRA_EXPORT bandwidth_manager | struct TORRENT_EXTRA_EXPORT bandwidth_manager | |||
{ | { | |||
bandwidth_manager(int channel | bandwidth_manager(int channel | |||
#ifdef TORRENT_VERBOSE_BANDWIDTH_LIMIT | #ifdef TORRENT_VERBOSE_BANDWIDTH_LIMIT | |||
, bool log = false | , bool log = false | |||
#endif | #endif | |||
); | ); | |||
void close(); | void close(); | |||
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS | #if TORRENT_USE_ASSERTS | |||
bool is_queued(bandwidth_socket const* peer) const; | bool is_queued(bandwidth_socket const* peer) const; | |||
#endif | #endif | |||
int queue_size() const; | int queue_size() const; | |||
int queued_bytes() const; | boost::int64_t queued_bytes() const; | |||
// non prioritized means that, if there's a line for bandwidth, | // non prioritized means that, if there's a line for bandwidth, | |||
// others will cut in front of the non-prioritized peers. | // others will cut in front of the non-prioritized peers. | |||
// this is used by web seeds | // this is used by web seeds | |||
// returns the number of bytes to assign to the peer, or 0 | // returns the number of bytes to assign to the peer, or 0 | |||
// if the peer's 'assign_bandwidth' callback will be called later | // if the peer's 'assign_bandwidth' callback will be called later | |||
int request_bandwidth(intrusive_ptr<bandwidth_socket> const& peer | int request_bandwidth(intrusive_ptr<bandwidth_socket> const& peer | |||
, int blk, int priority | , int blk, int priority | |||
, bandwidth_channel* chan1 = 0 | , bandwidth_channel* chan1 = 0 | |||
, bandwidth_channel* chan2 = 0 | , bandwidth_channel* chan2 = 0 | |||
, bandwidth_channel* chan3 = 0 | , bandwidth_channel* chan3 = 0 | |||
, bandwidth_channel* chan4 = 0 | , bandwidth_channel* chan4 = 0 | |||
, bandwidth_channel* chan5 = 0); | , bandwidth_channel* chan5 = 0); | |||
#ifdef TORRENT_DEBUG | #if TORRENT_USE_INVARIANT_CHECKS | |||
void check_invariant() const; | void check_invariant() const; | |||
#endif | #endif | |||
void update_quotas(time_duration const& dt); | void update_quotas(time_duration const& dt); | |||
private: | ||||
// these are the consumers that want bandwidth | // these are the consumers that want bandwidth | |||
typedef std::vector<bw_request> queue_t; | typedef std::vector<bw_request> queue_t; | |||
queue_t m_queue; | queue_t m_queue; | |||
// the number of bytes all the requests in queue are for | // the number of bytes all the requests in queue are for | |||
int m_queued_bytes; | boost::int64_t m_queued_bytes; | |||
// this is the channel within the consumers | // this is the channel within the consumers | |||
// that bandwidth is assigned to (upload or download) | // that bandwidth is assigned to (upload or download) | |||
int m_channel; | int m_channel; | |||
bool m_abort; | bool m_abort; | |||
#ifdef TORRENT_VERBOSE_BANDWIDTH_LIMIT | #ifdef TORRENT_VERBOSE_BANDWIDTH_LIMIT | |||
std::ofstream m_log; | std::ofstream m_log; | |||
ptime m_start; | ptime m_start; | |||
End of changes. 6 change blocks. | ||||
5 lines changed or deleted | 7 lines changed or added | |||
bandwidth_queue_entry.hpp | bandwidth_queue_entry.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2007, Arvid Norberg | Copyright (c) 2007-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 66 | skipping to change at line 66 | |||
// this ensures that requests gets responses at very low | // this ensures that requests gets responses at very low | |||
// rate limits, when the requested size would take a long | // rate limits, when the requested size would take a long | |||
// time to satisfy | // time to satisfy | |||
int ttl; | int ttl; | |||
// loops over the bandwidth channels and assigns bandwidth | // loops over the bandwidth channels and assigns bandwidth | |||
// from the most limiting one | // from the most limiting one | |||
int assign_bandwidth(); | int assign_bandwidth(); | |||
enum { max_bandwidth_channels = 5 }; | enum { max_bandwidth_channels = 5 }; | |||
// we don't actually support more than 5 channels per peer | ||||
bandwidth_channel* channel[max_bandwidth_channels]; | bandwidth_channel* channel[max_bandwidth_channels]; | |||
}; | }; | |||
} | } | |||
#endif | #endif | |||
End of changes. 2 change blocks. | ||||
1 lines changed or deleted | 2 lines changed or added | |||
bandwidth_socket.hpp | bandwidth_socket.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2009, Arvid Norberg | Copyright (c) 2009-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
bencode.hpp | bencode.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2003, Arvid Norberg | Copyright (c) 2003-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 36 | skipping to change at line 36 | |||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 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 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||
POSSIBILITY OF SUCH DAMAGE. | POSSIBILITY OF SUCH DAMAGE. | |||
*/ | */ | |||
#ifndef TORRENT_BENCODE_HPP_INCLUDED | #ifndef TORRENT_BENCODE_HPP_INCLUDED | |||
#define TORRENT_BENCODE_HPP_INCLUDED | #define TORRENT_BENCODE_HPP_INCLUDED | |||
/* | // OVERVIEW | |||
* This file declares the following functions: | // | |||
* | // Bencoding is a common representation in bittorrent used for | |||
*---------------------------------- | // for dictionary, list, int and string hierarchies. It's used | |||
* template<class OutIt> | // to encode .torrent files and some messages in the network | |||
* void libtorrent::bencode(OutIt out, const libtorrent::entry& e); | // protocol. libtorrent also uses it to store settings, resume | |||
* | // data and other state between sessions. | |||
* Encodes a message entry with bencoding into the output | // | |||
* iterator given. The bencoding is described in the BitTorrent | // Strings in bencoded structures are not necessarily representing | |||
* protocol description document OutIt must be an OutputIterator | // text. Strings are raw byte buffers of a certain length. If a | |||
* of type char. This may throw libtorrent::invalid_encoding if | // string is meant to be interpreted as text, it is required to | |||
* the entry contains invalid nodes (undefined_t for example). | // be UTF-8 encoded. See `BEP 3`_. | |||
* | // | |||
*---------------------------------- | // There are two mechanims to *decode* bencoded buffers in libtorrent. | |||
* template<class InIt> | // | |||
* libtorrent::entry libtorrent::bdecode(InIt start, InIt end); | // The most flexible one is bdecode(), which returns a structure | |||
* | // represented by entry. When a buffer is decoded with this function, | |||
* Decodes the buffer given by the start and end iterators | // it can be discarded. The entry does not contain any references back | |||
* and returns the decoded entry. InIt must be an InputIterator | // to it. This means that bdecode() actually copies all the data out | |||
* of type char. May throw libtorrent::invalid_encoding if | // of the buffer and into its own hierarchy. This makes this | |||
* the string is not correctly bencoded. | // function potentially expensive, if you're parsing large amounts | |||
* | // of data. | |||
*/ | // | |||
// Another consideration is that bdecode() is a recursive parser. | ||||
// For this reason, in order to avoid DoS attacks by triggering | ||||
// a stack overflow, there is a recursion limit. This limit is | ||||
// a sanity check to make sure it doesn't run the risk of | ||||
// busting the stack. | ||||
// | ||||
// The second mechanism is lazy_bdecode(), which returns a | ||||
// bencoded structure represented by lazy_entry. This function | ||||
// builds a tree that points back into the original buffer. | ||||
// The returned lazy_entry will not be valid once the buffer | ||||
// it was parsed out of is discarded. | ||||
// | ||||
// Not only is this function more efficient because of less | ||||
// memory allocation and data copy, the parser is also not | ||||
// recursive, which means it probably performs a little bit | ||||
// better and can have a higher recursion limit on the structures | ||||
// it's parsing. | ||||
#include <stdlib.h> | #include <stdlib.h> | |||
#include <string> | #include <string> | |||
#include <exception> | #include <exception> | |||
#include <iterator> // for distance | #include <iterator> // for distance | |||
#ifdef _MSC_VER | #ifdef _MSC_VER | |||
#pragma warning(push, 1) | #pragma warning(push, 1) | |||
#endif | #endif | |||
skipping to change at line 80 | skipping to change at line 97 | |||
#ifdef _MSC_VER | #ifdef _MSC_VER | |||
#pragma warning(pop) | #pragma warning(pop) | |||
#endif | #endif | |||
#include "libtorrent/entry.hpp" | #include "libtorrent/entry.hpp" | |||
#include "libtorrent/config.hpp" | #include "libtorrent/config.hpp" | |||
#include "libtorrent/assert.hpp" | #include "libtorrent/assert.hpp" | |||
#include "libtorrent/escape_string.hpp" | #include "libtorrent/escape_string.hpp" | |||
#include "libtorrent/io.hpp" // for write_string | ||||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
// thrown by bdecode() if the provided bencoded buffer does not cont | ||||
ain | ||||
// valid encoding. | ||||
struct TORRENT_EXPORT invalid_encoding: std::exception | struct TORRENT_EXPORT invalid_encoding: std::exception | |||
{ | { | |||
virtual const char* what() const throw() { return "invalid b encoding"; } | virtual const char* what() const throw() { return "invalid b encoding"; } | |||
}; | }; | |||
namespace detail | namespace detail | |||
{ | { | |||
template <class OutIt> | ||||
int write_string(OutIt& out, const std::string& val) | ||||
{ | ||||
for (std::string::const_iterator i = val.begin() | ||||
, end(val.end()); i != end; ++i) | ||||
*out++ = *i; | ||||
return int(val.length()); | ||||
} | ||||
// this is used in the template, so it must be available to the client | // this is used in the template, so it must be available to the client | |||
TORRENT_EXPORT char const* integer_to_str(char* buf, int siz e | TORRENT_EXPORT char const* integer_to_str(char* buf, int siz e | |||
, entry::integer_type val); | , entry::integer_type val); | |||
template <class OutIt> | template <class OutIt> | |||
int write_integer(OutIt& out, entry::integer_type val) | int write_integer(OutIt& out, entry::integer_type val) | |||
{ | { | |||
// the stack allocated buffer for keeping the | // the stack allocated buffer for keeping the | |||
// decimal representation of the number can | // decimal representation of the number can | |||
// not hold number bigger than this: | // not hold number bigger than this: | |||
skipping to change at line 168 | skipping to change at line 179 | |||
if (in == end) | if (in == end) | |||
{ | { | |||
err = true; | err = true; | |||
return; | return; | |||
} | } | |||
str += *in; | str += *in; | |||
++in; | ++in; | |||
} | } | |||
} | } | |||
// returns the number of bytes written | ||||
template<class OutIt> | template<class OutIt> | |||
int bencode_recursive(OutIt& out, const entry& e) | int bencode_recursive(OutIt& out, const entry& e) | |||
{ | { | |||
int ret = 0; | int ret = 0; | |||
switch(e.type()) | switch(e.type()) | |||
{ | { | |||
case entry::int_t: | case entry::int_t: | |||
write_char(out, 'i'); | write_char(out, 'i'); | |||
ret += write_integer(out, e.integer()); | ret += write_integer(out, e.integer()); | |||
write_char(out, 'e'); | write_char(out, 'e'); | |||
ret += 2; | ret += 2; | |||
break; | break; | |||
case entry::string_t: | case entry::string_t: | |||
ret += write_integer(out, e.string().length( )); | ret += write_integer(out, e.string().length( )); | |||
write_char(out, ':'); | write_char(out, ':'); | |||
ret += write_string(out, e.string()); | ret += write_string(e.string(), out); | |||
ret += 1; | ret += 1; | |||
break; | break; | |||
case entry::list_t: | case entry::list_t: | |||
write_char(out, 'l'); | write_char(out, 'l'); | |||
for (entry::list_type::const_iterator i = e. list().begin(); i != e.list().end(); ++i) | for (entry::list_type::const_iterator i = e. list().begin(); i != e.list().end(); ++i) | |||
ret += bencode_recursive(out, *i); | ret += bencode_recursive(out, *i); | |||
write_char(out, 'e'); | write_char(out, 'e'); | |||
ret += 2; | ret += 2; | |||
break; | break; | |||
case entry::dictionary_t: | case entry::dictionary_t: | |||
write_char(out, 'd'); | write_char(out, 'd'); | |||
for (entry::dictionary_type::const_iterator i = e.dict().begin(); | for (entry::dictionary_type::const_iterator i = e.dict().begin(); | |||
i != e.dict().end(); ++i) | i != e.dict().end(); ++i) | |||
{ | { | |||
// write key | // write key | |||
ret += write_integer(out, i->first.l ength()); | ret += write_integer(out, i->first.l ength()); | |||
write_char(out, ':'); | write_char(out, ':'); | |||
ret += write_string(out, i->first); | ret += write_string(i->first, out); | |||
// write value | // write value | |||
ret += bencode_recursive(out, i->sec ond); | ret += bencode_recursive(out, i->sec ond); | |||
ret += 1; | ret += 1; | |||
} | } | |||
write_char(out, 'e'); | write_char(out, 'e'); | |||
ret += 2; | ret += 2; | |||
break; | break; | |||
default: | default: | |||
// trying to encode a structure with uniniti alized values! | // trying to encode a structure with uniniti alized values! | |||
TORRENT_ASSERT_VAL(false, e.type()); | TORRENT_ASSERT_VAL(false, e.type()); | |||
skipping to change at line 378 | skipping to change at line 388 | |||
#endif | #endif | |||
return; | return; | |||
} | } | |||
#ifdef TORRENT_DEBUG | #ifdef TORRENT_DEBUG | |||
ret.m_type_queried = false; | ret.m_type_queried = false; | |||
#endif | #endif | |||
} | } | |||
} | } | |||
} | } | |||
template<class OutIt> | // These functions will encode data to bencoded_ or decode bencoded_ | |||
int bencode(OutIt out, const entry& e) | data. | |||
// | ||||
// If possible, lazy_bdecode() should be preferred over ``bdecode()` | ||||
`. | ||||
// | ||||
// The entry_ class is the internal representation of the bencoded d | ||||
ata | ||||
// and it can be used to retrieve information, an entry_ can also be | ||||
build by | ||||
// the program and given to ``bencode()`` to encode it into the ``Ou | ||||
tIt`` | ||||
// iterator. | ||||
// | ||||
// The ``OutIt`` and ``InIt`` are iterators | ||||
// (InputIterator_ and OutputIterator_ respectively). They | ||||
// are templates and are usually instantiated as ostream_iterator_, | ||||
// back_insert_iterator_ or istream_iterator_. These | ||||
// functions will assume that the iterator refers to a character | ||||
// (``char``). So, if you want to encode entry ``e`` into a buffer | ||||
// in memory, you can do it like this:: | ||||
// | ||||
// std::vector<char> buffer; | ||||
// bencode(std::back_inserter(buf), e); | ||||
// | ||||
// .. _InputIterator: http://www.sgi.com/tech/stl/InputIterator.html | ||||
// .. _OutputIterator: http://www.sgi.com/tech/stl/OutputIterator.ht | ||||
ml | ||||
// .. _ostream_iterator: http://www.sgi.com/tech/stl/ostream_iterato | ||||
r.html | ||||
// .. _back_insert_iterator: http://www.sgi.com/tech/stl/back_insert | ||||
_iterator.html | ||||
// .. _istream_iterator: http://www.sgi.com/tech/stl/istream_iterato | ||||
r.html | ||||
// | ||||
// If you want to decode a torrent file from a buffer in memory, you | ||||
can do it like this:: | ||||
// | ||||
// std::vector<char> buffer; | ||||
// // ... | ||||
// entry e = bdecode(buf.begin(), buf.end()); | ||||
// | ||||
// Or, if you have a raw char buffer:: | ||||
// | ||||
// const char* buf; | ||||
// // ... | ||||
// entry e = bdecode(buf, buf + data_size); | ||||
// | ||||
// Now we just need to know how to retrieve information from the ent | ||||
ry. | ||||
// | ||||
// If ``bdecode()`` encounters invalid encoded data in the range giv | ||||
en to it | ||||
// it will throw libtorrent_exception. | ||||
template<class OutIt> int bencode(OutIt out, const entry& e) | ||||
{ | { | |||
return detail::bencode_recursive(out, e); | return detail::bencode_recursive(out, e); | |||
} | } | |||
template<class InIt> entry bdecode(InIt start, InIt end) | ||||
template<class InIt> | ||||
entry bdecode(InIt start, InIt end) | ||||
{ | { | |||
entry e; | entry e; | |||
bool err = false; | bool err = false; | |||
detail::bdecode_recursive(start, end, e, err, 0); | detail::bdecode_recursive(start, end, e, err, 0); | |||
#ifdef TORRENT_DEBUG | #ifdef TORRENT_DEBUG | |||
TORRENT_ASSERT(e.m_type_queried == false); | TORRENT_ASSERT(e.m_type_queried == false); | |||
#endif | #endif | |||
if (err) return entry(); | if (err) return entry(); | |||
return e; | return e; | |||
} | } | |||
template<class InIt> entry bdecode(InIt start, InIt end, int& len) | ||||
template<class InIt> | ||||
entry bdecode(InIt start, InIt end, int& len) | ||||
{ | { | |||
entry e; | entry e; | |||
bool err = false; | bool err = false; | |||
InIt s = start; | InIt s = start; | |||
detail::bdecode_recursive(start, end, e, err, 0); | detail::bdecode_recursive(start, end, e, err, 0); | |||
len = std::distance(s, start); | len = std::distance(s, start); | |||
TORRENT_ASSERT(len >= 0); | TORRENT_ASSERT(len >= 0); | |||
if (err) return entry(); | if (err) return entry(); | |||
return e; | return e; | |||
} | } | |||
End of changes. 11 change blocks. | ||||
44 lines changed or deleted | 104 lines changed or added | |||
bitfield.hpp | bitfield.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2008, Arvid Norberg | Copyright (c) 2008-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 41 | skipping to change at line 41 | |||
*/ | */ | |||
#ifndef TORRENT_BITFIELD_HPP_INCLUDED | #ifndef TORRENT_BITFIELD_HPP_INCLUDED | |||
#define TORRENT_BITFIELD_HPP_INCLUDED | #define TORRENT_BITFIELD_HPP_INCLUDED | |||
#include "libtorrent/assert.hpp" | #include "libtorrent/assert.hpp" | |||
#include "libtorrent/config.hpp" | #include "libtorrent/config.hpp" | |||
#include <cstring> // for memset and memcpy | #include <cstring> // for memset and memcpy | |||
#include <cstdlib> // for malloc, free and realloc | #include <cstdlib> // for malloc, free and realloc | |||
#include <boost/cstdint.hpp> // uint32_t | #include <boost/cstdint.hpp> // uint32_t | |||
#include <algorithm> // for min() | ||||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
// The bitfiled type stores any number of bits as a bitfield | ||||
// in a heap allocated or borrowed array. | ||||
struct TORRENT_EXPORT bitfield | struct TORRENT_EXPORT bitfield | |||
{ | { | |||
// constructs a new bitfield. The default constructor create | ||||
s an empty | ||||
// bitfield. ``bits`` is the size of the bitfield (specified | ||||
in bits). | ||||
// ``val`` is the value to initialize the bits to. If not sp | ||||
ecified | ||||
// all bits are initialized to 0. | ||||
// | ||||
// The constructor taking a pointer ``b`` and ``bits`` copie | ||||
s a bitfield | ||||
// from the specified buffer, and ``bits`` number of bits (r | ||||
ounded up to | ||||
// the nearest byte boundry). | ||||
bitfield(): m_bytes(0), m_size(0), m_own(false) {} | bitfield(): m_bytes(0), m_size(0), m_own(false) {} | |||
bitfield(int bits): m_bytes(0), m_size(0), m_own(false) | bitfield(int bits): m_bytes(0), m_size(0), m_own(false) | |||
{ resize(bits); } | { resize(bits); } | |||
bitfield(int bits, bool val): m_bytes(0), m_size(0), m_own(f alse) | bitfield(int bits, bool val): m_bytes(0), m_size(0), m_own(f alse) | |||
{ resize(bits, val); } | { resize(bits, val); } | |||
bitfield(char const* b, int bits): m_bytes(0), m_size(0), m_ own(false) | bitfield(char const* b, int bits): m_bytes(0), m_size(0), m_ own(false) | |||
{ assign(b, bits); } | { assign(b, bits); } | |||
bitfield(bitfield const& rhs): m_bytes(0), m_size(0), m_own( false) | bitfield(bitfield const& rhs): m_bytes(0), m_size(0), m_own( false) | |||
{ assign(rhs.bytes(), rhs.size()); } | { assign(rhs.bytes(), rhs.size()); } | |||
#if __cplusplus > 199711L | ||||
bitfield(bitfield&& rhs): m_bytes(rhs.m_bytes), m_size(rhs.m | ||||
_size), m_own(rhs.m_own) | ||||
{ rhs.m_bytes = NULL; } | ||||
#endif | ||||
// assigns a bitfield pointed to ``b`` of ``bits`` number of | ||||
bits, without | ||||
// taking ownership of the buffer. This is a way to avoid co | ||||
pying data and | ||||
// yet provide a raw buffer to functions that may operate on | ||||
the bitfield | ||||
// type. It is the user's responsibility to make sure the pa | ||||
ssed-in buffer's | ||||
// life time exceeds all uses of the bitfield. | ||||
void borrow_bytes(char* b, int bits) | void borrow_bytes(char* b, int bits) | |||
{ | { | |||
dealloc(); | dealloc(); | |||
m_bytes = (unsigned char*)b; | m_bytes = (unsigned char*)b; | |||
m_size = bits; | m_size = bits; | |||
m_own = false; | m_own = false; | |||
} | } | |||
// hidden | ||||
~bitfield() { dealloc(); } | ~bitfield() { dealloc(); } | |||
// copy bitfield from buffer ``b`` of ``bits`` number of bit | ||||
s, rounded up to | ||||
// the nearest byte boundary. | ||||
void assign(char const* b, int bits) | void assign(char const* b, int bits) | |||
{ resize(bits); std::memcpy(m_bytes, b, (bits + 7) / 8); cle ar_trailing_bits(); } | { resize(bits); std::memcpy(m_bytes, b, (bits + 7) / 8); cle ar_trailing_bits(); } | |||
// query bit at ``index``. Returns true if bit is 1, otherwi se false. | ||||
bool operator[](int index) const | bool operator[](int index) const | |||
{ return get_bit(index); } | { return get_bit(index); } | |||
bool get_bit(int index) const | bool get_bit(int index) const | |||
{ | { | |||
TORRENT_ASSERT(index >= 0); | TORRENT_ASSERT(index >= 0); | |||
TORRENT_ASSERT(index < m_size); | TORRENT_ASSERT(index < m_size); | |||
return (m_bytes[index / 8] & (0x80 >> (index & 7))) != 0; | return (m_bytes[index / 8] & (0x80 >> (index & 7))) != 0; | |||
} | } | |||
// set bit at ``index`` to 0 (clear_bit) or 1 (set_bit). | ||||
void clear_bit(int index) | void clear_bit(int index) | |||
{ | { | |||
TORRENT_ASSERT(index >= 0); | TORRENT_ASSERT(index >= 0); | |||
TORRENT_ASSERT(index < m_size); | TORRENT_ASSERT(index < m_size); | |||
m_bytes[index / 8] &= ~(0x80 >> (index & 7)); | m_bytes[index / 8] &= ~(0x80 >> (index & 7)); | |||
} | } | |||
void set_bit(int index) | void set_bit(int index) | |||
{ | { | |||
TORRENT_ASSERT(index >= 0); | TORRENT_ASSERT(index >= 0); | |||
TORRENT_ASSERT(index < m_size); | TORRENT_ASSERT(index < m_size); | |||
m_bytes[index / 8] |= (0x80 >> (index & 7)); | m_bytes[index / 8] |= (0x80 >> (index & 7)); | |||
} | } | |||
// returns true if all bits in the bitfield are set | ||||
bool all_set() const | ||||
{ | ||||
boost::uint8_t* bytes = m_bytes; | ||||
int num_bytes = m_size / 8; | ||||
int num_words = 0; | ||||
// head | ||||
if (num_bytes >= 4) | ||||
{ | ||||
switch (uintptr_t(bytes) & 0x3) | ||||
{ | ||||
case 0: break; | ||||
case 1: | ||||
if (bytes[0] != 0xff) return | ||||
false; | ||||
if (bytes[1] != 0xff) return | ||||
false; | ||||
if (bytes[2] != 0xff) return | ||||
false; | ||||
bytes += 3; | ||||
num_bytes -= 3; | ||||
break; | ||||
case 2: | ||||
if (bytes[0] != 0xff) return | ||||
false; | ||||
if (bytes[1] != 0xff) return | ||||
false; | ||||
bytes += 2; | ||||
num_bytes -= 2; | ||||
break; | ||||
case 3: | ||||
if (bytes[0] != 0xff) return | ||||
false; | ||||
++bytes; | ||||
--num_bytes; | ||||
break; | ||||
} | ||||
num_words = num_bytes / 4; | ||||
TORRENT_ASSERT((uintptr_t(bytes) & 0x3) == 0 | ||||
); | ||||
boost::uint32_t* words = (boost::uint32_t*)b | ||||
ytes; | ||||
for (int i = 0; i < num_words; ++i) | ||||
{ | ||||
if (words[i] != 0xffffffff) return f | ||||
alse; | ||||
} | ||||
} | ||||
// tail | ||||
for (int i = num_words * 4; i < num_bytes; ++i) | ||||
{ | ||||
if (bytes[i] != 0xff) return false; | ||||
} | ||||
int rest = m_size & 0x7; | ||||
boost::uint8_t mask = (0xff << (8-rest)) & 0xff; | ||||
if (rest > 0 && (bytes[num_bytes] & mask) != mask) | ||||
return false; | ||||
return true; | ||||
} | ||||
// returns the size of the bitfield in bits. | ||||
std::size_t size() const { return m_size; } | std::size_t size() const { return m_size; } | |||
// returns true if the bitfield has zero size. | ||||
bool empty() const { return m_size == 0; } | bool empty() const { return m_size == 0; } | |||
// returns a pointer to the internal buffer of the bitfield. | ||||
char const* bytes() const { return (char*)m_bytes; } | char const* bytes() const { return (char*)m_bytes; } | |||
// copy operator | ||||
bitfield& operator=(bitfield const& rhs) | bitfield& operator=(bitfield const& rhs) | |||
{ | { | |||
assign(rhs.bytes(), rhs.size()); | assign(rhs.bytes(), rhs.size()); | |||
return *this; | return *this; | |||
} | } | |||
// count the number of bits in the bitfield that are set to 1. | ||||
int count() const | int count() const | |||
{ | { | |||
// 0000, 0001, 0010, 0011, 0100, 0101, 0110, 0111, | // 0000, 0001, 0010, 0011, 0100, 0101, 0110, 0111, | |||
// 1000, 1001, 1010, 1011, 1100, 1101, 1110, 1111 | // 1000, 1001, 1010, 1011, 1100, 1101, 1110, 1111 | |||
const static char num_bits[] = | const static char num_bits[] = | |||
{ | { | |||
0, 1, 1, 2, 1, 2, 2, 3, | 0, 1, 1, 2, 1, 2, 2, 3, | |||
1, 2, 2, 3, 2, 3, 3, 4 | 1, 2, 2, 3, 2, 3, 3, 4 | |||
}; | }; | |||
skipping to change at line 191 | skipping to change at line 276 | |||
} | } | |||
const_iterator(unsigned char const* ptr, int offset) | const_iterator(unsigned char const* ptr, int offset) | |||
: byte(ptr), bit(0x80 >> offset) {} | : byte(ptr), bit(0x80 >> offset) {} | |||
unsigned char const* byte; | unsigned char const* byte; | |||
int bit; | int bit; | |||
}; | }; | |||
const_iterator begin() const { return const_iterator(m_bytes , 0); } | const_iterator begin() const { return const_iterator(m_bytes , 0); } | |||
const_iterator end() const { return const_iterator(m_bytes + m_size / 8, m_size & 7); } | const_iterator end() const { return const_iterator(m_bytes + m_size / 8, m_size & 7); } | |||
// set the size of the bitfield to ``bits`` length. If the b | ||||
itfield is extended, | ||||
// the new bits are initialized to ``val``. | ||||
void resize(int bits, bool val) | void resize(int bits, bool val) | |||
{ | { | |||
int s = m_size; | int s = m_size; | |||
int b = m_size & 7; | int b = m_size & 7; | |||
resize(bits); | resize(bits); | |||
if (s >= m_size) return; | if (s >= m_size) return; | |||
int old_size_bytes = (s + 7) / 8; | int old_size_bytes = (s + 7) / 8; | |||
int new_size_bytes = (m_size + 7) / 8; | int new_size_bytes = (m_size + 7) / 8; | |||
if (val) | if (val) | |||
{ | { | |||
skipping to change at line 212 | skipping to change at line 299 | |||
if (old_size_bytes < new_size_bytes) | if (old_size_bytes < new_size_bytes) | |||
std::memset(m_bytes + old_size_bytes , 0xff, new_size_bytes - old_size_bytes); | std::memset(m_bytes + old_size_bytes , 0xff, new_size_bytes - old_size_bytes); | |||
clear_trailing_bits(); | clear_trailing_bits(); | |||
} | } | |||
else | else | |||
{ | { | |||
if (old_size_bytes < new_size_bytes) | if (old_size_bytes < new_size_bytes) | |||
std::memset(m_bytes + old_size_bytes , 0x00, new_size_bytes - old_size_bytes); | std::memset(m_bytes + old_size_bytes , 0x00, new_size_bytes - old_size_bytes); | |||
} | } | |||
} | } | |||
void set_all() | ||||
{ | ||||
std::memset(m_bytes, 0xff, (m_size + 7) / 8); | ||||
clear_trailing_bits(); | ||||
} | ||||
void clear_all() | ||||
{ | ||||
std::memset(m_bytes, 0x00, (m_size + 7) / 8); | ||||
} | ||||
void resize(int bits) | void resize(int bits) | |||
{ | { | |||
TORRENT_ASSERT(bits >= 0); | TORRENT_ASSERT(bits >= 0); | |||
const int b = (bits + 7) / 8; | const int b = (bits + 7) / 8; | |||
if (m_bytes) | if (m_bytes) | |||
{ | { | |||
if (m_own) | if (m_own) | |||
{ | { | |||
m_bytes = (unsigned char*)std::reall oc(m_bytes, b); | m_bytes = (unsigned char*)std::reall oc(m_bytes, b); | |||
m_own = true; | m_own = true; | |||
skipping to change at line 252 | skipping to change at line 327 | |||
} | } | |||
else if (bits > 0) | else if (bits > 0) | |||
{ | { | |||
m_bytes = (unsigned char*)std::malloc(b); | m_bytes = (unsigned char*)std::malloc(b); | |||
m_own = true; | m_own = true; | |||
} | } | |||
m_size = bits; | m_size = bits; | |||
clear_trailing_bits(); | clear_trailing_bits(); | |||
} | } | |||
void free() { dealloc(); m_size = 0; } | // set all bits in the bitfield to 1 (set_all) or 0 (clear_a | |||
ll). | ||||
void set_all() | ||||
{ | ||||
std::memset(m_bytes, 0xff, (m_size + 7) / 8); | ||||
clear_trailing_bits(); | ||||
} | ||||
void clear_all() | ||||
{ | ||||
std::memset(m_bytes, 0x00, (m_size + 7) / 8); | ||||
} | ||||
// make the bitfield empty, of zero size. | ||||
void clear() { dealloc(); m_size = 0; } | ||||
private: | private: | |||
void clear_trailing_bits() | void clear_trailing_bits() | |||
{ | { | |||
// clear the tail bits in the last byte | // clear the tail bits in the last byte | |||
if (m_size & 7) m_bytes[(m_size + 7) / 8 - 1] &= 0xf f << (8 - (m_size & 7)); | if (m_size & 7) m_bytes[(m_size + 7) / 8 - 1] &= 0xf f << (8 - (m_size & 7)); | |||
} | } | |||
void dealloc() { if (m_own) std::free(m_bytes); m_bytes = 0; } | void dealloc() { if (m_own) std::free(m_bytes); m_bytes = 0; } | |||
End of changes. 19 change blocks. | ||||
17 lines changed or deleted | 126 lines changed or added | |||
bloom_filter.hpp | bloom_filter.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2010, Arvid Norberg | Copyright (c) 2010-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
broadcast_socket.hpp | broadcast_socket.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2007, Arvid Norberg | Copyright (c) 2007-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 48 | skipping to change at line 48 | |||
#include "libtorrent/socket.hpp" | #include "libtorrent/socket.hpp" | |||
#include "libtorrent/address.hpp" | #include "libtorrent/address.hpp" | |||
#include "libtorrent/error_code.hpp" | #include "libtorrent/error_code.hpp" | |||
#include <boost/shared_ptr.hpp> | #include <boost/shared_ptr.hpp> | |||
#include <boost/function/function3.hpp> | #include <boost/function/function3.hpp> | |||
#include <list> | #include <list> | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
TORRENT_EXPORT bool is_local(address const& a); | TORRENT_EXTRA_EXPORT bool is_local(address const& a); | |||
TORRENT_EXPORT bool is_loopback(address const& addr); | TORRENT_EXTRA_EXPORT bool is_loopback(address const& addr); | |||
TORRENT_EXPORT bool is_multicast(address const& addr); | TORRENT_EXTRA_EXPORT bool is_multicast(address const& addr); | |||
TORRENT_EXPORT bool is_any(address const& addr); | TORRENT_EXTRA_EXPORT bool is_any(address const& addr); | |||
TORRENT_EXPORT bool is_teredo(address const& addr); | TORRENT_EXTRA_EXPORT bool is_teredo(address const& addr); | |||
TORRENT_EXTRA_EXPORT int cidr_distance(address const& a1, address co nst& a2); | TORRENT_EXTRA_EXPORT int cidr_distance(address const& a1, address co nst& a2); | |||
// determines if the operating system supports IPv6 | // determines if the operating system supports IPv6 | |||
TORRENT_EXPORT bool supports_ipv6(); | TORRENT_EXTRA_EXPORT bool supports_ipv6(); | |||
TORRENT_EXTRA_EXPORT int common_bits(unsigned char const* b1 | TORRENT_EXTRA_EXPORT int common_bits(unsigned char const* b1 | |||
, unsigned char const* b2, int n); | , unsigned char const* b2, int n); | |||
TORRENT_EXPORT address guess_local_address(io_service&); | TORRENT_EXTRA_EXPORT address guess_local_address(io_service&); | |||
typedef boost::function<void(udp::endpoint const& from | typedef boost::function<void(udp::endpoint const& from | |||
, char* buffer, int size)> receive_handler_t; | , char* buffer, int size)> receive_handler_t; | |||
class TORRENT_EXTRA_EXPORT broadcast_socket | class TORRENT_EXTRA_EXPORT broadcast_socket | |||
{ | { | |||
public: | public: | |||
broadcast_socket(udp::endpoint const& multicast_endpoint | broadcast_socket(udp::endpoint const& multicast_endpoint | |||
, receive_handler_t const& handler); | , receive_handler_t const& handler); | |||
~broadcast_socket() { close(); } | ~broadcast_socket() { close(); } | |||
End of changes. 4 change blocks. | ||||
8 lines changed or deleted | 8 lines changed or added | |||
bt_peer_connection.hpp | bt_peer_connection.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2003 - 2006, Arvid Norberg | Copyright (c) 2003-2014, Arvid Norberg | |||
Copyright (c) 2007, Arvid Norberg, Un Shyam | Copyright (c) 2007-2014, Arvid Norberg, Un Shyam | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 90 | skipping to change at line 90 | |||
: public peer_connection | : public peer_connection | |||
{ | { | |||
friend class invariant_access; | friend class invariant_access; | |||
public: | public: | |||
// this is the constructor where the we are the active part. | // this is the constructor where the we are the active part. | |||
// The peer_conenction should handshake and verify that the | // The peer_conenction should handshake and verify that the | |||
// other end has the correct id | // other end has the correct id | |||
bt_peer_connection( | bt_peer_connection( | |||
aux::session_impl& ses | aux::session_impl& ses | |||
, boost::weak_ptr<torrent> t | ||||
, boost::shared_ptr<socket_type> s | , boost::shared_ptr<socket_type> s | |||
, tcp::endpoint const& remote | , tcp::endpoint const& remote | |||
, policy::peer* peerinfo | , policy::peer* peerinfo | |||
, bool outgoing = true); | , peer_id const& pid | |||
, boost::weak_ptr<torrent> t = boost::weak_ptr<torre | ||||
// with this constructor we have been contacted and we still | nt>() | |||
don't | , bool outgoing = false); | |||
// know which torrent the connection belongs to | ||||
bt_peer_connection( | ||||
aux::session_impl& ses | ||||
, boost::shared_ptr<socket_type> s | ||||
, tcp::endpoint const& remote | ||||
, policy::peer* peerinfo); | ||||
void start(); | void start(); | |||
enum | enum | |||
{ | { | |||
// pex_msg = 1, | // pex_msg = 1, | |||
// metadata_msg = 2, | // metadata_msg = 2, | |||
upload_only_msg = 3, | upload_only_msg = 3, | |||
holepunch_msg = 4, | holepunch_msg = 4, | |||
// recommend_msg = 5, | // recommend_msg = 5, | |||
// comment_msg = 6, | // comment_msg = 6, | |||
dont_have_msg = 7, | dont_have_msg = 7, | |||
share_mode_msg = 8, | share_mode_msg = 8 | |||
}; | }; | |||
~bt_peer_connection(); | ~bt_peer_connection(); | |||
#ifndef TORRENT_DISABLE_ENCRYPTION | #ifndef TORRENT_DISABLE_ENCRYPTION | |||
bool supports_encryption() const | bool supports_encryption() const | |||
{ return m_encrypted; } | { return m_encrypted; } | |||
bool rc4_encrypted() const | bool rc4_encrypted() const | |||
{ return m_rc4_encrypted; } | { return m_rc4_encrypted; } | |||
#endif | #endif | |||
skipping to change at line 217 | skipping to change at line 210 | |||
void on_dht_port(int received); | void on_dht_port(int received); | |||
// FAST extension | // FAST extension | |||
void on_suggest_piece(int received); | void on_suggest_piece(int received); | |||
void on_have_all(int received); | void on_have_all(int received); | |||
void on_have_none(int received); | void on_have_none(int received); | |||
void on_reject_request(int received); | void on_reject_request(int received); | |||
void on_allowed_fast(int received); | void on_allowed_fast(int received); | |||
#ifndef TORRENT_DISABLE_EXTENSIONS | #ifndef TORRENT_DISABLE_EXTENSIONS | |||
void on_holepunch(); | void on_holepunch(); | |||
#endif | ||||
void on_extended(int received); | void on_extended(int received); | |||
void on_extended_handshake(); | void on_extended_handshake(); | |||
#endif | ||||
typedef void (bt_peer_connection::*message_handler)(int rece ived); | typedef void (bt_peer_connection::*message_handler)(int rece ived); | |||
// the following functions appends messages | // the following functions appends messages | |||
// to the send buffer | // to the send buffer | |||
void write_choke(); | void write_choke(); | |||
void write_unchoke(); | void write_unchoke(); | |||
void write_interested(); | void write_interested(); | |||
void write_not_interested(); | void write_not_interested(); | |||
void write_request(peer_request const& r); | void write_request(peer_request const& r); | |||
skipping to change at line 260 | skipping to change at line 253 | |||
// FAST extension | // FAST extension | |||
void write_have_all(); | void write_have_all(); | |||
void write_have_none(); | void write_have_none(); | |||
void write_reject_request(peer_request const&); | void write_reject_request(peer_request const&); | |||
void write_allow_fast(int piece); | void write_allow_fast(int piece); | |||
void write_suggest(int piece); | void write_suggest(int piece); | |||
void on_connected(); | void on_connected(); | |||
void on_metadata(); | void on_metadata(); | |||
#ifdef TORRENT_DEBUG | #if TORRENT_USE_INVARIANT_CHECKS | |||
void check_invariant() const; | void check_invariant() const; | |||
ptime m_last_choke; | ptime m_last_choke; | |||
#endif | #endif | |||
private: | private: | |||
bool dispatch_message(int received); | bool dispatch_message(int received); | |||
// returns the block currently being | // returns the block currently being | |||
// downloaded. And the progress of that | // downloaded. And the progress of that | |||
// block. If the peer isn't downloading | // block. If the peer isn't downloading | |||
skipping to change at line 355 | skipping to change at line 348 | |||
}; | }; | |||
#ifndef TORRENT_DISABLE_ENCRYPTION | #ifndef TORRENT_DISABLE_ENCRYPTION | |||
enum | enum | |||
{ | { | |||
handshake_len = 68, | handshake_len = 68, | |||
dh_key_len = 96 | dh_key_len = 96 | |||
}; | }; | |||
#endif | #endif | |||
std::string m_client_version; | ||||
// state of on_receive | // state of on_receive | |||
state m_state; | boost::uint8_t m_state; | |||
// this is set to true if the handshake from | ||||
// the peer indicated that it supports the | ||||
// extension protocol | ||||
bool m_supports_extensions:1; | ||||
bool m_supports_dht_port:1; | ||||
bool m_supports_fast:1; | ||||
#if TORRENT_USE_ASSERTS | ||||
// this is set to true when the client's | ||||
// bitfield is sent to this peer | ||||
bool m_sent_bitfield:1; | ||||
bool m_in_constructor:1; | ||||
bool m_sent_handshake:1; | ||||
#endif | ||||
#ifndef TORRENT_DISABLE_ENCRYPTION | ||||
// this is set to true after the encryption method has been | ||||
// succesfully negotiated (either plaintext or rc4), to sign | ||||
al | ||||
// automatic encryption/decryption. | ||||
bool m_encrypted:1; | ||||
// true if rc4, false if plaintext | ||||
bool m_rc4_encrypted:1; | ||||
#endif | ||||
#ifndef TORRENT_DISABLE_EXTENSIONS | ||||
// the message ID for upload only message | ||||
// 0 if not supported | ||||
boost::uint8_t m_upload_only_id; | ||||
// the message ID for holepunch messages | ||||
boost::uint8_t m_holepunch_id; | ||||
#endif | ||||
std::string m_client_version; | ||||
static const message_handler m_message_handler[num_supported _messages]; | static const message_handler m_message_handler[num_supported _messages]; | |||
// the peer ID we advertise for ourself | ||||
peer_id m_our_peer_id; | ||||
// this is a queue of ranges that describes | // this is a queue of ranges that describes | |||
// where in the send buffer actual payload | // where in the send buffer actual payload | |||
// data is located. This is currently | // data is located. This is currently | |||
// only used to be able to gather statistics | // only used to be able to gather statistics | |||
// seperately on payload and protocol data. | // seperately on payload and protocol data. | |||
struct range | struct range | |||
{ | { | |||
range(int s, int l) | range(int s, int l) | |||
: start(s) | : start(s) | |||
, length(l) | , length(l) | |||
skipping to change at line 387 | skipping to change at line 419 | |||
int length; | int length; | |||
}; | }; | |||
static bool range_below_zero(const range& r) | static bool range_below_zero(const range& r) | |||
{ return r.start < 0; } | { return r.start < 0; } | |||
std::vector<range> m_payloads; | std::vector<range> m_payloads; | |||
// we have suggested these pieces to the peer | // we have suggested these pieces to the peer | |||
// don't suggest it again | // don't suggest it again | |||
bitfield m_sent_suggested_pieces; | bitfield m_sent_suggested_pieces; | |||
#ifndef TORRENT_DISABLE_EXTENSIONS | ||||
// the message ID for upload only message | ||||
// 0 if not supported | ||||
boost::uint8_t m_upload_only_id; | ||||
// the message ID for holepunch messages | ||||
boost::uint8_t m_holepunch_id; | ||||
// the message ID for don't-have message | ||||
boost::uint8_t m_dont_have_id; | ||||
// the message ID for share mode message | ||||
// 0 if not supported | ||||
boost::uint8_t m_share_mode_id; | ||||
char m_reserved_bits[8]; | ||||
#endif | ||||
// this is set to true if the handshake from | ||||
// the peer indicated that it supports the | ||||
// extension protocol | ||||
bool m_supports_extensions:1; | ||||
bool m_supports_dht_port:1; | ||||
bool m_supports_fast:1; | ||||
#ifndef TORRENT_DISABLE_ENCRYPTION | #ifndef TORRENT_DISABLE_ENCRYPTION | |||
// this is set to true after the encryption method has been | ||||
// succesfully negotiated (either plaintext or rc4), to sign | ||||
al | ||||
// automatic encryption/decryption. | ||||
bool m_encrypted; | ||||
// true if rc4, false if plaintext | ||||
bool m_rc4_encrypted; | ||||
// used to disconnect peer if sync points are not found with | ||||
in | ||||
// the maximum number of bytes | ||||
int m_sync_bytes_read; | ||||
// initialized during write_pe1_2_dhkey, and destroyed on | // initialized during write_pe1_2_dhkey, and destroyed on | |||
// creation of m_enc_handler. Cannot reinitialize once | // creation of m_enc_handler. Cannot reinitialize once | |||
// initialized. | // initialized. | |||
boost::scoped_ptr<dh_key_exchange> m_dh_key_exchange; | boost::scoped_ptr<dh_key_exchange> m_dh_key_exchange; | |||
// if encryption is negotiated, this is used for | // if encryption is negotiated, this is used for | |||
// encryption/decryption during the entire session. Destroye d | // encryption/decryption during the entire session. Destroye d | |||
// if plaintext is selected | // if plaintext is selected | |||
boost::scoped_ptr<encryption_handler> m_enc_handler; | boost::scoped_ptr<encryption_handler> m_enc_handler; | |||
// (outgoing only) synchronize verification constant with | // (outgoing only) synchronize verification constant with | |||
// remote peer, this will hold rc4_decrypt(vc). Destroyed | // remote peer, this will hold rc4_decrypt(vc). Destroyed | |||
// after the sync step. | // after the sync step. | |||
boost::scoped_array<char> m_sync_vc; | boost::scoped_array<char> m_sync_vc; | |||
// (incoming only) synchronize hash with remote peer, holds | // (incoming only) synchronize hash with remote peer, holds | |||
// the sync hash (hash("req1",secret)). Destroyed after the | // the sync hash (hash("req1",secret)). Destroyed after the | |||
// sync step. | // sync step. | |||
boost::scoped_ptr<sha1_hash> m_sync_hash; | boost::scoped_ptr<sha1_hash> m_sync_hash; | |||
// used to disconnect peer if sync points are not found with | ||||
in | ||||
// the maximum number of bytes | ||||
int m_sync_bytes_read; | ||||
#endif // #ifndef TORRENT_DISABLE_ENCRYPTION | #endif // #ifndef TORRENT_DISABLE_ENCRYPTION | |||
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS | #ifndef TORRENT_DISABLE_EXTENSIONS | |||
// this is set to true when the client's | // the message ID for don't-have message | |||
// bitfield is sent to this peer | boost::uint8_t m_dont_have_id; | |||
bool m_sent_bitfield; | ||||
bool m_in_constructor; | // the message ID for share mode message | |||
// 0 if not supported | ||||
boost::uint8_t m_share_mode_id; | ||||
bool m_sent_handshake; | // the reserved bits received from the other peer | |||
// in the bittorrent handshake | ||||
char m_reserved_bits[8]; | ||||
#endif | #endif | |||
}; | }; | |||
} | } | |||
#endif // TORRENT_BT_PEER_CONNECTION_HPP_INCLUDED | #endif // TORRENT_BT_PEER_CONNECTION_HPP_INCLUDED | |||
End of changes. 17 change blocks. | ||||
64 lines changed or deleted | 66 lines changed or added | |||
buffer.hpp | buffer.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2007, Arvid Norberg | Copyright (c) 2007-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 117 | skipping to change at line 117 | |||
buffer(buffer const& b) | buffer(buffer const& b) | |||
: m_begin(0) | : m_begin(0) | |||
, m_end(0) | , m_end(0) | |||
, m_last(0) | , m_last(0) | |||
{ | { | |||
if (b.size() == 0) return; | if (b.size() == 0) return; | |||
resize(b.size()); | resize(b.size()); | |||
std::memcpy(m_begin, b.begin(), b.size()); | std::memcpy(m_begin, b.begin(), b.size()); | |||
} | } | |||
#if __cplusplus > 199711L | ||||
buffer(buffer&& b): m_begin(b.m_begin), m_end(b.m_end), m_last(b.m_l | ||||
ast) | ||||
{ b.m_begin = b.m_end = b.m_last = NULL; } | ||||
#endif | ||||
buffer& operator=(buffer const& b) | buffer& operator=(buffer const& b) | |||
{ | { | |||
if (&b == this) return *this; | if (&b == this) return *this; | |||
resize(b.size()); | resize(b.size()); | |||
if (b.size() == 0) return *this; | if (b.size() == 0) return *this; | |||
std::memcpy(m_begin, b.begin(), b.size()); | std::memcpy(m_begin, b.begin(), b.size()); | |||
return *this; | return *this; | |||
} | } | |||
~buffer() | ~buffer() | |||
End of changes. 2 change blocks. | ||||
1 lines changed or deleted | 7 lines changed or added | |||
build_config.hpp | build_config.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2010, Arvid Norberg | Copyright (c) 2010-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 40 | skipping to change at line 40 | |||
*/ | */ | |||
#ifndef TORRENT_BUILD_CONFIG_HPP_INCLUDED | #ifndef TORRENT_BUILD_CONFIG_HPP_INCLUDED | |||
#define TORRENT_BUILD_CONFIG_HPP_INCLUDED | #define TORRENT_BUILD_CONFIG_HPP_INCLUDED | |||
#include "libtorrent/config.hpp" | #include "libtorrent/config.hpp" | |||
#include <boost/preprocessor/cat.hpp> | #include <boost/preprocessor/cat.hpp> | |||
#include <boost/preprocessor/stringize.hpp> | #include <boost/preprocessor/stringize.hpp> | |||
#ifdef TORRENT_DEBUG | ||||
#define TORRENT_CFG_DEBUG dbg_ | ||||
#else | ||||
#define TORRENT_CFG_DEBUG rel_ | ||||
#endif | ||||
#if TORRENT_USE_BOOST_DATE_TIME | #if TORRENT_USE_BOOST_DATE_TIME | |||
#define TORRENT_CFG_TIME boosttime_ | #define TORRENT_CFG_TIME boosttime_ | |||
#elif TORRENT_USE_ABSOLUTE_TIME | #elif TORRENT_USE_ABSOLUTE_TIME | |||
#define TORRENT_CFG_TIME absolutetime_ | #define TORRENT_CFG_TIME absolutetime_ | |||
#elif TORRENT_USE_QUERY_PERFORMANCE_TIMER | #elif TORRENT_USE_QUERY_PERFORMANCE_TIMER | |||
#define TORRENT_CFG_TIME performancetimer_ | #define TORRENT_CFG_TIME performancetimer_ | |||
#elif TORRENT_USE_CLOCK_GETTIME | #elif TORRENT_USE_CLOCK_GETTIME | |||
#define TORRENT_CFG_TIME clocktime_ | #define TORRENT_CFG_TIME clocktime_ | |||
#elif TORRENT_USE_SYSTEM_TIME | #elif TORRENT_USE_SYSTEM_TIME | |||
#define TORRENT_CFG_TIME systime_ | #define TORRENT_CFG_TIME systime_ | |||
#else | #else | |||
#error what timer is used? | #error what timer is used? | |||
#endif | #endif | |||
#if TORRENT_USE_IPV6 | #if TORRENT_USE_IPV6 | |||
#define TORRENT_CFG_IPV6 ipv6_ | #define TORRENT_CFG_IPV6 ipv6_ | |||
#else | #else | |||
#define TORRENT_CFG_IPV6 noipv_- | #define TORRENT_CFG_IPV6 noipv_- | |||
#endif | #endif | |||
#ifdef TORRENT_DISABLE_DHT | ||||
#define TORRENT_CFG_DHT nodht_ | ||||
#else | ||||
#define TORRENT_CFG_DHT dht_ | ||||
#endif | ||||
#ifdef TORRENT_DISABLE_POOL_ALLOCATORS | ||||
#define TORRENT_CFG_POOL nopools_ | ||||
#else | ||||
#define TORRENT_CFG_POOL pools_ | ||||
#endif | ||||
#ifdef TORRENT_VERBOSE_LOGGING | ||||
#define TORRENT_CFG_LOG verboselog_ | ||||
#elif defined TORRENT_LOGGING | ||||
#define TORRENT_CFG_LOG log_ | ||||
#else | ||||
#define TORRENT_CFG_LOG nolog_ | ||||
#endif | ||||
#ifdef _UNICODE | ||||
#define TORRENT_CFG_UNICODE unicode_ | ||||
#else | ||||
#define TORRENT_CFG_UNICODE ansi_ | ||||
#endif | ||||
#ifdef TORRENT_DISABLE_RESOLVE_COUNTRIES | ||||
#define TORRENT_CFG_RESOLVE noresolvecountries_ | ||||
#else | ||||
#define TORRENT_CFG_RESOLVE resolvecountries_ | ||||
#endif | ||||
#ifdef TORRENT_NO_DEPRECATE | #ifdef TORRENT_NO_DEPRECATE | |||
#define TORRENT_CFG_DEPR nodeprecate_ | #define TORRENT_CFG_DEPR nodeprecate_ | |||
#else | #else | |||
#define TORRENT_CFG_DEPR deprecated_ | #define TORRENT_CFG_DEPR deprecated_ | |||
#endif | #endif | |||
#ifdef TORRENT_DISABLE_FULL_STATS | ||||
#define TORRENT_CFG_STATS partialstats_ | ||||
#else | ||||
#define TORRENT_CFG_STATS fullstats_ | ||||
#endif | ||||
#ifdef TORRENT_DISABLE_EXTENSIONS | ||||
#define TORRENT_CFG_EXT noext_ | ||||
#else | ||||
#define TORRENT_CFG_EXT ext_ | ||||
#endif | ||||
#define TORRENT_CFG \ | #define TORRENT_CFG \ | |||
BOOST_PP_CAT(TORRENT_CFG_DEBUG, \ | ||||
BOOST_PP_CAT(TORRENT_CFG_TIME, \ | BOOST_PP_CAT(TORRENT_CFG_TIME, \ | |||
BOOST_PP_CAT(TORRENT_CFG_POOL, \ | TORRENT_CFG_DEPR) | |||
BOOST_PP_CAT(TORRENT_CFG_LOG, \ | ||||
BOOST_PP_CAT(TORRENT_CFG_RESOLVE, \ | ||||
BOOST_PP_CAT(TORRENT_CFG_DEPR, \ | ||||
BOOST_PP_CAT(TORRENT_CFG_DHT, \ | ||||
TORRENT_CFG_EXT))))))) | ||||
#define TORRENT_CFG_STRING BOOST_PP_STRINGIZE(TORRENT_CFG) | #define TORRENT_CFG_STRING BOOST_PP_STRINGIZE(TORRENT_CFG) | |||
#endif | #endif | |||
End of changes. 6 change blocks. | ||||
58 lines changed or deleted | 2 lines changed or added | |||
chained_buffer.hpp | chained_buffer.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2007, Arvid Norberg | Copyright (c) 2007-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 57 | skipping to change at line 57 | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
#if BOOST_VERSION >= 103500 | #if BOOST_VERSION >= 103500 | |||
namespace asio = boost::asio; | namespace asio = boost::asio; | |||
#endif | #endif | |||
struct TORRENT_EXTRA_EXPORT chained_buffer | struct TORRENT_EXTRA_EXPORT chained_buffer | |||
{ | { | |||
chained_buffer(): m_bytes(0), m_capacity(0) | chained_buffer(): m_bytes(0), m_capacity(0) | |||
{ | { | |||
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS | #if TORRENT_USE_ASSERTS | |||
m_destructed = false; | m_destructed = false; | |||
#endif | #endif | |||
} | } | |||
struct buffer_t | struct buffer_t | |||
{ | { | |||
boost::function<void(char*)> free; // destructs the buffer | boost::function<void(char*)> free; // destructs the buffer | |||
char* buf; // the first byte of the buffer | char* buf; // the first byte of the buffer | |||
int size; // the total size of the buffer | ||||
char* start; // the first byte to send/receive in th e buffer | char* start; // the first byte to send/receive in th e buffer | |||
int size; // the total size of the buffer | ||||
int used_size; // this is the number of bytes to sen d/receive | int used_size; // this is the number of bytes to sen d/receive | |||
}; | }; | |||
bool empty() const { return m_bytes == 0; } | bool empty() const { return m_bytes == 0; } | |||
int size() const { return m_bytes; } | int size() const { return m_bytes; } | |||
int capacity() const { return m_capacity; } | int capacity() const { return m_capacity; } | |||
void pop_front(int bytes_to_pop); | void pop_front(int bytes_to_pop); | |||
void append_buffer(char* buffer, int s, int used_size | void append_buffer(char* buffer, int s, int used_size | |||
skipping to change at line 105 | skipping to change at line 104 | |||
std::list<asio::const_buffer> const& build_iovec(int to_send ); | std::list<asio::const_buffer> const& build_iovec(int to_send ); | |||
~chained_buffer(); | ~chained_buffer(); | |||
private: | private: | |||
// this is the list of all the buffers we want to | // this is the list of all the buffers we want to | |||
// send | // send | |||
std::list<buffer_t> m_vec; | std::list<buffer_t> m_vec; | |||
// this is the vector of buffers used when | ||||
// invoking the async write call | ||||
std::list<asio::const_buffer> m_tmp_vec; | ||||
// this is the number of bytes in the send buf. | // this is the number of bytes in the send buf. | |||
// this will always be equal to the sum of the | // this will always be equal to the sum of the | |||
// size of all buffers in vec | // size of all buffers in vec | |||
int m_bytes; | int m_bytes; | |||
// the total size of all buffers in the chain | // the total size of all buffers in the chain | |||
// including unused space | // including unused space | |||
int m_capacity; | int m_capacity; | |||
// this is the vector of buffers used when | #if TORRENT_USE_ASSERTS | |||
// invoking the async write call | ||||
std::list<asio::const_buffer> m_tmp_vec; | ||||
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS | ||||
bool m_destructed; | bool m_destructed; | |||
#endif | #endif | |||
}; | }; | |||
} | } | |||
#endif | #endif | |||
End of changes. 6 change blocks. | ||||
9 lines changed or deleted | 8 lines changed or added | |||
config.hpp | config.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2005, Arvid Norberg | Copyright (c) 2005-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 36 | skipping to change at line 36 | |||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 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 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||
POSSIBILITY OF SUCH DAMAGE. | POSSIBILITY OF SUCH DAMAGE. | |||
*/ | */ | |||
#ifndef TORRENT_CONFIG_HPP_INCLUDED | #ifndef TORRENT_CONFIG_HPP_INCLUDED | |||
#define TORRENT_CONFIG_HPP_INCLUDED | #define TORRENT_CONFIG_HPP_INCLUDED | |||
#if !defined _MSC_VER || _MSC_VER >= 1600 | ||||
#ifndef __STDC_LIMIT_MACROS | ||||
#define __STDC_LIMIT_MACROS 1 | ||||
#endif | ||||
#ifndef __STDC_CONSTANT_MACROS | ||||
#define __STDC_CONSTANT_MACROS 1 | ||||
#endif | ||||
#endif | ||||
#include <boost/config.hpp> | #include <boost/config.hpp> | |||
#include <boost/version.hpp> | #include <boost/version.hpp> | |||
#include <boost/detail/endian.hpp> | ||||
#include <stdio.h> // for snprintf | #include <stdio.h> // for snprintf | |||
#include <limits.h> // for IOV_MAX | #include <limits.h> // for IOV_MAX | |||
#include "libtorrent/export.hpp" | ||||
#if defined TORRENT_DEBUG_BUFFERS && !defined TORRENT_DISABLE_POOL_ALLOCATO R | #if defined TORRENT_DEBUG_BUFFERS && !defined TORRENT_DISABLE_POOL_ALLOCATO R | |||
#error TORRENT_DEBUG_BUFFERS only works if you also disable pool allocators with TORRENT_DISABLE_POOL_ALLOCATOR | #error TORRENT_DEBUG_BUFFERS only works if you also disable pool allocators with TORRENT_DISABLE_POOL_ALLOCATOR | |||
#endif | #endif | |||
#if !defined BOOST_ASIO_SEPARATE_COMPILATION && !defined BOOST_ASIO_DYN_LIN K | #if !defined BOOST_ASIO_SEPARATE_COMPILATION && !defined BOOST_ASIO_DYN_LIN K | |||
#error you must define either BOOST_ASIO_SEPARATE_COMPILATION or BOOST_ASIO _DYN_LINK in your project in \ | #error you must define either BOOST_ASIO_SEPARATE_COMPILATION or BOOST_ASIO _DYN_LINK in your project in \ | |||
order for asio's declarations to be correct. If you're linking dynam ically against libtorrent, define \ | order for asios declarations to be correct. If you are linking dynam ically against libtorrent, define \ | |||
BOOST_ASIO_DYN_LINK otherwise BOOST_ASIO_SEPARATE_COMPILATION. You c an also use pkg-config or boost \ | BOOST_ASIO_DYN_LINK otherwise BOOST_ASIO_SEPARATE_COMPILATION. You c an also use pkg-config or boost \ | |||
build, to automatically apply these defines | build, to automatically apply these defines | |||
#endif | #endif | |||
#if !defined _MSC_VER || _MSC_VER >= 1600 | // some parts pulled out of stdint.h | |||
#ifndef __STDC_LIMIT_MACROS | // to avoid C99 or C++11 dependency | |||
#define __STDC_LIMIT_MACROS 1 | ||||
#endif | ||||
#include <stdint.h> // for INT64_MAX | ||||
#else | ||||
#if !defined INT64_MAX | #if !defined INT64_MAX | |||
#define INT64_MAX 0x7fffffffffffffffLL | #define INT64_MAX 0x7fffffffffffffffLL | |||
#endif | #endif | |||
#if !defined INT16_MAX | ||||
#define INT16_MAX 32767 | ||||
#endif | ||||
#if !defined INT16_MIN | ||||
#define INT16_MIN -32768 | ||||
#endif | #endif | |||
#ifndef _MSC_VER | #ifndef _MSC_VER | |||
#ifndef __STDC_FORMAT_MACROS | #ifndef __STDC_FORMAT_MACROS | |||
#define __STDC_FORMAT_MACROS 1 | #define __STDC_FORMAT_MACROS 1 | |||
#endif | #endif | |||
#include <inttypes.h> // for PRId64 et.al. | #include <inttypes.h> // for PRId64 et.al. | |||
#endif | #endif | |||
#ifndef PRId64 | #ifndef PRId64 | |||
// MinGW uses microsofts runtime | // MinGW uses microsofts runtime | |||
#if defined _MSC_VER || defined __MINGW32__ | #if defined _MSC_VER || defined __MINGW32__ | |||
#define PRId64 "I64d" | #define PRId64 "I64d" | |||
#define PRIu64 "I64u" | #define PRIu64 "I64u" | |||
#define PRIx64 "I64x" | ||||
#define PRIu32 "u" | #define PRIu32 "u" | |||
#else | #else | |||
#define PRId64 "lld" | #define PRId64 "lld" | |||
#define PRIu64 "llu" | #define PRIu64 "llu" | |||
#define PRIx64 "llx" | ||||
#define PRIu32 "u" | #define PRIu32 "u" | |||
#endif | #endif | |||
#endif | #endif | |||
// backwards compatibility with older versions of boost | ||||
#if !defined BOOST_SYMBOL_EXPORT && !defined BOOST_SYMBOL_IMPORT | ||||
# if defined _MSC_VER || defined __MINGW32__ | ||||
# define BOOST_SYMBOL_EXPORT __declspec(dllexport) | ||||
# define BOOST_SYMBOL_IMPORT __declspec(dllimport) | ||||
# elif __GNU__ >= 4 | ||||
# define BOOST_SYMBOL_EXPORT __attribute__((visibility("default"))) | ||||
# define BOOST_SYMBOL_IMPORT __attribute__((visibility("default"))) | ||||
# else | ||||
# define BOOST_SYMBOL_EXPORT | ||||
# define BOOST_SYMBOL_IMPORT | ||||
# endif | ||||
#endif | ||||
#if defined TORRENT_BUILDING_SHARED | ||||
# define TORRENT_EXPORT BOOST_SYMBOL_EXPORT | ||||
#elif defined TORRENT_LINKING_SHARED | ||||
# define TORRENT_EXPORT BOOST_SYMBOL_IMPORT | ||||
#endif | ||||
// when this is specified, export a bunch of extra | ||||
// symbols, mostly for the unit tests to reach | ||||
#if TORRENT_EXPORT_EXTRA | ||||
# if defined TORRENT_BUILDING_SHARED | ||||
# define TORRENT_EXTRA_EXPORT BOOST_SYMBOL_EXPORT | ||||
# elif defined TORRENT_LINKING_SHARED | ||||
# define TORRENT_EXTRA_EXPORT BOOST_SYMBOL_IMPORT | ||||
# endif | ||||
#endif | ||||
#ifndef TORRENT_EXTRA_EXPORT | ||||
# define TORRENT_EXTRA_EXPORT | ||||
#endif | ||||
// ======= GCC ========= | // ======= GCC ========= | |||
#if defined __GNUC__ | #if defined __GNUC__ | |||
# if __GNUC__ >= 3 | # if __GNUC__ >= 3 | |||
# define TORRENT_DEPRECATED __attribute__ ((deprecated)) | # define TORRENT_DEPRECATED __attribute__ ((deprecated)) | |||
# endif | # endif | |||
// ======= SUNPRO ========= | // ======= SUNPRO ========= | |||
skipping to change at line 182 | skipping to change at line 163 | |||
|| defined __OpenBSD__ || defined __bsdi__ || defined __DragonFly__ \ | || defined __OpenBSD__ || defined __bsdi__ || defined __DragonFly__ \ | |||
|| defined __FreeBSD_kernel__ | || defined __FreeBSD_kernel__ | |||
#define TORRENT_BSD | #define TORRENT_BSD | |||
// we don't need iconv on mac, because | // we don't need iconv on mac, because | |||
// the locale is always utf-8 | // the locale is always utf-8 | |||
#if defined __APPLE__ | #if defined __APPLE__ | |||
#ifndef TORRENT_USE_ICONV | #ifndef TORRENT_USE_ICONV | |||
#define TORRENT_USE_ICONV 0 | #define TORRENT_USE_ICONV 0 | |||
#define TORRENT_USE_LOCALE 0 | #define TORRENT_USE_LOCALE 0 | |||
#define TORRENT_CLOSE_MAY_BLOCK 1 | #define TORRENT_CLOSE_MAY_BLOCK 1 | |||
#include <AvailabilityMacros.h> | ||||
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 | ||||
#ifdef TORRENT_USE_OPENSSL | ||||
#define TORRENT_USE_COMMONCRYPTO 1 | ||||
#endif // TORRENT_USE_OPENSSL | ||||
#endif // MAC_OS_X_VERSION_MIN_REQUIRED | ||||
// execinfo.h is available in the MacOS X 10.5 SDK. | // execinfo.h is available in the MacOS X 10.5 SDK. | |||
#define TORRENT_USE_EXECINFO MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 | #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 | |||
#define TORRENT_USE_EXECINFO 1 | ||||
#endif | #endif | |||
#endif // __APPLE__ | ||||
#else | #else | |||
// FreeBSD has a reasonable iconv signature | // FreeBSD has a reasonable iconv signature | |||
// unless we're on glibc | // unless we're on glibc | |||
#ifndef __GLIBC__ | #ifndef __GLIBC__ | |||
# define TORRENT_ICONV_ARG (const char**) | # define TORRENT_ICONV_ARG (const char**) | |||
#endif | #endif | |||
#endif | #endif | |||
#define TORRENT_HAS_FALLOCATE 0 | #define TORRENT_HAS_FALLOCATE 0 | |||
#define TORRENT_USE_IFADDRS 1 | #define TORRENT_USE_IFADDRS 1 | |||
#define TORRENT_USE_SYSCTL 1 | #define TORRENT_USE_SYSCTL 1 | |||
#define TORRENT_USE_IFCONF 1 | #define TORRENT_USE_IFCONF 1 | |||
// ==== LINUX === | // ==== LINUX === | |||
#elif defined __linux__ | #elif defined __linux__ | |||
#define TORRENT_LINUX | #define TORRENT_LINUX | |||
#define TORRENT_USE_IFADDRS 1 | ||||
#define TORRENT_USE_NETLINK 1 | #define TORRENT_USE_NETLINK 1 | |||
#define TORRENT_USE_IFCONF 1 | #define TORRENT_USE_IFCONF 1 | |||
#define TORRENT_HAS_SALEN 0 | #define TORRENT_HAS_SALEN 0 | |||
// ===== ANDROID ===== (almost linux, sort of) | ||||
#if defined __ANDROID__ | ||||
#define TORRENT_ANDROID | ||||
#define TORRENT_HAS_FALLOCATE 0 | ||||
#define TORRENT_USE_ICONV 0 | ||||
#define TORRENT_USE_IFADDRS 0 | ||||
#define TORRENT_USE_MEMALIGN 1 | ||||
#else | ||||
#define TORRENT_USE_IFADDRS 1 | ||||
#define TORRENT_USE_POSIX_MEMALIGN 1 | #define TORRENT_USE_POSIX_MEMALIGN 1 | |||
#endif | ||||
#if __amd64__ || __i386__ | #if __amd64__ || __i386__ | |||
#define TORRENT_USE_EXECINFO 1 | #define TORRENT_USE_EXECINFO 1 | |||
#endif | #endif | |||
// ==== MINGW === | // ==== MINGW === | |||
#elif defined __MINGW32__ | #elif defined __MINGW32__ | |||
#define TORRENT_MINGW | #define TORRENT_MINGW | |||
#define TORRENT_WINDOWS | #define TORRENT_WINDOWS | |||
#ifndef TORRENT_USE_ICONV | #ifndef TORRENT_USE_ICONV | |||
# define TORRENT_USE_ICONV 0 | # define TORRENT_USE_ICONV 0 | |||
skipping to change at line 268 | skipping to change at line 273 | |||
#ifndef TORRENT_USE_ICONV | #ifndef TORRENT_USE_ICONV | |||
#define TORRENT_USE_ICONV 0 | #define TORRENT_USE_ICONV 0 | |||
#endif | #endif | |||
// ==== GNU/Hurd === | // ==== GNU/Hurd === | |||
#elif defined __GNU__ | #elif defined __GNU__ | |||
#define TORRENT_HURD | #define TORRENT_HURD | |||
#define TORRENT_USE_IFADDRS 1 | #define TORRENT_USE_IFADDRS 1 | |||
#define TORRENT_USE_IFCONF 1 | #define TORRENT_USE_IFCONF 1 | |||
// ==== eCS(OS/2) === | ||||
#elif defined __OS2__ | ||||
#define TORRENT_OS2 | ||||
#define TORRENT_HAS_FALLOCATE 0 | ||||
#define TORRENT_USE_IFCONF 1 | ||||
#define TORRENT_USE_SYSCTL 1 | ||||
#define TORRENT_USE_MLOCK 0 | ||||
#define TORRENT_USE_IPV6 0 | ||||
#define TORRENT_ICONV_ARG (const char**) | ||||
#define TORRENT_USE_WRITEV 0 | ||||
#define TORRENT_USE_READV 0 | ||||
#else | #else | |||
#warning unknown OS, assuming BSD | #warning unknown OS, assuming BSD | |||
#define TORRENT_BSD | #define TORRENT_BSD | |||
#endif | #endif | |||
// on windows, NAME_MAX refers to Unicode characters | // on windows, NAME_MAX refers to Unicode characters | |||
// on linux it refers to bytes (utf-8 encoded) | // on linux it refers to bytes (utf-8 encoded) | |||
// TODO: Make this count Unicode characters instead of bytes on windows | // TODO: Make this count Unicode characters instead of bytes on windows | |||
// windows | // windows | |||
skipping to change at line 306 | skipping to change at line 323 | |||
// path element / filename on windows | // path element / filename on windows | |||
#define TORRENT_MAX_PATH 255 | #define TORRENT_MAX_PATH 255 | |||
#warning unknown platform, assuming the longest path is 255 | #warning unknown platform, assuming the longest path is 255 | |||
#endif | #endif | |||
#if defined TORRENT_WINDOWS && !defined TORRENT_MINGW | #if defined TORRENT_WINDOWS && !defined TORRENT_MINGW | |||
#include <stdarg.h> | #include <stdarg.h> | |||
inline int snprintf(char* buf, int len, char const* fmt, ...) | // internal | |||
#ifdef __cplusplus | ||||
inline | ||||
#else | ||||
static | ||||
#endif | ||||
int snprintf(char* buf, int len, char const* fmt, ...) | ||||
{ | { | |||
va_list lp; | va_list lp; | |||
int ret; | ||||
va_start(lp, fmt); | va_start(lp, fmt); | |||
int ret = _vsnprintf(buf, len, fmt, lp); | ret = _vsnprintf(buf, len, fmt, lp); | |||
va_end(lp); | va_end(lp); | |||
if (ret < 0) { buf[len-1] = 0; ret = len-1; } | if (ret < 0) { buf[len-1] = 0; ret = len-1; } | |||
return ret; | return ret; | |||
} | } | |||
#define strtoll _strtoi64 | #define strtoll _strtoi64 | |||
#else | #else | |||
#include <limits.h> | #include <limits.h> | |||
#endif | #endif | |||
skipping to change at line 387 | skipping to change at line 411 | |||
#define TORRENT_USE_WSTRING 1 | #define TORRENT_USE_WSTRING 1 | |||
#else | #else | |||
#define TORRENT_USE_WSTRING 0 | #define TORRENT_USE_WSTRING 0 | |||
#endif // BOOST_NO_STD_WSTRING | #endif // BOOST_NO_STD_WSTRING | |||
#endif // TORRENT_USE_WSTRING | #endif // TORRENT_USE_WSTRING | |||
#ifndef TORRENT_HAS_FALLOCATE | #ifndef TORRENT_HAS_FALLOCATE | |||
#define TORRENT_HAS_FALLOCATE 1 | #define TORRENT_HAS_FALLOCATE 1 | |||
#endif | #endif | |||
#ifndef TORRENT_EXPORT | ||||
# define TORRENT_EXPORT | ||||
#endif | ||||
#ifndef TORRENT_DEPRECATED_PREFIX | #ifndef TORRENT_DEPRECATED_PREFIX | |||
#define TORRENT_DEPRECATED_PREFIX | #define TORRENT_DEPRECATED_PREFIX | |||
#endif | #endif | |||
#ifndef TORRENT_USE_COMMONCRYPTO | ||||
#define TORRENT_USE_COMMONCRYPTO 0 | ||||
#endif | ||||
#ifndef TORRENT_DEPRECATED | #ifndef TORRENT_DEPRECATED | |||
#define TORRENT_DEPRECATED | #define TORRENT_DEPRECATED | |||
#endif | #endif | |||
#ifndef TORRENT_COMPLETE_TYPES_REQUIRED | #ifndef TORRENT_COMPLETE_TYPES_REQUIRED | |||
#define TORRENT_COMPLETE_TYPES_REQUIRED 0 | #define TORRENT_COMPLETE_TYPES_REQUIRED 0 | |||
#endif | #endif | |||
#ifndef TORRENT_USE_UNC_PATHS | #ifndef TORRENT_USE_UNC_PATHS | |||
#define TORRENT_USE_UNC_PATHS 0 | #define TORRENT_USE_UNC_PATHS 0 | |||
skipping to change at line 465 | skipping to change at line 489 | |||
#define TORRENT_IOV_MAX IOV_MAX | #define TORRENT_IOV_MAX IOV_MAX | |||
#else | #else | |||
#define TORRENT_IOV_MAX INT_MAX | #define TORRENT_IOV_MAX INT_MAX | |||
#endif | #endif | |||
#endif | #endif | |||
#if !defined(TORRENT_READ_HANDLER_MAX_SIZE) | #if !defined(TORRENT_READ_HANDLER_MAX_SIZE) | |||
# ifdef _GLIBCXX_DEBUG | # ifdef _GLIBCXX_DEBUG | |||
# define TORRENT_READ_HANDLER_MAX_SIZE 400 | # define TORRENT_READ_HANDLER_MAX_SIZE 400 | |||
# else | # else | |||
# define TORRENT_READ_HANDLER_MAX_SIZE 300 | // if this is not divisible by 8, we're wasting space | |||
# define TORRENT_READ_HANDLER_MAX_SIZE 336 | ||||
# endif | # endif | |||
#endif | #endif | |||
#if !defined(TORRENT_WRITE_HANDLER_MAX_SIZE) | #if !defined(TORRENT_WRITE_HANDLER_MAX_SIZE) | |||
# ifdef _GLIBCXX_DEBUG | # ifdef _GLIBCXX_DEBUG | |||
# define TORRENT_WRITE_HANDLER_MAX_SIZE 400 | # define TORRENT_WRITE_HANDLER_MAX_SIZE 400 | |||
# else | # else | |||
# define TORRENT_WRITE_HANDLER_MAX_SIZE 300 | // if this is not divisible by 8, we're wasting space | |||
# define TORRENT_WRITE_HANDLER_MAX_SIZE 336 | ||||
# endif | # endif | |||
#endif | #endif | |||
#if defined _MSC_VER && _MSC_VER <= 1200 | #if defined _MSC_VER && _MSC_VER <= 1200 | |||
#define for if (false) {} else for | #define for if (false) {} else for | |||
#endif | #endif | |||
#if TORRENT_BROKEN_UNIONS | #if TORRENT_BROKEN_UNIONS | |||
#define TORRENT_UNION struct | #define TORRENT_UNION struct | |||
#else | #else | |||
skipping to change at line 514 | skipping to change at line 540 | |||
#elif defined(TORRENT_AMIGA) | #elif defined(TORRENT_AMIGA) | |||
#define TORRENT_USE_ECLOCK 1 | #define TORRENT_USE_ECLOCK 1 | |||
#elif defined(TORRENT_BEOS) | #elif defined(TORRENT_BEOS) | |||
#define TORRENT_USE_SYSTEM_TIME 1 | #define TORRENT_USE_SYSTEM_TIME 1 | |||
#else | #else | |||
#define TORRENT_USE_BOOST_DATE_TIME 1 | #define TORRENT_USE_BOOST_DATE_TIME 1 | |||
#endif | #endif | |||
#endif | #endif | |||
// debug builds have asserts enabled by default, release | ||||
// builds have asserts if they are explicitly enabled by | ||||
// the release_asserts macro. | ||||
#ifndef TORRENT_USE_ASSERTS | ||||
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS | ||||
#define TORRENT_USE_ASSERTS 1 | ||||
#else | ||||
#define TORRENT_USE_ASSERTS 0 | ||||
#endif | ||||
#endif // TORRENT_USE_ASSERTS | ||||
#if defined TORRENT_DEBUG && TORRENT_USE_ASSERTS \ | ||||
&& !defined TORRENT_DISABLE_INVARIANT_CHECKS | ||||
#define TORRENT_USE_INVARIANT_CHECKS 1 | ||||
#else | ||||
#define TORRENT_USE_INVARIANT_CHECKS 0 | ||||
#endif | ||||
// for non-exception builds | // for non-exception builds | |||
#ifdef BOOST_NO_EXCEPTIONS | #ifdef BOOST_NO_EXCEPTIONS | |||
#define TORRENT_TRY if (true) | #define TORRENT_TRY if (true) | |||
#define TORRENT_CATCH(x) else if (false) | #define TORRENT_CATCH(x) else if (false) | |||
#define TORRENT_CATCH_ALL else if (false) | ||||
#define TORRENT_DECLARE_DUMMY(x, y) x y | #define TORRENT_DECLARE_DUMMY(x, y) x y | |||
#else | #else | |||
#define TORRENT_TRY try | #define TORRENT_TRY try | |||
#define TORRENT_CATCH(x) catch(x) | #define TORRENT_CATCH(x) catch(x) | |||
#define TORRENT_CATCH_ALL catch(...) | ||||
#define TORRENT_DECLARE_DUMMY(x, y) | #define TORRENT_DECLARE_DUMMY(x, y) | |||
#endif // BOOST_NO_EXCEPTIONS | #endif // BOOST_NO_EXCEPTIONS | |||
#endif // TORRENT_CONFIG_HPP_INCLUDED | #endif // TORRENT_CONFIG_HPP_INCLUDED | |||
End of changes. 27 change blocks. | ||||
54 lines changed or deleted | 96 lines changed or added | |||
connection_queue.hpp | connection_queue.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2007, Arvid Norberg | Copyright (c) 2007-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 65 | skipping to change at line 65 | |||
public: | public: | |||
connection_queue(io_service& ios); | connection_queue(io_service& ios); | |||
// if there are no free slots, returns the negative | // if there are no free slots, returns the negative | |||
// number of queued up connections | // number of queued up connections | |||
int free_slots() const; | int free_slots() const; | |||
void enqueue(boost::function<void(int)> const& on_connect | void enqueue(boost::function<void(int)> const& on_connect | |||
, boost::function<void()> const& on_timeout | , boost::function<void()> const& on_timeout | |||
, time_duration timeout, int priority = 0); | , time_duration timeout, int priority = 0); | |||
void done(int ticket); | bool done(int ticket); | |||
void limit(int limit); | void limit(int limit); | |||
int limit() const; | int limit() const; | |||
void close(); | void close(); | |||
int size() const { return m_queue.size(); } | int size() const { return m_queue.size(); } | |||
int num_connecting() const { return m_num_connecting; } | int num_connecting() const { return m_num_connecting; } | |||
#if defined TORRENT_ASIO_DEBUGGING | #if defined TORRENT_ASIO_DEBUGGING | |||
float next_timeout() const { return total_milliseconds(m_timer.expir es_at() - time_now_hires()) / 1000.f; } | float next_timeout() const { return total_milliseconds(m_timer.expir es_at() - time_now_hires()) / 1000.f; } | |||
float max_timeout() const | float max_timeout() const | |||
{ | { | |||
ptime max_timeout = min_time(); | ptime max_timeout = min_time(); | |||
skipping to change at line 87 | skipping to change at line 87 | |||
, end(m_queue.end()); i != end; ++i) | , end(m_queue.end()); i != end; ++i) | |||
{ | { | |||
if (!i->connecting) continue; | if (!i->connecting) continue; | |||
if (i->expires > max_timeout) max_timeout = i->expir es; | if (i->expires > max_timeout) max_timeout = i->expir es; | |||
} | } | |||
if (max_timeout == min_time()) return 0.f; | if (max_timeout == min_time()) return 0.f; | |||
return total_milliseconds(max_timeout - time_now_hires()) / 1000.f; | return total_milliseconds(max_timeout - time_now_hires()) / 1000.f; | |||
} | } | |||
#endif | #endif | |||
#ifdef TORRENT_DEBUG | #if TORRENT_USE_INVARIANT_CHECKS | |||
void check_invariant() const; | void check_invariant() const; | |||
#endif | #endif | |||
private: | private: | |||
typedef mutex mutex_t; | typedef mutex mutex_t; | |||
void try_connect(mutex_t::scoped_lock& l); | void try_connect(mutex_t::scoped_lock& l); | |||
void on_timeout(error_code const& e); | void on_timeout(error_code const& e); | |||
void on_try_connect(); | void on_try_connect(); | |||
struct entry | struct entry | |||
{ | { | |||
entry(): connecting(false), ticket(0), expires(max_time()), | entry() | |||
priority(0) {} | : expires(max_time()) | |||
, ticket(0) | ||||
, connecting(false) | ||||
, priority(0) | ||||
{} | ||||
// called when the connection is initiated | // called when the connection is initiated | |||
// this is when the timeout countdown starts | // this is when the timeout countdown starts | |||
// TODO: if we don't actually need the connection queue | ||||
// to hold ownership of objects, replace these boost functio | ||||
ns | ||||
// with pointer to a pure virtual interface class | ||||
boost::function<void(int)> on_connect; | boost::function<void(int)> on_connect; | |||
// called if done hasn't been called within the timeout | // called if done hasn't been called within the timeout | |||
// or if the connection queue aborts. This means there | // or if the connection queue aborts. This means there | |||
// are 3 different interleaves of these function calls: | // are 3 different interleaves of these function calls: | |||
// 1. on_connect | // 1. on_connect | |||
// 2. on_connect, on_timeout | // 2. on_connect, on_timeout | |||
// 3. on_timeout | // 3. on_timeout | |||
boost::function<void()> on_timeout; | boost::function<void()> on_timeout; | |||
bool connecting; | ||||
int ticket; | ||||
ptime expires; | ptime expires; | |||
time_duration timeout; | time_duration timeout; | |||
int priority; | boost::int32_t ticket; | |||
bool connecting; | ||||
boost::uint8_t priority; | ||||
}; | }; | |||
// TODO: split this into a queue and connecting map. The key for the | ||||
map | ||||
// is the ticket. Most field in entry would only be necessary for th | ||||
e | ||||
// connecting map. | ||||
std::list<entry> m_queue; | std::list<entry> m_queue; | |||
// the next ticket id a connection will be given | // the next ticket id a connection will be given | |||
int m_next_ticket; | int m_next_ticket; | |||
int m_num_connecting; | int m_num_connecting; | |||
int m_half_open_limit; | int m_half_open_limit; | |||
bool m_abort; | bool m_abort; | |||
// the number of outstanding timers | // the number of outstanding timers | |||
int m_num_timers; | int m_num_timers; | |||
End of changes. 8 change blocks. | ||||
17 lines changed or deleted | 12 lines changed or added | |||
copy_ptr.hpp | copy_ptr.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2010, Arvid Norberg | Copyright (c) 2010-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
create_torrent.hpp | create_torrent.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2008, Arvid Norberg | Copyright (c) 2008-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 61 | skipping to change at line 61 | |||
#pragma warning(push, 1) | #pragma warning(push, 1) | |||
#endif | #endif | |||
#include <boost/scoped_ptr.hpp> | #include <boost/scoped_ptr.hpp> | |||
#include <boost/config.hpp> | #include <boost/config.hpp> | |||
#ifdef _MSC_VER | #ifdef _MSC_VER | |||
#pragma warning(pop) | #pragma warning(pop) | |||
#endif | #endif | |||
// OVERVIEW | ||||
// | ||||
// This section describes the functions and classes that are used | ||||
// to create torrent files. It is a layered API with low level classes | ||||
// and higher level convenience functions. A torrent is created in 4 | ||||
// steps: | ||||
// | ||||
// 1. first the files that will be part of the torrent are determined. | ||||
// 2. the torrent properties are set, such as tracker url, web seeds, | ||||
// DHT nodes etc. | ||||
// 3. Read through all the files in the torrent, SHA-1 all the data | ||||
// and set the piece hashes. | ||||
// 4. The torrent is bencoded into a file or buffer. | ||||
// | ||||
// If there are a lot of files and or deep directoy hierarchies to | ||||
// traverse, step one can be time consuming. | ||||
// | ||||
// Typically step 3 is by far the most time consuming step, since it | ||||
// requires to read all the bytes from all the files in the torrent. | ||||
// | ||||
// All of these classes and functions are declared by including | ||||
// ``libtorrent/create_torrent.hpp``. | ||||
// | ||||
// example:: | ||||
// | ||||
// file_storage fs; | ||||
// | ||||
// // recursively adds files in directories | ||||
// add_files(fs, "./my_torrent"); | ||||
// | ||||
// create_torrent t(fs); | ||||
// t.add_tracker("http://my.tracker.com/announce"); | ||||
// t.set_creator("libtorrent example"); | ||||
// | ||||
// // reads the files and calculates the hashes | ||||
// set_piece_hashes(t, "."); | ||||
// | ||||
// ofstream out("my_torrent.torrent", std::ios_base::binary); | ||||
// bencode(std::ostream_iterator<char>(out), t.generate()); | ||||
// | ||||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
class torrent_info; | class torrent_info; | |||
// This class holds state for creating a torrent. After having added | ||||
// all information to it, call create_torrent::generate() to generat | ||||
e | ||||
// the torrent. The entry that's returned can then be bencoded into | ||||
a | ||||
// .torrent file using bencode(). | ||||
struct TORRENT_EXPORT create_torrent | struct TORRENT_EXPORT create_torrent | |||
{ | { | |||
// flags for create_torrent::create_torrent(). | ||||
enum flags_t | enum flags_t | |||
{ | { | |||
// This will insert pad files to align the files to | ||||
piece boundaries, for | ||||
// optimized disk-I/O. | ||||
optimize = 1 | optimize = 1 | |||
// This will create a merkle hash tree torrent. A me | ||||
rkle torrent cannot | ||||
// be opened in clients that don't specifically supp | ||||
ort merkle torrents. | ||||
// The benefit is that the resulting torrent file wi | ||||
ll be much smaller and | ||||
// not grow with more pieces. When this option is sp | ||||
ecified, it is | ||||
// recommended to have a fairly small piece size, sa | ||||
y 64 kiB. | ||||
// When creating merkle torrents, the full hash tree | ||||
is also generated | ||||
// and should be saved off separately. It is accesse | ||||
d through the | ||||
// create_torrent::merkle_tree() function. | ||||
, merkle = 2 | , merkle = 2 | |||
// This will include the file modification time as p | ||||
art of the torrent. | ||||
// This is not enabled by default, as it might cause | ||||
problems when you | ||||
// create a torrent from separate files with the sam | ||||
e content, hoping to | ||||
// yield the same info-hash. If the files have diffe | ||||
rent modification times, | ||||
// with this option enabled, you would get different | ||||
info-hashes for the | ||||
// files. | ||||
, modification_time = 4 | , modification_time = 4 | |||
// If this flag is set, files that are symlinks get | ||||
a symlink attribute | ||||
// set on them and their data will not be included i | ||||
n the torrent. This | ||||
// is useful if you need to reconstruct a file hiera | ||||
rchy which contains | ||||
// symlinks. | ||||
, symlinks = 8 | , symlinks = 8 | |||
// If this is set, the set_piece_hashes() function w | ||||
ill, as it calculates | ||||
// the piece hashes, also calculate the file hashes | ||||
and add those associated | ||||
// with each file. Note that unless you use the set_ | ||||
piece_hashes() function, | ||||
// this flag will have no effect. | ||||
, calculate_file_hashes = 16 | , calculate_file_hashes = 16 | |||
}; | }; | |||
// The ``piece_size`` is the size of each piece in bytes. It | ||||
must | ||||
// be a multiple of 16 kiB. If a piece size of 0 is specifie | ||||
d, a | ||||
// piece_size will be calculated such that the torrent file | ||||
is roughly 40 kB. | ||||
// | ||||
// If a ``pad_size_limit`` is specified (other than -1), any | ||||
file larger than | ||||
// the specified number of bytes will be preceeded by a pad | ||||
file to align it | ||||
// with the start of a piece. The pad_file_limit is ignored | ||||
unless the | ||||
// ``optimize`` flag is passed. Typically it doesn't make se | ||||
nse to set this | ||||
// any lower than 4kiB. | ||||
// | ||||
// The overload that takes a ``torrent_info`` object will ma | ||||
ke a verbatim | ||||
// copy of its info dictionary (to preserve the info-hash). | ||||
The copy of | ||||
// the info dictionary will be used by create_torrent::gener | ||||
ate(). This means | ||||
// that none of the member functions of create_torrent that | ||||
affects | ||||
// the content of the info dictionary (such as ``set_hash()` | ||||
`), will | ||||
// have any affect. | ||||
// | ||||
// The ``flags`` arguments specifies options for the torrent | ||||
creation. It can | ||||
// be any combination of the flags defined by create_torrent | ||||
::flags_t. | ||||
// | ||||
// ``alignment`` is used when pad files are enabled. This is | ||||
the size | ||||
// eligible files are aligned to. The default is -1, which m | ||||
eans the | ||||
// piece size of the torrent. | ||||
create_torrent(file_storage& fs, int piece_size = 0 | create_torrent(file_storage& fs, int piece_size = 0 | |||
, int pad_file_limit = -1, int flags = optimize); | , int pad_file_limit = -1, int flags = optimize, int alignment = -1); | |||
create_torrent(torrent_info const& ti); | create_torrent(torrent_info const& ti); | |||
// internal | ||||
~create_torrent(); | ~create_torrent(); | |||
// This function will generate the .torrent file as a bencod | ||||
e tree. In order to | ||||
// generate the flat file, use the bencode() function. | ||||
// | ||||
// It may be useful to add custom entries to the torrent fil | ||||
e before bencoding it | ||||
// and saving it to disk. | ||||
// | ||||
// If anything goes wrong during torrent generation, this fu | ||||
nction will return | ||||
// an empty ``entry`` structure. You can test for this condi | ||||
tion by querying the | ||||
// type of the entry:: | ||||
// | ||||
// file_storage fs; | ||||
// // add file ... | ||||
// create_torrent t(fs); | ||||
// // add trackers and piece hashes ... | ||||
// e = t.generate(); | ||||
// | ||||
// if (e.type() == entry::undefined_t) | ||||
// { | ||||
// // something went wrong | ||||
// } | ||||
// | ||||
// For instance, you cannot generate a torrent with 0 files | ||||
in it. If you don't add | ||||
// any files to the ``file_storage``, torrent generation wil | ||||
l fail. | ||||
entry generate() const; | entry generate() const; | |||
// returns an immutable reference to the file_storage used t | ||||
o create | ||||
// the torrent from. | ||||
file_storage const& files() const { return m_files; } | file_storage const& files() const { return m_files; } | |||
// Sets the comment for the torrent. The string ``str`` shou | ||||
ld be utf-8 encoded. | ||||
// The comment in a torrent file is optional. | ||||
void set_comment(char const* str); | void set_comment(char const* str); | |||
// Sets the creator of the torrent. The string ``str`` shoul | ||||
d be utf-8 encoded. | ||||
// This is optional. | ||||
void set_creator(char const* str); | void set_creator(char const* str); | |||
// This sets the SHA-1 hash for the specified piece (``index | ||||
``). You are required | ||||
// to set the hash for every piece in the torrent before gen | ||||
erating it. If you have | ||||
// the files on disk, you can use the high level convenience | ||||
function to do this. | ||||
// See set_piece_hashes(). | ||||
void set_hash(int index, sha1_hash const& h); | void set_hash(int index, sha1_hash const& h); | |||
// This sets the sha1 hash for this file. This hash will end | ||||
up under the key ``sha1`` | ||||
// associated with this file (for multi-file torrents) or in | ||||
the root info dictionary | ||||
// for single-file torrents. | ||||
void set_file_hash(int index, sha1_hash const& h); | void set_file_hash(int index, sha1_hash const& h); | |||
// This adds a url seed to the torrent. You can have any num | ||||
ber of url seeds. For a | ||||
// single file torrent, this should be an HTTP url, pointing | ||||
to a file with identical | ||||
// content as the file of the torrent. For a multi-file torr | ||||
ent, it should point to | ||||
// a directory containing a directory with the same name as | ||||
this torrent, and all the | ||||
// files of the torrent in it. | ||||
// | ||||
// The second function, ``add_http_seed()`` adds an HTTP see | ||||
d instead. | ||||
void add_url_seed(std::string const& url); | void add_url_seed(std::string const& url); | |||
void add_http_seed(std::string const& url); | void add_http_seed(std::string const& url); | |||
// This adds a DHT node to the torrent. This especially usef | ||||
ul if you're creating a | ||||
// tracker less torrent. It can be used by clients to bootst | ||||
rap their DHT node from. | ||||
// The node is a hostname and a port number where there is a | ||||
DHT node running. | ||||
// You can have any number of DHT nodes in a torrent. | ||||
void add_node(std::pair<std::string, int> const& node); | void add_node(std::pair<std::string, int> const& node); | |||
// Adds a tracker to the torrent. This is not strictly requi | ||||
red, but most torrents | ||||
// use a tracker as their main source of peers. The url shou | ||||
ld be an http:// or udp:// | ||||
// url to a machine running a bittorrent tracker that accept | ||||
s announces for this torrent's | ||||
// info-hash. The tier is the fallback priority of the track | ||||
er. All trackers with tier 0 are | ||||
// tried first (in any order). If all fail, trackers with ti | ||||
er 1 are tried. If all of those | ||||
// fail, trackers with tier 2 are tried, and so on. | ||||
void add_tracker(std::string const& url, int tier = 0); | void add_tracker(std::string const& url, int tier = 0); | |||
// This function sets an X.509 certificate in PEM format to | ||||
the torrent. This makes the | ||||
// torrent an *SSL torrent*. An SSL torrent requires that ea | ||||
ch peer has a valid certificate | ||||
// signed by this root certificate. For SSL torrents, all pe | ||||
ers are connecting over SSL | ||||
// connections. For more information, see the section on ssl | ||||
-torrents_. | ||||
// | ||||
// The string is not the path to the cert, it's the actual c | ||||
ontent of the certificate, | ||||
// loaded into a std::string. | ||||
void set_root_cert(std::string const& pem); | void set_root_cert(std::string const& pem); | |||
// Sets and queries the private flag of the torrent. | ||||
// Torrents with the private flag set ask clients to not use | ||||
any other | ||||
// sources than the tracker for peers, and to not advertize | ||||
itself publicly, | ||||
// apart from the tracker. | ||||
void set_priv(bool p) { m_private = p; } | void set_priv(bool p) { m_private = p; } | |||
bool priv() const { return m_private; } | ||||
// returns the number of pieces in the associated file_stora ge object. | ||||
int num_pieces() const { return m_files.num_pieces(); } | int num_pieces() const { return m_files.num_pieces(); } | |||
// ``piece_length()`` returns the piece size of all pieces b | ||||
ut the | ||||
// last one. ``piece_size()`` returns the size of the specif | ||||
ied piece. | ||||
// these functions are just forwarding to the associated fil | ||||
e_storage. | ||||
int piece_length() const { return m_files.piece_length(); } | int piece_length() const { return m_files.piece_length(); } | |||
int piece_size(int i) const { return m_files.piece_size(i); } | int piece_size(int i) const { return m_files.piece_size(i); } | |||
bool priv() const { return m_private; } | ||||
// internal | ||||
bool should_add_file_hashes() const { return m_calculate_fil e_hashes; } | bool should_add_file_hashes() const { return m_calculate_fil e_hashes; } | |||
// This function returns the merkle hash tree, if the torren | ||||
t was created as a merkle | ||||
// torrent. The tree is created by ``generate()`` and won't | ||||
be valid until that function | ||||
// has been called. When creating a merkle tree torrent, the | ||||
actual tree itself has to | ||||
// be saved off separately and fed into libtorrent the first | ||||
time you start seeding it, | ||||
// through the ``torrent_info::set_merkle_tree()`` function. | ||||
From that point onwards, the | ||||
// tree will be saved in the resume data. | ||||
std::vector<sha1_hash> const& merkle_tree() const { return m _merkle_tree; } | std::vector<sha1_hash> const& merkle_tree() const { return m _merkle_tree; } | |||
private: | private: | |||
file_storage& m_files; | file_storage& m_files; | |||
// if m_info_dict is initialized, it is | // if m_info_dict is initialized, it is | |||
// used instead of m_files to generate | // used instead of m_files to generate | |||
// the info dictionary | // the info dictionary | |||
entry m_info_dict; | entry m_info_dict; | |||
skipping to change at line 188 | skipping to change at line 372 | |||
bool m_calculate_file_hashes:1; | bool m_calculate_file_hashes:1; | |||
}; | }; | |||
namespace detail | namespace detail | |||
{ | { | |||
inline bool default_pred(std::string const&) { return true; } | inline bool default_pred(std::string const&) { return true; } | |||
inline bool ignore_subdir(std::string const& leaf) | inline bool ignore_subdir(std::string const& leaf) | |||
{ return leaf == ".." || leaf == "."; } | { return leaf == ".." || leaf == "."; } | |||
inline void nop(int i) {} | inline void nop(int) {} | |||
int get_file_attributes(std::string const& p); | int get_file_attributes(std::string const& p); | |||
std::string get_symlink_path(std::string const& p); | std::string get_symlink_path(std::string const& p); | |||
// internal | ||||
TORRENT_EXPORT void add_files_impl(file_storage& fs, std::st ring const& p | TORRENT_EXPORT void add_files_impl(file_storage& fs, std::st ring const& p | |||
, std::string const& l, boost::function<bool(std::st ring)> pred | , std::string const& l, boost::function<bool(std::st ring)> pred | |||
, boost::uint32_t flags); | , boost::uint32_t flags); | |||
} | } | |||
template <class Pred> | // Adds the file specified by ``path`` to the file_storage object. I | |||
void add_files(file_storage& fs, std::string const& file, Pred p, bo | n case ``path`` | |||
ost::uint32_t flags = 0) | // refers to a diretory, files will be added recursively from the di | |||
rectory. | ||||
// | ||||
// If specified, the predicate ``p`` is called once for every file a | ||||
nd directory that | ||||
// is encountered. files for which ``p`` returns true are added, and | ||||
directories for | ||||
// which ``p`` returns true are traversed. ``p`` must have the follo | ||||
wing signature:: | ||||
// | ||||
// bool Pred(std::string const& p); | ||||
// | ||||
// The path that is passed in to the predicate is the full path of t | ||||
he file or | ||||
// directory. If no predicate is specified, all files are added, and | ||||
all directories | ||||
// are traveresed. | ||||
// | ||||
// The ".." directory is never traversed. | ||||
// | ||||
// The ``flags`` argument should be the same as the flags passed to | ||||
the `create_torrent`_ | ||||
// constructor. | ||||
template <class Pred> void add_files(file_storage& fs, std::string c | ||||
onst& file, Pred p, boost::uint32_t flags = 0) | ||||
{ | { | |||
detail::add_files_impl(fs, parent_path(complete(file)), file name(file), p, flags); | detail::add_files_impl(fs, parent_path(complete(file)), file name(file), p, flags); | |||
} | } | |||
inline void add_files(file_storage& fs, std::string const& file, boo st::uint32_t flags = 0) | inline void add_files(file_storage& fs, std::string const& file, boo st::uint32_t flags = 0) | |||
{ | { | |||
detail::add_files_impl(fs, parent_path(complete(file)), file name(file) | detail::add_files_impl(fs, parent_path(complete(file)), file name(file) | |||
, detail::default_pred, flags); | , detail::default_pred, flags); | |||
} | } | |||
// This function will assume that the files added to the torrent fil | ||||
e exists at path | ||||
// ``p``, read those files and hash the content and set the hashes i | ||||
n the ``create_torrent`` | ||||
// object. The optional function ``f`` is called in between every ha | ||||
sh that is set. ``f`` | ||||
// must have the following signature:: | ||||
// | ||||
// void Fun(int); | ||||
// | ||||
// The overloads that don't take an ``error_code&`` may throw an exc | ||||
eption in case of a | ||||
// file error, the other overloads sets the error code to reflect th | ||||
e error, if any. | ||||
TORRENT_EXPORT void set_piece_hashes(create_torrent& t, std::string const& p | TORRENT_EXPORT void set_piece_hashes(create_torrent& t, std::string const& p | |||
, boost::function<void(int)> f, error_code& ec); | , boost::function<void(int)> f, error_code& ec); | |||
inline void set_piece_hashes(create_torrent& t, std::string const& p | ||||
#ifndef BOOST_NO_EXCEPTIONS | , error_code& ec) | |||
template <class Fun> | ||||
void set_piece_hashes(create_torrent& t, std::string const& p, Fun f | ||||
) | ||||
{ | { | |||
error_code ec; | set_piece_hashes(t, p, detail::nop, ec); | |||
set_piece_hashes(t, p, f, ec); | ||||
if (ec) throw libtorrent_exception(ec); | ||||
} | } | |||
#ifndef BOOST_NO_EXCEPTIONS | ||||
inline void set_piece_hashes(create_torrent& t, std::string const& p ) | inline void set_piece_hashes(create_torrent& t, std::string const& p ) | |||
{ | { | |||
error_code ec; | error_code ec; | |||
set_piece_hashes(t, p, detail::nop, ec); | set_piece_hashes(t, p, detail::nop, ec); | |||
if (ec) throw libtorrent_exception(ec); | if (ec) throw libtorrent_exception(ec); | |||
} | } | |||
#endif | template <class Fun> | |||
void set_piece_hashes(create_torrent& t, std::string const& p, Fun f | ||||
inline void set_piece_hashes(create_torrent& t, std::string const& p | ) | |||
, error_code& ec) | ||||
{ | { | |||
set_piece_hashes(t, p, detail::nop, ec); | error_code ec; | |||
set_piece_hashes(t, p, f, ec); | ||||
if (ec) throw libtorrent_exception(ec); | ||||
} | } | |||
#endif | ||||
#if TORRENT_USE_WSTRING | #if TORRENT_USE_WSTRING | |||
// wstring versions | // wstring versions | |||
// all wstring APIs are deprecated since 0.16.11 | // all wstring APIs are deprecated since 0.16.11 | |||
// instead, use the wchar -> utf8 conversion functions | // instead, use the wchar -> utf8 conversion functions | |||
// and pass in utf8 strings | // and pass in utf8 strings | |||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
template <class Pred> | template <class Pred> | |||
End of changes. 40 change blocks. | ||||
22 lines changed or deleted | 320 lines changed or added | |||
deadline_timer.hpp | deadline_timer.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2009, Arvid Norberg | Copyright (c) 2009-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
debug.hpp | debug.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2003, Arvid Norberg | Copyright (c) 2003-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 42 | skipping to change at line 42 | |||
#ifndef TORRENT_DEBUG_HPP_INCLUDED | #ifndef TORRENT_DEBUG_HPP_INCLUDED | |||
#define TORRENT_DEBUG_HPP_INCLUDED | #define TORRENT_DEBUG_HPP_INCLUDED | |||
#if defined TORRENT_ASIO_DEBUGGING | #if defined TORRENT_ASIO_DEBUGGING | |||
#include "libtorrent/assert.hpp" | #include "libtorrent/assert.hpp" | |||
#include "libtorrent/thread.hpp" | #include "libtorrent/thread.hpp" | |||
#include <map> | #include <map> | |||
#include <cstring> | ||||
std::string demangle(char const* name); | std::string demangle(char const* name); | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
struct async_t | struct async_t | |||
{ | { | |||
async_t() : refs(0) {} | async_t() : refs(0) {} | |||
std::string stack; | std::string stack; | |||
int refs; | int refs; | |||
skipping to change at line 148 | skipping to change at line 149 | |||
mutex::scoped_lock l(file_mutex); | mutex::scoped_lock l(file_mutex); | |||
log_file.close(); | log_file.close(); | |||
open_filename.clear(); | open_filename.clear(); | |||
} | } | |||
logger(std::string const& logpath, std::string const& filena me | logger(std::string const& logpath, std::string const& filena me | |||
, int instance, bool append) | , int instance, bool append) | |||
{ | { | |||
char log_name[512]; | char log_name[512]; | |||
snprintf(log_name, sizeof(log_name), "libtorrent_log s%d", instance); | snprintf(log_name, sizeof(log_name), "libtorrent_log s%d", instance); | |||
std::string dir(complete(combine_path(logpath, log_n ame))); | std::string dir(complete(combine_path(combine_path(l ogpath, log_name), filename)) + ".log"); | |||
error_code ec; | error_code ec; | |||
if (!exists(dir)) create_directories(dir, ec); | if (!exists(parent_path(dir))) | |||
m_filename = combine_path(dir, filename); | create_directories(parent_path(dir), ec); | |||
m_filename = dir; | ||||
mutex::scoped_lock l(file_mutex); | mutex::scoped_lock l(file_mutex); | |||
open(!append); | open(!append); | |||
log_file << "\n\n\n*** starting log ***\n"; | log_file << "\n\n\n*** starting log ***\n"; | |||
} | } | |||
void move_log_file(std::string const& logpath, std::string c | ||||
onst& new_name, int instance) | ||||
{ | ||||
mutex::scoped_lock l(file_mutex); | ||||
if (open_filename == m_filename) | ||||
{ | ||||
log_file.close(); | ||||
open_filename.clear(); | ||||
} | ||||
char log_name[512]; | ||||
snprintf(log_name, sizeof(log_name), "libtorrent_log | ||||
s%d", instance); | ||||
std::string dir(combine_path(combine_path(complete(l | ||||
ogpath), log_name), new_name) + ".log"); | ||||
error_code ec; | ||||
create_directories(parent_path(dir), ec); | ||||
if (ec) | ||||
fprintf(stderr, "Failed to create logfile di | ||||
rectory %s: %s\n" | ||||
, parent_path(dir).c_str(), ec.messa | ||||
ge().c_str()); | ||||
ec.clear(); | ||||
rename(m_filename, dir, ec); | ||||
if (ec) | ||||
fprintf(stderr, "Failed to move logfile %s: | ||||
%s\n" | ||||
, parent_path(dir).c_str(), ec.messa | ||||
ge().c_str()); | ||||
m_filename = dir; | ||||
} | ||||
#if TORRENT_USE_IOSTREAM | #if TORRENT_USE_IOSTREAM | |||
void open(bool truncate) | void open(bool truncate) | |||
{ | { | |||
if (open_filename == m_filename) return; | if (open_filename == m_filename) return; | |||
log_file.close(); | log_file.close(); | |||
log_file.clear(); | log_file.clear(); | |||
log_file.open(m_filename.c_str(), truncate ? std::io s_base::trunc : std::ios_base::app); | log_file.open(m_filename.c_str(), truncate ? std::io s_base::trunc : std::ios_base::app); | |||
open_filename = m_filename; | open_filename = m_filename; | |||
if (!log_file.good()) | if (!log_file.good()) | |||
fprintf(stderr, "Failed to open logfile %s: %s\n", m_filename.c_str(), strerror(errno)); | fprintf(stderr, "Failed to open logfile %s: %s\n", m_filename.c_str(), strerror(errno)); | |||
End of changes. 5 change blocks. | ||||
4 lines changed or deleted | 41 lines changed or added | |||
dht_tracker.hpp | dht_tracker.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2006, Arvid Norberg | Copyright (c) 2006-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 74 | skipping to change at line 74 | |||
#ifdef TORRENT_DHT_VERBOSE_LOGGING | #ifdef TORRENT_DHT_VERBOSE_LOGGING | |||
TORRENT_DECLARE_LOG(dht_tracker); | TORRENT_DECLARE_LOG(dht_tracker); | |||
#endif | #endif | |||
struct dht_tracker; | struct dht_tracker; | |||
TORRENT_EXTRA_EXPORT void intrusive_ptr_add_ref(dht_tracker const*); | TORRENT_EXTRA_EXPORT void intrusive_ptr_add_ref(dht_tracker const*); | |||
TORRENT_EXTRA_EXPORT void intrusive_ptr_release(dht_tracker const*); | TORRENT_EXTRA_EXPORT void intrusive_ptr_release(dht_tracker const*); | |||
struct dht_tracker | struct dht_tracker : udp_socket_interface, udp_socket_observer | |||
{ | { | |||
friend void intrusive_ptr_add_ref(dht_tracker const*); | friend void intrusive_ptr_add_ref(dht_tracker const*); | |||
friend void intrusive_ptr_release(dht_tracker const*); | friend void intrusive_ptr_release(dht_tracker const*); | |||
friend bool send_callback(void* userdata, entry& e, udp::end point const& addr, int flags); | ||||
dht_tracker(libtorrent::aux::session_impl& ses, rate_limited _udp_socket& sock | dht_tracker(libtorrent::aux::session_impl& ses, rate_limited _udp_socket& sock | |||
, dht_settings const& settings, entry const* state = 0); | , dht_settings const& settings, entry const* state = 0); | |||
virtual ~dht_tracker(); | ||||
void start(entry const& bootstrap | void start(entry const& bootstrap | |||
, find_data::nodes_callback const& f); | , find_data::nodes_callback const& f); | |||
void stop(); | void stop(); | |||
void add_node(udp::endpoint node); | void add_node(udp::endpoint node); | |||
void add_node(std::pair<std::string, int> const& node); | void add_node(std::pair<std::string, int> const& node); | |||
void add_router_node(udp::endpoint const& node); | void add_router_node(udp::endpoint const& node); | |||
entry state() const; | entry state() const; | |||
void announce(sha1_hash const& ih, int listen_port, bool see | enum flags_t { flag_seed = 1, flag_implied_port = 2 }; | |||
d | void announce(sha1_hash const& ih, int listen_port, int flag | |||
s | ||||
, boost::function<void(std::vector<tcp::endpoint> co nst&)> f); | , boost::function<void(std::vector<tcp::endpoint> co nst&)> f); | |||
void get_item(sha1_hash const& target | ||||
, boost::function<void(item const&)> cb); | ||||
// key is a 32-byte binary string, the public key to look up | ||||
. | ||||
// the salt is optional | ||||
void get_item(char const* key | ||||
, boost::function<void(item const&)> cb | ||||
, std::string salt = std::string()); | ||||
void put_item(entry data | ||||
, boost::function<void()> cb); | ||||
void put_item(char const* key | ||||
, boost::function<void(item&)> cb, std::string salt | ||||
= std::string()); | ||||
void dht_status(session_status& s); | void dht_status(session_status& s); | |||
void network_stats(int& sent, int& received); | void network_stats(int& sent, int& received); | |||
// translate bittorrent kademlia message into the generic ka demlia message | // translate bittorrent kademlia message into the generic ka demlia message | |||
// used by the library | // used by the library | |||
void on_receive(udp::endpoint const& ep, char const* pkt, in | virtual bool incoming_packet(error_code const& ec | |||
t size); | , udp::endpoint const&, char const* buf, int size); | |||
void on_unreachable(udp::endpoint const& ep); | ||||
private: | private: | |||
boost::intrusive_ptr<dht_tracker> self() | boost::intrusive_ptr<dht_tracker> self() | |||
{ return boost::intrusive_ptr<dht_tracker>(this); } | { return boost::intrusive_ptr<dht_tracker>(this); } | |||
void on_name_lookup(error_code const& e | void on_name_lookup(error_code const& e | |||
, udp::resolver::iterator host); | , udp::resolver::iterator host); | |||
void on_router_name_lookup(error_code const& e | void on_router_name_lookup(error_code const& e | |||
, udp::resolver::iterator host); | , udp::resolver::iterator host); | |||
void connection_timeout(error_code const& e); | void connection_timeout(error_code const& e); | |||
void refresh_timeout(error_code const& e); | void refresh_timeout(error_code const& e); | |||
void tick(error_code const& e); | void tick(error_code const& e); | |||
bool send_packet(libtorrent::entry& e, udp::endpoint const& | // implements udp_socket_interface | |||
addr, int send_flags); | virtual bool send_packet(libtorrent::entry& e, udp::endpoint | |||
const& addr | ||||
, int send_flags); | ||||
node_impl m_dht; | node_impl m_dht; | |||
libtorrent::aux::session_impl& m_ses; | ||||
rate_limited_udp_socket& m_sock; | rate_limited_udp_socket& m_sock; | |||
std::vector<char> m_send_buf; | std::vector<char> m_send_buf; | |||
ptime m_last_new_key; | ptime m_last_new_key; | |||
deadline_timer m_timer; | deadline_timer m_timer; | |||
deadline_timer m_connection_timer; | deadline_timer m_connection_timer; | |||
deadline_timer m_refresh_timer; | deadline_timer m_refresh_timer; | |||
dht_settings const& m_settings; | dht_settings const& m_settings; | |||
int m_refresh_bucket; | int m_refresh_bucket; | |||
End of changes. 9 change blocks. | ||||
11 lines changed or deleted | 30 lines changed or added | |||
disk_buffer_holder.hpp | disk_buffer_holder.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2008, Arvid Norberg | Copyright (c) 2008-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 46 | skipping to change at line 46 | |||
#include "libtorrent/config.hpp" | #include "libtorrent/config.hpp" | |||
#include "libtorrent/assert.hpp" | #include "libtorrent/assert.hpp" | |||
#include <algorithm> | #include <algorithm> | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
namespace aux { struct session_impl; } | namespace aux { struct session_impl; } | |||
struct disk_buffer_pool; | struct disk_buffer_pool; | |||
struct TORRENT_EXTRA_EXPORT disk_buffer_holder | // The disk buffer holder acts like a ``scoped_ptr`` that frees a di | |||
sk buffer | ||||
// when it's destructed, unless it's released. ``release`` returns t | ||||
he disk | ||||
// buffer and transferres ownership and responsibility to free it to | ||||
the caller. | ||||
// | ||||
// A disk buffer is freed by passing it to ``session_impl::free_disk | ||||
_buffer()``. | ||||
// | ||||
// ``buffer()`` returns the pointer without transferring responsibil | ||||
ity. If | ||||
// this buffer has been released, ``buffer()`` will return 0. | ||||
struct TORRENT_EXPORT disk_buffer_holder | ||||
{ | { | |||
// internal | ||||
disk_buffer_holder(aux::session_impl& ses, char* buf); | disk_buffer_holder(aux::session_impl& ses, char* buf); | |||
// construct a buffer holder that will free the held buffer | ||||
// using a disk buffer pool directly (there's only one | ||||
// disk_buffer_pool per session) | ||||
disk_buffer_holder(disk_buffer_pool& disk_pool, char* buf); | disk_buffer_holder(disk_buffer_pool& disk_pool, char* buf); | |||
// frees any unreleased disk buffer held by this object | ||||
~disk_buffer_holder(); | ~disk_buffer_holder(); | |||
// return the held disk buffer and clear it from the | ||||
// holder. The responsibility to free it is passed on | ||||
// to the caller | ||||
char* release(); | char* release(); | |||
// return a pointer to the held buffer | ||||
char* get() const { return m_buf; } | char* get() const { return m_buf; } | |||
// set the holder object to hold the specified buffer | ||||
// (or NULL by default). If it's already holding a | ||||
// disk buffer, it will first be freed. | ||||
void reset(char* buf = 0); | void reset(char* buf = 0); | |||
// swap pointers of two disk buffer holders. | ||||
void swap(disk_buffer_holder& h) | void swap(disk_buffer_holder& h) | |||
{ | { | |||
TORRENT_ASSERT(&h.m_disk_pool == &m_disk_pool); | TORRENT_ASSERT(&h.m_disk_pool == &m_disk_pool); | |||
std::swap(h.m_buf, m_buf); | std::swap(h.m_buf, m_buf); | |||
} | } | |||
typedef char* (disk_buffer_holder::*unspecified_bool_type)() ; | typedef char* (disk_buffer_holder::*unspecified_bool_type)() ; | |||
// internal | ||||
operator unspecified_bool_type() const | operator unspecified_bool_type() const | |||
{ return m_buf == 0? 0: &disk_buffer_holder::release; } | { return m_buf == 0? 0: &disk_buffer_holder::release; } | |||
private: | private: | |||
disk_buffer_pool& m_disk_pool; | disk_buffer_pool& m_disk_pool; | |||
char* m_buf; | char* m_buf; | |||
}; | }; | |||
} | } | |||
End of changes. 10 change blocks. | ||||
2 lines changed or deleted | 36 lines changed or added | |||
disk_buffer_pool.hpp | disk_buffer_pool.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2007-2011, Arvid Norberg | Copyright (c) 2007-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 43 | skipping to change at line 43 | |||
#ifndef TORRENT_DISK_BUFFER_POOL | #ifndef TORRENT_DISK_BUFFER_POOL | |||
#define TORRENT_DISK_BUFFER_POOL | #define TORRENT_DISK_BUFFER_POOL | |||
#include <boost/utility.hpp> | #include <boost/utility.hpp> | |||
#include "libtorrent/config.hpp" | #include "libtorrent/config.hpp" | |||
#include "libtorrent/thread.hpp" | #include "libtorrent/thread.hpp" | |||
#include "libtorrent/session_settings.hpp" | #include "libtorrent/session_settings.hpp" | |||
#include "libtorrent/allocator.hpp" | #include "libtorrent/allocator.hpp" | |||
#ifndef TORRENT_DISABLE_POOL_ALLOCATOR | ||||
#include <boost/pool/pool.hpp> | ||||
#endif | ||||
#ifdef TORRENT_DISK_STATS | #ifdef TORRENT_DISK_STATS | |||
#include <fstream> | #include <fstream> | |||
#endif | #endif | |||
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS || TORRENT_DISK_STATS | #if TORRENT_USE_ASSERTS || TORRENT_DISK_STATS | |||
#include <map> | #include <boost/unordered_map.hpp> | |||
#endif | #endif | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
struct TORRENT_EXTRA_EXPORT disk_buffer_pool : boost::noncopyable | struct TORRENT_EXTRA_EXPORT disk_buffer_pool : boost::noncopyable | |||
{ | { | |||
disk_buffer_pool(int block_size); | disk_buffer_pool(int block_size); | |||
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS | #if TORRENT_USE_ASSERTS | |||
~disk_buffer_pool(); | ~disk_buffer_pool(); | |||
#endif | #endif | |||
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS || defined TORRENT_DIS K_STATS | #if TORRENT_USE_ASSERTS || TORRENT_DISK_STATS | |||
bool is_disk_buffer(char* buffer | bool is_disk_buffer(char* buffer | |||
, mutex::scoped_lock& l) const; | , mutex::scoped_lock& l) const; | |||
bool is_disk_buffer(char* buffer) const; | bool is_disk_buffer(char* buffer) const; | |||
#endif | #endif | |||
char* allocate_buffer(char const* category); | char* allocate_buffer(char const* category); | |||
void free_buffer(char* buf); | void free_buffer(char* buf); | |||
void free_multiple_buffers(char** bufvec, int numbufs); | void free_multiple_buffers(char** bufvec, int numbufs); | |||
int block_size() const { return m_block_size; } | int block_size() const { return m_block_size; } | |||
skipping to change at line 102 | skipping to change at line 106 | |||
// number of disk buffers currently allocated | // number of disk buffers currently allocated | |||
int m_in_use; | int m_in_use; | |||
session_settings m_settings; | session_settings m_settings; | |||
private: | private: | |||
mutable mutex m_pool_mutex; | mutable mutex m_pool_mutex; | |||
#ifndef TORRENT_DISABLE_POOL_ALLOCATOR | ||||
// if this is true, all buffers are allocated | ||||
// from m_pool. If this is false, all buffers | ||||
// are allocated using page_aligned_allocator. | ||||
// if the settings change to prefer the other | ||||
// allocator, this bool will not switch over | ||||
// to match the settings until all buffers have | ||||
// been freed. That way, we never have a mixture | ||||
// of buffers allocated from different sources. | ||||
// in essence, this make the setting only take | ||||
// effect after a restart (which seems fine). | ||||
// or once the client goes idle for a while. | ||||
bool m_using_pool_allocator; | ||||
// memory pool for read and write operations | ||||
// and disk cache | ||||
boost::pool<page_aligned_allocator> m_pool; | ||||
#endif | ||||
#if defined TORRENT_DISK_STATS || defined TORRENT_STATS | #if defined TORRENT_DISK_STATS || defined TORRENT_STATS | |||
int m_allocations; | int m_allocations; | |||
#endif | #endif | |||
#ifdef TORRENT_DISK_STATS | #ifdef TORRENT_DISK_STATS | |||
public: | public: | |||
void rename_buffer(char* buf, char const* category); | void rename_buffer(char* buf, char const* category); | |||
protected: | protected: | |||
std::map<std::string, int> m_categories; | boost::unordered_map<std::string, int> m_categories; | |||
std::map<char*, std::string> m_buf_to_category; | boost::unordered_map<char*, std::string> m_buf_to_category; | |||
std::ofstream m_log; | std::ofstream m_log; | |||
private: | private: | |||
#endif | #endif | |||
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS | #if TORRENT_USE_ASSERTS | |||
int m_magic; | int m_magic; | |||
#endif | #endif | |||
}; | }; | |||
} | } | |||
#endif // TORRENT_DISK_BUFFER_POOL | #endif // TORRENT_DISK_BUFFER_POOL | |||
End of changes. 8 change blocks. | ||||
8 lines changed or deleted | 31 lines changed or added | |||
disk_io_thread.hpp | disk_io_thread.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2007, Arvid Norberg | Copyright (c) 2007-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 66 | skipping to change at line 66 | |||
{ | { | |||
using boost::multi_index::multi_index_container; | using boost::multi_index::multi_index_container; | |||
using boost::multi_index::ordered_non_unique; | using boost::multi_index::ordered_non_unique; | |||
using boost::multi_index::ordered_unique; | using boost::multi_index::ordered_unique; | |||
using boost::multi_index::indexed_by; | using boost::multi_index::indexed_by; | |||
using boost::multi_index::member; | using boost::multi_index::member; | |||
using boost::multi_index::const_mem_fun; | using boost::multi_index::const_mem_fun; | |||
struct cached_piece_info | struct cached_piece_info | |||
{ | { | |||
// the piece index for this cache entry. | ||||
int piece; | int piece; | |||
// holds one entry for each block in this piece. ``true`` re | ||||
presents | ||||
// the data for that block being in the disk cache and ``fal | ||||
se`` means it's not. | ||||
std::vector<bool> blocks; | std::vector<bool> blocks; | |||
// the time when a block was last written to this piece. The | ||||
older | ||||
// a piece is, the more likely it is to be flushed to disk. | ||||
ptime last_use; | ptime last_use; | |||
// The index of the next block that needs to be hashed. | ||||
// Blocks are hashed as they are downloaded in order to not | ||||
// have to re-read them from disk once the piece is complete | ||||
, to | ||||
// compare its hash against the hashes in the .torrent file. | ||||
int next_to_hash; | int next_to_hash; | |||
enum kind_t { read_cache = 0, write_cache = 1 }; | enum kind_t { read_cache = 0, write_cache = 1 }; | |||
// specifies if this piece is part of the read cache or the | ||||
write cache. | ||||
kind_t kind; | kind_t kind; | |||
}; | }; | |||
struct disk_io_job | struct disk_io_job | |||
{ | { | |||
disk_io_job() | disk_io_job() | |||
: action(read) | : buffer(0) | |||
, buffer(0) | ||||
, buffer_size(0) | , buffer_size(0) | |||
, piece(0) | , piece(0) | |||
, offset(0) | , offset(0) | |||
, max_cache_line(0) | , max_cache_line(0) | |||
, cache_min_time(0) | , cache_min_time(0) | |||
, action(read) | ||||
{} | {} | |||
enum action_t | enum action_t | |||
{ | { | |||
read | read | |||
, write | , write | |||
, hash | , hash | |||
, move_storage | , move_storage | |||
, release_files | , release_files | |||
, delete_files | , delete_files | |||
, check_fastresume | , check_fastresume | |||
, check_files | , check_files | |||
, save_resume_data | , save_resume_data | |||
, rename_file | , rename_file | |||
, abort_thread | , abort_thread | |||
, clear_read_cache | , clear_read_cache | |||
, abort_torrent | , abort_torrent | |||
, update_settings | , update_settings | |||
, read_and_hash | , read_and_hash | |||
, cache_piece | , cache_piece | |||
, file_priority | ||||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
, finalize_file | , finalize_file | |||
#endif | #endif | |||
}; | }; | |||
action_t action; | ||||
char* buffer; | char* buffer; | |||
int buffer_size; | ||||
// this is called when operation completes | ||||
boost::function<void(int, disk_io_job const&)> callback; | ||||
boost::intrusive_ptr<piece_manager> storage; | boost::intrusive_ptr<piece_manager> storage; | |||
// arguments used for read and write | ||||
int piece, offset; | boost::shared_ptr<entry> resume_data; | |||
// the error code from the file operation | ||||
error_code error; | ||||
// the time when this job was issued. This is used to | ||||
// keep track of disk I/O congestion | ||||
ptime start_time; | ||||
// used for move_storage and rename_file. On errors, this is set | // used for move_storage and rename_file. On errors, this is set | |||
// to the error message | // to the error message | |||
std::string str; | std::string str; | |||
// on error, this is set to the path of the | // on error, this is set to the path of the | |||
// file the disk operation failed on | // file the disk operation failed on | |||
std::string error_file; | std::string error_file; | |||
int buffer_size; | ||||
// arguments used for read and write | ||||
// piece is used as flags for move_storage | ||||
int piece, offset; | ||||
// if this is > 0, it specifies the max number of blocks to read | // if this is > 0, it specifies the max number of blocks to read | |||
// ahead in the read cache for this access. This is only val id | // ahead in the read cache for this access. This is only val id | |||
// for 'read' actions | // for 'read' actions | |||
int max_cache_line; | int max_cache_line; | |||
// if this is > 0, it may increase the minimum time the cach e | // if this is > 0, it may increase the minimum time the cach e | |||
// line caused by this operation stays in the cache | // line caused by this operation stays in the cache | |||
int cache_min_time; | int cache_min_time; | |||
boost::shared_ptr<entry> resume_data; | boost::uint8_t action; | |||
// the error code from the file operation | ||||
error_code error; | ||||
// this is called when operation completes | ||||
boost::function<void(int, disk_io_job const&)> callback; | ||||
// the time when this job was issued. This is used to | ||||
// keep track of disk I/O congestion | ||||
ptime start_time; | ||||
}; | }; | |||
// returns true if the fundamental operation | // returns true if the fundamental operation | |||
// of the given disk job is a read operation | // of the given disk job is a read operation | |||
bool is_read_operation(disk_io_job const& j); | bool is_read_operation(disk_io_job const& j); | |||
// this is true if the buffer field in the disk_io_job | // this is true if the buffer field in the disk_io_job | |||
// points to a disk buffer | // points to a disk buffer | |||
bool operation_has_buffer(disk_io_job const& j); | bool operation_has_buffer(disk_io_job const& j); | |||
struct cache_status | // this struct holds a number of statistics counters | |||
// relevant for the disk io thread and disk cache. | ||||
struct TORRENT_EXPORT cache_status | ||||
{ | { | |||
// initializes all counters to 0 | ||||
cache_status() | cache_status() | |||
: blocks_written(0) | : blocks_written(0) | |||
, writes(0) | , writes(0) | |||
, blocks_read(0) | , blocks_read(0) | |||
, blocks_read_hit(0) | , blocks_read_hit(0) | |||
, reads(0) | , reads(0) | |||
, queued_bytes(0) | , queued_bytes(0) | |||
, cache_size(0) | , cache_size(0) | |||
, read_cache_size(0) | , read_cache_size(0) | |||
, total_used_buffers(0) | , total_used_buffers(0) | |||
skipping to change at line 182 | skipping to change at line 206 | |||
, job_queue_length(0) | , job_queue_length(0) | |||
, cumulative_job_time(0) | , cumulative_job_time(0) | |||
, cumulative_read_time(0) | , cumulative_read_time(0) | |||
, cumulative_write_time(0) | , cumulative_write_time(0) | |||
, cumulative_hash_time(0) | , cumulative_hash_time(0) | |||
, cumulative_sort_time(0) | , cumulative_sort_time(0) | |||
, total_read_back(0) | , total_read_back(0) | |||
, read_queue_size(0) | , read_queue_size(0) | |||
{} | {} | |||
// the number of 16kB blocks written | // the total number of 16 KiB blocks written to disk | |||
// since this session was started. | ||||
size_type blocks_written; | size_type blocks_written; | |||
// the number of write operations used | ||||
// the total number of write operations performed since this | ||||
// session was started. | ||||
// | ||||
// The ratio (``blocks_written`` - ``writes``) / ``blocks_wr | ||||
itten`` represents | ||||
// the number of saved write operations per total write oper | ||||
ations. i.e. a kind | ||||
// of cache hit ratio for the write cahe. | ||||
size_type writes; | size_type writes; | |||
// (blocks_written - writes) / blocks_written represents the | ||||
// "cache hit" ratio in the write cache | ||||
// the number of blocks read | ||||
// the number of blocks passed back to the bittorrent engine | // the number of blocks that were requested from the | |||
// bittorrent engine (from peers), that were served from dis | ||||
k or cache. | ||||
size_type blocks_read; | size_type blocks_read; | |||
// the number of blocks that was just copied from the read c ache | // the number of blocks that was just copied from the read c ache | |||
// | ||||
// The ratio ``blocks_read_hit`` / ``blocks_read`` is the ca | ||||
che hit ratio | ||||
// for the read cache. | ||||
size_type blocks_read_hit; | size_type blocks_read_hit; | |||
// the number of read operations used | // the number of read operations used | |||
size_type reads; | size_type reads; | |||
// the number of bytes waiting, in the disk job queue, to be | ||||
written | ||||
// or inserted into the disk cache | ||||
mutable size_type queued_bytes; | mutable size_type queued_bytes; | |||
// the number of blocks in the cache (both read and write) | // the number of 16 KiB blocks currently in the disk cache ( | |||
both read and write). | ||||
// This includes both read and write cache. | ||||
int cache_size; | int cache_size; | |||
// the number of blocks in the cache used for read cache | // the number of 16KiB blocks in the read cache. | |||
int read_cache_size; | int read_cache_size; | |||
// the total number of blocks that are currently in use | // the total number of buffers currently in use. | |||
// this includes send and receive buffers | // This includes the read/write disk cache as well as send a | |||
nd receive buffers | ||||
// used in peer connections. | ||||
mutable int total_used_buffers; | mutable int total_used_buffers; | |||
// times in microseconds | // the number of microseconds an average disk I/O job | |||
// has to wait in the job queue before it get processed. | ||||
int average_queue_time; | int average_queue_time; | |||
// the time read jobs takes on average to complete | ||||
// (not including the time in the queue), in microseconds. T | ||||
his only measures | ||||
// read cache misses. | ||||
int average_read_time; | int average_read_time; | |||
// the time write jobs takes to complete, on average, | ||||
// in microseconds. This does not include the time the job s | ||||
its in the disk job | ||||
// queue or in the write cache, only blocks that are flushed | ||||
to disk. | ||||
int average_write_time; | int average_write_time; | |||
// the time hash jobs takes to complete on average, in | ||||
// microseconds. Hash jobs include running SHA-1 on the data | ||||
(which for the most | ||||
// part is done incrementally) and sometimes reading back pa | ||||
rts of the piece. It | ||||
// also includes checking files without valid resume data. | ||||
int average_hash_time; | int average_hash_time; | |||
int average_job_time; | int average_job_time; | |||
int average_sort_time; | int average_sort_time; | |||
// the number of jobs in the job queue. | ||||
int job_queue_length; | int job_queue_length; | |||
// the number of milliseconds spent in all disk jobs, and sp | ||||
ecific ones | ||||
// since the start of the session. Times are specified in mi | ||||
lliseconds | ||||
boost::uint32_t cumulative_job_time; | boost::uint32_t cumulative_job_time; | |||
boost::uint32_t cumulative_read_time; | boost::uint32_t cumulative_read_time; | |||
boost::uint32_t cumulative_write_time; | boost::uint32_t cumulative_write_time; | |||
boost::uint32_t cumulative_hash_time; | boost::uint32_t cumulative_hash_time; | |||
boost::uint32_t cumulative_sort_time; | boost::uint32_t cumulative_sort_time; | |||
// the number of blocks that had to be read back from disk b | ||||
ecause | ||||
// they were flushed before the SHA-1 hash got to hash them. | ||||
If this | ||||
// is large, a larger cache could significantly improve perf | ||||
ormance | ||||
int total_read_back; | int total_read_back; | |||
// number of read jobs in the disk job queue | ||||
int read_queue_size; | int read_queue_size; | |||
}; | }; | |||
// this is a singleton consisting of the thread and a queue | // this is a singleton consisting of the thread and a queue | |||
// of disk io jobs | // of disk io jobs | |||
struct TORRENT_EXTRA_EXPORT disk_io_thread : disk_buffer_pool | struct TORRENT_EXTRA_EXPORT disk_io_thread : disk_buffer_pool | |||
{ | { | |||
disk_io_thread(io_service& ios | disk_io_thread(io_service& ios | |||
, boost::function<void()> const& queue_callback | , boost::function<void()> const& queue_callback | |||
, file_pool& fp | , file_pool& fp | |||
skipping to change at line 262 | skipping to change at line 324 | |||
size_type queue_buffer_size() const; | size_type queue_buffer_size() const; | |||
bool can_write() const; | bool can_write() const; | |||
void get_cache_info(sha1_hash const& ih | void get_cache_info(sha1_hash const& ih | |||
, std::vector<cached_piece_info>& ret) const; | , std::vector<cached_piece_info>& ret) const; | |||
cache_status status() const; | cache_status status() const; | |||
void thread_fun(); | void thread_fun(); | |||
#ifdef TORRENT_DEBUG | #if TORRENT_USE_INVARIANT_CHECKS | |||
void check_invariant() const; | void check_invariant() const; | |||
#endif | #endif | |||
struct cached_block_entry | struct cached_block_entry | |||
{ | { | |||
cached_block_entry(): buf(0) {} | cached_block_entry(): buf(0) {} | |||
// the buffer pointer (this is a disk_pool buffer) | // the buffer pointer (this is a disk_pool buffer) | |||
// or 0 | // or 0 | |||
char* buf; | char* buf; | |||
skipping to change at line 460 | skipping to change at line 522 | |||
boost::optional<io_service::work> m_work; | boost::optional<io_service::work> m_work; | |||
// reference to the file_pool which is a member of | // reference to the file_pool which is a member of | |||
// the session_impl object | // the session_impl object | |||
file_pool& m_file_pool; | file_pool& m_file_pool; | |||
// when completion notifications are queued, they're stuck | // when completion notifications are queued, they're stuck | |||
// in this list | // in this list | |||
std::list<std::pair<disk_io_job, int> > m_queued_completions ; | std::list<std::pair<disk_io_job, int> > m_queued_completions ; | |||
#if TORRENT_USE_ASSERTS | ||||
int m_magic; | ||||
#endif | ||||
// thread for performing blocking disk io operations | // thread for performing blocking disk io operations | |||
thread m_disk_io_thread; | thread m_disk_io_thread; | |||
}; | }; | |||
} | } | |||
#endif | #endif | |||
End of changes. 38 change blocks. | ||||
32 lines changed or deleted | 120 lines changed or added | |||
entry.hpp | entry.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2003, Arvid Norberg | Copyright (c) 2003-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 80 | skipping to change at line 80 | |||
#include "libtorrent/max.hpp" | #include "libtorrent/max.hpp" | |||
#if TORRENT_USE_IOSTREAM | #if TORRENT_USE_IOSTREAM | |||
#include <iosfwd> | #include <iosfwd> | |||
#endif | #endif | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
struct lazy_entry; | struct lazy_entry; | |||
// thrown by any accessor function of entry if the accessor | ||||
// function requires a type different than the actual type | ||||
// of the entry object. | ||||
struct TORRENT_EXPORT type_error: std::runtime_error | struct TORRENT_EXPORT type_error: std::runtime_error | |||
{ | { | |||
type_error(const char* error): std::runtime_error(error) {} | type_error(const char* error): std::runtime_error(error) {} | |||
}; | }; | |||
class entry; | // The ``entry`` class represents one node in a bencoded hierarchy. | |||
It works as a | ||||
// variant type, it can be either a list, a dictionary (``std::map`` | ||||
), an integer | ||||
// or a string. | ||||
class TORRENT_EXPORT entry | class TORRENT_EXPORT entry | |||
{ | { | |||
public: | public: | |||
// the key is always a string. If a generic entry would be a llowed | // the key is always a string. If a generic entry would be a llowed | |||
// as a key, sorting would become a problem (e.g. to compare a string | // as a key, sorting would become a problem (e.g. to compare a string | |||
// to a list). The definition doesn't mention such a limit t hough. | // to a list). The definition doesn't mention such a limit t hough. | |||
typedef std::map<std::string, entry> dictionary_type; | typedef std::map<std::string, entry> dictionary_type; | |||
typedef std::string string_type; | typedef std::string string_type; | |||
typedef std::list<entry> list_type; | typedef std::list<entry> list_type; | |||
typedef size_type integer_type; | typedef size_type integer_type; | |||
// the types an entry can have | ||||
enum data_type | enum data_type | |||
{ | { | |||
int_t, | int_t, | |||
string_t, | string_t, | |||
list_t, | list_t, | |||
dictionary_t, | dictionary_t, | |||
undefined_t | undefined_t | |||
}; | }; | |||
// returns the concrete type of the entry | ||||
data_type type() const; | data_type type() const; | |||
// constructors directly from a specific type. | ||||
// The content of the argument is copied into the | ||||
// newly constructed entry | ||||
entry(dictionary_type const&); | entry(dictionary_type const&); | |||
entry(string_type const&); | entry(string_type const&); | |||
entry(list_type const&); | entry(list_type const&); | |||
entry(integer_type const&); | entry(integer_type const&); | |||
entry(); | // construct an empty entry of the specified type. | |||
// see data_type enum. | ||||
entry(data_type t); | entry(data_type t); | |||
// hidden | ||||
entry(entry const& e); | entry(entry const& e); | |||
// hidden | ||||
entry(); | ||||
// hidden | ||||
~entry(); | ~entry(); | |||
// hidden | ||||
bool operator==(entry const& e) const; | bool operator==(entry const& e) const; | |||
bool operator!=(entry const& e) const { return !(*this == e) ; } | ||||
// copies the structure of the right hand side into this | ||||
// entry. | ||||
void operator=(lazy_entry const&); | void operator=(lazy_entry const&); | |||
void operator=(entry const&); | void operator=(entry const&); | |||
void operator=(dictionary_type const&); | void operator=(dictionary_type const&); | |||
void operator=(string_type const&); | void operator=(string_type const&); | |||
void operator=(list_type const&); | void operator=(list_type const&); | |||
void operator=(integer_type const&); | void operator=(integer_type const&); | |||
// The ``integer()``, ``string()``, ``list()`` and ``dict()` | ||||
` functions | ||||
// are accessors that return the respective type. If the ``e | ||||
ntry`` object | ||||
// isn't of the type you request, the accessor will throw | ||||
// libtorrent_exception (which derives from ``std::runtime_e | ||||
rror``). You | ||||
// can ask an ``entry`` for its type through the ``type()`` | ||||
function. | ||||
// | ||||
// If you want to create an ``entry`` you give it the type y | ||||
ou want it to | ||||
// have in its constructor, and then use one of the non-cons | ||||
t accessors | ||||
// to get a reference which you then can assign the value yo | ||||
u want it to | ||||
// have. | ||||
// | ||||
// The typical code to get info from a torrent file will the | ||||
n look like | ||||
// this:: | ||||
// | ||||
// entry torrent_file; | ||||
// // ... | ||||
// | ||||
// // throws if this is not a dictionary | ||||
// entry::dictionary_type const& dict = torrent_file.di | ||||
ct(); | ||||
// entry::dictionary_type::const_iterator i; | ||||
// i = dict.find("announce"); | ||||
// if (i != dict.end()) | ||||
// { | ||||
// std::string tracker_url = i->second.string() | ||||
; | ||||
// std::cout << tracker_url << "\n"; | ||||
// } | ||||
// | ||||
// | ||||
// The following code is equivalent, but a little bit shorte | ||||
r:: | ||||
// | ||||
// entry torrent_file; | ||||
// // ... | ||||
// | ||||
// // throws if this is not a dictionary | ||||
// if (entry* i = torrent_file.find_key("announce")) | ||||
// { | ||||
// std::string tracker_url = i->string(); | ||||
// std::cout << tracker_url << "\n"; | ||||
// } | ||||
// | ||||
// | ||||
// To make it easier to extract information from a torrent f | ||||
ile, the | ||||
// class torrent_info exists. | ||||
integer_type& integer(); | integer_type& integer(); | |||
const integer_type& integer() const; | const integer_type& integer() const; | |||
string_type& string(); | string_type& string(); | |||
const string_type& string() const; | const string_type& string() const; | |||
list_type& list(); | list_type& list(); | |||
const list_type& list() const; | const list_type& list() const; | |||
dictionary_type& dict(); | dictionary_type& dict(); | |||
const dictionary_type& dict() const; | const dictionary_type& dict() const; | |||
// swaps the content of *this* with ``e``. | ||||
void swap(entry& e); | void swap(entry& e); | |||
// these functions requires that the entry | // All of these functions requires the entry to be a diction | |||
// is a dictionary, otherwise they will throw | ary, if it | |||
entry& operator[](char const* key); | // isn't they will throw ``libtorrent::type_error``. | |||
// | ||||
// The non-const versions of the ``operator[]`` will return | ||||
a reference | ||||
// to either the existing element at the given key or, if th | ||||
ere is no | ||||
// element with the given key, a reference to a newly insert | ||||
ed element at | ||||
// that key. | ||||
// | ||||
// The const version of ``operator[]`` will only return a re | ||||
ference to an | ||||
// existing element at the given key. If the key is not foun | ||||
d, it will | ||||
// throw ``libtorrent::type_error``. | ||||
entry& operator[](char const* key); | ||||
entry& operator[](std::string const& key); | entry& operator[](std::string const& key); | |||
#ifndef BOOST_NO_EXCEPTIONS | #ifndef BOOST_NO_EXCEPTIONS | |||
const entry& operator[](char const* key) const; | const entry& operator[](char const* key) const; | |||
const entry& operator[](std::string const& key) const; | const entry& operator[](std::string const& key) const; | |||
#endif | #endif | |||
// These functions requires the entry to be a dictionary, if | ||||
it isn't | ||||
// they will throw ``libtorrent::type_error``. | ||||
// | ||||
// They will look for an element at the given key in the dic | ||||
tionary, if | ||||
// the element cannot be found, they will return 0. If an el | ||||
ement with | ||||
// the given key is found, the return a pointer to it. | ||||
entry* find_key(char const* key); | entry* find_key(char const* key); | |||
entry const* find_key(char const* key) const; | entry const* find_key(char const* key) const; | |||
entry* find_key(std::string const& key); | entry* find_key(std::string const& key); | |||
entry const* find_key(std::string const& key) const; | entry const* find_key(std::string const& key) const; | |||
#if (defined TORRENT_VERBOSE_LOGGING || defined TORRENT_DEBUG) && TORRENT_U | // returns a pretty-printed string representation | |||
SE_IOSTREAM | // of the bencoded structure, with JSON-style syntax | |||
void print(std::ostream& os, int indent = 0) const; | std::string to_string() const; | |||
#endif | ||||
protected: | protected: | |||
void construct(data_type t); | void construct(data_type t); | |||
void copy(const entry& e); | void copy(const entry& e); | |||
void destruct(); | void destruct(); | |||
private: | private: | |||
#ifndef TORRENT_DEBUG | void to_string_impl(std::string& out, int indent) const; | |||
data_type m_type; | ||||
#else | ||||
// the bitfield is used so that the m_type_queried | ||||
// field still fits, so that the ABI is the same for | ||||
// debug builds and release builds. It appears to be | ||||
// very hard to match debug builds with debug versions | ||||
// of libtorrent | ||||
data_type m_type:31; | ||||
public: | ||||
// in debug mode this is set to false by bdecode | ||||
// to indicate that the program has not yet queried | ||||
// the type of this entry, and sould not assume | ||||
// that it has a certain type. This is asserted in | ||||
// the accessor functions. This does not apply if | ||||
// exceptions are used. | ||||
mutable bool m_type_queried:1; | ||||
protected: | ||||
#endif // TORRENT_DEBUG | ||||
#if (defined(_MSC_VER) && _MSC_VER < 1310) || TORRENT_COMPLETE_TYPES_REQUIR ED | #if (defined(_MSC_VER) && _MSC_VER < 1310) || TORRENT_COMPLETE_TYPES_REQUIR ED | |||
// workaround for msvc-bug. | // workaround for msvc-bug. | |||
// assumes sizeof(map<string, char>) == sizeof(map<string, e ntry>) | // assumes sizeof(map<string, char>) == sizeof(map<string, e ntry>) | |||
// and sizeof(list<char>) == sizeof(list<entry>) | // and sizeof(list<char>) == sizeof(list<entry>) | |||
enum { union_size | enum { union_size | |||
= max4<sizeof(std::list<char>) | = max4<sizeof(std::list<char>) | |||
, sizeof(std::map<std::string, char>) | , sizeof(std::map<std::string, char>) | |||
, sizeof(string_type) | , sizeof(string_type) | |||
, sizeof(integer_type)>::value | , sizeof(integer_type)>::value | |||
skipping to change at line 206 | skipping to change at line 268 | |||
#else | #else | |||
enum { union_size | enum { union_size | |||
= max4<sizeof(list_type) | = max4<sizeof(list_type) | |||
, sizeof(dictionary_type) | , sizeof(dictionary_type) | |||
, sizeof(string_type) | , sizeof(string_type) | |||
, sizeof(integer_type)>::value | , sizeof(integer_type)>::value | |||
}; | }; | |||
#endif | #endif | |||
integer_type data[(union_size + sizeof(integer_type) - 1) | integer_type data[(union_size + sizeof(integer_type) - 1) | |||
/ sizeof(integer_type)]; | / sizeof(integer_type)]; | |||
// the bitfield is used so that the m_type_queried field sti | ||||
ll fits, so | ||||
// that the ABI is the same for debug builds and release bui | ||||
lds. It | ||||
// appears to be very hard to match debug builds with debug | ||||
versions of | ||||
// libtorrent | ||||
boost::uint8_t m_type:7; | ||||
public: | ||||
// in debug mode this is set to false by bdecode to indicate | ||||
that the | ||||
// program has not yet queried the type of this entry, and s | ||||
ould not | ||||
// assume that it has a certain type. This is asserted in th | ||||
e accessor | ||||
// functions. This does not apply if exceptions are used. | ||||
mutable boost::uint8_t m_type_queried:1; | ||||
}; | }; | |||
#if defined TORRENT_DEBUG && TORRENT_USE_IOSTREAM | #if TORRENT_USE_IOSTREAM | |||
// prints the bencoded structure to the ostream as a JSON-style stru | ||||
cture. | ||||
inline std::ostream& operator<<(std::ostream& os, const entry& e) | inline std::ostream& operator<<(std::ostream& os, const entry& e) | |||
{ | { | |||
e.print(os, 0); | os << e.to_string(); | |||
return os; | return os; | |||
} | } | |||
#endif | #endif | |||
#ifndef BOOST_NO_EXCEPTIONS | #ifndef BOOST_NO_EXCEPTIONS | |||
// internal | ||||
inline void throw_type_error() | inline void throw_type_error() | |||
{ | { | |||
throw libtorrent_exception(error_code(errors::invalid_entry_ type | throw libtorrent_exception(error_code(errors::invalid_entry_ type | |||
, get_libtorrent_category())); | , get_libtorrent_category())); | |||
} | } | |||
#endif | #endif | |||
} | } | |||
#endif // TORRENT_ENTRY_HPP_INCLUDED | #endif // TORRENT_ENTRY_HPP_INCLUDED | |||
End of changes. 22 change blocks. | ||||
33 lines changed or deleted | 139 lines changed or added | |||
enum_net.hpp | enum_net.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2007, Arvid Norberg | Copyright (c) 2007-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 65 | skipping to change at line 65 | |||
{ | { | |||
address destination; | address destination; | |||
address netmask; | address netmask; | |||
address gateway; | address gateway; | |||
char name[64]; | char name[64]; | |||
int mtu; | int mtu; | |||
}; | }; | |||
// returns a list of the configured IP interfaces | // returns a list of the configured IP interfaces | |||
// on the machine | // on the machine | |||
TORRENT_EXPORT std::vector<ip_interface> enum_net_interfaces(io_serv ice& ios | TORRENT_EXTRA_EXPORT std::vector<ip_interface> enum_net_interfaces(i o_service& ios | |||
, error_code& ec); | , error_code& ec); | |||
TORRENT_EXPORT std::vector<ip_route> enum_routes(io_service& ios, er ror_code& ec); | TORRENT_EXTRA_EXPORT std::vector<ip_route> enum_routes(io_service& i os, error_code& ec); | |||
// return (a1 & mask) == (a2 & mask) | // return (a1 & mask) == (a2 & mask) | |||
TORRENT_EXPORT bool match_addr_mask(address const& a1, address const & a2, address const& mask); | TORRENT_EXTRA_EXPORT bool match_addr_mask(address const& a1, address const& a2, address const& mask); | |||
// returns true if the specified address is on the same | // returns true if the specified address is on the same | |||
// local network as us | // local network as us | |||
TORRENT_EXPORT bool in_local_network(io_service& ios, address const& addr | TORRENT_EXTRA_EXPORT bool in_local_network(io_service& ios, address const& addr | |||
, error_code& ec); | , error_code& ec); | |||
TORRENT_EXPORT address get_default_gateway(io_service& ios | TORRENT_EXTRA_EXPORT address get_default_gateway(io_service& ios | |||
, error_code& ec); | , error_code& ec); | |||
} | } | |||
#endif | #endif | |||
End of changes. 6 change blocks. | ||||
6 lines changed or deleted | 6 lines changed or added | |||
error.hpp | error.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2009, Arvid Norberg | Copyright (c) 2009-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
error_code.hpp | error_code.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2008, Arvid Norberg | Copyright (c) 2008-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 62 | skipping to change at line 62 | |||
#ifndef BOOST_SYSTEM_NOEXCEPT | #ifndef BOOST_SYSTEM_NOEXCEPT | |||
#define BOOST_SYSTEM_NOEXCEPT throw() | #define BOOST_SYSTEM_NOEXCEPT throw() | |||
#endif | #endif | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
namespace errors | namespace errors | |||
{ | { | |||
// libtorrent uses boost.system's ``error_code`` class to re | ||||
present errors. libtorrent has | ||||
// its own error category get_libtorrent_category() whith th | ||||
e error codes defined by error_code_enum. | ||||
enum error_code_enum | enum error_code_enum | |||
{ | { | |||
// Not an error | ||||
no_error = 0, | no_error = 0, | |||
// Two torrents has files which end up overwriting e ach other | ||||
file_collision, | file_collision, | |||
// A piece did not match its piece hash | ||||
failed_hash_check, | failed_hash_check, | |||
// The .torrent file does not contain a bencoded dic | ||||
tionary at | ||||
// its top level | ||||
torrent_is_no_dict, | torrent_is_no_dict, | |||
// The .torrent file does not have an ``info`` dicti onary | ||||
torrent_missing_info, | torrent_missing_info, | |||
// The .torrent file's ``info`` entry is not a dicti onary | ||||
torrent_info_no_dict, | torrent_info_no_dict, | |||
// The .torrent file does not have a ``piece length` ` entry | ||||
torrent_missing_piece_length, | torrent_missing_piece_length, | |||
// The .torrent file does not have a ``name`` entry | ||||
torrent_missing_name, | torrent_missing_name, | |||
// The .torrent file's name entry is invalid | ||||
torrent_invalid_name, | torrent_invalid_name, | |||
// The length of a file, or of the whole .torrent fi | ||||
le is invalid. | ||||
// Either negative or not an integer | ||||
torrent_invalid_length, | torrent_invalid_length, | |||
// Failed to parse a file entry in the .torrent | ||||
torrent_file_parse_failed, | torrent_file_parse_failed, | |||
// The ``pieces`` field is missing or invalid in the .torrent file | ||||
torrent_missing_pieces, | torrent_missing_pieces, | |||
// The ``pieces`` string has incorrect length | ||||
torrent_invalid_hashes, | torrent_invalid_hashes, | |||
// The .torrent file has more pieces than is support ed by libtorrent | ||||
too_many_pieces_in_torrent, | too_many_pieces_in_torrent, | |||
// The metadata (.torrent file) that was received fr | ||||
om the swarm | ||||
// matched the info-hash, but failed to be parsed | ||||
invalid_swarm_metadata, | invalid_swarm_metadata, | |||
// The file or buffer is not correctly bencoded | ||||
invalid_bencoding, | invalid_bencoding, | |||
// The .torrent file does not contain any files | ||||
no_files_in_torrent, | no_files_in_torrent, | |||
// The string was not properly url-encoded as expect ed | ||||
invalid_escaped_string, | invalid_escaped_string, | |||
// Operation is not permitted since the session is s hutting down | ||||
session_is_closing, | session_is_closing, | |||
// There's already a torrent with that info-hash add | ||||
ed to the | ||||
// session | ||||
duplicate_torrent, | duplicate_torrent, | |||
// The supplied torrent_handle is not referring to a valid torrent | ||||
invalid_torrent_handle, | invalid_torrent_handle, | |||
// The type requested from the entry did not match i ts type | ||||
invalid_entry_type, | invalid_entry_type, | |||
// The specified URI does not contain a valid info-h ash | ||||
missing_info_hash_in_uri, | missing_info_hash_in_uri, | |||
// One of the files in the torrent was unexpectadly | ||||
small. This | ||||
// might be caused by files being changed by an exte | ||||
rnal process | ||||
file_too_short, | file_too_short, | |||
// The URL used an unknown protocol. Currently ``htt | ||||
p`` and | ||||
// ``https`` (if built with openssl support) are rec | ||||
ognized. For | ||||
// trackers ``udp`` is recognized as well. | ||||
unsupported_url_protocol, | unsupported_url_protocol, | |||
// The URL did not conform to URL syntax and failed to be parsed | ||||
url_parse_error, | url_parse_error, | |||
// The peer sent a 'piece' message of length 0 | ||||
peer_sent_empty_piece, | peer_sent_empty_piece, | |||
// A bencoded structure was currupt and failed to be parsed | ||||
parse_failed, | parse_failed, | |||
// The fast resume file was missing or had an invali | ||||
d file version | ||||
// tag | ||||
invalid_file_tag, | invalid_file_tag, | |||
// The fast resume file was missing or had an invali d info-hash | ||||
missing_info_hash, | missing_info_hash, | |||
// The info-hash did not match the torrent | ||||
mismatching_info_hash, | mismatching_info_hash, | |||
// The URL contained an invalid hostname | ||||
invalid_hostname, | invalid_hostname, | |||
// The URL had an invalid port | ||||
invalid_port, | invalid_port, | |||
// The port is blocked by the port-filter, and preve | ||||
nted the | ||||
// connection | ||||
port_blocked, | port_blocked, | |||
// The IPv6 address was expected to end with ']' | ||||
expected_close_bracket_in_address, | expected_close_bracket_in_address, | |||
// The torrent is being destructed, preventing the o | ||||
peration to | ||||
// succeed | ||||
destructing_torrent, | destructing_torrent, | |||
// The connection timed out | ||||
timed_out, | timed_out, | |||
// The peer is upload only, and we are upload only. | ||||
There's no point | ||||
// in keeping the connection | ||||
upload_upload_connection, | upload_upload_connection, | |||
// The peer is upload only, and we're not interested | ||||
in it. There's | ||||
// no point in keeping the connection | ||||
uninteresting_upload_peer, | uninteresting_upload_peer, | |||
// The peer sent an unknown info-hash | ||||
invalid_info_hash, | invalid_info_hash, | |||
// The torrent is paused, preventing the operation f rom succeeding | ||||
torrent_paused, | torrent_paused, | |||
// The peer sent an invalid have message, either wro | ||||
ng size or | ||||
// referring to a piece that doesn't exist in the to | ||||
rrent | ||||
invalid_have, | invalid_have, | |||
// The bitfield message had the incorrect size | ||||
invalid_bitfield_size, | invalid_bitfield_size, | |||
// The peer kept requesting pieces after it was chok | ||||
ed, possible | ||||
// abuse attempt. | ||||
too_many_requests_when_choked, | too_many_requests_when_choked, | |||
// The peer sent a piece message that does not corre | ||||
spond to a | ||||
// piece request sent by the client | ||||
invalid_piece, | invalid_piece, | |||
// memory allocation failed | ||||
no_memory, | no_memory, | |||
// The torrent is aborted, preventing the operation to succeed | ||||
torrent_aborted, | torrent_aborted, | |||
// The peer is a connection to ourself, no point in keeping it | ||||
self_connection, | self_connection, | |||
// The peer sent a piece message with invalid size, | ||||
either negative | ||||
// or greater than one block | ||||
invalid_piece_size, | invalid_piece_size, | |||
// The peer has not been interesting or interested i | ||||
n us for too | ||||
// long, no point in keeping it around | ||||
timed_out_no_interest, | timed_out_no_interest, | |||
// The peer has not said anything in a long time, po ssibly dead | ||||
timed_out_inactivity, | timed_out_inactivity, | |||
// The peer did not send a handshake within a reason | ||||
able amount of | ||||
// time, it might not be a bittorrent peer | ||||
timed_out_no_handshake, | timed_out_no_handshake, | |||
// The peer has been unchoked for too long without r | ||||
equesting any | ||||
// data. It might be lying about its interest in us | ||||
timed_out_no_request, | timed_out_no_request, | |||
// The peer sent an invalid choke message | ||||
invalid_choke, | invalid_choke, | |||
// The peer send an invalid unchoke message | ||||
invalid_unchoke, | invalid_unchoke, | |||
// The peer sent an invalid interested message | ||||
invalid_interested, | invalid_interested, | |||
// The peer sent an invalid not-interested message | ||||
invalid_not_interested, | invalid_not_interested, | |||
// The peer sent an invalid piece request message | ||||
invalid_request, | invalid_request, | |||
// The peer sent an invalid hash-list message (this | ||||
is part of the | ||||
// merkle-torrent extension) | ||||
invalid_hash_list, | invalid_hash_list, | |||
// The peer sent an invalid hash-piece message (this | ||||
is part of the | ||||
// merkle-torrent extension) | ||||
invalid_hash_piece, | invalid_hash_piece, | |||
// The peer sent an invalid cancel message | ||||
invalid_cancel, | invalid_cancel, | |||
// The peer sent an invalid DHT port-message | ||||
invalid_dht_port, | invalid_dht_port, | |||
// The peer sent an invalid suggest piece-message | ||||
invalid_suggest, | invalid_suggest, | |||
// The peer sent an invalid have all-message | ||||
invalid_have_all, | invalid_have_all, | |||
// The peer sent an invalid have none-message | ||||
invalid_have_none, | invalid_have_none, | |||
// The peer sent an invalid reject message | ||||
invalid_reject, | invalid_reject, | |||
// The peer sent an invalid allow fast-message | ||||
invalid_allow_fast, | invalid_allow_fast, | |||
// The peer sent an invalid extesion message ID | ||||
invalid_extended, | invalid_extended, | |||
// The peer sent an invalid message ID | ||||
invalid_message, | invalid_message, | |||
// The synchronization hash was not found in the enc rypted handshake | ||||
sync_hash_not_found, | sync_hash_not_found, | |||
// The encryption constant in the handshake is inval id | ||||
invalid_encryption_constant, | invalid_encryption_constant, | |||
// The peer does not support plaintext, which is the selected mode | ||||
no_plaintext_mode, | no_plaintext_mode, | |||
// The peer does not support rc4, which is the selec ted mode | ||||
no_rc4_mode, | no_rc4_mode, | |||
// The peer does not support any of the encryption m | ||||
odes that the | ||||
// client supports | ||||
unsupported_encryption_mode, | unsupported_encryption_mode, | |||
// The peer selected an encryption mode that the cli | ||||
ent did not | ||||
// advertise and does not support | ||||
unsupported_encryption_mode_selected, | unsupported_encryption_mode_selected, | |||
// The pad size used in the encryption handshake is of invalid size | ||||
invalid_pad_size, | invalid_pad_size, | |||
// The encryption handshake is invalid | ||||
invalid_encrypt_handshake, | invalid_encrypt_handshake, | |||
// The client is set to not support incoming encrypt | ||||
ed connections | ||||
// and this is an encrypted connection | ||||
no_incoming_encrypted, | no_incoming_encrypted, | |||
// The client is set to not support incoming regular | ||||
bittorrent | ||||
// connections, and this is a regular connection | ||||
no_incoming_regular, | no_incoming_regular, | |||
// The client is already connected to this peer-ID | ||||
duplicate_peer_id, | duplicate_peer_id, | |||
// Torrent was removed | ||||
torrent_removed, | torrent_removed, | |||
// The packet size exceeded the upper sanity check-l imit | ||||
packet_too_large, | packet_too_large, | |||
reserved, | reserved, | |||
// The web server responded with an error | ||||
http_error, | http_error, | |||
// The web server response is missing a location hea der | ||||
missing_location, | missing_location, | |||
// The web seed redirected to a path that no longer | ||||
matches the | ||||
// .torrent directory structure | ||||
invalid_redirection, | invalid_redirection, | |||
// The connection was closed becaused it redirected | ||||
to a different | ||||
// URL | ||||
redirecting, | redirecting, | |||
// The HTTP range header is invalid | ||||
invalid_range, | invalid_range, | |||
// The HTTP response did not have a content length | ||||
no_content_length, | no_content_length, | |||
// The IP is blocked by the IP filter | ||||
banned_by_ip_filter, | banned_by_ip_filter, | |||
// At the connection limit | ||||
too_many_connections, | too_many_connections, | |||
// The peer is marked as banned | ||||
peer_banned, | peer_banned, | |||
// The torrent is stopping, causing the operation to fail | ||||
stopping_torrent, | stopping_torrent, | |||
// The peer has sent too many corrupt pieces and is banned | ||||
too_many_corrupt_pieces, | too_many_corrupt_pieces, | |||
// The torrent is not ready to receive peers | ||||
torrent_not_ready, | torrent_not_ready, | |||
// The peer is not completely constructed yet | ||||
peer_not_constructed, | peer_not_constructed, | |||
// The session is closing, causing the operation to fail | ||||
session_closing, | session_closing, | |||
// The peer was disconnected in order to leave room | ||||
for a | ||||
// potentially better peer | ||||
optimistic_disconnect, | optimistic_disconnect, | |||
// The torrent is finished | ||||
torrent_finished, | torrent_finished, | |||
// No UPnP router found | ||||
no_router, | no_router, | |||
// The metadata message says the metadata exceeds th e limit | ||||
metadata_too_large, | metadata_too_large, | |||
// The peer sent an invalid metadata request message | ||||
invalid_metadata_request, | invalid_metadata_request, | |||
// The peer advertised an invalid metadata size | ||||
invalid_metadata_size, | invalid_metadata_size, | |||
// The peer sent a message with an invalid metadata offset | ||||
invalid_metadata_offset, | invalid_metadata_offset, | |||
// The peer sent an invalid metadata message | ||||
invalid_metadata_message, | invalid_metadata_message, | |||
// The peer sent a peer exchange message that was to o large | ||||
pex_message_too_large, | pex_message_too_large, | |||
// The peer sent an invalid peer exchange message | ||||
invalid_pex_message, | invalid_pex_message, | |||
// The peer sent an invalid tracker exchange message | ||||
invalid_lt_tracker_message, | invalid_lt_tracker_message, | |||
// The peer sent an pex messages too often. This is | ||||
a possible | ||||
// attempt of and attack | ||||
too_frequent_pex, | too_frequent_pex, | |||
// The operation failed because it requires the torr | ||||
ent to have | ||||
// the metadata (.torrent file) and it doesn't have | ||||
it yet. | ||||
// This happens for magnet links before they have do | ||||
wnloaded the | ||||
// metadata, and also torrents added by URL. | ||||
no_metadata, | no_metadata, | |||
// The peer sent an invalid ``dont_have`` message. T | ||||
he dont have | ||||
// message is an extension to allow peers to adverti | ||||
se that the | ||||
// no longer has a piece they previously had. | ||||
invalid_dont_have, | invalid_dont_have, | |||
// The peer tried to connect to an SSL torrent witho | ||||
ut connecting | ||||
// over SSL. | ||||
requires_ssl_connection, | requires_ssl_connection, | |||
// The peer tried to connect to a torrent with a cer | ||||
tificate | ||||
// for a different torrent. | ||||
invalid_ssl_cert, | invalid_ssl_cert, | |||
reserved113, | // the torrent is not an SSL torrent, and the operat | |||
reserved114, | ion requires | |||
reserved115, | // an SSL torrent | |||
reserved116, | not_an_ssl_torrent, | |||
reserved117, | ||||
reserved118, | // The NAT-PMP router responded with an unsupported | |||
reserved119, | protocol version | |||
unsupported_protocol_version = 120, | ||||
// natpmp errors | // You are not authorized to map ports on this NAT-P | |||
unsupported_protocol_version, // 120 | MP router | |||
natpmp_not_authorized, | natpmp_not_authorized, | |||
// The NAT-PMP router failed because of a network fa ilure | ||||
network_failure, | network_failure, | |||
// The NAT-PMP router failed because of lack of reso urces | ||||
no_resources, | no_resources, | |||
// The NAT-PMP router failed because an unsupported opcode was sent | ||||
unsupported_opcode, | unsupported_opcode, | |||
reserved125, | ||||
reserved126, | ||||
reserved127, | ||||
reserved128, | ||||
reserved129, | ||||
// fastresume errors | // The resume data file is missing the 'file sizes' | |||
missing_file_sizes, // 130 | entry | |||
missing_file_sizes = 130, | ||||
// The resume data file 'file sizes' entry is empty | ||||
no_files_in_resume_data, | no_files_in_resume_data, | |||
// The resume data file is missing the 'pieces' and 'slots' entry | ||||
missing_pieces, | missing_pieces, | |||
// The number of files in the resume data does not m | ||||
atch the number | ||||
// of files in the torrent | ||||
mismatching_number_of_files, | mismatching_number_of_files, | |||
// One of the files on disk has a different size tha | ||||
n in the fast | ||||
// resume file | ||||
mismatching_file_size, | mismatching_file_size, | |||
// One of the files on disk has a different timestam | ||||
p than in the | ||||
// fast resume file | ||||
mismatching_file_timestamp, | mismatching_file_timestamp, | |||
// The resume data file is not a dictionary | ||||
not_a_dictionary, | not_a_dictionary, | |||
// The 'blocks per piece' entry is invalid in the re sume data file | ||||
invalid_blocks_per_piece, | invalid_blocks_per_piece, | |||
// The resume file is missing the 'slots' entry, whi | ||||
ch is required | ||||
// for torrents with compact allocation | ||||
missing_slots, | missing_slots, | |||
// The resume file contains more slots than the torr ent | ||||
too_many_slots, | too_many_slots, | |||
// The 'slot' entry is invalid in the resume data | ||||
invalid_slot_list, | invalid_slot_list, | |||
// One index in the 'slot' list is invalid | ||||
invalid_piece_index, | invalid_piece_index, | |||
// The pieces on disk needs to be re-ordered for the | ||||
specified | ||||
// allocation mode. This happens if you specify spar | ||||
se allocation | ||||
// and the files on disk are using compact storage. | ||||
The pieces needs | ||||
// to be moved to their right position | ||||
pieces_need_reorder, | pieces_need_reorder, | |||
reserved143, | ||||
reserved144, | ||||
reserved145, | ||||
reserved146, | ||||
reserved147, | ||||
reserved148, | ||||
reserved149, | ||||
// HTTP errors | // The HTTP header was not correctly formatted | |||
http_parse_error, // 150 | http_parse_error = 150, | |||
// The HTTP response was in the 300-399 range but la | ||||
cked a location | ||||
// header | ||||
http_missing_location, | http_missing_location, | |||
// The HTTP response was encoded with gzip or deflat | ||||
e but | ||||
// decompressing it failed | ||||
http_failed_decompress, | http_failed_decompress, | |||
reserved153, | ||||
reserved154, | ||||
reserved155, | ||||
reserved156, | ||||
reserved157, | ||||
reserved158, | ||||
reserved159, | ||||
// i2p errors | ||||
no_i2p_router, // 160 | ||||
reserved161, | ||||
reserved162, | ||||
reserved163, | ||||
reserved164, | ||||
reserved165, | ||||
reserved166, | ||||
reserved167, | ||||
reserved168, | ||||
reserved169, | ||||
// tracker errors | // The URL specified an i2p address, but no i2p rout | |||
scrape_not_available, // 170 | er is configured | |||
no_i2p_router = 160, | ||||
// The tracker URL doesn't support transforming it i | ||||
nto a scrape | ||||
// URL. i.e. it doesn't contain "announce. | ||||
scrape_not_available = 170, | ||||
// invalid tracker response | ||||
invalid_tracker_response, | invalid_tracker_response, | |||
// invalid peer dictionary entry. Not a dictionary | ||||
invalid_peer_dict, | invalid_peer_dict, | |||
// tracker sent a failure message | ||||
tracker_failure, | tracker_failure, | |||
// missing or invalid 'files' entry | ||||
invalid_files_entry, | invalid_files_entry, | |||
// missing or invalid 'hash' entry | ||||
invalid_hash_entry, | invalid_hash_entry, | |||
// missing or invalid 'peers' and 'peers6' entry | ||||
invalid_peers_entry, | invalid_peers_entry, | |||
// udp tracker response packet has invalid size | ||||
invalid_tracker_response_length, | invalid_tracker_response_length, | |||
// invalid transaction id in udp tracker response | ||||
invalid_tracker_transaction_id, | invalid_tracker_transaction_id, | |||
// invalid action field in udp tracker response | ||||
invalid_tracker_action, | invalid_tracker_action, | |||
reserved180, | ||||
reserved181, | ||||
reserved182, | ||||
reserved183, | ||||
reserved184, | ||||
reserved185, | ||||
reserved186, | ||||
reserved187, | ||||
reserved188, | ||||
reserved189, | ||||
// bdecode errors | #ifndef TORRENT_NO_DEPRECATE | |||
expected_string, // 190 | // expected string in bencoded string | |||
expected_string = 190, | ||||
// expected colon in bencoded string | ||||
expected_colon, | expected_colon, | |||
// unexpected end of file in bencoded string | ||||
unexpected_eof, | unexpected_eof, | |||
// expected value (list, dict, int or string) in ben coded string | ||||
expected_value, | expected_value, | |||
// bencoded recursion depth limit exceeded | ||||
depth_exceeded, | depth_exceeded, | |||
// bencoded item count limit exceeded | ||||
limit_exceeded, | limit_exceeded, | |||
// integer overflow | ||||
overflow, | overflow, | |||
#endif | ||||
// the number of error codes | ||||
error_code_max | error_code_max | |||
}; | }; | |||
// HTTP errors are reported in the libtorrent::http_category | ||||
, with error code enums in | ||||
// the ``libtorrent::errors`` namespace. | ||||
enum http_errors | enum http_errors | |||
{ | { | |||
cont = 100, | cont = 100, | |||
ok = 200, | ok = 200, | |||
created = 201, | created = 201, | |||
accepted = 202, | accepted = 202, | |||
no_content = 204, | no_content = 204, | |||
multiple_choices = 300, | multiple_choices = 300, | |||
moved_permanently = 301, | moved_permanently = 301, | |||
moved_temporarily = 302, | moved_temporarily = 302, | |||
not_modified = 304, | not_modified = 304, | |||
bad_request = 400, | bad_request = 400, | |||
unauthorized = 401, | unauthorized = 401, | |||
forbidden = 403, | forbidden = 403, | |||
not_found = 404, | not_found = 404, | |||
internal_server_error = 500, | internal_server_error = 500, | |||
not_implemented = 501, | not_implemented = 501, | |||
bad_gateway = 502, | bad_gateway = 502, | |||
service_unavailable = 503 | service_unavailable = 503 | |||
}; | }; | |||
} | ||||
} | ||||
#if BOOST_VERSION >= 103500 | ||||
namespace boost { namespace system { | ||||
template<> struct is_error_code_enum<libtorrent::errors::error_code_ | ||||
enum> | ||||
{ static const bool value = true; }; | ||||
template<> struct is_error_condition_enum<libtorrent::errors::error_ | // hidden | |||
code_enum> | TORRENT_EXPORT boost::system::error_code make_error_code(err | |||
{ static const bool value = true; }; | or_code_enum e); | |||
} } | ||||
#endif | } // namespace errors | |||
namespace libtorrent | ||||
{ | ||||
#if BOOST_VERSION < 103500 | #if BOOST_VERSION < 103500 | |||
typedef asio::error_code error_code; | typedef asio::error_code error_code; | |||
inline asio::error::error_category get_posix_category() { return asi | // hidden | |||
o::error::system_category; } | inline asio::error::error_category get_posix_category() | |||
inline asio::error::error_category get_system_category() { return as | { return asio::error::system_category; } | |||
io::error::system_category; } | // hidden | |||
inline asio::error::error_category get_system_category() | ||||
{ return asio::error::system_category; } | ||||
inline boost::system::error_category const& get_libtorrent_category( | // hidden | |||
) | boost::system::error_category const& get_libtorrent_category() | |||
{ | { | |||
static ::asio::error::error_category libtorrent_category(20) ; | static ::asio::error::error_category libtorrent_category(20) ; | |||
return libtorrent_category; | return libtorrent_category; | |||
} | } | |||
inline boost::system::error_category const& get_http_category() | // hidden | |||
boost::system::error_category const& get_http_category() | ||||
{ | { | |||
static ::asio::error::error_category http_category(21); | static ::asio::error::error_category http_category(21); | |||
return http_category; | return http_category; | |||
} | } | |||
#else | #else | |||
struct TORRENT_EXPORT libtorrent_error_category : boost::system::err | // return the instance of the libtorrent_error_category which | |||
or_category | // maps libtorrent error codes to human readable error messages. | |||
{ | ||||
virtual const char* name() const BOOST_SYSTEM_NOEXCEPT; | ||||
virtual std::string message(int ev) const BOOST_SYSTEM_NOEXC | ||||
EPT; | ||||
virtual boost::system::error_condition default_error_conditi | ||||
on(int ev) const BOOST_SYSTEM_NOEXCEPT | ||||
{ return boost::system::error_condition(ev, *this); } | ||||
}; | ||||
TORRENT_EXPORT boost::system::error_category& get_libtorrent_categor y(); | TORRENT_EXPORT boost::system::error_category& get_libtorrent_categor y(); | |||
struct TORRENT_EXPORT http_error_category : boost::system::error_cat | // returns the error_category for HTTP errors | |||
egory | ||||
{ | ||||
virtual const char* name() const BOOST_SYSTEM_NOEXCEPT; | ||||
virtual std::string message(int ev) const BOOST_SYSTEM_NOEXC | ||||
EPT; | ||||
virtual boost::system::error_condition default_error_conditi | ||||
on(int ev) const BOOST_SYSTEM_NOEXCEPT | ||||
{ return boost::system::error_condition(ev, *this); } | ||||
}; | ||||
TORRENT_EXPORT boost::system::error_category& get_http_category(); | TORRENT_EXPORT boost::system::error_category& get_http_category(); | |||
namespace errors | ||||
{ | ||||
inline boost::system::error_code make_error_code(error_code_ | ||||
enum e) | ||||
{ | ||||
return boost::system::error_code(e, get_libtorrent_c | ||||
ategory()); | ||||
} | ||||
} | ||||
using boost::system::error_code; | using boost::system::error_code; | |||
#if BOOST_VERSION < 104400 | // hidden | |||
inline boost::system::error_category const& get_system_category() | inline boost::system::error_category const& get_system_category() | |||
#if BOOST_VERSION < 104400 | ||||
{ return boost::system::get_system_category(); } | { return boost::system::get_system_category(); } | |||
#else | #else | |||
inline boost::system::error_category const& get_system_category() | ||||
{ return boost::system::system_category(); } | { return boost::system::system_category(); } | |||
#endif | #endif | |||
// hidden | ||||
inline boost::system::error_category const& get_posix_category() | inline boost::system::error_category const& get_posix_category() | |||
#if BOOST_VERSION < 103600 | #if BOOST_VERSION < 103600 | |||
{ return boost::system::get_posix_category(); } | { return boost::system::get_posix_category(); } | |||
#elif BOOST_VERSION < 104400 | #elif BOOST_VERSION < 104400 | |||
{ return boost::system::get_generic_category(); } | { return boost::system::get_generic_category(); } | |||
#else | #else | |||
{ return boost::system::generic_category(); } | { return boost::system::generic_category(); } | |||
#endif // BOOST_VERSION < 103600 | #endif // BOOST_VERSION < 103600 | |||
#endif // BOOST_VERSION < 103500 | #endif // BOOST_VERSION < 103500 | |||
// internal | ||||
inline boost::system::error_category const& generic_category() | ||||
{ return get_posix_category(); } | ||||
#ifndef BOOST_NO_EXCEPTIONS | #ifndef BOOST_NO_EXCEPTIONS | |||
struct TORRENT_EXPORT libtorrent_exception: std::exception | struct TORRENT_EXPORT libtorrent_exception: std::exception | |||
{ | { | |||
libtorrent_exception(error_code const& s): m_error(s), m_msg (0) {} | libtorrent_exception(error_code const& s): m_error(s), m_msg (0) {} | |||
virtual const char* what() const throw(); | virtual const char* what() const throw(); | |||
virtual ~libtorrent_exception() throw(); | virtual ~libtorrent_exception() throw(); | |||
error_code error() const { return m_error; } | error_code error() const { return m_error; } | |||
private: | private: | |||
error_code m_error; | error_code m_error; | |||
mutable char* m_msg; | mutable char* m_msg; | |||
}; | }; | |||
#endif | #endif | |||
} | } | |||
#if BOOST_VERSION >= 103500 | ||||
namespace boost { namespace system { | ||||
template<> struct is_error_code_enum<libtorrent::errors::error_code_ | ||||
enum> | ||||
{ static const bool value = true; }; | ||||
template<> struct is_error_condition_enum<libtorrent::errors::error_ | ||||
code_enum> | ||||
{ static const bool value = true; }; | ||||
template<> struct is_error_code_enum<libtorrent::errors::http_errors | ||||
> | ||||
{ static const bool value = true; }; | ||||
template<> struct is_error_condition_enum<libtorrent::errors::http_e | ||||
rrors> | ||||
{ static const bool value = true; }; | ||||
} } | ||||
#endif // BOOST_VERSION | ||||
#endif | #endif | |||
End of changes. 170 change blocks. | ||||
119 lines changed or deleted | 321 lines changed or added | |||
escape_string.hpp | escape_string.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2003, Arvid Norberg | Copyright (c) 2003-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 62 | skipping to change at line 62 | |||
// if the url does not appear to be encoded, and it contains illegal url characters | // if the url does not appear to be encoded, and it contains illegal url characters | |||
// it will be encoded | // it will be encoded | |||
TORRENT_EXTRA_EXPORT std::string maybe_url_encode(std::string const& url); | TORRENT_EXTRA_EXPORT std::string maybe_url_encode(std::string const& url); | |||
// returns true if the given string (not null terminated) contains | // returns true if the given string (not null terminated) contains | |||
// characters that would need to be escaped if used in a URL | // characters that would need to be escaped if used in a URL | |||
TORRENT_EXTRA_EXPORT bool need_encoding(char const* str, int len); | TORRENT_EXTRA_EXPORT bool need_encoding(char const* str, int len); | |||
// encodes a string using the base64 scheme | // encodes a string using the base64 scheme | |||
TORRENT_EXTRA_EXPORT std::string base64encode(std::string const& s); | TORRENT_EXTRA_EXPORT std::string base64encode(std::string const& s); | |||
TORRENT_EXTRA_EXPORT std::string base64decode(std::string const& s); | ||||
// encodes a string using the base32 scheme | // encodes a string using the base32 scheme | |||
TORRENT_EXTRA_EXPORT std::string base32encode(std::string const& s); | TORRENT_EXTRA_EXPORT std::string base32encode(std::string const& s); | |||
TORRENT_EXTRA_EXPORT std::string base32decode(std::string const& s); | TORRENT_EXTRA_EXPORT std::string base32decode(std::string const& s); | |||
TORRENT_EXTRA_EXPORT std::string url_has_argument( | TORRENT_EXTRA_EXPORT std::string url_has_argument( | |||
std::string const& url, std::string argument, std::string::s ize_type* out_pos = 0); | std::string const& url, std::string argument, std::string::s ize_type* out_pos = 0); | |||
// replaces \ with / | // replaces \ with / | |||
TORRENT_EXTRA_EXPORT void convert_path_to_posix(std::string& path); | TORRENT_EXTRA_EXPORT void convert_path_to_posix(std::string& path); | |||
TORRENT_EXTRA_EXPORT std::string read_until(char const*& str, char d elim, char const* end); | TORRENT_EXTRA_EXPORT std::string read_until(char const*& str, char d elim, char const* end); | |||
TORRENT_EXTRA_EXPORT int hex_to_int(char in); | ||||
TORRENT_EXTRA_EXPORT bool is_hex(char const *in, int len); | ||||
// converts (binary) the string ``s`` to hexadecimal representation | ||||
and | ||||
// returns it. | ||||
TORRENT_EXPORT std::string to_hex(std::string const& s); | TORRENT_EXPORT std::string to_hex(std::string const& s); | |||
TORRENT_EXPORT bool is_hex(char const *in, int len); | ||||
// converts the binary buffer [``in``, ``in`` + len) to hexadecimal | ||||
// and prints it to the buffer ``out``. The caller is responsible fo | ||||
r | ||||
// making sure the buffer pointed to by ``out`` is large enough, | ||||
// i.e. has at least len * 2 bytes of space. | ||||
TORRENT_EXPORT void to_hex(char const *in, int len, char* out); | TORRENT_EXPORT void to_hex(char const *in, int len, char* out); | |||
// converts the buffer [``in``, ``in`` + len) from hexadecimal to | ||||
// binary. The binary output is written to the buffer pointed to | ||||
// by ``out``. The caller is responsible for making sure the buffer | ||||
// at ``out`` has enough space for the result to be written to, i.e. | ||||
// (len + 1) / 2 bytes. | ||||
TORRENT_EXPORT bool from_hex(char const *in, int len, char* out); | TORRENT_EXPORT bool from_hex(char const *in, int len, char* out); | |||
#if defined TORRENT_WINDOWS && TORRENT_USE_WSTRING | #if defined TORRENT_WINDOWS && TORRENT_USE_WSTRING | |||
TORRENT_EXTRA_EXPORT std::wstring convert_to_wstring(std::string con st& s); | TORRENT_EXTRA_EXPORT std::wstring convert_to_wstring(std::string con st& s); | |||
TORRENT_EXTRA_EXPORT std::string convert_from_wstring(std::wstring c onst& s); | TORRENT_EXTRA_EXPORT std::string convert_from_wstring(std::wstring c onst& s); | |||
#endif | #endif | |||
#if TORRENT_USE_ICONV || TORRENT_USE_LOCALE || defined TORRENT_WINDOWS | #if TORRENT_USE_ICONV || TORRENT_USE_LOCALE || defined TORRENT_WINDOWS | |||
TORRENT_EXTRA_EXPORT std::string convert_to_native(std::string const & s); | TORRENT_EXTRA_EXPORT std::string convert_to_native(std::string const & s); | |||
TORRENT_EXTRA_EXPORT std::string convert_from_native(std::string con st& s); | TORRENT_EXTRA_EXPORT std::string convert_from_native(std::string con st& s); | |||
#else | #else | |||
// internal | ||||
inline std::string const& convert_to_native(std::string const& s) { return s; } | inline std::string const& convert_to_native(std::string const& s) { return s; } | |||
// internal | ||||
inline std::string const& convert_from_native(std::string const& s) { return s; } | inline std::string const& convert_from_native(std::string const& s) { return s; } | |||
#endif | #endif | |||
} | } | |||
#endif // TORRENT_ESCAPE_STRING_HPP_INCLUDED | #endif // TORRENT_ESCAPE_STRING_HPP_INCLUDED | |||
End of changes. 7 change blocks. | ||||
3 lines changed or deleted | 22 lines changed or added | |||
extensions.hpp | extensions.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2006, Arvid Norberg | Copyright (c) 2006-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 36 | skipping to change at line 36 | |||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 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 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||
POSSIBILITY OF SUCH DAMAGE. | POSSIBILITY OF SUCH DAMAGE. | |||
*/ | */ | |||
#ifndef TORRENT_EXTENSIONS_HPP_INCLUDED | #ifndef TORRENT_EXTENSIONS_HPP_INCLUDED | |||
#define TORRENT_EXTENSIONS_HPP_INCLUDED | #define TORRENT_EXTENSIONS_HPP_INCLUDED | |||
// OVERVIEW | ||||
// | ||||
// libtorrent has a plugin interface for implementing extensions to the pro | ||||
tocol. | ||||
// These can be general extensions for transferring metadata or peer exchan | ||||
ge | ||||
// extensions, or it could be used to provide a way to customize the protoc | ||||
ol | ||||
// to fit a particular (closed) network. | ||||
// | ||||
// In short, the plugin interface makes it possible to: | ||||
// | ||||
// * register extension messages (sent in the extension handshake), see | ||||
// extensions_. | ||||
// * add data and parse data from the extension handshake. | ||||
// * send extension messages and standard bittorrent messages. | ||||
// * override or block the handling of standard bittorrent messages. | ||||
// * save and restore state via the session state | ||||
// * see all alerts that are posted | ||||
// | ||||
// .. _extensions: extension_protocol.html | ||||
// | ||||
// a word of caution | ||||
// ----------------- | ||||
// | ||||
// Writing your own plugin is a very easy way to introduce serious bugs suc | ||||
h as | ||||
// dead locks and race conditions. Since a plugin has access to internal | ||||
// structures it is also quite easy to sabotage libtorrent's operation. | ||||
// | ||||
// All the callbacks in this interface are called with the main libtorrent | ||||
thread | ||||
// mutex locked. And they are always called from the libtorrent network thr | ||||
ead. In | ||||
// case portions of your plugin are called from other threads, typically th | ||||
e main | ||||
// thread, you cannot use any of the member functions on the internal struc | ||||
tures | ||||
// in libtorrent, since those require the mutex to be locked. Futhermore, y | ||||
ou would | ||||
// also need to have a mutex on your own shared data within the plugin, to | ||||
make | ||||
// sure it is not accessed at the same time from the libtorrent thread (thr | ||||
ough a | ||||
// callback). See `boost thread's mutex`_. If you need to send out a messag | ||||
e from | ||||
// another thread, it is advised to use an internal queue, and do the actua | ||||
l | ||||
// sending in ``tick()``. | ||||
// | ||||
// Since the plugin interface gives you easy access to internal structures, | ||||
it | ||||
// is not supported as a stable API. Plugins should be considered spcific t | ||||
o a | ||||
// specific version of libtorrent. Although, in practice the internals most | ||||
ly | ||||
// don't change that dramatically. | ||||
// | ||||
// .. _`boost thread's mutex`: http://www.boost.org/doc/html/mutex.html | ||||
// | ||||
// | ||||
// plugin-interface | ||||
// ================ | ||||
// | ||||
// The plugin interface consists of three base classes that the plugin may | ||||
// implement. These are called plugin, torrent_plugin and peer_plugin. | ||||
// They are found in the ``<libtorrent/extensions.hpp>`` header. | ||||
// | ||||
// These plugins are instantiated for each session, torrent and possibly ea | ||||
ch peer, | ||||
// respectively. | ||||
// | ||||
// For plugins that only need per torrent state, it is enough to only imple | ||||
ment | ||||
// ``torrent_plugin`` and pass a constructor function or function object to | ||||
// ``session::add_extension()`` or ``torrent_handle::add_extension()`` (if | ||||
the | ||||
// torrent has already been started and you want to hook in the extension a | ||||
t | ||||
// run-time). | ||||
// | ||||
// The signature of the function is:: | ||||
// | ||||
// boost::shared_ptr<torrent_plugin> (*)(torrent*, void*); | ||||
// | ||||
// The first argument is the internal torrent object, the second argument | ||||
// is the userdata passed to ``session::add_torrent()`` or | ||||
// ``torrent_handle::add_extension()``. | ||||
// | ||||
// The function should return a ``boost::shared_ptr<torrent_plugin>`` which | ||||
// may or may not be 0. If it is a null pointer, the extension is simply ig | ||||
nored | ||||
// for this torrent. If it is a valid pointer (to a class inheriting | ||||
// ``torrent_plugin``), it will be associated with this torrent and callbac | ||||
ks | ||||
// will be made on torrent events. | ||||
// | ||||
// For more elaborate plugins which require session wide state, you would | ||||
// implement ``plugin``, construct an object (in a ``boost::shared_ptr``) a | ||||
nd pass | ||||
// it in to ``session::add_extension()``. | ||||
// | ||||
// custom alerts | ||||
// ============= | ||||
// | ||||
// Since plugins are running within internal libtorrent threads, one conven | ||||
ient | ||||
// way to communicate with the client is to post custom alerts. | ||||
// | ||||
// The expected interface of any alert, apart from deriving from the alert | ||||
// base class, looks like this: | ||||
// | ||||
// .. parsed-literal:: | ||||
// | ||||
// const static int alert_type = *<unique alert ID>*; | ||||
// virtual int type() const { return alert_type; } | ||||
// | ||||
// virtual std::string message() const; | ||||
// | ||||
// virtual std::auto_ptr<alert> clone() const | ||||
// { return std::auto_ptr<alert>(new name(\*this)); } | ||||
// | ||||
// const static int static_category = *<bitmask of alert::category_t fl | ||||
ags>*; | ||||
// virtual int category() const { return static_category; } | ||||
// | ||||
// virtual char const* what() const { return *<string literal of the na | ||||
me of this alert>*; } | ||||
// | ||||
// The ``alert_type`` is used for the type-checking in ``alert_cast``. It m | ||||
ust | ||||
// not collide with any other alert. The built-in alerts in libtorrent will | ||||
// not use alert type IDs greater than ``user_alert_id``. When defining you | ||||
r | ||||
// own alert, make sure it's greater than this constant. | ||||
// | ||||
// ``type()`` is the run-time equivalence of the ``alert_type``. | ||||
// | ||||
// The ``message()`` virtual function is expected to construct a useful | ||||
// string representation of the alert and the event or data it represents. | ||||
// Something convenient to put in a log file for instance. | ||||
// | ||||
// ``clone()`` is used internally to copy alerts. The suggested implementat | ||||
ion | ||||
// of simply allocating a new instance as a copy of ``*this`` is all that's | ||||
// expected. | ||||
// | ||||
// The static category is required for checking wether or not the category | ||||
// for a specific alert is enabled or not, without instantiating the alert. | ||||
// The ``category`` virtual function is the run-time equivalence. | ||||
// | ||||
// The ``what()`` virtual function may simply be a string literal of the cl | ||||
ass | ||||
// name of your alert. | ||||
// | ||||
// For more information, see the `alert section`_. | ||||
// | ||||
// .. _`alert section`: reference-Alerts.html | ||||
#ifndef TORRENT_DISABLE_EXTENSIONS | #ifndef TORRENT_DISABLE_EXTENSIONS | |||
#ifdef _MSC_VER | #ifdef _MSC_VER | |||
#pragma warning(push, 1) | #pragma warning(push, 1) | |||
#endif | #endif | |||
#include <boost/weak_ptr.hpp> | #include <boost/weak_ptr.hpp> | |||
#ifdef _MSC_VER | #ifdef _MSC_VER | |||
#pragma warning(pop) | #pragma warning(pop) | |||
#endif | #endif | |||
#include <vector> | #include <vector> | |||
#include "libtorrent/config.hpp" | #include "libtorrent/config.hpp" | |||
#include "libtorrent/buffer.hpp" | #include "libtorrent/buffer.hpp" | |||
#include "libtorrent/socket.hpp" | #include "libtorrent/socket.hpp" | |||
#include "libtorrent/error_code.hpp" | ||||
#include "libtorrent/policy.hpp" // for policy::peer | ||||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
namespace aux { struct session_impl; } | namespace aux { struct session_impl; } | |||
struct peer_plugin; | struct peer_plugin; | |||
class bt_peer_connection; | class bt_peer_connection; | |||
struct peer_request; | struct peer_request; | |||
class peer_connection; | class peer_connection; | |||
class entry; | class entry; | |||
struct lazy_entry; | struct lazy_entry; | |||
struct disk_buffer_holder; | struct disk_buffer_holder; | |||
struct bitfield; | struct bitfield; | |||
class alert; | class alert; | |||
struct torrent_plugin; | struct torrent_plugin; | |||
class torrent; | class torrent; | |||
struct torrent_peer; | ||||
// this is the base class for a session plugin. One primary feature | ||||
// is that it is notified of all torrents that are added to the sess | ||||
ion, | ||||
// and can add its own torrent_plugins. | ||||
struct TORRENT_EXPORT plugin | struct TORRENT_EXPORT plugin | |||
{ | { | |||
// hidden | ||||
virtual ~plugin() {} | virtual ~plugin() {} | |||
virtual boost::shared_ptr<torrent_plugin> new_torrent(torren | // this is called by the session every time a new torrent is | |||
t* t, void* user) | added. | |||
// The ``torrent*`` points to the internal torrent object cr | ||||
eated | ||||
// for the new torrent. The ``void*`` is the userdata pointe | ||||
r as | ||||
// passed in via add_torrent_params. | ||||
// | ||||
// If the plugin returns a torrent_plugin instance, it will | ||||
be added | ||||
// to the new torrent. Otherwise, return an empty shared_ptr | ||||
to a | ||||
// torrent_plugin (the default). | ||||
virtual boost::shared_ptr<torrent_plugin> new_torrent(torren | ||||
t*, void*) | ||||
{ return boost::shared_ptr<torrent_plugin>(); } | { return boost::shared_ptr<torrent_plugin>(); } | |||
// called when plugin is added to a session | // called when plugin is added to a session | |||
virtual void added(boost::weak_ptr<aux::session_impl> s) {} | virtual void added(aux::session_impl*) {} | |||
// called when an alert is posted | // called when an alert is posted | |||
// alerts that are filtered are not | // alerts that are filtered are not | |||
// posted | // posted | |||
virtual void on_alert(alert const* a) {} | virtual void on_alert(alert const*) {} | |||
// called once per second | // called once per second | |||
virtual void on_tick() {} | virtual void on_tick() {} | |||
// called when choosing peers to optimisticly unchoke | ||||
// peer's will be unchoked in the order they appear in the g | ||||
iven | ||||
// vector which is initiallity sorted by when they were last | ||||
// optimistically unchoked. | ||||
// if the plugin returns true then the ordering provided wil | ||||
l be | ||||
// used and no other plugin will be allowed to change it. | ||||
virtual bool on_optimistic_unchoke(std::vector<policy::peer* | ||||
>& /* peers */) | ||||
{ return false; } | ||||
// called when saving settings state | // called when saving settings state | |||
virtual void save_state(entry& ent) const {} | virtual void save_state(entry&) const {} | |||
// called when loading settings state | // called when loading settings state | |||
virtual void load_state(lazy_entry const& ent) {} | virtual void load_state(lazy_entry const&) {} | |||
}; | }; | |||
// Torrent plugins are associated with a single torrent and have a n | ||||
umber | ||||
// of functions called at certain events. Many of its functions have | ||||
the | ||||
// ability to change or override the default libtorrent behavior. | ||||
struct TORRENT_EXPORT torrent_plugin | struct TORRENT_EXPORT torrent_plugin | |||
{ | { | |||
// hidden | ||||
virtual ~torrent_plugin() {} | virtual ~torrent_plugin() {} | |||
// throwing an exception closes the connection | ||||
// returning a 0 pointer is valid and will not add | // This function is called each time a new peer is connected | |||
// the peer_plugin to the peer_connection | to the torrent. You | |||
// may choose to ignore this by just returning a default con | ||||
structed | ||||
// ``shared_ptr`` (in which case you don't need to override | ||||
this member | ||||
// function). | ||||
// | ||||
// If you need an extension to the peer connection (which mo | ||||
st plugins do) you | ||||
// are supposed to return an instance of your peer_plugin cl | ||||
ass. Which in | ||||
// turn will have its hook functions called on event specifi | ||||
c to that peer. | ||||
// | ||||
// The ``peer_connection`` will be valid as long as the ``sh | ||||
ared_ptr`` is being | ||||
// held by the torrent object. So, it is generally a good id | ||||
ea to not keep a | ||||
// ``shared_ptr`` to your own peer_plugin. If you want to ke | ||||
ep references to it, | ||||
// use ``weak_ptr``. | ||||
// | ||||
// If this function throws an exception, the connection will | ||||
be closed. | ||||
virtual boost::shared_ptr<peer_plugin> new_connection(peer_c onnection*) | virtual boost::shared_ptr<peer_plugin> new_connection(peer_c onnection*) | |||
{ return boost::shared_ptr<peer_plugin>(); } | { return boost::shared_ptr<peer_plugin>(); } | |||
virtual void on_piece_pass(int index) {} | // These hooks are called when a piece passes the hash check | |||
virtual void on_piece_failed(int index) {} | or fails the hash | |||
// check, respectively. The ``index`` is the piece index tha | ||||
t was downloaded. | ||||
// It is possible to access the list of peers that participa | ||||
ted in sending the | ||||
// piece through the ``torrent`` and the ``piece_picker``. | ||||
virtual void on_piece_pass(int /*index*/) {} | ||||
virtual void on_piece_failed(int /*index*/) {} | ||||
// called aproximately once every second | // This hook is called approximately once per second. It is | |||
a way of making it | ||||
// easy for plugins to do timed events, for sending messages | ||||
or whatever. | ||||
virtual void tick() {} | virtual void tick() {} | |||
// if true is returned, it means the handler handled the eve | // These hooks are called when the torrent is paused and unp | |||
nt, | aused respectively. | |||
// and no other plugins will have their handlers called, and | // The return value indicates if the event was handled. A re | |||
the | turn value of | |||
// default behavior will be skipped | // ``true`` indicates that it was handled, and no other plug | |||
in after this one | ||||
// will have this hook function called, and the standard han | ||||
dler will also not be | ||||
// invoked. So, returning true effectively overrides the sta | ||||
ndard behavior of | ||||
// pause or unpause. | ||||
// | ||||
// Note that if you call ``pause()`` or ``resume()`` on the | ||||
torrent from your | ||||
// handler it will recurse back into your handler, so in ord | ||||
er to invoke the | ||||
// standard handler, you have to keep your own state on whet | ||||
her you want standard | ||||
// behavior or overridden behavior. | ||||
virtual bool on_pause() { return false; } | virtual bool on_pause() { return false; } | |||
virtual bool on_resume() { return false; } | virtual bool on_resume() { return false; } | |||
// this is called when the initial checking of | // This function is called when the initial files of the tor | |||
// files is completed. | rent have been | |||
// checked. If there are no files to check, this function is | ||||
called immediately. | ||||
// | ||||
// i.e. This function is always called when the torrent is i | ||||
n a state where it | ||||
// can start downloading. | ||||
virtual void on_files_checked() {} | virtual void on_files_checked() {} | |||
// called when the torrent changes state | // called when the torrent changes state | |||
// the state is one of torrent_status::state_t | // the state is one of torrent_status::state_t | |||
// enum members | // enum members | |||
virtual void on_state(int s) {} | virtual void on_state(int /*s*/) {} | |||
// called every time policy::add_peer is called | ||||
// src is a bitmask of which sources this peer | ||||
// has been seen from. flags is a bitmask of: | ||||
enum flags_t { | enum flags_t { | |||
// this is the first time we see this peer | // this is the first time we see this peer | |||
first_time = 1, | first_time = 1, | |||
// this peer was not added because it was | // this peer was not added because it was | |||
// filtered by the IP filter | // filtered by the IP filter | |||
filtered = 2 | filtered = 2 | |||
}; | }; | |||
virtual void on_add_peer(tcp::endpoint const& ip | // called every time a new peer is added to the peer list. | |||
, int src, int flags) {} | // This is before the peer is connected to. For ``flags``, s | |||
ee | ||||
// torrent_plugin::flags_t. The ``source`` argument refers t | ||||
o | ||||
// the source where we learned about this peer from. It's a | ||||
// bitmask, because many sources may have told us about the | ||||
same | ||||
// peer. For peer source flags, see peer_info::peer_source_f | ||||
lags. | ||||
virtual void on_add_peer(tcp::endpoint const&, | ||||
int /*src*/, int /*flags*/) {} | ||||
}; | }; | |||
// peer plugins are associated with a specific peer. A peer could be | ||||
// both a regular bittorrent peer (``bt_peer_connection``) or one of | ||||
the | ||||
// web seed connections (``web_peer_connection`` or ``http_seed_conn | ||||
ection``). | ||||
// In order to only attach to certain peers, make your | ||||
// torrent_plugin::new_connection only return a plugin for certain p | ||||
eer | ||||
// connection types | ||||
struct TORRENT_EXPORT peer_plugin | struct TORRENT_EXPORT peer_plugin | |||
{ | { | |||
// hidden | ||||
virtual ~peer_plugin() {} | virtual ~peer_plugin() {} | |||
// This function is expected to return the name of | ||||
// the plugin. | ||||
virtual char const* type() const { return ""; } | virtual char const* type() const { return ""; } | |||
// can add entries to the extension handshake | // can add entries to the extension handshake | |||
// this is not called for web seeds | // this is not called for web seeds | |||
virtual void add_handshake(entry&) {} | virtual void add_handshake(entry&) {} | |||
// called when the peer is being disconnected. | ||||
virtual void on_disconnect(error_code const& /*ec*/) {} | ||||
// called when the peer is successfully connected. Note that | ||||
// incoming connections will have been connected by the time | ||||
// the peer plugin is attached to it, and won't have this ho | ||||
ok | ||||
// called. | ||||
virtual void on_connected() {} | ||||
// throwing an exception from any of the handlers (except ad d_handshake) | // throwing an exception from any of the handlers (except ad d_handshake) | |||
// closes the connection | // closes the connection | |||
// this is called when the initial BT handshake is received. Returning false | // this is called when the initial BT handshake is received. Returning false | |||
// means that the other end doesn't support this extension a nd will remove | // means that the other end doesn't support this extension a nd will remove | |||
// it from the list of plugins. | // it from the list of plugins. | |||
// this is not called for web seeds | // this is not called for web seeds | |||
virtual bool on_handshake(char const* reserved_bits) { retur n true; } | virtual bool on_handshake(char const* /*reserved_bits*/) { r eturn true; } | |||
// called when the extension handshake from the other end is received | // called when the extension handshake from the other end is received | |||
// if this returns false, it means that this extension isn't | // if this returns false, it means that this extension isn't | |||
// supported by this peer. It will result in this peer_plugi n | // supported by this peer. It will result in this peer_plugi n | |||
// being removed from the peer_connection and destructed. | // being removed from the peer_connection and destructed. | |||
// this is not called for web seeds | // this is not called for web seeds | |||
virtual bool on_extension_handshake(lazy_entry const& h) { r eturn true; } | virtual bool on_extension_handshake(lazy_entry const&) { ret urn true; } | |||
// returning true from any of the message handlers | // returning true from any of the message handlers | |||
// indicates that the plugin has handeled the message. | // indicates that the plugin has handeled the message. | |||
// it will break the plugin chain traversing and not let | // it will break the plugin chain traversing and not let | |||
// anyone else handle the message, including the default | // anyone else handle the message, including the default | |||
// handler. | // handler. | |||
virtual bool on_choke() { return false; } | ||||
virtual bool on_choke() | virtual bool on_unchoke() { return false; } | |||
{ return false; } | virtual bool on_interested() { return false; } | |||
virtual bool on_not_interested() { return false; } | ||||
virtual bool on_unchoke() | virtual bool on_have(int /*index*/) { return false; } | |||
{ return false; } | virtual bool on_dont_have(int /*index*/) { return false; } | |||
virtual bool on_bitfield(bitfield const& /*bitfield*/) { ret | ||||
virtual bool on_interested() | urn false; } | |||
{ return false; } | virtual bool on_have_all() { return false; } | |||
virtual bool on_have_none() { return false; } | ||||
virtual bool on_not_interested() | virtual bool on_allowed_fast(int /*index*/) { return false; | |||
{ return false; } | } | |||
virtual bool on_request(peer_request const&) { return false; | ||||
virtual bool on_have(int index) | } | |||
{ return false; } | virtual bool on_piece(peer_request const& /*piece*/ | |||
, disk_buffer_holder& /*data*/) { return false; } | ||||
virtual bool on_dont_have(int index) | virtual bool on_cancel(peer_request const&) { return false; | |||
{ return false; } | } | |||
virtual bool on_reject(peer_request const&) { return false; | ||||
virtual bool on_bitfield(bitfield const& bitfield) | } | |||
{ return false; } | virtual bool on_suggest(int /*index*/) { return false; } | |||
virtual bool on_have_all() | // called after a choke message has been sent to the peer | |||
{ return false; } | virtual void sent_unchoke() {} | |||
virtual bool on_have_none() | // called when libtorrent think this peer should be disconne | |||
{ return false; } | cted. | |||
// if the plugin returns false, the peer will not be disconn | ||||
virtual bool on_allowed_fast(int index) | ected. | |||
{ return false; } | virtual bool can_disconnect(error_code const& /*ec*/) { retu | |||
rn true; } | ||||
virtual bool on_request(peer_request const& req) | ||||
{ return false; } | ||||
virtual bool on_piece(peer_request const& piece, disk_buffer | ||||
_holder& data) | ||||
{ return false; } | ||||
virtual bool on_cancel(peer_request const& req) | ||||
{ return false; } | ||||
virtual bool on_reject(peer_request const& req) | ||||
{ return false; } | ||||
virtual bool on_suggest(int index) | ||||
{ return false; } | ||||
// called when an extended message is received. If returning true, | // called when an extended message is received. If returning true, | |||
// the message is not processed by any other plugin and if f alse | // the message is not processed by any other plugin and if f alse | |||
// is returned the next plugin in the chain will receive it to | // is returned the next plugin in the chain will receive it to | |||
// be able to handle it | // be able to handle it | |||
// this is not called for web seeds | // this is not called for web seeds | |||
virtual bool on_extended(int length | virtual bool on_extended(int /*length*/, int /*msg*/, | |||
, int msg, buffer::const_interval body) | buffer::const_interval /*body*/) | |||
{ return false; } | { return false; } | |||
// this is not called for web seeds | // this is not called for web seeds | |||
virtual bool on_unknown_message(int length, int msg | virtual bool on_unknown_message(int /*length*/, int /*msg*/, | |||
, buffer::const_interval body) | buffer::const_interval /*body*/) | |||
{ return false; } | { return false; } | |||
// called when a piece that this peer participated in either | // called when a piece that this peer participated in either | |||
// fails or passes the hash_check | // fails or passes the hash_check | |||
virtual void on_piece_pass(int index) {} | virtual void on_piece_pass(int /*index*/) {} | |||
virtual void on_piece_failed(int index) {} | virtual void on_piece_failed(int /*index*/) {} | |||
// called aproximately once every second | // called aproximately once every second | |||
virtual void tick() {} | virtual void tick() {} | |||
// called each time a request message is to be sent. If true | // called each time a request message is to be sent. If true | |||
// is returned, the original request message won't be sent a nd | // is returned, the original request message won't be sent a nd | |||
// no other plugin will have this function called. | // no other plugin will have this function called. | |||
virtual bool write_request(peer_request const& r) { return f alse; } | virtual bool write_request(peer_request const&) { return fal se; } | |||
}; | }; | |||
} | } | |||
#endif | #endif | |||
#endif // TORRENT_EXTENSIONS_HPP_INCLUDED | #endif // TORRENT_EXTENSIONS_HPP_INCLUDED | |||
End of changes. 32 change blocks. | ||||
82 lines changed or deleted | 346 lines changed or added | |||
file.hpp | file.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2003, Arvid Norberg | Copyright (c) 2003-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 111 | skipping to change at line 111 | |||
directory = 0040000, // directory | directory = 0040000, // directory | |||
block_special = 0060000, // block special | block_special = 0060000, // block special | |||
regular_file = 0100000, // regular | regular_file = 0100000, // regular | |||
link = 0120000, // symbolic link | link = 0120000, // symbolic link | |||
socket = 0140000 // socket | socket = 0140000 // socket | |||
#endif | #endif | |||
} modes_t; | } modes_t; | |||
int mode; | int mode; | |||
}; | }; | |||
enum stat_flags_t { dont_follow_links = 1 }; | // internal flags for stat_file | |||
TORRENT_EXPORT void stat_file(std::string f, file_status* s | enum { dont_follow_links = 1 }; | |||
TORRENT_EXTRA_EXPORT void stat_file(std::string f, file_status* s | ||||
, error_code& ec, int flags = 0); | , error_code& ec, int flags = 0); | |||
TORRENT_EXPORT void rename(std::string const& f | TORRENT_EXTRA_EXPORT void rename(std::string const& f | |||
, std::string const& newf, error_code& ec); | , std::string const& newf, error_code& ec); | |||
TORRENT_EXPORT void create_directories(std::string const& f | TORRENT_EXTRA_EXPORT void create_directories(std::string const& f | |||
, error_code& ec); | , error_code& ec); | |||
TORRENT_EXPORT void create_directory(std::string const& f | TORRENT_EXTRA_EXPORT void create_directory(std::string const& f | |||
, error_code& ec); | , error_code& ec); | |||
TORRENT_EXPORT void remove_all(std::string const& f | TORRENT_EXTRA_EXPORT void remove_all(std::string const& f | |||
, error_code& ec); | , error_code& ec); | |||
TORRENT_EXPORT void remove(std::string const& f, error_code& ec); | TORRENT_EXTRA_EXPORT void remove(std::string const& f, error_code& e | |||
TORRENT_EXPORT bool exists(std::string const& f); | c); | |||
TORRENT_EXPORT size_type file_size(std::string const& f); | TORRENT_EXTRA_EXPORT bool exists(std::string const& f); | |||
TORRENT_EXPORT bool is_directory(std::string const& f | TORRENT_EXTRA_EXPORT size_type file_size(std::string const& f); | |||
TORRENT_EXTRA_EXPORT bool is_directory(std::string const& f | ||||
, error_code& ec); | , error_code& ec); | |||
TORRENT_EXPORT void recursive_copy(std::string const& old_path | TORRENT_EXTRA_EXPORT void recursive_copy(std::string const& old_path | |||
, std::string const& new_path, error_code& ec); | , std::string const& new_path, error_code& ec); | |||
TORRENT_EXPORT void copy_file(std::string const& f | TORRENT_EXTRA_EXPORT void copy_file(std::string const& f | |||
, std::string const& newf, error_code& ec); | , std::string const& newf, error_code& ec); | |||
TORRENT_EXPORT std::string split_path(std::string const& f); | TORRENT_EXTRA_EXPORT std::string split_path(std::string const& f); | |||
TORRENT_EXPORT char const* next_path_element(char const* p); | TORRENT_EXTRA_EXPORT char const* next_path_element(char const* p); | |||
TORRENT_EXPORT std::string extension(std::string const& f); | TORRENT_EXTRA_EXPORT std::string extension(std::string const& f); | |||
TORRENT_EXPORT void replace_extension(std::string& f, std::string co | TORRENT_EXTRA_EXPORT std::string remove_extension(std::string const& | |||
nst& ext); | f); | |||
TORRENT_EXPORT bool is_root_path(std::string const& f); | TORRENT_EXTRA_EXPORT void replace_extension(std::string& f, std::str | |||
ing const& ext); | ||||
TORRENT_EXTRA_EXPORT bool is_root_path(std::string const& f); | ||||
// internal used by create_torrent.hpp | ||||
TORRENT_EXPORT std::string parent_path(std::string const& f); | TORRENT_EXPORT std::string parent_path(std::string const& f); | |||
TORRENT_EXPORT bool has_parent_path(std::string const& f); | TORRENT_EXTRA_EXPORT bool has_parent_path(std::string const& f); | |||
// internal used by create_torrent.hpp | ||||
TORRENT_EXPORT std::string filename(std::string const& f); | TORRENT_EXPORT std::string filename(std::string const& f); | |||
TORRENT_EXPORT std::string combine_path(std::string const& lhs | TORRENT_EXTRA_EXPORT std::string combine_path(std::string const& lhs | |||
, std::string const& rhs); | , std::string const& rhs); | |||
// internal used by create_torrent.hpp | ||||
TORRENT_EXPORT std::string complete(std::string const& f); | TORRENT_EXPORT std::string complete(std::string const& f); | |||
TORRENT_EXPORT bool is_complete(std::string const& f); | TORRENT_EXTRA_EXPORT bool is_complete(std::string const& f); | |||
TORRENT_EXPORT std::string current_working_directory(); | TORRENT_EXTRA_EXPORT std::string current_working_directory(); | |||
#if TORRENT_USE_UNC_PATHS | #if TORRENT_USE_UNC_PATHS | |||
TORRENT_EXTRA_EXPORT std::string canonicalize_path(std::string const & f); | TORRENT_EXTRA_EXPORT std::string canonicalize_path(std::string const & f); | |||
#endif | #endif | |||
class TORRENT_EXPORT directory : public boost::noncopyable | class TORRENT_EXTRA_EXPORT directory : public boost::noncopyable | |||
{ | { | |||
public: | public: | |||
directory(std::string const& path, error_code& ec); | directory(std::string const& path, error_code& ec); | |||
~directory(); | ~directory(); | |||
void next(error_code& ec); | void next(error_code& ec); | |||
std::string file() const; | std::string file() const; | |||
boost::uint64_t inode() const; | ||||
bool done() const { return m_done; } | bool done() const { return m_done; } | |||
private: | private: | |||
#ifdef TORRENT_WINDOWS | #ifdef TORRENT_WINDOWS | |||
HANDLE m_handle; | HANDLE m_handle; | |||
int m_inode; | ||||
#if TORRENT_USE_WSTRING | #if TORRENT_USE_WSTRING | |||
WIN32_FIND_DATAW m_fd; | WIN32_FIND_DATAW m_fd; | |||
#else | #else | |||
WIN32_FIND_DATAA m_fd; | WIN32_FIND_DATAA m_fd; | |||
#endif | #endif | |||
#else | #else | |||
DIR* m_handle; | DIR* m_handle; | |||
// the dirent struct contains a zero-sized | // the dirent struct contains a zero-sized | |||
// array at the end, it will end up referring | // array at the end, it will end up referring | |||
// to the m_name field | // to the m_name field | |||
struct dirent m_dirent; | struct dirent m_dirent; | |||
char m_name[TORRENT_MAX_PATH + 1]; // +1 to make room for nu ll | char m_name[TORRENT_MAX_PATH + 1]; // +1 to make room for nu ll | |||
#endif | #endif | |||
bool m_done; | bool m_done; | |||
}; | }; | |||
struct TORRENT_EXPORT file: boost::noncopyable, intrusive_ptr_base<f ile> | struct TORRENT_EXTRA_EXPORT file: boost::noncopyable, intrusive_ptr_ base<file> | |||
{ | { | |||
enum | // the open mode for files. Used for the file constructor or | |||
// file::open(). | ||||
enum open_mode_t | ||||
{ | { | |||
// when a file is opened with no_buffer | // open the file for reading only | |||
// file offsets have to be aligned to | ||||
// pos_alignment() and buffer addresses | ||||
// to buf_alignment() and read/write sizes | ||||
// to size_alignment() | ||||
read_only = 0, | read_only = 0, | |||
// open the file for writing only | ||||
write_only = 1, | write_only = 1, | |||
// open the file for reading and writing | ||||
read_write = 2, | read_write = 2, | |||
// the mask for the bits determining read or write m | ||||
ode | ||||
rw_mask = read_only | write_only | read_write, | rw_mask = read_only | write_only | read_write, | |||
// indicate that the file should be opened in | ||||
// *direct io* mode, i.e. bypassing the operating | ||||
// system's disk cache, or as much as possible of it | ||||
// depending on the system. | ||||
// when a file is opened with no_buffer, | ||||
// file offsets have to be aligned to | ||||
// pos_alignment() and buffer addresses | ||||
// to buf_alignment() and read/write sizes | ||||
// to size_alignment() | ||||
no_buffer = 4, | no_buffer = 4, | |||
// open the file in sparse mode (if supported by the | ||||
// filesystem). | ||||
sparse = 8, | sparse = 8, | |||
// don't update the access timestamps on the file (i | ||||
f | ||||
// supported by the operating system and filesystem) | ||||
. | ||||
// this generally improves disk performance. | ||||
no_atime = 16, | no_atime = 16, | |||
// open the file for random acces. This disables rea | ||||
d-ahead | ||||
// logic | ||||
random_access = 32, | random_access = 32, | |||
// prevent the file from being opened by another pro | ||||
cess | ||||
// while it's still being held open by this handle | ||||
lock_file = 64, | lock_file = 64, | |||
// when creating a file, set the hidden attribute (w indows only) | ||||
attribute_hidden = 0x1000, | attribute_hidden = 0x1000, | |||
// when creating a file, set the executable attribut | ||||
e | ||||
attribute_executable = 0x2000, | attribute_executable = 0x2000, | |||
// the mask of all attribute bits | ||||
attribute_mask = attribute_hidden | attribute_execut able | attribute_mask = attribute_hidden | attribute_execut able | |||
}; | }; | |||
#ifdef TORRENT_WINDOWS | #ifdef TORRENT_WINDOWS | |||
struct iovec_t | struct iovec_t | |||
{ | { | |||
void* iov_base; | void* iov_base; | |||
size_t iov_len; | size_t iov_len; | |||
}; | }; | |||
#else | #else | |||
End of changes. 31 change blocks. | ||||
31 lines changed or deleted | 79 lines changed or added | |||
file_pool.hpp | file_pool.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2006, Arvid Norberg | Copyright (c) 2006-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 54 | skipping to change at line 54 | |||
#endif | #endif | |||
#include <map> | #include <map> | |||
#include "libtorrent/file.hpp" | #include "libtorrent/file.hpp" | |||
#include "libtorrent/ptime.hpp" | #include "libtorrent/ptime.hpp" | |||
#include "libtorrent/thread.hpp" | #include "libtorrent/thread.hpp" | |||
#include "libtorrent/file_storage.hpp" | #include "libtorrent/file_storage.hpp" | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
// this is an internal cache of open file handles. It's primarily us | ||||
ed by | ||||
// storage_interface implementations. It provides semi weak guarante | ||||
es of | ||||
// not opening more file handles than specified. Given multiple thre | ||||
ads, | ||||
// each with the ability to lock a file handle (via smart pointer), | ||||
there | ||||
// may be windows where more file handles are open. | ||||
struct TORRENT_EXPORT file_pool : boost::noncopyable | struct TORRENT_EXPORT file_pool : boost::noncopyable | |||
{ | { | |||
// ``size`` specifies the number of allowed files handles | ||||
// to hold open at any given time. | ||||
file_pool(int size = 40); | file_pool(int size = 40); | |||
~file_pool(); | ~file_pool(); | |||
// return an open file handle to file at ``file_index`` in t | ||||
he | ||||
// file_storage ``fs`` opened at save path ``p``. ``m`` is t | ||||
he | ||||
// file open mode (see file::open_mode_t). | ||||
boost::intrusive_ptr<file> open_file(void* st, std::string c onst& p | boost::intrusive_ptr<file> open_file(void* st, std::string c onst& p | |||
, file_storage::iterator fe, file_storage const& fs, | , int file_index, file_storage const& fs, int m, err | |||
int m, error_code& ec); | or_code& ec); | |||
// release all files belonging to the specified storage_inte | ||||
rface (``st``) | ||||
// the overload that takes ``file_index`` releases only the | ||||
file with | ||||
// that index in storage ``st``. | ||||
void release(void* st); | void release(void* st); | |||
void release(void* st, int file_index); | void release(void* st, int file_index); | |||
// update the allowed number of open file handles to ``size` | ||||
`. | ||||
void resize(int size); | void resize(int size); | |||
// returns the current limit of number of allowed open file | ||||
handles held | ||||
// by the file_pool. | ||||
int size_limit() const { return m_size; } | int size_limit() const { return m_size; } | |||
// internal | ||||
void set_low_prio_io(bool b) { m_low_prio_io = b; } | void set_low_prio_io(bool b) { m_low_prio_io = b; } | |||
private: | private: | |||
void remove_oldest(); | void remove_oldest(); | |||
int m_size; | int m_size; | |||
bool m_low_prio_io; | bool m_low_prio_io; | |||
struct lru_file_entry | struct lru_file_entry | |||
End of changes. 8 change blocks. | ||||
3 lines changed or deleted | 34 lines changed or added | |||
file_storage.hpp | file_storage.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2003-2008, Arvid Norberg | Copyright (c) 2003-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 49 | skipping to change at line 49 | |||
#include "libtorrent/size_type.hpp" | #include "libtorrent/size_type.hpp" | |||
#include "libtorrent/assert.hpp" | #include "libtorrent/assert.hpp" | |||
#include "libtorrent/peer_request.hpp" | #include "libtorrent/peer_request.hpp" | |||
#include "libtorrent/peer_id.hpp" | #include "libtorrent/peer_id.hpp" | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
struct file; | struct file; | |||
// information about a file in a file_storage | ||||
struct TORRENT_EXPORT file_entry | struct TORRENT_EXPORT file_entry | |||
{ | { | |||
// hidden | ||||
file_entry(); | file_entry(); | |||
// hidden | ||||
~file_entry(); | ~file_entry(); | |||
// the full path of this file. The paths are unicode strings | ||||
// encoded in UTF-8. | ||||
std::string path; | std::string path; | |||
size_type offset; // the offset of this file inside the torr | ||||
ent | // the path which this is a symlink to, or empty if this is | |||
size_type size; // the size of this file | // not a symlink. This field is only used if the ``symlink_a | |||
// the offset in the file where the storage starts. | ttribute`` is set. | |||
// This is always 0 unless parts of the torrent is | std::string symlink_path; | |||
// compressed into a single file, such as a so-called part f | ||||
ile. | // the offset of this file inside the torrent | |||
size_type offset; | ||||
// the size of the file (in bytes) and ``offset`` is the byt | ||||
e offset | ||||
// of the file within the torrent. i.e. the sum of all the s | ||||
izes of the files | ||||
// before it in the list. | ||||
size_type size; | ||||
// the offset in the file where the storage should start. Th | ||||
e normal | ||||
// case is to have this set to 0, so that the storage starts | ||||
saving data at the start | ||||
// if the file. In cases where multiple files are mapped int | ||||
o the same file though, | ||||
// the ``file_base`` should be set to an offset so that the | ||||
different regions do | ||||
// not overlap. This is used when mapping "unselected" files | ||||
into a so-called part | ||||
// file. | ||||
size_type file_base; | size_type file_base; | |||
// the modification time of this file specified in posix tim | ||||
e. | ||||
std::time_t mtime; | std::time_t mtime; | |||
// a sha-1 hash of the content of the file, or zeroes, if no | ||||
// file hash was present in the torrent file. It can be used | ||||
to potentially | ||||
// find alternative sources for the file. | ||||
sha1_hash filehash; | sha1_hash filehash; | |||
// set to true for files that are not part of the data of th | ||||
e torrent. | ||||
// They are just there to make sure the next file is aligned | ||||
to a particular byte offset | ||||
// or piece boundry. These files should typically be hidden | ||||
from an end user. They are | ||||
// not written to disk. | ||||
bool pad_file:1; | bool pad_file:1; | |||
// true if the file was marked as hidden (on windows). | ||||
bool hidden_attribute:1; | bool hidden_attribute:1; | |||
// true if the file was marked as executable (posix) | ||||
bool executable_attribute:1; | bool executable_attribute:1; | |||
// true if the file was a symlink. If this is the case | ||||
// the ``symlink_index`` refers to a string which specifies | ||||
the original location | ||||
// where the data for this file was found. | ||||
bool symlink_attribute:1; | bool symlink_attribute:1; | |||
std::string symlink_path; | ||||
}; | }; | |||
// this is used internally to hold the file entry | // only export this type if deprecated functions are enabled | |||
// it's smaller and optimized for smaller memory | #ifdef TORRENT_NO_DEPRECATED | |||
// footprint, as opposed to file_entry, which is | #define TORRENT_DEPRECATED_EXPORT | |||
// optimized for convenience | #else | |||
struct TORRENT_EXPORT internal_file_entry | #define TORRENT_DEPRECATED_EXPORT TORRENT_EXPORT | |||
#endif | ||||
// internal | ||||
struct TORRENT_DEPRECATED_EXPORT internal_file_entry | ||||
{ | { | |||
friend class file_storage; | friend class file_storage; | |||
#ifdef TORRENT_DEBUG | #ifdef TORRENT_DEBUG | |||
// for torrent_info::invariant_check | // for torrent_info::invariant_check | |||
friend class torrent_info; | friend class torrent_info; | |||
#endif | #endif | |||
enum { no_symlink_idx = 0xffff }; | ||||
internal_file_entry() | internal_file_entry() | |||
: name(0) | : offset(0) | |||
, offset(0) | , symlink_index(not_a_symlink) | |||
, symlink_index(no_symlink_idx) | , no_root_dir(false) | |||
, size(0) | , size(0) | |||
, name_len(0) | , name_len(name_is_owned) | |||
, pad_file(false) | , pad_file(false) | |||
, hidden_attribute(false) | , hidden_attribute(false) | |||
, executable_attribute(false) | , executable_attribute(false) | |||
, symlink_attribute(false) | , symlink_attribute(false) | |||
, no_root_dir(false) | , name(NULL) | |||
, path_index(-1) | , path_index(-1) | |||
{} | {} | |||
internal_file_entry(file_entry const& e) | internal_file_entry(file_entry const& e) | |||
: name(0) | : offset(e.offset) | |||
, offset(e.offset) | , symlink_index(not_a_symlink) | |||
, symlink_index(no_symlink_idx) | , no_root_dir(false) | |||
, size(e.size) | , size(e.size) | |||
, name_len(0) | , name_len(name_is_owned) | |||
, pad_file(e.pad_file) | , pad_file(e.pad_file) | |||
, hidden_attribute(e.hidden_attribute) | , hidden_attribute(e.hidden_attribute) | |||
, executable_attribute(e.executable_attribute) | , executable_attribute(e.executable_attribute) | |||
, symlink_attribute(e.symlink_attribute) | , symlink_attribute(e.symlink_attribute) | |||
, no_root_dir(false) | , name(NULL) | |||
, path_index(-1) | , path_index(-1) | |||
{ | { | |||
set_name(e.path.c_str()); | set_name(e.path.c_str()); | |||
} | } | |||
internal_file_entry(internal_file_entry const& fe); | internal_file_entry(internal_file_entry const& fe); | |||
internal_file_entry& operator=(internal_file_entry const& fe ); | internal_file_entry& operator=(internal_file_entry const& fe ); | |||
~internal_file_entry(); | ~internal_file_entry(); | |||
void set_name(char const* n, int borrow_chars = 0); | void set_name(char const* n, bool borrow_string = false, int string_len = 0); | |||
std::string filename() const; | std::string filename() const; | |||
// make it available for logging | enum { | |||
#if !defined TORRENT_VERBOSE_LOGGING \ | name_is_owned = (1<<12)-1, | |||
&& !defined TORRENT_LOGGING \ | not_a_symlink = (1<<15)-1 | |||
&& !defined TORRENT_ERROR_LOGGING | }; | |||
private: | ||||
#endif | ||||
// This string is not necessarily null terminated! | ||||
// that's why it's private, to keep people away from it | ||||
char const* name; | ||||
public: | ||||
// the offset of this file inside the torrent | // the offset of this file inside the torrent | |||
boost::uint64_t offset:48; | boost::uint64_t offset:48; | |||
// index into file_storage::m_symlinks or -1 | // index into file_storage::m_symlinks or not_a_symlink | |||
// if this is not a symlink | // if this is not a symlink | |||
boost::uint64_t symlink_index:16; | boost::uint64_t symlink_index:15; | |||
// if this is true, don't include m_name as part of the | ||||
// path to this file | ||||
boost::uint64_t no_root_dir:1; | ||||
// the size of this file | // the size of this file | |||
boost::uint64_t size:48; | boost::uint64_t size:48; | |||
// the number of characters in the name. If this is | // the number of characters in the name. If this is | |||
// 0, name is null terminated and owned by this object | // name_is_owned, name is null terminated and owned by this object | |||
// (i.e. it should be freed in the destructor). If | // (i.e. it should be freed in the destructor). If | |||
// the len is > 0, the name pointer doesn not belong | // the len is not name_is_owned, the name pointer doesn not belong | |||
// to this object, and it's not null terminated | // to this object, and it's not null terminated | |||
size_type name_len:10; | boost::uint64_t name_len:12; | |||
bool pad_file:1; | boost::uint64_t pad_file:1; | |||
bool hidden_attribute:1; | boost::uint64_t hidden_attribute:1; | |||
bool executable_attribute:1; | boost::uint64_t executable_attribute:1; | |||
bool symlink_attribute:1; | boost::uint64_t symlink_attribute:1; | |||
// if this is true, don't include m_name as part of the | // make it available for logging | |||
// path to this file | private: | |||
boost::uint64_t no_root_dir:1; | // This string is not necessarily null terminated! | |||
// that's why it's private, to keep people away from it | ||||
char const* name; | ||||
public: | ||||
// the index into file_storage::m_paths. To get | // the index into file_storage::m_paths. To get | |||
// the full path to this file, concatenate the path | // the full path to this file, concatenate the path | |||
// from that array with the 'name' field in | // from that array with the 'name' field in | |||
// this struct | // this struct | |||
// values for path_index include: | // values for path_index include: | |||
// -1 means no path (i.e. single file torrent) | // -1 means no path (i.e. single file torrent) | |||
// -2, it means the filename | ||||
// in this field contains the full, absolute path | ||||
// to the file | ||||
int path_index; | int path_index; | |||
}; | }; | |||
// represents a window of a file in a torrent. | ||||
// | ||||
// The ``file_index`` refers to the index of the file (in the torren | ||||
t_info). | ||||
// To get the path and filename, use ``file_at()`` and give the ``fi | ||||
le_index`` | ||||
// as argument. The ``offset`` is the byte offset in the file where | ||||
the range | ||||
// starts, and ``size`` is the number of bytes this range is. The si | ||||
ze + offset | ||||
// will never be greater than the file size. | ||||
struct TORRENT_EXPORT file_slice | struct TORRENT_EXPORT file_slice | |||
{ | { | |||
// the index of the file | ||||
int file_index; | int file_index; | |||
// the offset from the start of the file, in bytes | ||||
size_type offset; | size_type offset; | |||
// the size of the window, in bytes | ||||
size_type size; | size_type size; | |||
}; | }; | |||
// The ``file_storage`` class represents a file list and the piece | ||||
// size. Everything necessary to interpret a regular bittorrent stor | ||||
age | ||||
// file structure. | ||||
class TORRENT_EXPORT file_storage | class TORRENT_EXPORT file_storage | |||
{ | { | |||
friend class torrent_info; | friend class torrent_info; | |||
public: | public: | |||
// hidden | ||||
file_storage(); | file_storage(); | |||
// hidden | ||||
~file_storage() {} | ~file_storage() {} | |||
// returns true if the piece length has been initialized | ||||
// on the file_storage. This is typically taken as a proxy | ||||
// of whether the file_storage as a whole is initialized or | ||||
// not. | ||||
bool is_valid() const { return m_piece_length > 0; } | bool is_valid() const { return m_piece_length > 0; } | |||
// file attribute flags | ||||
enum flags_t | enum flags_t | |||
{ | { | |||
// the file is a pad file. It's required to contain | ||||
zeroes | ||||
// at it will not be saved to disk. Its purpose is t | ||||
o make | ||||
// the following file start on a piece boundary. | ||||
pad_file = 1, | pad_file = 1, | |||
// this file has the hidden attribute set. This is p | ||||
rimarily | ||||
// a windows attribute | ||||
attribute_hidden = 2, | attribute_hidden = 2, | |||
// this file has the executable attribute set. | ||||
attribute_executable = 4, | attribute_executable = 4, | |||
// this file is a symbilic link. It should have a li | ||||
nk | ||||
// target string associated with it. | ||||
attribute_symlink = 8 | attribute_symlink = 8 | |||
}; | }; | |||
// allocates space for ``num_files`` in the internal file li | ||||
st. This can | ||||
// be used to avoid reallocating the internal file list when | ||||
the number | ||||
// of files to be added is known up-front. | ||||
void reserve(int num_files); | void reserve(int num_files); | |||
// Adds a file to the file storage. The ``flags`` argument s | ||||
ets attributes on the file. | ||||
// The file attributes is an extension and may not work in a | ||||
ll bittorrent clients. | ||||
// | ||||
// For possible file attributes, see file_storage::flags_t. | ||||
// | ||||
// If more files than one are added, certain restrictions to | ||||
their paths apply. | ||||
// In a multi-file file storage (torrent), all files must sh | ||||
are the same root directory. | ||||
// | ||||
// That is, the first path element of all files must be the | ||||
same. | ||||
// This shared path element is also set to the name of the t | ||||
orrent. It | ||||
// can be changed by calling ``set_name``. | ||||
// | ||||
// The built in functions to traverse a directory to add fil | ||||
es will | ||||
// make sure this requirement is fulfilled. | ||||
void add_file(file_entry const& e, char const* filehash = 0) ; | void add_file(file_entry const& e, char const* filehash = 0) ; | |||
void add_file(std::string const& p, size_type size, int flag s = 0 | void add_file(std::string const& p, size_type size, int flag s = 0 | |||
, std::time_t mtime = 0, std::string const& s_p = "" ); | , std::time_t mtime = 0, std::string const& s_p = "" ); | |||
// renames the file at ``index`` to ``new_filename``. Keep i | ||||
n mind | ||||
// that filenames are expected to be UTF-8 encoded. | ||||
void rename_file(int index, std::string const& new_filename) ; | void rename_file(int index, std::string const& new_filename) ; | |||
// this is a low-level function that sets the name of a file | ||||
// by making it reference a buffer that is not owned by the | ||||
file_storage. | ||||
// it's an optimization used when loading .torrent files, to | ||||
not | ||||
// duplicate names in memory. | ||||
void rename_file_borrow(int index, char const* new_filename, | ||||
int len); | ||||
#if TORRENT_USE_WSTRING | #if TORRENT_USE_WSTRING | |||
// all wstring APIs are deprecated since 0.16.11 | // all wstring APIs are deprecated since 0.16.11 | |||
// instead, use the wchar -> utf8 conversion functions | // instead, use the wchar -> utf8 conversion functions | |||
// and pass in utf8 strings | // and pass in utf8 strings | |||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
void add_file(std::wstring const& p, size_type size, int fla gs = 0 | void add_file(std::wstring const& p, size_type size, int fla gs = 0 | |||
, std::time_t mtime = 0, std::string const& s_p = "" ) TORRENT_DEPRECATED; | , std::time_t mtime = 0, std::string const& s_p = "" ) TORRENT_DEPRECATED; | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
void rename_file(int index, std::wstring const& new_filename ) TORRENT_DEPRECATED; | void rename_file(int index, std::wstring const& new_filename ) TORRENT_DEPRECATED; | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
void set_name(std::wstring const& n) TORRENT_DEPRECATED; | void set_name(std::wstring const& n) TORRENT_DEPRECATED; | |||
void rename_file_deprecated(int index, std::wstring const& n | ||||
ew_filename); | ||||
#endif // TORRENT_NO_DEPRECATE | #endif // TORRENT_NO_DEPRECATE | |||
#endif // TORRENT_USE_WSTRING | #endif // TORRENT_USE_WSTRING | |||
// returns a list of file_slice objects representing the por | ||||
tions of | ||||
// files the specified piece index, byte offset and size ran | ||||
ge overlaps. | ||||
// this is the inverse mapping of map_file(). | ||||
std::vector<file_slice> map_block(int piece, size_type offse t | std::vector<file_slice> map_block(int piece, size_type offse t | |||
, int size) const; | , int size) const; | |||
// returns a peer_request representing the piece index, byte | ||||
offset | ||||
// and size the specified file range overlaps. This is the i | ||||
nverse | ||||
// mapping ove map_block(). | ||||
peer_request map_file(int file, size_type offset, int size) const; | peer_request map_file(int file, size_type offset, int size) const; | |||
#ifndef TORRENT_NO_DEPRECATE | ||||
// all functions depending on internal_file_entry | ||||
// were deprecated in 1.0. Use the variants that take an | ||||
// index instead | ||||
typedef std::vector<internal_file_entry>::const_iterator ite rator; | typedef std::vector<internal_file_entry>::const_iterator ite rator; | |||
typedef std::vector<internal_file_entry>::const_reverse_iter ator reverse_iterator; | typedef std::vector<internal_file_entry>::const_reverse_iter ator reverse_iterator; | |||
iterator file_at_offset(size_type offset) const; | TORRENT_DEPRECATED_PREFIX | |||
iterator begin() const { return m_files.begin(); } | iterator file_at_offset(size_type offset) const TORRENT_DEPR | |||
iterator end() const { return m_files.end(); } | ECATED; | |||
reverse_iterator rbegin() const { return m_files.rbegin(); } | TORRENT_DEPRECATED_PREFIX | |||
reverse_iterator rend() const { return m_files.rend(); } | iterator begin() const TORRENT_DEPRECATED { return m_files.b | |||
int num_files() const | egin(); } | |||
{ return int(m_files.size()); } | TORRENT_DEPRECATED_PREFIX | |||
iterator end() const TORRENT_DEPRECATED { return m_files.end | ||||
file_entry at(int index) const; | (); } | |||
file_entry at(iterator i) const; | TORRENT_DEPRECATED_PREFIX | |||
internal_file_entry const& internal_at(int index) const | reverse_iterator rbegin() const TORRENT_DEPRECATED { return | |||
m_files.rbegin(); } | ||||
TORRENT_DEPRECATED_PREFIX | ||||
reverse_iterator rend() const TORRENT_DEPRECATED { return m_ | ||||
files.rend(); } | ||||
TORRENT_DEPRECATED_PREFIX | ||||
internal_file_entry const& internal_at(int index) const TORR | ||||
ENT_DEPRECATED | ||||
{ | { | |||
TORRENT_ASSERT(index >= 0); | TORRENT_ASSERT(index >= 0); | |||
TORRENT_ASSERT(index < int(m_files.size())); | TORRENT_ASSERT(index < int(m_files.size())); | |||
return m_files[index]; | return m_files[index]; | |||
} | } | |||
TORRENT_DEPRECATED_PREFIX | ||||
file_entry at(iterator i) const TORRENT_DEPRECATED; | ||||
iterator begin_deprecated() const { return m_files.begin(); | ||||
} | ||||
iterator end_deprecated() const { return m_files.end(); } | ||||
reverse_iterator rbegin_deprecated() const { return m_files. | ||||
rbegin(); } | ||||
reverse_iterator rend_deprecated() const { return m_files.re | ||||
nd(); } | ||||
iterator file_at_offset_deprecated(size_type offset) const; | ||||
#endif // TORRENT_NO_DEPRECATE | ||||
// returns the number of files in the file_storage | ||||
int num_files() const | ||||
{ return int(m_files.size()); } | ||||
// returns a file_entry with information about the file | ||||
// at ``index``. Index must be in the range [0, ``num_files( | ||||
)`` ). | ||||
file_entry at(int index) const; | ||||
// returns the total number of bytes all the files in this t | ||||
orrent spans | ||||
size_type total_size() const { return m_total_size; } | size_type total_size() const { return m_total_size; } | |||
// set and get the number of pieces in the torrent | ||||
void set_num_pieces(int n) { m_num_pieces = n; } | void set_num_pieces(int n) { m_num_pieces = n; } | |||
int num_pieces() const { TORRENT_ASSERT(m_piece_length > 0); return m_num_pieces; } | int num_pieces() const { TORRENT_ASSERT(m_piece_length > 0); return m_num_pieces; } | |||
// set and get the size of each piece in this torrent. This | ||||
size is typically an even power | ||||
// of 2. It doesn't have to be though. It should be divisibl | ||||
e by 16kiB however. | ||||
void set_piece_length(int l) { m_piece_length = l; } | void set_piece_length(int l) { m_piece_length = l; } | |||
int piece_length() const { TORRENT_ASSERT(m_piece_length > 0 ); return m_piece_length; } | int piece_length() const { TORRENT_ASSERT(m_piece_length > 0 ); return m_piece_length; } | |||
// returns the piece size of ``index``. This will be the sam | ||||
e as piece_length(), except | ||||
// for the last piece, which may be shorter. | ||||
int piece_size(int index) const; | int piece_size(int index) const; | |||
// set and get the name of this torrent. For multi-file torr | ||||
ents, this is also | ||||
// the name of the root directory all the files are stored i | ||||
n. | ||||
void set_name(std::string const& n) { m_name = n; } | void set_name(std::string const& n) { m_name = n; } | |||
const std::string& name() const { return m_name; } | const std::string& name() const { return m_name; } | |||
// swap all content of *this* with *ti*. | ||||
void swap(file_storage& ti) | void swap(file_storage& ti) | |||
{ | { | |||
using std::swap; | using std::swap; | |||
swap(ti.m_files, m_files); | swap(ti.m_files, m_files); | |||
swap(ti.m_file_hashes, m_file_hashes); | swap(ti.m_file_hashes, m_file_hashes); | |||
swap(ti.m_symlinks, m_symlinks); | swap(ti.m_symlinks, m_symlinks); | |||
swap(ti.m_mtime, m_mtime); | swap(ti.m_mtime, m_mtime); | |||
swap(ti.m_file_base, m_file_base); | swap(ti.m_file_base, m_file_base); | |||
swap(ti.m_paths, m_paths); | swap(ti.m_paths, m_paths); | |||
swap(ti.m_name, m_name); | swap(ti.m_name, m_name); | |||
swap(ti.m_total_size, m_total_size); | swap(ti.m_total_size, m_total_size); | |||
swap(ti.m_num_pieces, m_num_pieces); | swap(ti.m_num_pieces, m_num_pieces); | |||
swap(ti.m_piece_length, m_piece_length); | swap(ti.m_piece_length, m_piece_length); | |||
} | } | |||
// if pad_file_limit >= 0, files larger than | // if pad_file_limit >= 0, files larger than that limit will | |||
// that limit will be padded, default is to | be padded, | |||
// not add any padding | // default is to not add any padding (-1). The alignment spe | |||
void optimize(int pad_file_limit = -1); | cifies the | |||
// alignment files should be padded to. This defaults to the | ||||
piece size | ||||
// (-1) but it may also make sense to set it to 16 kiB, or s | ||||
omething | ||||
// divisible by 16 kiB. | ||||
// If pad_file_limit is 0, every file will be padded (except | ||||
empty ones). | ||||
void optimize(int pad_file_limit = -1, int alignment = -1); | ||||
// These functions are used to query attributes of files at | ||||
// a given index. | ||||
// | ||||
// The ``file_hash()`` is a sha-1 hash of the file, or 0 if | ||||
none was | ||||
// provided in the torrent file. This can potentially be use | ||||
d to | ||||
// join a bittorrent network with other file sharing network | ||||
s. | ||||
// | ||||
// The ``mtime()`` is the modification time is the posix | ||||
// time when a file was last modified when the torrent | ||||
// was created, or 0 if it was not included in the torrent f | ||||
ile. | ||||
// | ||||
// ``file_path()`` returns the full path to a file. | ||||
// | ||||
// ``file_size()`` returns the size of a file. | ||||
// | ||||
// ``pad_file_at()`` returns true if the file at the given | ||||
// index is a pad-file. | ||||
// | ||||
// ``file_name()`` returns *just* the name of the file, wher | ||||
eas | ||||
// ``file_path()`` returns the path (inside the torrent file | ||||
) with | ||||
// the filename appended. | ||||
// | ||||
// ``file_offset()`` returns the byte offset within the torr | ||||
ent file | ||||
// where this file starts. It can be used to map the file to | ||||
a piece | ||||
// index (given the piece size). | ||||
sha1_hash hash(int index) const; | sha1_hash hash(int index) const; | |||
std::string const& symlink(int index) const; | std::string const& symlink(int index) const; | |||
time_t mtime(int index) const; | time_t mtime(int index) const; | |||
int file_index(int index) const; | std::string file_path(int index, std::string const& save_pat | |||
h = "") const; | ||||
std::string file_name(int index) const; | ||||
size_type file_size(int index) const; | ||||
bool pad_file_at(int index) const; | ||||
size_type file_offset(int index) const; | ||||
// flags indicating various attributes for files in | ||||
// a file_storage. | ||||
enum file_flags_t | ||||
{ | ||||
// this file is a pad file. The creator of the | ||||
// torrent promises the file is entirely filled with | ||||
// zeroes and does not need to be downloaded. The | ||||
// purpose is just to align the next file to either | ||||
// a block or piece boundary. | ||||
flag_pad_file = 1, | ||||
// this file is hiddent (sets the hidden attribute | ||||
// on windows) | ||||
flag_hidden = 2, | ||||
// this file is executable (sets the executable bit | ||||
// on posix like systems) | ||||
flag_executable = 4, | ||||
// this file is a symlink. The symlink target is | ||||
// specified in a separate field | ||||
flag_symlink = 8 | ||||
}; | ||||
// returns a bitmask of flags from file_flags_t that apply | ||||
// to file at ``index``. | ||||
int file_flags(int index) const; | ||||
// The file base of a file is the offset within the file on | ||||
the filsystem | ||||
// where it starts to write. For the most part, this is alwa | ||||
ys 0. It's | ||||
// possible to map several files (in the torrent) into a sin | ||||
gle file on | ||||
// the filesystem by making them all point to the same filen | ||||
ame, but with | ||||
// different file bases, so that they don't overlap. | ||||
// torrent_info::remap_files() can be used to use a new file | ||||
layout. | ||||
size_type file_base(int index) const; | size_type file_base(int index) const; | |||
void set_file_base(int index, size_type off); | void set_file_base(int index, size_type off); | |||
std::string file_path(int index) const; | ||||
size_type file_size(int index) const; | ||||
std::string file_name(int index) const; | ||||
sha1_hash hash(internal_file_entry const& fe) const; | // returns the index of the file at the given offset in the | |||
std::string const& symlink(internal_file_entry const& fe) co | torrent | |||
nst; | int file_index_at_offset(size_type offset) const; | |||
time_t mtime(internal_file_entry const& fe) const; | ||||
int file_index(internal_file_entry const& fe) const; | // low-level function. returns a pointer to the internal sto | |||
size_type file_base(internal_file_entry const& fe) const; | rage for | |||
void set_file_base(internal_file_entry const& fe, size_type | // the filename. This string may not be null terinated! | |||
off); | // the ``file_name_len()`` function returns the length of th | |||
std::string file_path(internal_file_entry const& fe) const; | e filename. | |||
size_type file_size(internal_file_entry const& fe) const; | char const* file_name_ptr(int index) const; | |||
int file_name_len(int index) const; | ||||
#if !defined TORRENT_VERBOSE_LOGGING \ | ||||
&& !defined TORRENT_LOGGING \ | #ifndef TORRENT_NO_DEPRECATE | |||
&& !defined TORRENT_ERROR_LOGGING | // these were deprecated in 1.0. Use the versions that take | |||
private: | an index instead | |||
TORRENT_DEPRECATED_PREFIX | ||||
sha1_hash hash(internal_file_entry const& fe) const TORRENT_ | ||||
DEPRECATED; | ||||
TORRENT_DEPRECATED_PREFIX | ||||
std::string const& symlink(internal_file_entry const& fe) co | ||||
nst TORRENT_DEPRECATED; | ||||
TORRENT_DEPRECATED_PREFIX | ||||
time_t mtime(internal_file_entry const& fe) const TORRENT_DE | ||||
PRECATED; | ||||
TORRENT_DEPRECATED_PREFIX | ||||
int file_index(internal_file_entry const& fe) const TORRENT_ | ||||
DEPRECATED; | ||||
TORRENT_DEPRECATED_PREFIX | ||||
size_type file_base(internal_file_entry const& fe) const TOR | ||||
RENT_DEPRECATED; | ||||
TORRENT_DEPRECATED_PREFIX | ||||
void set_file_base(internal_file_entry const& fe, size_type | ||||
off) TORRENT_DEPRECATED; | ||||
TORRENT_DEPRECATED_PREFIX | ||||
std::string file_path(internal_file_entry const& fe, std::st | ||||
ring const& save_path = "") const TORRENT_DEPRECATED; | ||||
TORRENT_DEPRECATED_PREFIX | ||||
std::string file_name(internal_file_entry const& fe) const T | ||||
ORRENT_DEPRECATED; | ||||
TORRENT_DEPRECATED_PREFIX | ||||
size_type file_size(internal_file_entry const& fe) const TOR | ||||
RENT_DEPRECATED; | ||||
TORRENT_DEPRECATED_PREFIX | ||||
bool pad_file_at(internal_file_entry const& fe) const TORREN | ||||
T_DEPRECATED; | ||||
TORRENT_DEPRECATED_PREFIX | ||||
size_type file_offset(internal_file_entry const& fe) const T | ||||
ORRENT_DEPRECATED; | ||||
#endif | #endif | |||
private: | ||||
void update_path_index(internal_file_entry& e); | void update_path_index(internal_file_entry& e); | |||
void reorder_file(int index, int dst); | void reorder_file(int index, int dst); | |||
// the list of files that this torrent consists of | // the list of files that this torrent consists of | |||
std::vector<internal_file_entry> m_files; | std::vector<internal_file_entry> m_files; | |||
// if there are sha1 hashes for each individual file | // if there are sha1 hashes for each individual file | |||
// there are as many entries in this array as the | // there are as many entries in this array as the | |||
// m_files array. Each entry in m_files has a corresponding | // m_files array. Each entry in m_files has a corresponding | |||
// hash pointer in this array. The reason to split it up | // hash pointer in this array. The reason to split it up | |||
End of changes. 65 change blocks. | ||||
84 lines changed or deleted | 401 lines changed or added | |||
find_data.hpp | find_data.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2006, Arvid Norberg & Daniel Wallin | Copyright (c) 2006-2014, Arvid Norberg & Daniel Wallin | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 60 | skipping to change at line 60 | |||
namespace libtorrent { namespace dht | namespace libtorrent { namespace dht | |||
{ | { | |||
typedef std::vector<char> packet_t; | typedef std::vector<char> packet_t; | |||
class rpc_manager; | class rpc_manager; | |||
class node_impl; | class node_impl; | |||
// -------- find data ----------- | // -------- find data ----------- | |||
//TODO: rename this to find_peers | struct find_data : traversal_algorithm | |||
class find_data : public traversal_algorithm | ||||
{ | { | |||
public: | typedef boost::function<void(std::vector<std::pair<node_entry, std:: | |||
typedef boost::function<void(std::vector<tcp::endpoint> const&)> dat | string> > const&)> nodes_callback; | |||
a_callback; | ||||
typedef boost::function<void(std::vector<std::pair<node_entry, std:: | find_data(node_impl& node, node_id target | |||
string> > const&, bool)> nodes_callback; | , nodes_callback const& ncallback); | |||
void got_peers(std::vector<tcp::endpoint> const& peers); | ||||
void got_write_token(node_id const& n, std::string const& write_toke n); | void got_write_token(node_id const& n, std::string const& write_toke n); | |||
find_data(node_impl& node, node_id target | virtual void start(); | |||
, data_callback const& dcallback | ||||
, nodes_callback const& ncallback | ||||
, bool noseeds); | ||||
virtual char const* name() const { return "get_peers"; } | virtual char const* name() const; | |||
node_id const target() const { return m_target; } | node_id const target() const { return m_target; } | |||
protected: | protected: | |||
void done(); | virtual void done(); | |||
observer_ptr new_observer(void* ptr, udp::endpoint const& ep, node_i | virtual observer_ptr new_observer(void* ptr, udp::endpoint const& ep | |||
d const& id); | , node_id const& id); | |||
virtual bool invoke(observer_ptr o); | ||||
private: | ||||
data_callback m_data_callback; | ||||
nodes_callback m_nodes_callback; | nodes_callback m_nodes_callback; | |||
std::map<node_id, std::string> m_write_tokens; | std::map<node_id, std::string> m_write_tokens; | |||
node_id const m_target; | bool m_done; | |||
bool m_done:1; | ||||
bool m_got_peers:1; | ||||
bool m_noseeds:1; | ||||
}; | }; | |||
class find_data_observer : public observer | struct find_data_observer : traversal_observer | |||
{ | { | |||
public: | ||||
find_data_observer( | find_data_observer( | |||
boost::intrusive_ptr<traversal_algorithm> const& algorithm | boost::intrusive_ptr<traversal_algorithm> const& algorithm | |||
, udp::endpoint const& ep, node_id const& id) | , udp::endpoint const& ep, node_id const& id) | |||
: observer(algorithm, ep, id) | : traversal_observer(algorithm, ep, id) | |||
{} | {} | |||
void reply(msg const&); | ||||
virtual void reply(msg const&); | ||||
}; | }; | |||
} } // namespace libtorrent::dht | } } // namespace libtorrent::dht | |||
#endif // FIND_DATA_050323_HPP | #endif // FIND_DATA_050323_HPP | |||
End of changes. 13 change blocks. | ||||
29 lines changed or deleted | 17 lines changed or added | |||
fingerprint.hpp | fingerprint.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2003, Arvid Norberg | Copyright (c) 2003-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 46 | skipping to change at line 46 | |||
#include <string> | #include <string> | |||
#include <cstdio> | #include <cstdio> | |||
#include "libtorrent/config.hpp" | #include "libtorrent/config.hpp" | |||
#include "libtorrent/peer_id.hpp" | #include "libtorrent/peer_id.hpp" | |||
#include "libtorrent/assert.hpp" | #include "libtorrent/assert.hpp" | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
// The fingerprint class represents information about a client and i | ||||
ts version. It is used | ||||
// to encode this information into the client's peer id. | ||||
struct fingerprint | struct fingerprint | |||
{ | { | |||
// The constructor takes a ``char const*`` that should point | ||||
to a string constant containing | ||||
// exactly two characters. These are the characters that sho | ||||
uld be unique for your client. Make | ||||
// sure not to clash with anybody else. Here are some taken | ||||
id's: | ||||
// | ||||
// +----------+-----------------------+ | ||||
// | id chars | client | | ||||
// +==========+=======================+ | ||||
// | 'AZ' | Azureus | | ||||
// +----------+-----------------------+ | ||||
// | 'LT' | libtorrent (default) | | ||||
// +----------+-----------------------+ | ||||
// | 'BX' | BittorrentX | | ||||
// +----------+-----------------------+ | ||||
// | 'MT' | Moonlight Torrent | | ||||
// +----------+-----------------------+ | ||||
// | 'TS' | Torrent Storm | | ||||
// +----------+-----------------------+ | ||||
// | 'SS' | Swarm Scope | | ||||
// +----------+-----------------------+ | ||||
// | 'XT' | Xan Torrent | | ||||
// +----------+-----------------------+ | ||||
// | ||||
// There's an informal directory of client id's here_. | ||||
// | ||||
// .. _here: http://wiki.theory.org/BitTorrentSpecification# | ||||
peer_id | ||||
// | ||||
// The ``major``, ``minor``, ``revision`` and ``tag`` parame | ||||
ters are used to identify the | ||||
// version of your client. | ||||
fingerprint(const char* id_string, int major, int minor, int revision, int tag) | fingerprint(const char* id_string, int major, int minor, int revision, int tag) | |||
: major_version(major) | : major_version(major) | |||
, minor_version(minor) | , minor_version(minor) | |||
, revision_version(revision) | , revision_version(revision) | |||
, tag_version(tag) | , tag_version(tag) | |||
{ | { | |||
TORRENT_ASSERT(id_string); | TORRENT_ASSERT(id_string); | |||
TORRENT_ASSERT(major >= 0); | TORRENT_ASSERT(major >= 0); | |||
TORRENT_ASSERT(minor >= 0); | TORRENT_ASSERT(minor >= 0); | |||
TORRENT_ASSERT(revision >= 0); | TORRENT_ASSERT(revision >= 0); | |||
TORRENT_ASSERT(tag >= 0); | TORRENT_ASSERT(tag >= 0); | |||
TORRENT_ASSERT(std::strlen(id_string) == 2); | TORRENT_ASSERT(std::strlen(id_string) == 2); | |||
name[0] = id_string[0]; | name[0] = id_string[0]; | |||
name[1] = id_string[1]; | name[1] = id_string[1]; | |||
} | } | |||
// generates the actual string put in the peer-id, and retur n it. | ||||
std::string to_string() const | std::string to_string() const | |||
{ | { | |||
char s[100]; | char s[100]; | |||
snprintf(s, 100, "-%c%c%c%c%c%c-" | snprintf(s, 100, "-%c%c%c%c%c%c-" | |||
, name[0], name[1] | , name[0], name[1] | |||
, version_to_char(major_version) | , version_to_char(major_version) | |||
, version_to_char(minor_version) | , version_to_char(minor_version) | |||
, version_to_char(revision_version) | , version_to_char(revision_version) | |||
, version_to_char(tag_version)); | , version_to_char(tag_version)); | |||
return s; | return s; | |||
End of changes. 4 change blocks. | ||||
1 lines changed or deleted | 39 lines changed or added | |||
gzip.hpp | gzip.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2007, Arvid Norberg | Copyright (c) 2007-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 37 | skipping to change at line 37 | |||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 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 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||
POSSIBILITY OF SUCH DAMAGE. | POSSIBILITY OF SUCH DAMAGE. | |||
*/ | */ | |||
#ifndef TORRENT_GZIP_HPP_INCLUDED | #ifndef TORRENT_GZIP_HPP_INCLUDED | |||
#define TORRENT_GZIP_HPP_INCLUDED | #define TORRENT_GZIP_HPP_INCLUDED | |||
#include "libtorrent/config.hpp" | #include "libtorrent/config.hpp" | |||
#include <string> | #include "libtorrent/error_code.hpp" | |||
#include <vector> | #include <vector> | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
TORRENT_EXTRA_EXPORT bool inflate_gzip( | TORRENT_EXTRA_EXPORT void inflate_gzip( | |||
char const* in, int size | char const* in, int size | |||
, std::vector<char>& buffer | , std::vector<char>& buffer | |||
, int maximum_size | , int maximum_size | |||
, std::string& error); | , error_code& error); | |||
// get the ``error_category`` for zip errors | ||||
TORRENT_EXPORT boost::system::error_category& get_gzip_category(); | ||||
namespace gzip_errors | ||||
{ | ||||
// libtorrent uses boost.system's ``error_code`` class to re | ||||
present errors. libtorrent has | ||||
// its own error category get_gzip_category() whith the erro | ||||
r codes defined by error_code_enum. | ||||
enum error_code_enum | ||||
{ | ||||
// Not an error | ||||
no_error = 0, | ||||
// the supplied gzip buffer has invalid header | ||||
invalid_gzip_header, | ||||
// the gzip buffer would inflate to more bytes than | ||||
the specified | ||||
// maximum size, and was rejected. | ||||
inflated_data_too_large, | ||||
// available inflate data did not terminate | ||||
data_did_not_terminate, | ||||
// output space exhausted before completing inflate | ||||
space_exhausted, | ||||
// invalid block type (type == 3) | ||||
invalid_block_type, | ||||
// stored block length did not match one's complemen | ||||
t | ||||
invalid_stored_block_length, | ||||
// dynamic block code description: too many length o | ||||
r distance codes | ||||
too_many_length_or_distance_codes, | ||||
// dynamic block code description: code lengths code | ||||
s incomplete | ||||
code_lengths_codes_incomplete, | ||||
// dynamic block code description: repeat lengths wi | ||||
th no first length | ||||
repeat_lengths_with_no_first_length, | ||||
// dynamic block code description: repeat more than | ||||
specified lengths | ||||
repeat_more_than_specified_lengths, | ||||
// dynamic block code description: invalid literal/l | ||||
ength code lengths | ||||
invalid_literal_length_code_lengths, | ||||
// dynamic block code description: invalid distance | ||||
code lengths | ||||
invalid_distance_code_lengths, | ||||
// invalid literal/length or distance code in fixed | ||||
or dynamic block | ||||
invalid_literal_code_in_block, | ||||
// distance is too far back in fixed or dynamic bloc | ||||
k | ||||
distance_too_far_back_in_block, | ||||
// an unknown error occurred during gzip inflation | ||||
unknown_gzip_error, | ||||
// the number of error codes | ||||
error_code_max | ||||
}; | ||||
// hidden | ||||
TORRENT_EXPORT boost::system::error_code make_error_code(err | ||||
or_code_enum e); | ||||
} | ||||
} | } | |||
#if BOOST_VERSION >= 103500 | ||||
namespace boost { namespace system { | ||||
template<> | ||||
struct is_error_code_enum<libtorrent::gzip_errors::error_code_enum> | ||||
{ static const bool value = true; }; | ||||
template<> | ||||
struct is_error_condition_enum<libtorrent::gzip_errors::error_code_enum> | ||||
{ static const bool value = true; }; | ||||
} } | ||||
#endif // BOOST_VERSION | ||||
#endif | #endif | |||
End of changes. 5 change blocks. | ||||
4 lines changed or deleted | 98 lines changed or added | |||
hasher.hpp | hasher.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2003, Arvid Norberg | Copyright (c) 2003-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 44 | skipping to change at line 44 | |||
#define TORRENT_HASHER_HPP_INCLUDED | #define TORRENT_HASHER_HPP_INCLUDED | |||
#include <boost/cstdint.hpp> | #include <boost/cstdint.hpp> | |||
#include "libtorrent/peer_id.hpp" | #include "libtorrent/peer_id.hpp" | |||
#include "libtorrent/config.hpp" | #include "libtorrent/config.hpp" | |||
#include "libtorrent/assert.hpp" | #include "libtorrent/assert.hpp" | |||
#ifdef TORRENT_USE_GCRYPT | #ifdef TORRENT_USE_GCRYPT | |||
#include <gcrypt.h> | #include <gcrypt.h> | |||
#elif TORRENT_USE_COMMONCRYPTO | ||||
#include <CommonCrypto/CommonDigest.h> | ||||
#elif defined TORRENT_USE_OPENSSL | #elif defined TORRENT_USE_OPENSSL | |||
extern "C" | extern "C" | |||
{ | { | |||
#include <openssl/sha.h> | #include <openssl/sha.h> | |||
} | } | |||
#else | #else | |||
// from sha1.cpp | // from sha1.cpp | |||
struct TORRENT_EXTRA_EXPORT SHA_CTX | namespace libtorrent | |||
{ | { | |||
boost::uint32_t state[5]; | ||||
boost::uint32_t count[2]; | struct TORRENT_EXTRA_EXPORT sha_ctx | |||
boost::uint8_t buffer[64]; | { | |||
}; | boost::uint32_t state[5]; | |||
boost::uint32_t count[2]; | ||||
TORRENT_EXTRA_EXPORT void SHA1_Init(SHA_CTX* context); | boost::uint8_t buffer[64]; | |||
TORRENT_EXTRA_EXPORT void SHA1_Update(SHA_CTX* context, boost::uint8_t cons | }; | |||
t* data, boost::uint32_t len); | ||||
TORRENT_EXTRA_EXPORT void SHA1_Final(boost::uint8_t* digest, SHA_CTX* conte | TORRENT_EXTRA_EXPORT void SHA1_init(sha_ctx* context); | |||
xt); | TORRENT_EXTRA_EXPORT void SHA1_update(sha_ctx* context, boost::uint8 | |||
_t const* data, boost::uint32_t len); | ||||
TORRENT_EXTRA_EXPORT void SHA1_final(boost::uint8_t* digest, sha_ctx | ||||
* context); | ||||
} // namespace libtorrent | ||||
#endif | #endif | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
class TORRENT_EXTRA_EXPORT hasher | // this is a SHA-1 hash class. | |||
// | ||||
// You use it by first instantiating it, then call ``update()`` to f | ||||
eed it | ||||
// with data. i.e. you don't have to keep the entire buffer of which | ||||
you want to | ||||
// create the hash in memory. You can feed the hasher parts of it at | ||||
a time. When | ||||
// You have fed the hasher with all the data, you call ``final()`` a | ||||
nd it | ||||
// will return the sha1-hash of the data. | ||||
// | ||||
// The constructor that takes a ``char const*`` and an integer will | ||||
construct the | ||||
// sha1 context and feed it the data passed in. | ||||
// | ||||
// If you want to reuse the hasher object once you have created a ha | ||||
sh, you have to | ||||
// call ``reset()`` to reinitialize it. | ||||
// | ||||
// The sha1-algorithm used was implemented by Steve Reid and release | ||||
d as public domain. | ||||
// For more info, see ``src/sha1.cpp``. | ||||
class TORRENT_EXPORT hasher | ||||
{ | { | |||
public: | public: | |||
hasher() | hasher(); | |||
{ | ||||
#ifdef TORRENT_USE_GCRYPT | // this is the same as default constructing followed by a ca | |||
gcry_md_open(&m_context, GCRY_MD_SHA1, 0); | ll to | |||
#else | // ``update(data, len)``. | |||
SHA1_Init(&m_context); | hasher(const char* data, int len); | |||
#endif | ||||
} | ||||
hasher(const char* data, int len) | ||||
{ | ||||
TORRENT_ASSERT(data != 0); | ||||
TORRENT_ASSERT(len > 0); | ||||
#ifdef TORRENT_USE_GCRYPT | ||||
gcry_md_open(&m_context, GCRY_MD_SHA1, 0); | ||||
gcry_md_write(m_context, data, len); | ||||
#else | ||||
SHA1_Init(&m_context); | ||||
SHA1_Update(&m_context, reinterpret_cast<unsigned ch | ||||
ar const*>(data), len); | ||||
#endif | ||||
} | ||||
#ifdef TORRENT_USE_GCRYPT | #ifdef TORRENT_USE_GCRYPT | |||
hasher(hasher const& h) | hasher(hasher const& h); | |||
{ | hasher& operator=(hasher const& h); | |||
gcry_md_copy(&m_context, h.m_context); | ||||
} | ||||
hasher& operator=(hasher const& h) | ||||
{ | ||||
gcry_md_close(m_context); | ||||
gcry_md_copy(&m_context, h.m_context); | ||||
return *this; | ||||
} | ||||
#endif | #endif | |||
// append the following bytes to what is being hashed | ||||
hasher& update(std::string const& data) { update(data.c_str( ), data.size()); return *this; } | hasher& update(std::string const& data) { update(data.c_str( ), data.size()); return *this; } | |||
hasher& update(const char* data, int len) | hasher& update(const char* data, int len); | |||
{ | ||||
TORRENT_ASSERT(data != 0); | ||||
TORRENT_ASSERT(len > 0); | ||||
#ifdef TORRENT_USE_GCRYPT | ||||
gcry_md_write(m_context, data, len); | ||||
#else | ||||
SHA1_Update(&m_context, reinterpret_cast<unsigned ch | ||||
ar const*>(data), len); | ||||
#endif | ||||
return *this; | ||||
} | ||||
sha1_hash final() | // returns the SHA-1 digest of the buffers previously passed | |||
{ | to | |||
sha1_hash digest; | // update() and the hasher constructor. | |||
#ifdef TORRENT_USE_GCRYPT | sha1_hash final(); | |||
gcry_md_final(m_context); | ||||
digest.assign((const char*)gcry_md_read(m_context, 0 | ||||
)); | ||||
#else | ||||
SHA1_Final(digest.begin(), &m_context); | ||||
#endif | ||||
return digest; | ||||
} | ||||
void reset() | // restore the hasher state to be as if the hasher has just | |||
{ | been | |||
#ifdef TORRENT_USE_GCRYPT | // default constructed. | |||
gcry_md_reset(m_context); | void reset(); | |||
#else | ||||
SHA1_Init(&m_context); | ||||
#endif | ||||
} | ||||
#ifdef TORRENT_USE_GCRYPT | #ifdef TORRENT_USE_GCRYPT | |||
~hasher() | ~hasher(); | |||
{ | ||||
gcry_md_close(m_context); | ||||
} | ||||
#endif | #endif | |||
private: | private: | |||
#ifdef TORRENT_USE_GCRYPT | #ifdef TORRENT_USE_GCRYPT | |||
gcry_md_hd_t m_context; | gcry_md_hd_t m_context; | |||
#else | #elif TORRENT_USE_COMMONCRYPTO | |||
CC_SHA1_CTX m_context; | ||||
#elif defined TORRENT_USE_OPENSSL | ||||
SHA_CTX m_context; | SHA_CTX m_context; | |||
#else | ||||
sha_ctx m_context; | ||||
#endif | #endif | |||
}; | }; | |||
} | } | |||
#endif // TORRENT_HASHER_HPP_INCLUDED | #endif // TORRENT_HASHER_HPP_INCLUDED | |||
End of changes. 16 change blocks. | ||||
82 lines changed or deleted | 71 lines changed or added | |||
http_connection.hpp | http_connection.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2007, Arvid Norberg | Copyright (c) 2007-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 67 | skipping to change at line 67 | |||
#ifdef TORRENT_USE_OPENSSL | #ifdef TORRENT_USE_OPENSSL | |||
#include <boost/asio/ssl/context.hpp> | #include <boost/asio/ssl/context.hpp> | |||
#endif | #endif | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
struct http_connection; | struct http_connection; | |||
class connection_queue; | class connection_queue; | |||
const int default_max_bottled_buffer_size = 2*1024*1024; | ||||
typedef boost::function<void(error_code const& | typedef boost::function<void(error_code const& | |||
, http_parser const&, char const* data, int size, http_connection&)> http_handler; | , http_parser const&, char const* data, int size, http_connection&)> http_handler; | |||
typedef boost::function<void(http_connection&)> http_connect_handler; | typedef boost::function<void(http_connection&)> http_connect_handler; | |||
typedef boost::function<void(http_connection&, std::list<tcp::endpoint>&)> http_filter_handler; | typedef boost::function<void(http_connection&, std::list<tcp::endpoint>&)> http_filter_handler; | |||
// when bottled, the last two arguments to the handler | // when bottled, the last two arguments to the handler | |||
// will always be 0 | // will always be 0 | |||
struct TORRENT_EXTRA_EXPORT http_connection : boost::enable_shared_from_thi | struct TORRENT_EXTRA_EXPORT http_connection | |||
s<http_connection>, boost::noncopyable | : boost::enable_shared_from_this<http_connection> | |||
, boost::noncopyable | ||||
{ | { | |||
http_connection(io_service& ios, connection_queue& cc | http_connection(io_service& ios, connection_queue& cc | |||
, http_handler const& handler, bool bottled = true | , http_handler const& handler, bool bottled = true | |||
, int max_bottled_buffer_size = default_max_bottled_buffer_s ize | ||||
, http_connect_handler const& ch = http_connect_handler() | , http_connect_handler const& ch = http_connect_handler() | |||
, http_filter_handler const& fh = http_filter_handler() | , http_filter_handler const& fh = http_filter_handler() | |||
#ifdef TORRENT_USE_OPENSSL | #ifdef TORRENT_USE_OPENSSL | |||
, boost::asio::ssl::context* ssl_ctx = 0 | , boost::asio::ssl::context* ssl_ctx = 0 | |||
#endif | #endif | |||
); | ); | |||
~http_connection(); | ~http_connection(); | |||
void rate_limit(int limit); | void rate_limit(int limit); | |||
skipping to change at line 155 | skipping to change at line 160 | |||
tcp::resolver m_resolver; | tcp::resolver m_resolver; | |||
http_parser m_parser; | http_parser m_parser; | |||
http_handler m_handler; | http_handler m_handler; | |||
http_connect_handler m_connect_handler; | http_connect_handler m_connect_handler; | |||
http_filter_handler m_filter_handler; | http_filter_handler m_filter_handler; | |||
deadline_timer m_timer; | deadline_timer m_timer; | |||
time_duration m_read_timeout; | time_duration m_read_timeout; | |||
time_duration m_completion_timeout; | time_duration m_completion_timeout; | |||
ptime m_last_receive; | ptime m_last_receive; | |||
ptime m_start_time; | ptime m_start_time; | |||
// bottled means that the handler is called once, when | // bottled means that the handler is called once, when | |||
// everything is received (and buffered in memory). | // everything is received (and buffered in memory). | |||
// non bottled means that once the headers have been | // non bottled means that once the headers have been | |||
// received, data is streamed to the handler | // received, data is streamed to the handler | |||
bool m_bottled; | bool m_bottled; | |||
// maximum size of bottled buffer | ||||
int m_max_bottled_buffer_size; | ||||
// set to true the first time the handler is called | // set to true the first time the handler is called | |||
bool m_called; | bool m_called; | |||
std::string m_hostname; | std::string m_hostname; | |||
std::string m_port; | std::string m_port; | |||
std::string m_url; | std::string m_url; | |||
std::string m_user_agent; | std::string m_user_agent; | |||
std::list<tcp::endpoint> m_endpoints; | std::list<tcp::endpoint> m_endpoints; | |||
#ifdef TORRENT_USE_OPENSSL | #ifdef TORRENT_USE_OPENSSL | |||
asio::ssl::context* m_ssl_ctx; | asio::ssl::context* m_ssl_ctx; | |||
End of changes. 6 change blocks. | ||||
3 lines changed or deleted | 12 lines changed or added | |||
http_parser.hpp | http_parser.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2008, Arvid Norberg | Copyright (c) 2008-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 65 | skipping to change at line 65 | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
// return true if the status code is 200, 206, or in the 300-400 ran ge | // return true if the status code is 200, 206, or in the 300-400 ran ge | |||
bool is_ok_status(int http_status); | bool is_ok_status(int http_status); | |||
// return true if the status code is a redirect | // return true if the status code is a redirect | |||
bool is_redirect(int http_status); | bool is_redirect(int http_status); | |||
std::string resolve_redirect_location(std::string referrer | ||||
, std::string location); | ||||
class TORRENT_EXTRA_EXPORT http_parser | class TORRENT_EXTRA_EXPORT http_parser | |||
{ | { | |||
public: | public: | |||
enum flags_t { dont_parse_chunks = 1 }; | enum flags_t { dont_parse_chunks = 1 }; | |||
http_parser(int flags = 0); | http_parser(int flags = 0); | |||
~http_parser(); | ~http_parser(); | |||
std::string const& header(char const* key) const | std::string const& header(char const* key) const | |||
{ | { | |||
static std::string empty; | static std::string empty; | |||
std::multimap<std::string, std::string>::const_itera tor i | std::multimap<std::string, std::string>::const_itera tor i | |||
skipping to change at line 127 | skipping to change at line 130 | |||
// chunk data. | // chunk data. | |||
// if the function returns false, the chunk size and header | // if the function returns false, the chunk size and header | |||
// size may still have been modified, but their values are | // size may still have been modified, but their values are | |||
// undefined | // undefined | |||
bool parse_chunk_header(buffer::const_interval buf | bool parse_chunk_header(buffer::const_interval buf | |||
, size_type* chunk_size, int* header_size); | , size_type* chunk_size, int* header_size); | |||
// reset the whole state and start over | // reset the whole state and start over | |||
void reset(); | void reset(); | |||
bool connection_close() const { return m_connection_close; } | ||||
std::multimap<std::string, std::string> const& headers() con st { return m_header; } | std::multimap<std::string, std::string> const& headers() con st { return m_header; } | |||
std::vector<std::pair<size_type, size_type> > const& chunks( ) const { return m_chunked_ranges; } | std::vector<std::pair<size_type, size_type> > const& chunks( ) const { return m_chunked_ranges; } | |||
private: | private: | |||
size_type m_recv_pos; | size_type m_recv_pos; | |||
int m_status_code; | int m_status_code; | |||
std::string m_method; | std::string m_method; | |||
std::string m_path; | std::string m_path; | |||
std::string m_protocol; | std::string m_protocol; | |||
std::string m_server_message; | std::string m_server_message; | |||
skipping to change at line 148 | skipping to change at line 153 | |||
size_type m_content_length; | size_type m_content_length; | |||
size_type m_range_start; | size_type m_range_start; | |||
size_type m_range_end; | size_type m_range_end; | |||
enum { read_status, read_header, read_body, error_state } m_ state; | enum { read_status, read_header, read_body, error_state } m_ state; | |||
std::multimap<std::string, std::string> m_header; | std::multimap<std::string, std::string> m_header; | |||
buffer::const_interval m_recv_buffer; | buffer::const_interval m_recv_buffer; | |||
int m_body_start_pos; | int m_body_start_pos; | |||
// this is true if the server is HTTP/1.0 or | ||||
// if it sent "connection: close" | ||||
bool m_connection_close; | ||||
bool m_chunked_encoding; | bool m_chunked_encoding; | |||
bool m_finished; | bool m_finished; | |||
// contains offsets of the first and one-past-end of | // contains offsets of the first and one-past-end of | |||
// each chunked range in the response | // each chunked range in the response | |||
std::vector<std::pair<size_type, size_type> > m_chunked_rang es; | std::vector<std::pair<size_type, size_type> > m_chunked_rang es; | |||
// while reading a chunk, this is the offset where the | // while reading a chunk, this is the offset where the | |||
// current chunk will end (it refers to the first character | // current chunk will end (it refers to the first character | |||
// in the chunk tail header or the next chunk header) | // in the chunk tail header or the next chunk header) | |||
End of changes. 4 change blocks. | ||||
1 lines changed or deleted | 9 lines changed or added | |||
http_seed_connection.hpp | http_seed_connection.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2008, Arvid Norberg | Copyright (c) 2008-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 89 | skipping to change at line 89 | |||
public: | public: | |||
// this is the constructor where the we are the active part. | // this is the constructor where the we are the active part. | |||
// The peer_conenction should handshake and verify that the | // The peer_conenction should handshake and verify that the | |||
// other end has the correct id | // other end has the correct id | |||
http_seed_connection( | http_seed_connection( | |||
aux::session_impl& ses | aux::session_impl& ses | |||
, boost::weak_ptr<torrent> t | , boost::weak_ptr<torrent> t | |||
, boost::shared_ptr<socket_type> s | , boost::shared_ptr<socket_type> s | |||
, tcp::endpoint const& remote | , tcp::endpoint const& remote | |||
, std::string const& url | , web_seed_entry& web); | |||
, policy::peer* peerinfo | ||||
, std::string const& ext_auth | ||||
, web_seed_entry::headers_t const& ext_headers); | ||||
virtual int type() const { return peer_connection::http_seed _connection; } | virtual int type() const { return peer_connection::http_seed _connection; } | |||
// called from the main loop when this connection has any | // called from the main loop when this connection has any | |||
// work to do. | // work to do. | |||
void on_receive(error_code const& error | void on_receive(error_code const& error | |||
, std::size_t bytes_transferred); | , std::size_t bytes_transferred); | |||
std::string const& url() const { return m_url; } | std::string const& url() const { return m_url; } | |||
End of changes. 2 change blocks. | ||||
5 lines changed or deleted | 2 lines changed or added | |||
http_stream.hpp | http_stream.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2007, Arvid Norberg | Copyright (c) 2007-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
http_tracker_connection.hpp | http_tracker_connection.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2003, Arvid Norberg | Copyright (c) 2003-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
i2p_stream.hpp | i2p_stream.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2009, Arvid Norberg | Copyright (c) 2009-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 54 | skipping to change at line 54 | |||
#include <boost/function/function2.hpp> | #include <boost/function/function2.hpp> | |||
#include <boost/bind.hpp> | #include <boost/bind.hpp> | |||
#include <boost/shared_ptr.hpp> | #include <boost/shared_ptr.hpp> | |||
#include "libtorrent/proxy_base.hpp" | #include "libtorrent/proxy_base.hpp" | |||
#include "libtorrent/session_settings.hpp" | #include "libtorrent/session_settings.hpp" | |||
namespace libtorrent { | namespace libtorrent { | |||
namespace i2p_error { | namespace i2p_error { | |||
// error values for the i2p_category error_category. | ||||
enum i2p_error_code | enum i2p_error_code | |||
{ | { | |||
no_error = 0, | no_error = 0, | |||
parse_failed, | parse_failed, | |||
cant_reach_peer, | cant_reach_peer, | |||
i2p_error, | i2p_error, | |||
invalid_key, | invalid_key, | |||
invalid_id, | invalid_id, | |||
timeout, | timeout, | |||
key_not_found, | key_not_found, | |||
duplicated_id, | duplicated_id, | |||
num_errors | num_errors | |||
}; | }; | |||
} | ||||
struct TORRENT_EXPORT i2p_error_category : boost::system::error_category | // hidden | |||
{ | TORRENT_EXPORT boost::system::error_code make_error_code(i2p | |||
virtual const char* name() const BOOST_SYSTEM_NOEXCEPT; | _error_code e); | |||
virtual std::string message(int ev) const BOOST_SYSTEM_NOEXCEPT; | } | |||
virtual boost::system::error_condition default_error_condition(int e | ||||
v) const BOOST_SYSTEM_NOEXCEPT | ||||
{ return boost::system::error_condition(ev, *this); } | ||||
}; | ||||
extern i2p_error_category i2p_category; | // returns the error category for I2P errors | |||
TORRENT_EXPORT boost::system::error_category& get_i2p_category(); | ||||
class i2p_stream : public proxy_base | class i2p_stream : public proxy_base | |||
{ | { | |||
public: | public: | |||
explicit i2p_stream(io_service& io_service); | explicit i2p_stream(io_service& io_service); | |||
~i2p_stream(); | ~i2p_stream(); | |||
enum command_t | enum command_t | |||
{ | { | |||
skipping to change at line 159 | skipping to change at line 156 | |||
enum state_t | enum state_t | |||
{ | { | |||
read_hello_response, | read_hello_response, | |||
read_connect_response, | read_connect_response, | |||
read_accept_response, | read_accept_response, | |||
read_session_create_response, | read_session_create_response, | |||
read_name_lookup_response | read_name_lookup_response | |||
}; | }; | |||
int m_state; | int m_state; | |||
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS | #if TORRENT_USE_ASSERTS | |||
int m_magic; | int m_magic; | |||
#endif | #endif | |||
}; | }; | |||
class i2p_connection | class i2p_connection | |||
{ | { | |||
public: | public: | |||
i2p_connection(io_service& ios); | i2p_connection(io_service& ios); | |||
~i2p_connection(); | ~i2p_connection(); | |||
skipping to change at line 197 | skipping to change at line 194 | |||
private: | private: | |||
void on_sam_connect(error_code const& ec, i2p_stream::handler_type c onst& h | void on_sam_connect(error_code const& ec, i2p_stream::handler_type c onst& h | |||
, boost::shared_ptr<i2p_stream>); | , boost::shared_ptr<i2p_stream>); | |||
void do_name_lookup(std::string const& name | void do_name_lookup(std::string const& name | |||
, name_lookup_handler const& h); | , name_lookup_handler const& h); | |||
void on_name_lookup(error_code const& ec | void on_name_lookup(error_code const& ec | |||
, name_lookup_handler handler | , name_lookup_handler handler | |||
, boost::shared_ptr<i2p_stream>); | , boost::shared_ptr<i2p_stream>); | |||
void set_local_endpoint(error_code const& ec, char const* dest | void set_local_endpoint(error_code const& ec, char const* dest); | |||
, i2p_stream::handler_type const& h); | ||||
// to talk to i2p SAM bridge | // to talk to i2p SAM bridge | |||
boost::shared_ptr<i2p_stream> m_sam_socket; | boost::shared_ptr<i2p_stream> m_sam_socket; | |||
proxy_settings m_sam_router; | proxy_settings m_sam_router; | |||
// our i2p endpoint key | // our i2p endpoint key | |||
std::string m_i2p_local_endpoint; | std::string m_i2p_local_endpoint; | |||
std::string m_session_id; | std::string m_session_id; | |||
std::list<std::pair<std::string, name_lookup_handler> > m_name_looku p; | std::list<std::pair<std::string, name_lookup_handler> > m_name_looku p; | |||
skipping to change at line 223 | skipping to change at line 219 | |||
sam_name_lookup, | sam_name_lookup, | |||
sam_idle | sam_idle | |||
}; | }; | |||
state_t m_state; | state_t m_state; | |||
io_service& m_io_service; | io_service& m_io_service; | |||
}; | }; | |||
} | } | |||
#if BOOST_VERSION >= 103500 | ||||
namespace boost { namespace system { | ||||
template<> | ||||
struct is_error_code_enum<libtorrent::i2p_error::i2p_error_code> | ||||
{ static const bool value = true; }; | ||||
template<> | ||||
struct is_error_condition_enum<libtorrent::i2p_error::i2p_error_code> | ||||
{ static const bool value = true; }; | ||||
} } | ||||
#endif // BOOST_VERSION | ||||
#endif // TORRENT_USE_I2P | #endif // TORRENT_USE_I2P | |||
#endif | #endif | |||
End of changes. 8 change blocks. | ||||
14 lines changed or deleted | 25 lines changed or added | |||
identify_client.hpp | identify_client.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2003, Arvid Norberg | Copyright (c) 2003-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 53 | skipping to change at line 53 | |||
#pragma warning(pop) | #pragma warning(pop) | |||
#endif | #endif | |||
#include "libtorrent/peer_id.hpp" | #include "libtorrent/peer_id.hpp" | |||
#include "libtorrent/fingerprint.hpp" | #include "libtorrent/fingerprint.hpp" | |||
#include "libtorrent/config.hpp" | #include "libtorrent/config.hpp" | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
// This function can can be used to extract a string describing a cl | ||||
ient | ||||
// version from its peer-id. It will recognize most clients that hav | ||||
e this | ||||
// kind of identification in the peer-id. | ||||
TORRENT_EXPORT std::string identify_client(const peer_id& p); | TORRENT_EXPORT std::string identify_client(const peer_id& p); | |||
// Returns an optional fingerprint if any can be identified from the | ||||
peer | ||||
// id. This can be used to automate the identification of clients. I | ||||
t will | ||||
// not be able to identify peers with non- standard encodings. Only | ||||
Azureus | ||||
// style, Shadow's style and Mainline style. | ||||
TORRENT_EXPORT boost::optional<fingerprint> client_fingerprint(peer_ id const& p); | TORRENT_EXPORT boost::optional<fingerprint> client_fingerprint(peer_ id const& p); | |||
} | } | |||
#endif // TORRENT_IDENTIFY_CLIENT_HPP_INCLUDED | #endif // TORRENT_IDENTIFY_CLIENT_HPP_INCLUDED | |||
End of changes. 3 change blocks. | ||||
1 lines changed or deleted | 14 lines changed or added | |||
instantiate_connection.hpp | instantiate_connection.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2007, Arvid Norberg | Copyright (c) 2007-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
intrusive_ptr_base.hpp | intrusive_ptr_base.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2007, Arvid Norberg | Copyright (c) 2007-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 50 | skipping to change at line 50 | |||
#include "libtorrent/assert.hpp" | #include "libtorrent/assert.hpp" | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
template<class T> | template<class T> | |||
struct intrusive_ptr_base | struct intrusive_ptr_base | |||
{ | { | |||
intrusive_ptr_base(intrusive_ptr_base<T> const&) | intrusive_ptr_base(intrusive_ptr_base<T> const&) | |||
: m_refs(0) {} | : m_refs(0) {} | |||
intrusive_ptr_base& operator=(intrusive_ptr_base const& rhs) | ||||
{ return *this; } | ||||
friend void intrusive_ptr_add_ref(intrusive_ptr_base<T> cons t* s) | friend void intrusive_ptr_add_ref(intrusive_ptr_base<T> cons t* s) | |||
{ | { | |||
TORRENT_ASSERT(s != 0); | TORRENT_ASSERT(s != 0); | |||
TORRENT_ASSERT(s->m_refs >= 0); | TORRENT_ASSERT(s->m_refs >= 0); | |||
++s->m_refs; | ++s->m_refs; | |||
} | } | |||
friend void intrusive_ptr_release(intrusive_ptr_base<T> cons t* s) | friend void intrusive_ptr_release(intrusive_ptr_base<T> cons t* s) | |||
{ | { | |||
TORRENT_ASSERT(s != 0); | TORRENT_ASSERT(s != 0); | |||
skipping to change at line 78 | skipping to change at line 75 | |||
boost::intrusive_ptr<T> self() | boost::intrusive_ptr<T> self() | |||
{ return boost::intrusive_ptr<T>((T*)this); } | { return boost::intrusive_ptr<T>((T*)this); } | |||
boost::intrusive_ptr<const T> self() const | boost::intrusive_ptr<const T> self() const | |||
{ return boost::intrusive_ptr<const T>((T const*)this); } | { return boost::intrusive_ptr<const T>((T const*)this); } | |||
int refcount() const { return m_refs; } | int refcount() const { return m_refs; } | |||
intrusive_ptr_base(): m_refs(0) {} | intrusive_ptr_base(): m_refs(0) {} | |||
// so that we can access this when logging | ||||
#if !defined TORRENT_LOGGING \ | ||||
&& !defined TORRENT_VERBOSE_LOGGING \ | ||||
&& !defined TORRENT_ERROR_LOGGING | ||||
private: | private: | |||
#endif | ||||
// reference counter for intrusive_ptr | // reference counter for intrusive_ptr | |||
mutable boost::detail::atomic_count m_refs; | mutable boost::detail::atomic_count m_refs; | |||
}; | }; | |||
} | } | |||
#endif | #endif | |||
End of changes. 4 change blocks. | ||||
9 lines changed or deleted | 2 lines changed or added | |||
invariant_check.hpp | invariant_check.hpp | |||
---|---|---|---|---|
// Copyright Daniel Wallin 2004. Use, modification and distribution is | // Copyright Daniel Wallin 2004. Use, modification and distribution is | |||
// subject to the Boost Software License, Version 1.0. (See accompanying | // subject to the Boost Software License, Version 1.0. (See accompanying | |||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |||
#ifndef TORRENT_INVARIANT_ACCESS_HPP_INCLUDED | #ifndef TORRENT_INVARIANT_ACCESS_HPP_INCLUDED | |||
#define TORRENT_INVARIANT_ACCESS_HPP_INCLUDED | #define TORRENT_INVARIANT_ACCESS_HPP_INCLUDED | |||
#include "libtorrent/assert.hpp" | ||||
#include "libtorrent/config.hpp" | #include "libtorrent/config.hpp" | |||
#include "libtorrent/assert.hpp" | ||||
#if TORRENT_USE_INVARIANT_CHECKS | ||||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
class invariant_access | class invariant_access | |||
{ | { | |||
public: | public: | |||
template<class T> | template<class T> | |||
static void check_invariant(T const& self) | static void check_invariant(T const& self) | |||
{ | { | |||
skipping to change at line 38 | skipping to change at line 40 | |||
} | } | |||
struct invariant_checker {}; | struct invariant_checker {}; | |||
template<class T> | template<class T> | |||
struct invariant_checker_impl : invariant_checker | struct invariant_checker_impl : invariant_checker | |||
{ | { | |||
invariant_checker_impl(T const& self_) | invariant_checker_impl(T const& self_) | |||
: self(self_) | : self(self_) | |||
{ | { | |||
TORRENT_TRY | try | |||
{ | { | |||
check_invariant(self); | check_invariant(self); | |||
} | } | |||
TORRENT_CATCH_ALL | catch (...) | |||
{ | { | |||
TORRENT_ASSERT(false); | TORRENT_ASSERT(false); | |||
} | } | |||
} | } | |||
~invariant_checker_impl() | ~invariant_checker_impl() | |||
{ | { | |||
TORRENT_TRY | try | |||
{ | { | |||
check_invariant(self); | check_invariant(self); | |||
} | } | |||
TORRENT_CATCH_ALL | catch (...) | |||
{ | { | |||
TORRENT_ASSERT(false); | TORRENT_ASSERT(false); | |||
} | } | |||
} | } | |||
T const& self; | T const& self; | |||
}; | }; | |||
template<class T> | template<class T> | |||
invariant_checker_impl<T> make_invariant_checker(T const& x) | invariant_checker_impl<T> make_invariant_checker(T const& x) | |||
{ | { | |||
return invariant_checker_impl<T>(x); | return invariant_checker_impl<T>(x); | |||
} | } | |||
} | } | |||
#if defined TORRENT_DEBUG && !defined TORRENT_DISABLE_INVARIANT_CHECKS | ||||
#define INVARIANT_CHECK \ | #define INVARIANT_CHECK \ | |||
invariant_checker const& _invariant_check = make_invariant_checker(* this); \ | invariant_checker const& _invariant_check = make_invariant_checker(* this); \ | |||
(void)_invariant_check; \ | (void)_invariant_check; \ | |||
do {} while (false) | do {} while (false) | |||
#else | #else | |||
#define INVARIANT_CHECK do {} while (false) | #define INVARIANT_CHECK do {} while (false) | |||
#endif | #endif | |||
#endif // TORRENT_INVARIANT_ACCESS_HPP_INCLUDED | #endif // TORRENT_INVARIANT_ACCESS_HPP_INCLUDED | |||
End of changes. 7 change blocks. | ||||
6 lines changed or deleted | 7 lines changed or added | |||
io.hpp | io.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2003, Arvid Norberg | Copyright (c) 2003-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 151 | skipping to change at line 151 | |||
{ write_impl(val, start); } | { write_impl(val, start); } | |||
template <class OutIt> | template <class OutIt> | |||
void write_uint8(boost::uint8_t val, OutIt& start) | void write_uint8(boost::uint8_t val, OutIt& start) | |||
{ write_impl(val, start); } | { write_impl(val, start); } | |||
template <class OutIt> | template <class OutIt> | |||
void write_int8(boost::int8_t val, OutIt& start) | void write_int8(boost::int8_t val, OutIt& start) | |||
{ write_impl(val, start); } | { write_impl(val, start); } | |||
inline void write_string(std::string const& str, char*& star t) | inline int write_string(std::string const& str, char*& start ) | |||
{ | { | |||
std::memcpy((void*)start, str.c_str(), str.size()); | std::memcpy((void*)start, str.c_str(), str.size()); | |||
start += str.size(); | start += str.size(); | |||
return str.size(); | ||||
} | } | |||
template <class OutIt> | template <class OutIt> | |||
void write_string(std::string const& str, OutIt& start) | int write_string(std::string const& val, OutIt& out) | |||
{ | { | |||
std::copy(str.begin(), str.end(), start); | for (std::string::const_iterator i = val.begin() | |||
, end(val.end()); i != end; ++i) | ||||
*out++ = *i; | ||||
return int(val.length()); | ||||
} | } | |||
} | } | |||
} | } | |||
#endif // TORRENT_IO_HPP_INCLUDED | #endif // TORRENT_IO_HPP_INCLUDED | |||
End of changes. 6 change blocks. | ||||
5 lines changed or deleted | 8 lines changed or added | |||
io_service.hpp | io_service.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2009, Arvid Norberg | Copyright (c) 2009-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
io_service_fwd.hpp | io_service_fwd.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2009, Arvid Norberg | Copyright (c) 2009-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
ip_filter.hpp | ip_filter.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2005, Arvid Norberg | Copyright (c) 2005-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 58 | skipping to change at line 58 | |||
#pragma warning(pop) | #pragma warning(pop) | |||
#endif | #endif | |||
#include "libtorrent/config.hpp" | #include "libtorrent/config.hpp" | |||
#include "libtorrent/address.hpp" | #include "libtorrent/address.hpp" | |||
#include "libtorrent/assert.hpp" | #include "libtorrent/assert.hpp" | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
// hidden | ||||
inline bool operator<=(address const& lhs | inline bool operator<=(address const& lhs | |||
, address const& rhs) | , address const& rhs) | |||
{ | { | |||
return lhs < rhs || lhs == rhs; | return lhs < rhs || lhs == rhs; | |||
} | } | |||
template <class Addr> | template <class Addr> | |||
struct ip_range | struct ip_range | |||
{ | { | |||
Addr first; | Addr first; | |||
skipping to change at line 261 | skipping to change at line 262 | |||
int access; | int access; | |||
}; | }; | |||
typedef std::set<range> range_t; | typedef std::set<range> range_t; | |||
range_t m_access_list; | range_t m_access_list; | |||
}; | }; | |||
} | } | |||
// The ``ip_filter`` class is a set of rules that uniquely categorizes all | ||||
// ip addresses as allowed or disallowed. The default constructor creates | ||||
// a single rule that allows all addresses (0.0.0.0 - 255.255.255.255 for | ||||
// the IPv4 range, and the equivalent range covering all addresses for the | ||||
// IPv6 range). | ||||
// | ||||
// A default constructed ip_filter does not filter any address. | ||||
struct TORRENT_EXPORT ip_filter | struct TORRENT_EXPORT ip_filter | |||
{ | { | |||
// the flags defined for an IP range | ||||
enum access_flags | enum access_flags | |||
{ | { | |||
// indicates that IPs in this range should not be connected | ||||
// to nor accepted as incoming connections | ||||
blocked = 1 | blocked = 1 | |||
}; | }; | |||
// both addresses MUST be of the same type (i.e. both must | // Adds a rule to the filter. ``first`` and ``last`` defines a range | |||
// be either IPv4 or both must be IPv6) | of | |||
// ip addresses that will be marked with the given flags. The ``flag | ||||
s`` | ||||
// can currently be 0, which means allowed, or ``ip_filter::blocked` | ||||
`, which | ||||
// means disallowed. | ||||
// | ||||
// precondition: | ||||
// ``first.is_v4() == last.is_v4() && first.is_v6() == last.is_v6()` | ||||
` | ||||
// | ||||
// postcondition: | ||||
// ``access(x) == flags`` for every ``x`` in the range [``first``, ` | ||||
`last``] | ||||
// | ||||
// This means that in a case of overlapping ranges, the last one app | ||||
lied takes | ||||
// precedence. | ||||
void add_rule(address first, address last, int flags); | void add_rule(address first, address last, int flags); | |||
// Returns the access permissions for the given address (``addr``). | ||||
The permission | ||||
// can currently be 0 or ``ip_filter::blocked``. The complexity of t | ||||
his operation | ||||
// is O(``log`` n), where n is the minimum number of non-overlapping | ||||
ranges to describe | ||||
// the current filter. | ||||
int access(address const& addr) const; | int access(address const& addr) const; | |||
#if TORRENT_USE_IPV6 | #if TORRENT_USE_IPV6 | |||
typedef boost::tuple<std::vector<ip_range<address_v4> > | typedef boost::tuple<std::vector<ip_range<address_v4> > | |||
, std::vector<ip_range<address_v6> > > filter_tuple_t; | , std::vector<ip_range<address_v6> > > filter_tuple_t; | |||
#else | #else | |||
typedef std::vector<ip_range<address_v4> > filter_tuple_t; | typedef std::vector<ip_range<address_v4> > filter_tuple_t; | |||
#endif | #endif | |||
// This function will return the current state of the filter in the | ||||
minimum number of | ||||
// ranges possible. They are sorted from ranges in low addresses to | ||||
high addresses. Each | ||||
// entry in the returned vector is a range with the access control s | ||||
pecified in its | ||||
// ``flags`` field. | ||||
// | ||||
// The return value is a tuple containing two range-lists. One for I | ||||
Pv4 addresses | ||||
// and one for IPv6 addresses. | ||||
filter_tuple_t export_filter() const; | filter_tuple_t export_filter() const; | |||
// void print() const; | // void print() const; | |||
private: | private: | |||
detail::filter_impl<address_v4::bytes_type> m_filter4; | detail::filter_impl<address_v4::bytes_type> m_filter4; | |||
#if TORRENT_USE_IPV6 | #if TORRENT_USE_IPV6 | |||
detail::filter_impl<address_v6::bytes_type> m_filter6; | detail::filter_impl<address_v6::bytes_type> m_filter6; | |||
#endif | #endif | |||
}; | }; | |||
// the port filter maps non-overlapping port ranges to flags. This | ||||
// is primarily used to indicate whether a range of ports should | ||||
// be connected to or not. The default is to have the full port | ||||
// range (0-65535) set to flag 0. | ||||
class TORRENT_EXPORT port_filter | class TORRENT_EXPORT port_filter | |||
{ | { | |||
public: | public: | |||
// the defined flags for a port range | ||||
enum access_flags | enum access_flags | |||
{ | { | |||
// this flag indicates that destination ports in the | ||||
// range should not be connected to | ||||
blocked = 1 | blocked = 1 | |||
}; | }; | |||
// set the flags for the specified port range (``first``, ``last``) | ||||
to | ||||
// ``flags`` overwriting any existing rule for those ports. The rang | ||||
e | ||||
// is inclusive, i.e. the port ``last`` also has the flag set on it. | ||||
void add_rule(boost::uint16_t first, boost::uint16_t last, int flags ); | void add_rule(boost::uint16_t first, boost::uint16_t last, int flags ); | |||
// test the specified port (``port``) for whether it is blocked | ||||
// or not. The returned value is the flags set for this port. | ||||
// see acces_flags. | ||||
int access(boost::uint16_t port) const; | int access(boost::uint16_t port) const; | |||
private: | private: | |||
detail::filter_impl<boost::uint16_t> m_filter; | detail::filter_impl<boost::uint16_t> m_filter; | |||
}; | }; | |||
} | } | |||
End of changes. 13 change blocks. | ||||
3 lines changed or deleted | 66 lines changed or added | |||
lazy_entry.hpp | lazy_entry.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2003, Arvid Norberg | Copyright (c) 2003-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 43 | skipping to change at line 43 | |||
#ifndef TORRENT_LAZY_ENTRY_HPP_INCLUDED | #ifndef TORRENT_LAZY_ENTRY_HPP_INCLUDED | |||
#define TORRENT_LAZY_ENTRY_HPP_INCLUDED | #define TORRENT_LAZY_ENTRY_HPP_INCLUDED | |||
#include <utility> | #include <utility> | |||
#include <vector> | #include <vector> | |||
#include <string> | #include <string> | |||
#include <cstring> | #include <cstring> | |||
#include <algorithm> | #include <algorithm> | |||
#include "libtorrent/config.hpp" | #include "libtorrent/config.hpp" | |||
#include "libtorrent/assert.hpp" | #include "libtorrent/assert.hpp" | |||
#include "libtorrent/size_type.hpp" | ||||
#include "libtorrent/error_code.hpp" | #include "libtorrent/error_code.hpp" | |||
#if TORRENT_USE_IOSTREAM | ||||
#include <iosfwd> | ||||
#endif | ||||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
struct lazy_entry; | struct lazy_entry; | |||
TORRENT_EXPORT char const* parse_int(char const* start, char const* | // This function decodes bencoded_ data. | |||
end | // | |||
, char delimiter, boost::int64_t& val); | // .. _bencoded: http://wiki.theory.org/index.php/BitTorrentSpecific | |||
ation | ||||
// return 0 = success | // | |||
// Whenever possible, ``lazy_bdecode()`` should be preferred over `` | ||||
bdecode()``. | ||||
// It is more efficient and more secure. It supports having constrai | ||||
nts on the | ||||
// amount of memory is consumed by the parser. | ||||
// | ||||
// *lazy* refers to the fact that it doesn't copy any actual data ou | ||||
t of the | ||||
// bencoded buffer. It builds a tree of ``lazy_entry`` which has poi | ||||
nters into | ||||
// the bencoded buffer. This makes it very fast and efficient. On to | ||||
p of that, | ||||
// it is not recursive, which saves a lot of stack space when parsin | ||||
g deeply | ||||
// nested trees. However, in order to protect against potential atta | ||||
cks, the | ||||
// ``depth_limit`` and ``item_limit`` control how many levels deep t | ||||
he tree is | ||||
// allowed to get. With recursive parser, a few thousand levels woul | ||||
d be enough | ||||
// to exhaust the threads stack and terminate the process. The ``ite | ||||
m_limit`` | ||||
// protects against very large structures, not necessarily deep. Eac | ||||
h bencoded | ||||
// item in the structure causes the parser to allocate some amount o | ||||
f memory, | ||||
// this memory is constant regardless of how much data actually is s | ||||
tored in | ||||
// the item. One potential attack is to create a bencoded list of hu | ||||
ndreds of | ||||
// thousands empty strings, which would cause the parser to allocate | ||||
a significant | ||||
// amount of memory, perhaps more than is available on the machine, | ||||
and effectively | ||||
// provide a denial of service. The default item limit is set as a r | ||||
easonable | ||||
// upper limit for desktop computers. Very few torrents have more it | ||||
ems in them. | ||||
// The limit corresponds to about 25 MB, which might be a bit much f | ||||
or embedded | ||||
// systems. | ||||
// | ||||
// ``start`` and ``end`` defines the bencoded buffer to be decoded. | ||||
``ret`` is | ||||
// the ``lazy_entry`` which is filled in with the whole decoded tree | ||||
. ``ec`` | ||||
// is a reference to an ``error_code`` which is set to describe the | ||||
error encountered | ||||
// in case the function fails. ``error_pos`` is an optional pointer | ||||
to an int, | ||||
// which will be set to the byte offset into the buffer where an err | ||||
or occurred, | ||||
// in case the function fails. | ||||
TORRENT_EXPORT int lazy_bdecode(char const* start, char const* end | TORRENT_EXPORT int lazy_bdecode(char const* start, char const* end | |||
, lazy_entry& ret, error_code& ec, int* error_pos = 0 | , lazy_entry& ret, error_code& ec, int* error_pos = 0 | |||
, int depth_limit = 1000, int item_limit = 1000000); | , int depth_limit = 1000, int item_limit = 1000000); | |||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
// for backwards compatibility, does not report error code | // for backwards compatibility, does not report error code | |||
// deprecated in 0.16 | // deprecated in 0.16 | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
TORRENT_EXPORT int lazy_bdecode(char const* start, char const* end | TORRENT_EXPORT int lazy_bdecode(char const* start, char const* end | |||
, lazy_entry& ret, int depth_limit = 1000, int item_limit = 1000000) TORRENT_DEPRECATED; | , lazy_entry& ret, int depth_limit = 1000, int item_limit = 1000000) TORRENT_DEPRECATED; | |||
#endif | #endif | |||
struct pascal_string | // this is a string that is not NULL-terminated. Instead it | |||
// comes with a length, specified in bytes. This is particularly | ||||
// useful when parsing bencoded structures, because strings are | ||||
// not NULL-terminated internally, and requiring NULL termination | ||||
// would require copying the string. | ||||
// | ||||
// see lazy_entry::string_pstr(). | ||||
struct TORRENT_EXPORT pascal_string | ||||
{ | { | |||
// construct a string pointing to the characters at ``p`` | ||||
// of length ``l`` characters. No NULL termination is requir | ||||
ed. | ||||
pascal_string(char const* p, int l): len(l), ptr(p) {} | pascal_string(char const* p, int l): len(l), ptr(p) {} | |||
// the number of characters in the string. | ||||
int len; | int len; | |||
// the pointer to the first character in the string. This is | ||||
// not NULL terminated, but instead consult the ``len`` fiel | ||||
d | ||||
// to know how many characters follow. | ||||
char const* ptr; | char const* ptr; | |||
// lexicographical comparison of strings. Order is consisten | ||||
// with memcmp. | ||||
bool operator<(pascal_string const& rhs) const | bool operator<(pascal_string const& rhs) const | |||
{ | { | |||
return std::memcmp(ptr, rhs.ptr, (std::min)(len, rhs .len)) < 0 | return std::memcmp(ptr, rhs.ptr, (std::min)(len, rhs .len)) < 0 | |||
|| len < rhs.len; | || len < rhs.len; | |||
} | } | |||
}; | }; | |||
struct lazy_dict_entry; | struct lazy_dict_entry; | |||
// this object represent a node in a bencoded structure. It is a var | ||||
iant | ||||
// type whose concrete type is one of: | ||||
// | ||||
// 1. dictionary (maps strings -> lazy_entry) | ||||
// 2. list (sequence of lazy_entry, i.e. heterogenous) | ||||
// 3. integer | ||||
// 4. string | ||||
// | ||||
// There is also a ``none`` type, which is used for uninitialized | ||||
// lazy_entries. | ||||
struct TORRENT_EXPORT lazy_entry | struct TORRENT_EXPORT lazy_entry | |||
{ | { | |||
// The different types a lazy_entry can have | ||||
enum entry_type_t | enum entry_type_t | |||
{ | { | |||
none_t, dict_t, list_t, string_t, int_t | none_t, dict_t, list_t, string_t, int_t | |||
}; | }; | |||
// internal | ||||
lazy_entry() : m_begin(0), m_len(0), m_size(0), m_capacity(0 ), m_type(none_t) | lazy_entry() : m_begin(0), m_len(0), m_size(0), m_capacity(0 ), m_type(none_t) | |||
{ m_data.start = 0; } | { m_data.start = 0; } | |||
// tells you which specific type this lazy entry has. | ||||
// See entry_type_t. The type determines which subset of | ||||
// member functions are valid to use. | ||||
entry_type_t type() const { return (entry_type_t)m_type; } | entry_type_t type() const { return (entry_type_t)m_type; } | |||
// start points to the first decimal digit | // start points to the first decimal digit | |||
// length is the number of digits | // length is the number of digits | |||
void construct_int(char const* start, int length) | void construct_int(char const* start, int length) | |||
{ | { | |||
TORRENT_ASSERT(m_type == none_t); | TORRENT_ASSERT(m_type == none_t); | |||
m_type = int_t; | m_type = int_t; | |||
m_data.start = start; | m_data.start = start; | |||
m_size = length; | m_size = length; | |||
m_begin = start - 1; // include 'i' | m_begin = start - 1; // include 'i' | |||
m_len = length + 2; // include 'e' | m_len = length + 2; // include 'e' | |||
} | } | |||
size_type int_value() const; | // requires the type to be an integer. return the integer va | |||
lue | ||||
// string functions | boost::int64_t int_value() const; | |||
// ================ | ||||
// internal | ||||
void construct_string(char const* start, int length); | void construct_string(char const* start, int length); | |||
// the string is not null-terminated! | // the string is not null-terminated! | |||
// use string_length() to determine how many bytes | ||||
// are part of the string. | ||||
char const* string_ptr() const | char const* string_ptr() const | |||
{ | { | |||
TORRENT_ASSERT(m_type == string_t); | TORRENT_ASSERT(m_type == string_t); | |||
return m_data.start; | return m_data.start; | |||
} | } | |||
// this will return a null terminated string | // this will return a null terminated string | |||
// it will write to the source buffer! | // it will write to the source buffer! | |||
char const* string_cstr() const | char const* string_cstr() const | |||
{ | { | |||
TORRENT_ASSERT(m_type == string_t); | TORRENT_ASSERT(m_type == string_t); | |||
const_cast<char*>(m_data.start)[m_size] = 0; | const_cast<char*>(m_data.start)[m_size] = 0; | |||
return m_data.start; | return m_data.start; | |||
} | } | |||
// if this is a string, returns a pascal_string | ||||
// representing the string value. | ||||
pascal_string string_pstr() const | pascal_string string_pstr() const | |||
{ | { | |||
TORRENT_ASSERT(m_type == string_t); | TORRENT_ASSERT(m_type == string_t); | |||
return pascal_string(m_data.start, m_size); | return pascal_string(m_data.start, m_size); | |||
} | } | |||
// if this is a string, returns the string as a std::string. | ||||
// (which requires a copy) | ||||
std::string string_value() const | std::string string_value() const | |||
{ | { | |||
TORRENT_ASSERT(m_type == string_t); | TORRENT_ASSERT(m_type == string_t); | |||
return std::string(m_data.start, m_size); | return std::string(m_data.start, m_size); | |||
} | } | |||
// if the lazy_entry is a string, returns the | ||||
// length of the string, in bytes. | ||||
int string_length() const | int string_length() const | |||
{ return m_size; } | { return m_size; } | |||
// dictionary functions | // internal | |||
// ==================== | ||||
void construct_dict(char const* begin) | void construct_dict(char const* begin) | |||
{ | { | |||
TORRENT_ASSERT(m_type == none_t); | TORRENT_ASSERT(m_type == none_t); | |||
m_type = dict_t; | m_type = dict_t; | |||
m_size = 0; | m_size = 0; | |||
m_capacity = 0; | m_capacity = 0; | |||
m_begin = begin; | m_begin = begin; | |||
} | } | |||
// internal | ||||
lazy_entry* dict_append(char const* name); | lazy_entry* dict_append(char const* name); | |||
// internal | ||||
void pop(); | void pop(); | |||
// if this is a dictionary, look for a key ``name``, and ret | ||||
urn | ||||
// a pointer to its value, or NULL if there is none. | ||||
lazy_entry* dict_find(char const* name); | lazy_entry* dict_find(char const* name); | |||
lazy_entry const* dict_find(char const* name) const | lazy_entry const* dict_find(char const* name) const | |||
{ return const_cast<lazy_entry*>(this)->dict_find(name); } | { return const_cast<lazy_entry*>(this)->dict_find(name); } | |||
lazy_entry* dict_find(std::string const& name); | lazy_entry const* dict_find_string(char const* name) const; | |||
lazy_entry const* dict_find(std::string const& name) const | ||||
{ return const_cast<lazy_entry*>(this)->dict_find(name); } | ||||
// if this is a dictionary, look for a key ``name`` whose va | ||||
lue | ||||
// is a string. If such key exist, return a pointer to | ||||
// its value, otherwise NULL. | ||||
std::string dict_find_string_value(char const* name) const; | std::string dict_find_string_value(char const* name) const; | |||
pascal_string dict_find_pstr(char const* name) const; | pascal_string dict_find_pstr(char const* name) const; | |||
size_type dict_find_int_value(char const* name, size_type de | ||||
fault_val = 0) const; | // if this is a dictionary, look for a key ``name`` whose va | |||
lue | ||||
// is an int. If such key exist, return a pointer to its val | ||||
ue, | ||||
// otherwise NULL. | ||||
boost::int64_t dict_find_int_value(char const* name, boost:: | ||||
int64_t default_val = 0) const; | ||||
lazy_entry const* dict_find_int(char const* name) const; | ||||
// these functions require that ``this`` is a dictionary. | ||||
// (this->type() == dict_t). They look for an element with t | ||||
he | ||||
// specified name in the dictionary. ``dict_find_dict`` only | ||||
// finds dictionaries and ``dict_find_list`` only finds list | ||||
s. | ||||
// if no key with the corresponding value of the right type | ||||
is | ||||
// found, NULL is returned. | ||||
lazy_entry const* dict_find_dict(char const* name) const; | lazy_entry const* dict_find_dict(char const* name) const; | |||
lazy_entry const* dict_find_dict(std::string const& name) co nst; | ||||
lazy_entry const* dict_find_list(char const* name) const; | lazy_entry const* dict_find_list(char const* name) const; | |||
lazy_entry const* dict_find_string(char const* name) const; | ||||
lazy_entry const* dict_find_int(char const* name) const; | ||||
// if this is a dictionary, return the key value pair at | ||||
// position ``i`` from the dictionary. | ||||
std::pair<std::string, lazy_entry const*> dict_at(int i) con st; | std::pair<std::string, lazy_entry const*> dict_at(int i) con st; | |||
// requires that ``this`` is a dictionary. return the | ||||
// number of items in it | ||||
int dict_size() const | int dict_size() const | |||
{ | { | |||
TORRENT_ASSERT(m_type == dict_t); | TORRENT_ASSERT(m_type == dict_t); | |||
return m_size; | return m_size; | |||
} | } | |||
// list functions | // internal | |||
// ============== | ||||
void construct_list(char const* begin) | void construct_list(char const* begin) | |||
{ | { | |||
TORRENT_ASSERT(m_type == none_t); | TORRENT_ASSERT(m_type == none_t); | |||
m_type = list_t; | m_type = list_t; | |||
m_size = 0; | m_size = 0; | |||
m_capacity = 0; | m_capacity = 0; | |||
m_begin = begin; | m_begin = begin; | |||
} | } | |||
// internal | ||||
lazy_entry* list_append(); | lazy_entry* list_append(); | |||
// requires that ``this`` is a list. return | ||||
// the item at index ``i``. | ||||
lazy_entry* list_at(int i) | lazy_entry* list_at(int i) | |||
{ | { | |||
TORRENT_ASSERT(m_type == list_t); | TORRENT_ASSERT(m_type == list_t); | |||
TORRENT_ASSERT(i < int(m_size)); | TORRENT_ASSERT(i < int(m_size)); | |||
return &m_data.list[i]; | return &m_data.list[i]; | |||
} | } | |||
lazy_entry const* list_at(int i) const | lazy_entry const* list_at(int i) const | |||
{ return const_cast<lazy_entry*>(this)->list_at(i); } | { return const_cast<lazy_entry*>(this)->list_at(i); } | |||
// these functions require ``this`` to have the type list. | ||||
// (this->type() == list_t). ``list_string_value_at`` return | ||||
s | ||||
// the string at index ``i``. ``list_pstr_at`` | ||||
// returns a pascal_string of the string value at index ``i` | ||||
`. | ||||
// if the element at ``i`` is not a string, an empty string | ||||
// is returned. | ||||
std::string list_string_value_at(int i) const; | std::string list_string_value_at(int i) const; | |||
pascal_string list_pstr_at(int i) const; | pascal_string list_pstr_at(int i) const; | |||
size_type list_int_value_at(int i, size_type default_val = 0 ) const; | ||||
// this function require ``this`` to have the type list. | ||||
// (this->type() == list_t). returns the integer value at | ||||
// index ``i``. If the element at ``i`` is not an integer | ||||
// ``default_val`` is returned, which defaults to 0. | ||||
boost::int64_t list_int_value_at(int i, boost::int64_t defau | ||||
lt_val = 0) const; | ||||
// if this is a list, return the number of items in it. | ||||
int list_size() const | int list_size() const | |||
{ | { | |||
TORRENT_ASSERT(m_type == list_t); | TORRENT_ASSERT(m_type == list_t); | |||
return int(m_size); | return int(m_size); | |||
} | } | |||
// end points one byte passed last byte | // internal: end points one byte passed last byte in the sou | |||
rce | ||||
// buffer backing the bencoded structure. | ||||
void set_end(char const* end) | void set_end(char const* end) | |||
{ | { | |||
TORRENT_ASSERT(end > m_begin); | TORRENT_ASSERT(end > m_begin); | |||
m_len = end - m_begin; | m_len = end - m_begin; | |||
} | } | |||
// internal | ||||
void clear(); | void clear(); | |||
// releases ownership of any memory allocated | // internal: releases ownership of any memory allocated | |||
void release() | void release() | |||
{ | { | |||
m_data.start = 0; | m_data.start = 0; | |||
m_size = 0; | m_size = 0; | |||
m_capacity = 0; | m_capacity = 0; | |||
m_type = none_t; | m_type = none_t; | |||
} | } | |||
// internal | ||||
~lazy_entry() | ~lazy_entry() | |||
{ clear(); } | { clear(); } | |||
// returns pointers into the source buffer where | // returns pointers into the source buffer where | |||
// this entry has its bencoded data | // this entry has its bencoded data | |||
std::pair<char const*, int> data_section() const; | std::pair<char const*, int> data_section() const; | |||
// swap values of ``this`` and ``e``. | ||||
void swap(lazy_entry& e) | void swap(lazy_entry& e) | |||
{ | { | |||
using std::swap; | using std::swap; | |||
boost::uint32_t tmp = e.m_type; | boost::uint32_t tmp = e.m_type; | |||
e.m_type = m_type; | e.m_type = m_type; | |||
m_type = tmp; | m_type = tmp; | |||
tmp = e.m_capacity; | tmp = e.m_capacity; | |||
e.m_capacity = m_capacity; | e.m_capacity = m_capacity; | |||
m_capacity = tmp; | m_capacity = tmp; | |||
swap(m_data.start, e.m_data.start); | swap(m_data.start, e.m_data.start); | |||
skipping to change at line 290 | skipping to change at line 389 | |||
lazy_entry(lazy_entry const&); | lazy_entry(lazy_entry const&); | |||
lazy_entry const& operator=(lazy_entry const&); | lazy_entry const& operator=(lazy_entry const&); | |||
}; | }; | |||
struct lazy_dict_entry | struct lazy_dict_entry | |||
{ | { | |||
char const* name; | char const* name; | |||
lazy_entry val; | lazy_entry val; | |||
}; | }; | |||
// print the bencoded structure in a human-readable format to a stti | ||||
ng | ||||
// that's returned. | ||||
TORRENT_EXPORT std::string print_entry(lazy_entry const& e | TORRENT_EXPORT std::string print_entry(lazy_entry const& e | |||
, bool single_line = false, int indent = 0); | , bool single_line = false, int indent = 0); | |||
#if TORRENT_USE_IOSTREAM | ||||
TORRENT_EXPORT std::ostream& operator<<(std::ostream& os, lazy_entry | // get the ``error_category`` for bdecode errors | |||
const& e); | TORRENT_EXPORT boost::system::error_category& get_bdecode_category() | |||
#endif | ; | |||
namespace bdecode_errors | ||||
{ | ||||
// libtorrent uses boost.system's ``error_code`` class to re | ||||
present errors. libtorrent has | ||||
// its own error category get_bdecode_category() whith the e | ||||
rror codes defined by error_code_enum. | ||||
enum error_code_enum | ||||
{ | ||||
// Not an error | ||||
no_error = 0, | ||||
// expected string in bencoded string | ||||
expected_string, | ||||
// expected colon in bencoded string | ||||
expected_colon, | ||||
// unexpected end of file in bencoded string | ||||
unexpected_eof, | ||||
// expected value (list, dict, int or string) in ben | ||||
coded string | ||||
expected_value, | ||||
// bencoded recursion depth limit exceeded | ||||
depth_exceeded, | ||||
// bencoded item count limit exceeded | ||||
limit_exceeded, | ||||
// integer overflow | ||||
overflow, | ||||
// the number of error codes | ||||
error_code_max | ||||
}; | ||||
// hidden | ||||
TORRENT_EXPORT boost::system::error_code make_error_code(err | ||||
or_code_enum e); | ||||
} | ||||
TORRENT_EXTRA_EXPORT char const* parse_int(char const* start | ||||
, char const* end, char delimiter, boost::int64_t& val | ||||
, bdecode_errors::error_code_enum& ec); | ||||
} | } | |||
#if BOOST_VERSION >= 103500 | ||||
namespace boost { namespace system { | ||||
template<> struct is_error_code_enum<libtorrent::bdecode_errors::err | ||||
or_code_enum> | ||||
{ static const bool value = true; }; | ||||
template<> struct is_error_condition_enum<libtorrent::bdecode_errors | ||||
::error_code_enum> | ||||
{ static const bool value = true; }; | ||||
} } | ||||
#endif | ||||
#endif | #endif | |||
End of changes. 44 change blocks. | ||||
37 lines changed or deleted | 232 lines changed or added | |||
logging.hpp | logging.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2006, Arvid Norberg & Daniel Wallin | Copyright (c) 2006-2014, Arvid Norberg & Daniel Wallin | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 90 | skipping to change at line 90 | |||
private: | private: | |||
char const* m_id; | char const* m_id; | |||
bool m_enabled; | bool m_enabled; | |||
std::ostream& m_stream; | std::ostream& m_stream; | |||
}; | }; | |||
class log_event | class log_event | |||
{ | { | |||
public: | public: | |||
log_event(log& log) | log_event(log& log); | |||
: log_(log) | ~log_event(); | |||
{ | ||||
if (log_.enabled()) | ||||
log_ << time_now_string() << " [" << log.id() << "] | ||||
"; | ||||
} | ||||
~log_event() | ||||
{ | ||||
if (log_.enabled()) | ||||
{ | ||||
log_ << "\n"; | ||||
log_.flush(); | ||||
} | ||||
} | ||||
template<class T> | template<class T> | |||
log_event& operator<<(T const& x) | log_event& operator<<(T const& x) | |||
{ | { | |||
log_ << x; | log_ << x; | |||
return *this; | return *this; | |||
} | } | |||
operator bool() const | operator bool() const | |||
{ | { | |||
End of changes. 2 change blocks. | ||||
17 lines changed or deleted | 3 lines changed or added | |||
lsd.hpp | lsd.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2007, Arvid Norberg | Copyright (c) 2007-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 47 | skipping to change at line 47 | |||
#include "libtorrent/peer_id.hpp" | #include "libtorrent/peer_id.hpp" | |||
#include "libtorrent/broadcast_socket.hpp" | #include "libtorrent/broadcast_socket.hpp" | |||
#include "libtorrent/intrusive_ptr_base.hpp" | #include "libtorrent/intrusive_ptr_base.hpp" | |||
#include "libtorrent/deadline_timer.hpp" | #include "libtorrent/deadline_timer.hpp" | |||
#include <boost/function/function2.hpp> | #include <boost/function/function2.hpp> | |||
#include <boost/noncopyable.hpp> | #include <boost/noncopyable.hpp> | |||
#include <boost/shared_ptr.hpp> | #include <boost/shared_ptr.hpp> | |||
#if defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING) | #if defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING) | |||
#include <fstream> | #include <stdio.h> | |||
#endif | #endif | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
typedef boost::function<void(tcp::endpoint, sha1_hash)> peer_callback_t; | typedef boost::function<void(tcp::endpoint, sha1_hash)> peer_callback_t; | |||
class lsd : public intrusive_ptr_base<lsd> | class lsd : public intrusive_ptr_base<lsd> | |||
{ | { | |||
public: | public: | |||
End of changes. 2 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
lt_trackers.hpp | lt_trackers.hpp | |||
---|---|---|---|---|
skipping to change at line 36 | skipping to change at line 36 | |||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 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 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||
POSSIBILITY OF SUCH DAMAGE. | POSSIBILITY OF SUCH DAMAGE. | |||
*/ | */ | |||
#ifndef TORRENT_LT_TRACKERS_HPP_INCLUDED | #ifndef TORRENT_LT_TRACKERS_HPP_INCLUDED | |||
#define TORRENT_LT_TRACKERS_HPP_INCLUDED | #define TORRENT_LT_TRACKERS_HPP_INCLUDED | |||
#ifndef TORRENT_DISABLE_EXTENSIONS | ||||
#ifdef _MSC_VER | #ifdef _MSC_VER | |||
#pragma warning(push, 1) | #pragma warning(push, 1) | |||
#endif | #endif | |||
#include <boost/shared_ptr.hpp> | #include <boost/shared_ptr.hpp> | |||
#include "libtorrent/config.hpp" | #include "libtorrent/config.hpp" | |||
#ifdef _MSC_VER | #ifdef _MSC_VER | |||
#pragma warning(pop) | #pragma warning(pop) | |||
#endif | #endif | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
struct torrent_plugin; | struct torrent_plugin; | |||
class torrent; | class torrent; | |||
// constructor function for the trackers exchange extension. This ca | ||||
n | ||||
// either be passed in the add_torrent_params::extensions field, or | ||||
// via torrent_handle::add_extension(). | ||||
boost::shared_ptr<torrent_plugin> TORRENT_EXPORT create_lt_trackers_ plugin(torrent*, void*); | boost::shared_ptr<torrent_plugin> TORRENT_EXPORT create_lt_trackers_ plugin(torrent*, void*); | |||
} | } | |||
#endif // TORRENT_DISABLE_EXTENSIONS | ||||
#endif // TORRENT_LT_TRACKERS_HPP_INCLUDED | #endif // TORRENT_LT_TRACKERS_HPP_INCLUDED | |||
End of changes. 3 change blocks. | ||||
0 lines changed or deleted | 9 lines changed or added | |||
magnet_uri.hpp | magnet_uri.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2007, Arvid Norberg | Copyright (c) 2007-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 46 | skipping to change at line 46 | |||
#include <string> | #include <string> | |||
#include "libtorrent/config.hpp" | #include "libtorrent/config.hpp" | |||
#include "libtorrent/torrent_handle.hpp" | #include "libtorrent/torrent_handle.hpp" | |||
#include "libtorrent/add_torrent_params.hpp" | #include "libtorrent/add_torrent_params.hpp" | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
struct torrent_handle; | struct torrent_handle; | |||
class session; | class session; | |||
// Generates a magnet URI from the specified torrent. If the torrent | ||||
// handle is invalid, an empty string is returned. | ||||
// | ||||
// For more information about magnet links, see magnet-links_. | ||||
// | ||||
std::string TORRENT_EXPORT make_magnet_uri(torrent_handle const& han dle); | std::string TORRENT_EXPORT make_magnet_uri(torrent_handle const& han dle); | |||
std::string TORRENT_EXPORT make_magnet_uri(torrent_info const& info) ; | std::string TORRENT_EXPORT make_magnet_uri(torrent_info const& info) ; | |||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
#ifndef BOOST_NO_EXCEPTIONS | #ifndef BOOST_NO_EXCEPTIONS | |||
// deprecated in 0.14 | // deprecated in 0.14 | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
torrent_handle TORRENT_EXPORT add_magnet_uri(session& ses, std::stri ng const& uri | torrent_handle TORRENT_EXPORT add_magnet_uri(session& ses, std::stri ng const& uri | |||
, std::string const& save_path | , std::string const& save_path | |||
, storage_mode_t storage_mode = storage_mode_sparse | , storage_mode_t storage_mode = storage_mode_sparse | |||
skipping to change at line 73 | skipping to change at line 78 | |||
, add_torrent_params p) TORRENT_DEPRECATED; | , add_torrent_params p) TORRENT_DEPRECATED; | |||
#endif | #endif | |||
// deprecated in 0.16. Instead, pass in the magnet link as add_torre nt_params::url | // deprecated in 0.16. Instead, pass in the magnet link as add_torre nt_params::url | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
torrent_handle TORRENT_EXPORT add_magnet_uri(session& ses, std::stri ng const& uri | torrent_handle TORRENT_EXPORT add_magnet_uri(session& ses, std::stri ng const& uri | |||
, add_torrent_params p, error_code& ec) TORRENT_DEPRECATED; | , add_torrent_params p, error_code& ec) TORRENT_DEPRECATED; | |||
#endif | #endif | |||
// This function parses out information from the magnet link and pop | ||||
ulates the | ||||
// add_torrent_params object. | ||||
TORRENT_EXPORT void parse_magnet_uri(std::string const& uri, add_tor rent_params& p, error_code& ec); | TORRENT_EXPORT void parse_magnet_uri(std::string const& uri, add_tor rent_params& p, error_code& ec); | |||
} | } | |||
#endif | #endif | |||
End of changes. 3 change blocks. | ||||
1 lines changed or deleted | 9 lines changed or added | |||
max.hpp | max.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2009, Arvid Norberg | Copyright (c) 2009-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
metadata_transfer.hpp | metadata_transfer.hpp | |||
---|---|---|---|---|
skipping to change at line 36 | skipping to change at line 36 | |||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 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 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||
POSSIBILITY OF SUCH DAMAGE. | POSSIBILITY OF SUCH DAMAGE. | |||
*/ | */ | |||
#ifndef TORRENT_METADATA_TRANSFER_HPP_INCLUDED | #ifndef TORRENT_METADATA_TRANSFER_HPP_INCLUDED | |||
#define TORRENT_METADATA_TRANSFER_HPP_INCLUDED | #define TORRENT_METADATA_TRANSFER_HPP_INCLUDED | |||
#ifndef TORRENT_DISABLE_EXTENSIONS | ||||
#ifdef _MSC_VER | #ifdef _MSC_VER | |||
#pragma warning(push, 1) | #pragma warning(push, 1) | |||
#endif | #endif | |||
#include <boost/shared_ptr.hpp> | #include <boost/shared_ptr.hpp> | |||
#include "libtorrent/config.hpp" | #include "libtorrent/config.hpp" | |||
#ifdef _MSC_VER | #ifdef _MSC_VER | |||
#pragma warning(pop) | #pragma warning(pop) | |||
#endif | #endif | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
struct torrent_plugin; | struct torrent_plugin; | |||
class torrent; | class torrent; | |||
TORRENT_EXPORT boost::shared_ptr<torrent_plugin> create_metadata_plu | ||||
gin(torrent*, void*); | #ifndef TORRENT_NO_DEPRECATE | |||
// constructor function for the metadata transfer extension. This | ||||
// extension has been superceded by the ut_metadata extension and | ||||
// is deprecated. It can be either be passed in the | ||||
// add_torrent_params::extensions field, or | ||||
// via torrent_handle::add_extension(). | ||||
TORRENT_DEPRECATED_PREFIX | ||||
TORRENT_EXPORT boost::shared_ptr<torrent_plugin> | ||||
create_metadata_plugin(torrent*, void*) TORRENT_DEPRECATED; | ||||
#endif | ||||
} | } | |||
#endif // TORRENT_DISABLE_EXTENSIONS | ||||
#endif // TORRENT_METADATA_TRANSFER_HPP_INCLUDED | #endif // TORRENT_METADATA_TRANSFER_HPP_INCLUDED | |||
End of changes. 3 change blocks. | ||||
2 lines changed or deleted | 15 lines changed or added | |||
msg.hpp | msg.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2007, Arvid Norberg | Copyright (c) 2007-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
natpmp.hpp | natpmp.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2007, Arvid Norberg | Copyright (c) 2007-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 56 | skipping to change at line 56 | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
// int: port mapping index | // int: port mapping index | |||
// int: external port | // int: external port | |||
// std::string: error message | // std::string: error message | |||
typedef boost::function<void(int, address, int, error_code const&)> portmap _callback_t; | typedef boost::function<void(int, address, int, error_code const&)> portmap _callback_t; | |||
typedef boost::function<void(char const*)> log_callback_t; | typedef boost::function<void(char const*)> log_callback_t; | |||
class TORRENT_EXPORT natpmp : public intrusive_ptr_base<natpmp> | class natpmp : public intrusive_ptr_base<natpmp> | |||
{ | { | |||
public: | public: | |||
natpmp(io_service& ios, address const& listen_interface | natpmp(io_service& ios, address const& listen_interface | |||
, portmap_callback_t const& cb | , portmap_callback_t const& cb | |||
, log_callback_t const& lcb); | , log_callback_t const& lcb); | |||
void rebind(address const& listen_interface); | void rebind(address const& listen_interface); | |||
// maps the ports, if a port is set to 0 | // maps the ports, if a port is set to 0 | |||
// it will not be mapped | // it will not be mapped | |||
End of changes. 2 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
node.hpp | node.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2006, Arvid Norberg | Copyright (c) 2006-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 46 | skipping to change at line 46 | |||
#include <algorithm> | #include <algorithm> | |||
#include <map> | #include <map> | |||
#include <set> | #include <set> | |||
#include <libtorrent/config.hpp> | #include <libtorrent/config.hpp> | |||
#include <libtorrent/kademlia/routing_table.hpp> | #include <libtorrent/kademlia/routing_table.hpp> | |||
#include <libtorrent/kademlia/rpc_manager.hpp> | #include <libtorrent/kademlia/rpc_manager.hpp> | |||
#include <libtorrent/kademlia/node_id.hpp> | #include <libtorrent/kademlia/node_id.hpp> | |||
#include <libtorrent/kademlia/msg.hpp> | #include <libtorrent/kademlia/msg.hpp> | |||
#include <libtorrent/kademlia/find_data.hpp> | #include <libtorrent/kademlia/find_data.hpp> | |||
#include <libtorrent/kademlia/item.hpp> | ||||
#include <libtorrent/io.hpp> | #include <libtorrent/io.hpp> | |||
#include <libtorrent/session_settings.hpp> | #include <libtorrent/session_settings.hpp> | |||
#include <libtorrent/assert.hpp> | #include <libtorrent/assert.hpp> | |||
#include <libtorrent/thread.hpp> | #include <libtorrent/thread.hpp> | |||
#include <libtorrent/bloom_filter.hpp> | #include <libtorrent/bloom_filter.hpp> | |||
#include <boost/cstdint.hpp> | #include <boost/cstdint.hpp> | |||
#include <boost/ref.hpp> | #include <boost/ref.hpp> | |||
#include "libtorrent/socket.hpp" | #include "libtorrent/socket.hpp" | |||
namespace libtorrent { | namespace libtorrent { | |||
class alert_manager; | class alert_manager; | |||
struct alert_dispatcher; | ||||
} | } | |||
namespace libtorrent { namespace dht | namespace libtorrent { namespace dht | |||
{ | { | |||
#ifdef TORRENT_DHT_VERBOSE_LOGGING | #ifdef TORRENT_DHT_VERBOSE_LOGGING | |||
TORRENT_DECLARE_LOG(node); | TORRENT_DECLARE_LOG(node); | |||
#endif | #endif | |||
struct traversal_algorithm; | struct traversal_algorithm; | |||
struct dht_observer; | ||||
struct key_desc_t | struct key_desc_t | |||
{ | { | |||
char const* name; | char const* name; | |||
int type; | int type; | |||
int size; | int size; | |||
int flags; | int flags; | |||
enum { | enum { | |||
// this argument is optional, parsing will not | // this argument is optional, parsing will not | |||
skipping to change at line 104 | skipping to change at line 107 | |||
}; | }; | |||
bool TORRENT_EXTRA_EXPORT verify_message(lazy_entry const* msg, key_desc_t const desc[] | bool TORRENT_EXTRA_EXPORT verify_message(lazy_entry const* msg, key_desc_t const desc[] | |||
, lazy_entry const* ret[], int size , char* error, int error_size); | , lazy_entry const* ret[], int size , char* error, int error_size); | |||
// this is the entry for every peer | // this is the entry for every peer | |||
// the timestamp is there to make it possible | // the timestamp is there to make it possible | |||
// to remove stale peers | // to remove stale peers | |||
struct peer_entry | struct peer_entry | |||
{ | { | |||
tcp::endpoint addr; | ||||
ptime added; | ptime added; | |||
tcp::endpoint addr; | ||||
bool seed; | bool seed; | |||
}; | }; | |||
// this is a group. It contains a set of group members | // this is a group. It contains a set of group members | |||
struct torrent_entry | struct torrent_entry | |||
{ | { | |||
std::string name; | std::string name; | |||
std::set<peer_entry> peers; | std::set<peer_entry> peers; | |||
}; | }; | |||
skipping to change at line 133 | skipping to change at line 136 | |||
// popularity if we reach the limit of items to store | // popularity if we reach the limit of items to store | |||
bloom_filter<128> ips; | bloom_filter<128> ips; | |||
// the last time we heard about this | // the last time we heard about this | |||
ptime last_seen; | ptime last_seen; | |||
// number of IPs in the bloom filter | // number of IPs in the bloom filter | |||
int num_announcers; | int num_announcers; | |||
// size of malloced space pointed to by value | // size of malloced space pointed to by value | |||
int size; | int size; | |||
}; | }; | |||
struct rsa_key { char bytes[268]; }; | struct ed25519_public_key { char bytes[item_pk_len]; }; | |||
struct dht_mutable_item : dht_immutable_item | struct dht_mutable_item : dht_immutable_item | |||
{ | { | |||
char sig[256]; | char sig[item_sig_len]; | |||
int seq; | boost::uint64_t seq; | |||
rsa_key key; | ed25519_public_key key; | |||
char* salt; | ||||
int salt_size; | ||||
}; | }; | |||
inline bool operator<(rsa_key const& lhs, rsa_key const& rhs) | // internal | |||
inline bool operator<(ed25519_public_key const& lhs, ed25519_public_key con | ||||
st& rhs) | ||||
{ | { | |||
return memcmp(lhs.bytes, rhs.bytes, sizeof(lhs.bytes)) < 0; | return memcmp(lhs.bytes, rhs.bytes, sizeof(lhs.bytes)) < 0; | |||
} | } | |||
// internal | ||||
inline bool operator<(peer_entry const& lhs, peer_entry const& rhs) | inline bool operator<(peer_entry const& lhs, peer_entry const& rhs) | |||
{ | { | |||
return lhs.addr.address() == rhs.addr.address() | return lhs.addr.address() == rhs.addr.address() | |||
? lhs.addr.port() < rhs.addr.port() | ? lhs.addr.port() < rhs.addr.port() | |||
: lhs.addr.address() < rhs.addr.address(); | : lhs.addr.address() < rhs.addr.address(); | |||
} | } | |||
struct null_type {}; | struct null_type {}; | |||
class announce_observer : public observer | class announce_observer : public observer | |||
skipping to change at line 178 | skipping to change at line 185 | |||
{ | { | |||
int& count; | int& count; | |||
count_peers(int& c): count(c) {} | count_peers(int& c): count(c) {} | |||
void operator()(std::pair<libtorrent::dht::node_id | void operator()(std::pair<libtorrent::dht::node_id | |||
, libtorrent::dht::torrent_entry> const& t) | , libtorrent::dht::torrent_entry> const& t) | |||
{ | { | |||
count += t.second.peers.size(); | count += t.second.peers.size(); | |||
} | } | |||
}; | }; | |||
struct udp_socket_interface | ||||
{ | ||||
virtual bool send_packet(entry& e, udp::endpoint const& addr, int fl | ||||
ags) = 0; | ||||
}; | ||||
class TORRENT_EXTRA_EXPORT node_impl : boost::noncopyable | class TORRENT_EXTRA_EXPORT node_impl : boost::noncopyable | |||
{ | { | |||
typedef std::map<node_id, torrent_entry> table_t; | typedef std::map<node_id, torrent_entry> table_t; | |||
typedef std::map<node_id, dht_immutable_item> dht_immutable_table_t; | typedef std::map<node_id, dht_immutable_item> dht_immutable_table_t; | |||
typedef std::map<node_id, dht_mutable_item> dht_mutable_table_t; | typedef std::map<node_id, dht_mutable_item> dht_mutable_table_t; | |||
public: | public: | |||
typedef boost::function3<void, address, int, address> external_ip_fu | node_impl(alert_dispatcher* alert_disp, udp_socket_interface* sock | |||
n; | , libtorrent::dht_settings const& settings, node_id nid, add | |||
ress const& external_address | ||||
node_impl(libtorrent::alert_manager& alerts | , dht_observer* observer); | |||
, bool (*f)(void*, entry&, udp::endpoint const&, int) | ||||
, dht_settings const& settings, node_id nid, address const& | ||||
external_address | ||||
, external_ip_fun ext_ip, void* userdata); | ||||
virtual ~node_impl() {} | virtual ~node_impl() {} | |||
void tick(); | void tick(); | |||
void refresh(node_id const& id, find_data::nodes_callback const& f); | void refresh(node_id const& id, find_data::nodes_callback const& f); | |||
void bootstrap(std::vector<udp::endpoint> const& nodes | void bootstrap(std::vector<udp::endpoint> const& nodes | |||
, find_data::nodes_callback const& f); | , find_data::nodes_callback const& f); | |||
void add_router_node(udp::endpoint router); | void add_router_node(udp::endpoint router); | |||
void unreachable(udp::endpoint const& ep); | void unreachable(udp::endpoint const& ep); | |||
skipping to change at line 226 | skipping to change at line 235 | |||
size_type num_global_nodes() const | size_type num_global_nodes() const | |||
{ return m_table.num_global_nodes(); } | { return m_table.num_global_nodes(); } | |||
int data_size() const { return int(m_map.size()); } | int data_size() const { return int(m_map.size()); } | |||
#ifdef TORRENT_DHT_VERBOSE_LOGGING | #ifdef TORRENT_DHT_VERBOSE_LOGGING | |||
void print_state(std::ostream& os) const | void print_state(std::ostream& os) const | |||
{ m_table.print_state(os); } | { m_table.print_state(os); } | |||
#endif | #endif | |||
void announce(sha1_hash const& info_hash, int listen_port, bool seed | enum flags_t { flag_seed = 1, flag_implied_port = 2 }; | |||
void announce(sha1_hash const& info_hash, int listen_port, int flags | ||||
, boost::function<void(std::vector<tcp::endpoint> const&)> f ); | , boost::function<void(std::vector<tcp::endpoint> const&)> f ); | |||
void get_item(sha1_hash const& target, boost::function<bool(item&)> | ||||
f); | ||||
void get_item(char const* pk, std::string const& salt, boost::functi | ||||
on<bool(item&)> f); | ||||
bool verify_token(std::string const& token, char const* info_hash | bool verify_token(std::string const& token, char const* info_hash | |||
, udp::endpoint const& addr); | , udp::endpoint const& addr); | |||
std::string generate_token(udp::endpoint const& addr, char const* in fo_hash); | std::string generate_token(udp::endpoint const& addr, char const* in fo_hash); | |||
// the returned time is the delay until connection_timeout() | // the returned time is the delay until connection_timeout() | |||
// should be called again the next time | // should be called again the next time | |||
time_duration connection_timeout(); | time_duration connection_timeout(); | |||
// generates a new secret number used to generate write tokens | // generates a new secret number used to generate write tokens | |||
skipping to change at line 265 | skipping to change at line 278 | |||
} | } | |||
void remove_traversal_algorithm(traversal_algorithm* a) | void remove_traversal_algorithm(traversal_algorithm* a) | |||
{ | { | |||
mutex_t::scoped_lock l(m_mutex); | mutex_t::scoped_lock l(m_mutex); | |||
m_running_requests.erase(a); | m_running_requests.erase(a); | |||
} | } | |||
void status(libtorrent::session_status& s); | void status(libtorrent::session_status& s); | |||
dht_settings const& settings() const { return m_settings; } | libtorrent::dht_settings const& settings() const { return m_settings ; } | |||
protected: | protected: | |||
void lookup_peers(sha1_hash const& info_hash, int prefix, entry& rep ly | void lookup_peers(sha1_hash const& info_hash, int prefix, entry& rep ly | |||
, bool noseed, bool scrape) const; | , bool noseed, bool scrape) const; | |||
bool lookup_torrents(sha1_hash const& target, entry& reply | bool lookup_torrents(sha1_hash const& target, entry& reply | |||
, char* tags) const; | , char* tags) const; | |||
dht_settings const& m_settings; | libtorrent::dht_settings const& m_settings; | |||
private: | private: | |||
typedef libtorrent::mutex mutex_t; | typedef libtorrent::mutex mutex_t; | |||
mutex_t m_mutex; | mutex_t m_mutex; | |||
// this list must be destructed after the rpc manager | // this list must be destructed after the rpc manager | |||
// since it might have references to it | // since it might have references to it | |||
std::set<traversal_algorithm*> m_running_requests; | std::set<traversal_algorithm*> m_running_requests; | |||
void incoming_request(msg const& h, entry& e); | void incoming_request(msg const& h, entry& e); | |||
node_id m_id; | node_id m_id; | |||
public: | public: | |||
routing_table m_table; | routing_table m_table; | |||
rpc_manager m_rpc; | rpc_manager m_rpc; | |||
private: | private: | |||
external_ip_fun m_ext_ip; | dht_observer* m_observer; | |||
table_t m_map; | table_t m_map; | |||
dht_immutable_table_t m_immutable_table; | dht_immutable_table_t m_immutable_table; | |||
dht_mutable_table_t m_mutable_table; | dht_mutable_table_t m_mutable_table; | |||
ptime m_last_tracker_tick; | ptime m_last_tracker_tick; | |||
// secret random numbers used to create write tokens | // secret random numbers used to create write tokens | |||
int m_secret[2]; | int m_secret[2]; | |||
libtorrent::alert_manager& m_alerts; | alert_dispatcher* m_post_alert; | |||
bool (*m_send)(void*, entry&, udp::endpoint const&, int); | udp_socket_interface* m_sock; | |||
void* m_userdata; | ||||
}; | }; | |||
} } // namespace libtorrent::dht | } } // namespace libtorrent::dht | |||
#endif // NODE_HPP | #endif // NODE_HPP | |||
End of changes. 18 change blocks. | ||||
22 lines changed or deleted | 37 lines changed or added | |||
node_entry.hpp | node_entry.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2006, Arvid Norberg | Copyright (c) 2006-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 39 | skipping to change at line 39 | |||
POSSIBILITY OF SUCH DAMAGE. | POSSIBILITY OF SUCH DAMAGE. | |||
*/ | */ | |||
#ifndef KADEMLIA_NODE_ENTRY_HPP | #ifndef KADEMLIA_NODE_ENTRY_HPP | |||
#define KADEMLIA_NODE_ENTRY_HPP | #define KADEMLIA_NODE_ENTRY_HPP | |||
#include "libtorrent/kademlia/node_id.hpp" | #include "libtorrent/kademlia/node_id.hpp" | |||
#include "libtorrent/socket.hpp" | #include "libtorrent/socket.hpp" | |||
#include "libtorrent/address.hpp" | #include "libtorrent/address.hpp" | |||
#include "libtorrent/union_endpoint.hpp" | ||||
#ifdef TORRENT_DHT_VERBOSE_LOGGING | ||||
#include "libtorrent/time.hpp" | ||||
#endif | ||||
namespace libtorrent { namespace dht | namespace libtorrent { namespace dht | |||
{ | { | |||
struct node_entry | struct node_entry | |||
{ | { | |||
node_entry(node_id const& id_, udp::endpoint ep, bool pinged = false | node_entry(node_id const& id_, udp::endpoint ep, int roundtriptime = | |||
) | 0xffff, bool pinged = false) | |||
: addr(ep.address()) | : id(id_) | |||
, port(ep.port()) | , endpoint(ep) | |||
, timeout_count(pinged ? 0 : 0xffff) | , rtt(roundtriptime & 0xffff) | |||
, id(id_) | , timeout_count(pinged ? 0 : 0xff) | |||
{ | { | |||
#ifdef TORRENT_DHT_VERBOSE_LOGGING | #ifdef TORRENT_DHT_VERBOSE_LOGGING | |||
first_seen = time_now(); | first_seen = time_now(); | |||
#endif | #endif | |||
} | } | |||
node_entry(udp::endpoint ep) | node_entry(udp::endpoint ep) | |||
: addr(ep.address()) | : id(0) | |||
, port(ep.port()) | , endpoint(ep) | |||
, timeout_count(0xffff) | , rtt(0xffff) | |||
, id(0) | , timeout_count(0xff) | |||
{ | { | |||
#ifdef TORRENT_DHT_VERBOSE_LOGGING | #ifdef TORRENT_DHT_VERBOSE_LOGGING | |||
first_seen = time_now(); | first_seen = time_now(); | |||
#endif | #endif | |||
} | } | |||
node_entry() | node_entry() | |||
: timeout_count(0xffff) | : id(0) | |||
, id(0) | , rtt(0xffff) | |||
, timeout_count(0xff) | ||||
{ | { | |||
#ifdef TORRENT_DHT_VERBOSE_LOGGING | #ifdef TORRENT_DHT_VERBOSE_LOGGING | |||
first_seen = time_now(); | first_seen = time_now(); | |||
#endif | #endif | |||
} | } | |||
bool pinged() const { return timeout_count != 0xffff; } | bool pinged() const { return timeout_count != 0xff; } | |||
void set_pinged() { if (timeout_count == 0xffff) timeout_count = 0; | void set_pinged() { if (timeout_count == 0xff) timeout_count = 0; } | |||
} | void timed_out() { if (pinged() && timeout_count < 0xfe) ++timeout_c | |||
void timed_out() { if (pinged()) ++timeout_count; } | ount; } | |||
int fail_count() const { return pinged() ? timeout_count : 0; } | int fail_count() const { return pinged() ? timeout_count : 0; } | |||
void reset_fail_count() { if (pinged()) timeout_count = 0; } | void reset_fail_count() { if (pinged()) timeout_count = 0; } | |||
udp::endpoint ep() const { return udp::endpoint(addr, port); } | udp::endpoint ep() const { return udp::endpoint(endpoint); } | |||
bool confirmed() const { return timeout_count == 0; } | bool confirmed() const { return timeout_count == 0; } | |||
void update_rtt(int new_rtt) | ||||
{ | ||||
if (rtt == 0xffff) rtt = new_rtt; | ||||
else rtt = int(rtt) / 3 + int(new_rtt) * 2 / 3; | ||||
} | ||||
address addr() const { return endpoint.address(); } | ||||
int port() const { return endpoint.port; } | ||||
// TODO: replace with a union of address_v4 and address_v6 | ||||
address addr; | ||||
boost::uint16_t port; | ||||
// the number of times this node has failed to | ||||
// respond in a row | ||||
boost::uint16_t timeout_count; | ||||
node_id id; | ||||
#ifdef TORRENT_DHT_VERBOSE_LOGGING | #ifdef TORRENT_DHT_VERBOSE_LOGGING | |||
ptime first_seen; | ptime first_seen; | |||
#endif | #endif | |||
node_id id; | ||||
union_endpoint endpoint; | ||||
// the average RTT of this node | ||||
boost::uint16_t rtt; | ||||
// the number of times this node has failed to | ||||
// respond in a row | ||||
boost::uint8_t timeout_count; | ||||
}; | }; | |||
} } // namespace libtorrent::dht | } } // namespace libtorrent::dht | |||
#endif | #endif | |||
End of changes. 10 change blocks. | ||||
25 lines changed or deleted | 42 lines changed or added | |||
node_id.hpp | node_id.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2006, Arvid Norberg | Copyright (c) 2006-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 46 | skipping to change at line 46 | |||
#include <boost/cstdint.hpp> | #include <boost/cstdint.hpp> | |||
#include "libtorrent/config.hpp" | #include "libtorrent/config.hpp" | |||
#include "libtorrent/peer_id.hpp" | #include "libtorrent/peer_id.hpp" | |||
#include "libtorrent/assert.hpp" | #include "libtorrent/assert.hpp" | |||
#include "libtorrent/address.hpp" | #include "libtorrent/address.hpp" | |||
namespace libtorrent { namespace dht | namespace libtorrent { namespace dht | |||
{ | { | |||
typedef libtorrent::big_number node_id; | struct node_entry; | |||
typedef libtorrent::sha1_hash node_id; | ||||
// returns the distance between the two nodes | // returns the distance between the two nodes | |||
// using the kademlia XOR-metric | // using the kademlia XOR-metric | |||
node_id TORRENT_EXTRA_EXPORT distance(node_id const& n1, node_id const& n2) ; | node_id TORRENT_EXTRA_EXPORT distance(node_id const& n1, node_id const& n2) ; | |||
// returns true if: distance(n1, ref) < distance(n2, ref) | // returns true if: distance(n1, ref) < distance(n2, ref) | |||
bool TORRENT_EXTRA_EXPORT compare_ref(node_id const& n1, node_id const& n2, node_id const& ref); | bool TORRENT_EXTRA_EXPORT compare_ref(node_id const& n1, node_id const& n2, node_id const& ref); | |||
// returns n in: 2^n <= distance(n1, n2) < 2^(n+1) | // returns n in: 2^n <= distance(n1, n2) < 2^(n+1) | |||
// usefult for finding out which bucket a node belongs to | // useful for finding out which bucket a node belongs to | |||
// the value that's returned is the number of trailing bits | ||||
// after the shared bit prefix of ``n1`` and ``n2``. | ||||
// if the first bits are different, that's 160. | ||||
int TORRENT_EXTRA_EXPORT distance_exp(node_id const& n1, node_id const& n2) ; | int TORRENT_EXTRA_EXPORT distance_exp(node_id const& n1, node_id const& n2) ; | |||
node_id TORRENT_EXTRA_EXPORT generate_id(address const& external_ip); | node_id TORRENT_EXTRA_EXPORT generate_id(address const& external_ip); | |||
node_id TORRENT_EXTRA_EXPORT generate_random_id(); | node_id TORRENT_EXTRA_EXPORT generate_random_id(); | |||
node_id TORRENT_EXTRA_EXPORT generate_id_impl(address const& ip_, boost::ui nt32_t r); | node_id TORRENT_EXTRA_EXPORT generate_id_impl(address const& ip_, boost::ui nt32_t r); | |||
bool TORRENT_EXTRA_EXPORT verify_id(node_id const& nid, address const& sour ce_ip); | bool TORRENT_EXTRA_EXPORT verify_id(node_id const& nid, address const& sour ce_ip); | |||
bool TORRENT_EXTRA_EXPORT matching_prefix(node_entry const& n, int mask, in | ||||
t prefix, int bucket_index); | ||||
node_id TORRENT_EXTRA_EXPORT generate_prefix_mask(int bits); | ||||
} } // namespace libtorrent::dht | } } // namespace libtorrent::dht | |||
#endif // NODE_ID_HPP | #endif // NODE_ID_HPP | |||
End of changes. 4 change blocks. | ||||
3 lines changed or deleted | 11 lines changed or added | |||
observer.hpp | observer.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2007, Arvid Norberg | Copyright (c) 2007-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 85 | skipping to change at line 85 | |||
, m_id(id) | , m_id(id) | |||
, m_port(0) | , m_port(0) | |||
, m_transaction_id() | , m_transaction_id() | |||
, flags(0) | , flags(0) | |||
{ | { | |||
TORRENT_ASSERT(a); | TORRENT_ASSERT(a); | |||
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS | #if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS | |||
m_in_constructor = true; | m_in_constructor = true; | |||
m_was_sent = false; | m_was_sent = false; | |||
m_was_abandoned = false; | m_was_abandoned = false; | |||
m_in_use = true; | ||||
#endif | #endif | |||
set_target(ep); | set_target(ep); | |||
} | } | |||
// defined in rpc_manager.cpp | ||||
virtual ~observer(); | virtual ~observer(); | |||
// this is called when a reply is received | // this is called when a reply is received | |||
virtual void reply(msg const& m) = 0; | virtual void reply(msg const& m) = 0; | |||
// this is called if no response has been received after | // this is called if no response has been received after | |||
// a few seconds, before the request has timed out | // a few seconds, before the request has timed out | |||
void short_timeout(); | void short_timeout(); | |||
bool has_short_timeout() const { return (flags & flag_short_timeout) != 0; } | bool has_short_timeout() const { return (flags & flag_short_timeout) != 0; } | |||
skipping to change at line 116 | skipping to change at line 118 | |||
// only clean up. It means the rpc-manager | // only clean up. It means the rpc-manager | |||
// is being destructed | // is being destructed | |||
void abort(); | void abort(); | |||
ptime sent() const { return m_sent; } | ptime sent() const { return m_sent; } | |||
void set_target(udp::endpoint const& ep); | void set_target(udp::endpoint const& ep); | |||
address target_addr() const; | address target_addr() const; | |||
udp::endpoint target_ep() const; | udp::endpoint target_ep() const; | |||
void set_id(node_id const& id) { m_id = id; } | void set_id(node_id const& id); | |||
node_id const& id() const { return m_id; } | node_id const& id() const { return m_id; } | |||
void set_transaction_id(boost::uint16_t tid) | void set_transaction_id(boost::uint16_t tid) | |||
{ m_transaction_id = tid; } | { m_transaction_id = tid; } | |||
boost::uint16_t transaction_id() const | boost::uint16_t transaction_id() const | |||
{ return m_transaction_id; } | { return m_transaction_id; } | |||
enum { | enum { | |||
flag_queried = 1, | flag_queried = 1, | |||
skipping to change at line 170 | skipping to change at line 172 | |||
// the transaction ID for this call | // the transaction ID for this call | |||
boost::uint16_t m_transaction_id; | boost::uint16_t m_transaction_id; | |||
public: | public: | |||
unsigned char flags; | unsigned char flags; | |||
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS | #if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS | |||
bool m_in_constructor:1; | bool m_in_constructor:1; | |||
bool m_was_sent:1; | bool m_was_sent:1; | |||
bool m_was_abandoned:1; | bool m_was_abandoned:1; | |||
bool m_in_use:1; | ||||
#endif | #endif | |||
}; | }; | |||
typedef boost::intrusive_ptr<observer> observer_ptr; | typedef boost::intrusive_ptr<observer> observer_ptr; | |||
} } | } } | |||
#endif | #endif | |||
End of changes. 5 change blocks. | ||||
2 lines changed or deleted | 5 lines changed or added | |||
packet_buffer.hpp | packet_buffer.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2010, Arvid Norberg, Daniel Wallin. | Copyright (c) 2010-2014, Arvid Norberg, Daniel Wallin. | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 97 | skipping to change at line 97 | |||
void* remove(index_type idx); | void* remove(index_type idx); | |||
void reserve(std::size_t size); | void reserve(std::size_t size); | |||
index_type cursor() const | index_type cursor() const | |||
{ return m_first; } | { return m_first; } | |||
index_type span() const | index_type span() const | |||
{ return (m_last - m_first) & 0xffff; } | { return (m_last - m_first) & 0xffff; } | |||
#ifdef TORRENT_DEBUG | #if TORRENT_USE_INVARIANT_CHECKS | |||
void check_invariant() const; | void check_invariant() const; | |||
#endif | #endif | |||
private: | private: | |||
void** m_storage; | void** m_storage; | |||
std::size_t m_capacity; | std::size_t m_capacity; | |||
// this is the total number of elements that are occupied | // this is the total number of elements that are occupied | |||
// in the array | // in the array | |||
std::size_t m_size; | std::size_t m_size; | |||
End of changes. 2 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
parse_url.hpp | parse_url.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2008, Arvid Norberg | Copyright (c) 2008-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
pe_crypto.hpp | pe_crypto.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2007, Un Shyam | Copyright (c) 2007-2014, Un Shyam & Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
peer.hpp | peer.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2003, Arvid Norberg | Copyright (c) 2003-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
peer_connection.hpp | peer_connection.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2003, Arvid Norberg | Copyright (c) 2003-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 82 | skipping to change at line 82 | |||
#include "libtorrent/socket_type_fwd.hpp" | #include "libtorrent/socket_type_fwd.hpp" | |||
#include "libtorrent/intrusive_ptr_base.hpp" | #include "libtorrent/intrusive_ptr_base.hpp" | |||
#include "libtorrent/assert.hpp" | #include "libtorrent/assert.hpp" | |||
#include "libtorrent/chained_buffer.hpp" | #include "libtorrent/chained_buffer.hpp" | |||
#include "libtorrent/disk_buffer_holder.hpp" | #include "libtorrent/disk_buffer_holder.hpp" | |||
#include "libtorrent/bitfield.hpp" | #include "libtorrent/bitfield.hpp" | |||
#include "libtorrent/bandwidth_socket.hpp" | #include "libtorrent/bandwidth_socket.hpp" | |||
#include "libtorrent/socket_type_fwd.hpp" | #include "libtorrent/socket_type_fwd.hpp" | |||
#include "libtorrent/error_code.hpp" | #include "libtorrent/error_code.hpp" | |||
#include "libtorrent/sliding_average.hpp" | #include "libtorrent/sliding_average.hpp" | |||
#include "libtorrent/io_service_fwd.hpp" | ||||
#ifdef TORRENT_STATS | #ifdef TORRENT_STATS | |||
#include "libtorrent/aux_/session_impl.hpp" | #include "libtorrent/aux_/session_impl.hpp" | |||
#endif | #endif | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
class torrent; | class torrent; | |||
struct peer_info; | struct peer_info; | |||
struct disk_io_job; | struct disk_io_job; | |||
skipping to change at line 177 | skipping to change at line 178 | |||
// The peer_conenction should handshake and verify that the | // The peer_conenction should handshake and verify that the | |||
// other end has the correct id | // other end has the correct id | |||
peer_connection( | peer_connection( | |||
aux::session_impl& ses | aux::session_impl& ses | |||
, boost::weak_ptr<torrent> t | , boost::weak_ptr<torrent> t | |||
, boost::shared_ptr<socket_type> s | , boost::shared_ptr<socket_type> s | |||
, tcp::endpoint const& remote | , tcp::endpoint const& remote | |||
, policy::peer* peerinfo | , policy::peer* peerinfo | |||
, bool outgoing = true); | , bool outgoing = true); | |||
// with this constructor we have been contacted and we still | ||||
don't | ||||
// know which torrent the connection belongs to | ||||
peer_connection( | ||||
aux::session_impl& ses | ||||
, boost::shared_ptr<socket_type> s | ||||
, tcp::endpoint const& remote | ||||
, policy::peer* peerinfo); | ||||
// this function is called after it has been constructed and properly | // this function is called after it has been constructed and properly | |||
// reference counted. It is safe to call self() in this func tion | // reference counted. It is safe to call self() in this func tion | |||
// and schedule events with references to itself (that is no t safe to | // and schedule events with references to itself (that is no t safe to | |||
// do in the constructor). | // do in the constructor). | |||
virtual void start(); | virtual void start(); | |||
virtual ~peer_connection(); | virtual ~peer_connection(); | |||
void set_peer_info(policy::peer* pi) | void set_peer_info(policy::peer* pi) | |||
{ | { | |||
TORRENT_ASSERT(m_peer_info == 0 || pi == 0 ); | TORRENT_ASSERT(m_peer_info == 0 || pi == 0 ); | |||
m_peer_info = pi; | m_peer_info = pi; | |||
} | } | |||
// this is called when the peer object is created, in case | ||||
// it was let in by the connections limit slack. This means | ||||
// the peer needs to, as soon as the handshake is done, eith | ||||
er | ||||
// disconnect itself or another peer. | ||||
void peer_exceeds_limit() | ||||
{ m_exceeded_limit = true; } | ||||
// this is called if this peer causes another peer | ||||
// to be disconnected, in which case it has fulfilled | ||||
// its requirement. | ||||
void peer_disconnected_other() | ||||
{ m_exceeded_limit = false; } | ||||
policy::peer* peer_info_struct() const | policy::peer* peer_info_struct() const | |||
{ return m_peer_info; } | { return m_peer_info; } | |||
enum peer_speed_t { slow = 1, medium, fast }; | enum peer_speed_t { slow = 1, medium, fast }; | |||
peer_speed_t peer_speed(); | peer_speed_t peer_speed(); | |||
void send_allowed_set(); | void send_allowed_set(); | |||
#ifndef TORRENT_DISABLE_EXTENSIONS | #ifndef TORRENT_DISABLE_EXTENSIONS | |||
void add_extension(boost::shared_ptr<peer_plugin>); | void add_extension(boost::shared_ptr<peer_plugin>); | |||
skipping to change at line 269 | skipping to change at line 275 | |||
void ignore_stats(bool b) { m_ignore_stats = b; } | void ignore_stats(bool b) { m_ignore_stats = b; } | |||
void set_priority(int p) | void set_priority(int p) | |||
{ | { | |||
TORRENT_ASSERT(p > 0); | TORRENT_ASSERT(p > 0); | |||
TORRENT_ASSERT(m_priority <= 255); | TORRENT_ASSERT(m_priority <= 255); | |||
if (p > 255) p = 255; | if (p > 255) p = 255; | |||
m_priority = p; | m_priority = p; | |||
} | } | |||
boost::uint32_t peer_rank() const; | ||||
void fast_reconnect(bool r); | void fast_reconnect(bool r); | |||
bool fast_reconnect() const { return m_fast_reconnect; } | bool fast_reconnect() const { return m_fast_reconnect; } | |||
// this adds an announcement in the announcement queue | // this adds an announcement in the announcement queue | |||
// it will let the peer know that we have the given piece | // it will let the peer know that we have the given piece | |||
void announce_piece(int index); | void announce_piece(int index); | |||
// this will tell the peer to announce the given piece | // this will tell the peer to announce the given piece | |||
// and only allow it to request that piece | // and only allow it to request that piece | |||
void superseed_piece(int index); | void superseed_piece(int replace_piece, int new_piece); | |||
int superseed_piece() const { return m_superseed_piece; } | bool super_seeded_piece(int index) const | |||
{ | ||||
return m_superseed_piece[0] == index | ||||
|| m_superseed_piece[1] == index; | ||||
} | ||||
// tells if this connection has data it want to send | // tells if this connection has data it want to send | |||
// and has enough upload bandwidth quota left to send it. | // and has enough upload bandwidth quota left to send it. | |||
bool can_write() const; | bool can_write() const; | |||
bool can_read(char* state = 0) const; | bool can_read(boost::uint8_t* state = 0) const; | |||
bool is_seed() const; | bool is_seed() const; | |||
int num_have_pieces() const { return m_num_pieces; } | int num_have_pieces() const { return m_num_pieces; } | |||
void set_share_mode(bool m); | void set_share_mode(bool m); | |||
bool share_mode() const { return m_share_mode; } | bool share_mode() const { return m_share_mode; } | |||
void set_upload_only(bool u); | void set_upload_only(bool u); | |||
bool upload_only() const { return m_upload_only; } | bool upload_only() const { return m_upload_only; } | |||
skipping to change at line 390 | skipping to change at line 402 | |||
// initiate the tcp connection. This may be postponed until | // initiate the tcp connection. This may be postponed until | |||
// the library isn't using up the limitation of half-open | // the library isn't using up the limitation of half-open | |||
// tcp connections. | // tcp connections. | |||
void on_connect(int ticket); | void on_connect(int ticket); | |||
// This is called for every peer right after the upload | // This is called for every peer right after the upload | |||
// bandwidth has been distributed among them | // bandwidth has been distributed among them | |||
// It will reset the used bandwidth to 0. | // It will reset the used bandwidth to 0. | |||
void reset_upload_quota(); | void reset_upload_quota(); | |||
// free upload. | ||||
size_type total_free_upload() const; | ||||
void add_free_upload(size_type free_upload); | ||||
// trust management. | // trust management. | |||
void received_valid_data(int index); | virtual void received_valid_data(int index); | |||
void received_invalid_data(int index); | // returns false if the peer should not be | |||
// disconnected | ||||
size_type share_diff() const; | virtual bool received_invalid_data(int index, bool single_pe | |||
er); | ||||
// a connection is local if it was initiated by us. | // a connection is local if it was initiated by us. | |||
// if it was an incoming connection, it is remote | // if it was an incoming connection, it is remote | |||
bool is_outgoing() const { return m_outgoing; } | bool is_outgoing() const { return m_outgoing; } | |||
bool received_listen_port() const { return m_received_listen _port; } | bool received_listen_port() const { return m_received_listen _port; } | |||
void received_listen_port() | void received_listen_port() | |||
{ m_received_listen_port = true; } | { m_received_listen_port = true; } | |||
bool on_local_network() const; | bool on_local_network() const; | |||
skipping to change at line 424 | skipping to change at line 432 | |||
bool ignore_unchoke_slots() const; | bool ignore_unchoke_slots() const; | |||
void ignore_unchoke_slots(bool i) | void ignore_unchoke_slots(bool i) | |||
{ m_ignore_unchoke_slots = i; } | { m_ignore_unchoke_slots = i; } | |||
bool failed() const { return m_failed; } | bool failed() const { return m_failed; } | |||
int desired_queue_size() const | int desired_queue_size() const | |||
{ | { | |||
// this peer is in end-game mode we only want | // this peer is in end-game mode we only want | |||
// one outstanding request | // one outstanding request | |||
return (m_endgame_mode || m_snubbed) ? 1: m_desired_ queue_size; | return m_endgame_mode ? 1: m_desired_queue_size; | |||
} | } | |||
bool bittyrant_unchoke_compare( | bool bittyrant_unchoke_compare( | |||
boost::intrusive_ptr<peer_connection const> const& p ) const; | boost::intrusive_ptr<peer_connection const> const& p ) const; | |||
// compares this connection against the given connection | // compares this connection against the given connection | |||
// for which one is more eligible for an unchoke. | // for which one is more eligible for an unchoke. | |||
// returns true if this is more eligible | // returns true if this is more eligible | |||
bool unchoke_compare(boost::intrusive_ptr<peer_connection co nst> const& p) const; | bool unchoke_compare(boost::intrusive_ptr<peer_connection co nst> const& p) const; | |||
bool upload_rate_compare(peer_connection const* p) const; | bool upload_rate_compare(peer_connection const* p) const; | |||
skipping to change at line 475 | skipping to change at line 483 | |||
void incoming_have(int piece_index); | void incoming_have(int piece_index); | |||
void incoming_dont_have(int piece_index); | void incoming_dont_have(int piece_index); | |||
void incoming_bitfield(bitfield const& bits); | void incoming_bitfield(bitfield const& bits); | |||
void incoming_request(peer_request const& r); | void incoming_request(peer_request const& r); | |||
void incoming_piece(peer_request const& p, disk_buffer_holde r& data); | void incoming_piece(peer_request const& p, disk_buffer_holde r& data); | |||
void incoming_piece(peer_request const& p, char const* data) ; | void incoming_piece(peer_request const& p, char const* data) ; | |||
void incoming_piece_fragment(int bytes); | void incoming_piece_fragment(int bytes); | |||
void start_receive_piece(peer_request const& r); | void start_receive_piece(peer_request const& r); | |||
void incoming_cancel(peer_request const& r); | void incoming_cancel(peer_request const& r); | |||
bool can_disconnect(error_code const& ec) const; | ||||
void incoming_dht_port(int listen_port); | void incoming_dht_port(int listen_port); | |||
void incoming_reject_request(peer_request const& r); | void incoming_reject_request(peer_request const& r); | |||
void incoming_have_all(); | void incoming_have_all(); | |||
void incoming_have_none(); | void incoming_have_none(); | |||
void incoming_allowed_fast(int index); | void incoming_allowed_fast(int index); | |||
void incoming_suggest(int index); | void incoming_suggest(int index); | |||
void set_has_metadata(bool m) { m_has_metadata = m; } | void set_has_metadata(bool m) { m_has_metadata = m; } | |||
bool has_metadata() const { return m_has_metadata; } | bool has_metadata() const { return m_has_metadata; } | |||
skipping to change at line 498 | skipping to change at line 507 | |||
bool send_choke(); | bool send_choke(); | |||
bool send_unchoke(); | bool send_unchoke(); | |||
void send_interested(); | void send_interested(); | |||
void send_not_interested(); | void send_not_interested(); | |||
void send_suggest(int piece); | void send_suggest(int piece); | |||
void snub_peer(); | void snub_peer(); | |||
bool can_request_time_critical() const; | bool can_request_time_critical() const; | |||
void make_time_critical(piece_block const& block); | // returns true if the specified block was actually made tim | |||
e-critical. | ||||
// if the block was already time-critical, it returns false. | ||||
bool make_time_critical(piece_block const& block); | ||||
// adds a block to the request queue | // adds a block to the request queue | |||
// returns true if successful, false otherwise | // returns true if successful, false otherwise | |||
enum flags_t { req_time_critical = 1, req_busy = 2 }; | enum flags_t { req_time_critical = 1, req_busy = 2 }; | |||
bool add_request(piece_block const& b, int flags = 0); | bool add_request(piece_block const& b, int flags = 0); | |||
// clears the request queue and sends cancels for all messag es | // clears the request queue and sends cancels for all messag es | |||
// in the download queue | // in the download queue | |||
void cancel_all_requests(); | void cancel_all_requests(); | |||
skipping to change at line 523 | skipping to change at line 534 | |||
// if force is true, the blocks is also freed from the piece | // if force is true, the blocks is also freed from the piece | |||
// picker, allowing another peer to request it immediately | // picker, allowing another peer to request it immediately | |||
void cancel_request(piece_block const& b, bool force = false ); | void cancel_request(piece_block const& b, bool force = false ); | |||
void send_block_requests(); | void send_block_requests(); | |||
int bandwidth_throttle(int channel) const | int bandwidth_throttle(int channel) const | |||
{ return m_bandwidth_channel[channel].throttle(); } | { return m_bandwidth_channel[channel].throttle(); } | |||
void assign_bandwidth(int channel, int amount); | void assign_bandwidth(int channel, int amount); | |||
#ifdef TORRENT_DEBUG | #if TORRENT_USE_INVARIANT_CHECKS | |||
void check_invariant() const; | void check_invariant() const; | |||
ptime m_last_choke; | ||||
#endif | #endif | |||
// is true until we can be sure that the other end | // is true until we can be sure that the other end | |||
// speaks our protocol (be it bittorrent or http). | // speaks our protocol (be it bittorrent or http). | |||
virtual bool in_handshake() const = 0; | virtual bool in_handshake() const = 0; | |||
// returns the block currently being | // returns the block currently being | |||
// downloaded. And the progress of that | // downloaded. And the progress of that | |||
// block. If the peer isn't downloading | // block. If the peer isn't downloading | |||
// a piece for the moment, the boost::optional | // a piece for the moment, the boost::optional | |||
skipping to change at line 602 | skipping to change at line 612 | |||
int send_buffer_capacity() const | int send_buffer_capacity() const | |||
{ return m_send_buffer.capacity(); } | { return m_send_buffer.capacity(); } | |||
int packet_size() const { return m_packet_size; } | int packet_size() const { return m_packet_size; } | |||
bool packet_finished() const | bool packet_finished() const | |||
{ return m_packet_size <= m_recv_pos; } | { return m_packet_size <= m_recv_pos; } | |||
int receive_pos() const { return m_recv_pos; } | int receive_pos() const { return m_recv_pos; } | |||
void max_out_request_queue(int s) | ||||
{ m_max_out_request_queue = s; } | ||||
int max_out_request_queue() const | ||||
{ return m_max_out_request_queue; } | ||||
#ifdef TORRENT_DEBUG | #ifdef TORRENT_DEBUG | |||
bool piece_failed; | bool piece_failed; | |||
#endif | #endif | |||
time_t last_seen_complete() const { return m_last_seen_compl ete; } | time_t last_seen_complete() const { return m_last_seen_compl ete; } | |||
void set_last_seen_complete(int ago) { m_last_seen_complete = time(0) - ago; } | void set_last_seen_complete(int ago) { m_last_seen_complete = time(0) - ago; } | |||
// upload and download channel state | ||||
// enum from peer_info::bw_state | ||||
char m_channel_state[2]; | ||||
size_type uploaded_in_last_round() const | size_type uploaded_in_last_round() const | |||
{ return m_statistics.total_payload_upload() - m_uploaded_at _last_round; } | { return m_statistics.total_payload_upload() - m_uploaded_at _last_round; } | |||
size_type downloaded_in_last_round() const | size_type downloaded_in_last_round() const | |||
{ return m_statistics.total_payload_download() - m_downloade d_at_last_round; } | { return m_statistics.total_payload_download() - m_downloade d_at_last_round; } | |||
size_type uploaded_since_unchoked() const | size_type uploaded_since_unchoked() const | |||
{ return m_statistics.total_payload_upload() - m_uploaded_at _last_unchoke; } | { return m_statistics.total_payload_upload() - m_uploaded_at _last_unchoke; } | |||
// called when the disk write buffer is drained again, and w e can | // called when the disk write buffer is drained again, and w e can | |||
skipping to change at line 706 | skipping to change at line 717 | |||
// if allow_encrypted is false, and the torrent 'ih' turns o ut | // if allow_encrypted is false, and the torrent 'ih' turns o ut | |||
// to be an encrypted torrent (AES-256 encrypted) the peer w ill | // to be an encrypted torrent (AES-256 encrypted) the peer w ill | |||
// be disconnected. This is to prevent non-encrypted peers t o | // be disconnected. This is to prevent non-encrypted peers t o | |||
// attach to an encrypted torrent | // attach to an encrypted torrent | |||
void attach_to_torrent(sha1_hash const& ih, bool allow_encry pted); | void attach_to_torrent(sha1_hash const& ih, bool allow_encry pted); | |||
bool verify_piece(peer_request const& p) const; | bool verify_piece(peer_request const& p) const; | |||
void update_desired_queue_size(); | void update_desired_queue_size(); | |||
// the bandwidth channels, upload and download | void set_timeout(int s) { m_timeout = s; } | |||
// keeps track of the current quotas | ||||
bandwidth_channel m_bandwidth_channel[num_channels]; | boost::intrusive_ptr<peer_connection> self() | |||
{ | ||||
TORRENT_ASSERT(!m_in_constructor); | ||||
return boost::intrusive_ptr<peer_connection>(this); | ||||
} | ||||
// TODO: make this private | ||||
public: | ||||
// upload and download channel state | ||||
// enum from peer_info::bw_state | ||||
boost::uint8_t m_channel_state[2]; | ||||
private: | ||||
// is true if we learn the incoming connections listening | ||||
// during the extended handshake | ||||
bool m_received_listen_port:1; | ||||
// this is set to true when a have_all | ||||
// message is received. This information | ||||
// is used to fill the bitmask in init() | ||||
bool m_have_all:1; | ||||
// other side says that it's interested in downloading | ||||
// from us. | ||||
bool m_peer_interested:1; | ||||
// the other side has told us that it won't send anymore | ||||
// data to us for a while | ||||
bool m_peer_choked:1; | ||||
// the peer has pieces we are interested in | ||||
bool m_interesting:1; | ||||
// we have choked the upload to the peer | ||||
bool m_choked:1; | ||||
// this is set to true if the connection timed | ||||
// out or closed the connection. In that | ||||
// case we will not try to reconnect to | ||||
// this peer | ||||
bool m_failed:1; | ||||
// this is true if this connection has been added | ||||
// to the list of connections that will be closed. | ||||
bool m_disconnecting:1; | ||||
// this is set to true once the bitfield is received | ||||
bool m_bitfield_received:1; | ||||
// this is set to true if the last time we tried to | ||||
// pick a piece to download, we could only find | ||||
// blocks that were already requested from other | ||||
// peers. In this case, we should not try to pick | ||||
// another piece until the last one we requested is done | ||||
bool m_endgame_mode:1; | ||||
// set to true when we've sent the first round of suggests | ||||
bool m_sent_suggests:1; | ||||
// set to true while we're trying to holepunch | ||||
bool m_holepunch_mode:1; | ||||
// when this is set, the transfer stats for this connection | ||||
// is not included in the torrent or session stats | ||||
bool m_ignore_stats:1; | ||||
// when this is set, the peer_connection socket is | ||||
// corked, similar to the linux TCP feature TCP_CORK. | ||||
// we won't send anything to the actual socket, just | ||||
// buffer messages up in the application layer send | ||||
// buffer, and send it once we're uncorked. | ||||
bool m_corked:1; | ||||
// set to true if this peer has metadata, and false | ||||
// otherwise. | ||||
bool m_has_metadata:1; | ||||
// this is set to true if this peer was accepted exceeding | ||||
// the connection limit. It means it has to disconnect | ||||
// itself, or some other peer, as soon as it's completed | ||||
// the handshake. We need to wait for the handshake in | ||||
// order to know which torrent it belongs to, to know which | ||||
// other peers to compare it to. | ||||
bool m_exceeded_limit:1; | ||||
// TODO: make these private as well | ||||
protected: | ||||
// number of bytes this peer can send and receive | // number of bytes this peer can send and receive | |||
int m_quota[2]; | int m_quota[2]; | |||
// statistics about upload and download speeds | // statistics about upload and download speeds | |||
// and total amount of uploads and downloads for | // and total amount of uploads and downloads for | |||
// this peer | // this peer | |||
stat m_statistics; | stat m_statistics; | |||
// a back reference to the session | // a back reference to the session | |||
// the peer belongs to. | // the peer belongs to. | |||
aux::session_impl& m_ses; | aux::session_impl& m_ses; | |||
#ifndef TORRENT_DISABLE_EXTENSIONS | ||||
typedef std::list<boost::shared_ptr<peer_plugin> > extension | ||||
_list_t; | ||||
extension_list_t m_extensions; | ||||
#endif | ||||
// called from the main loop when this connection has any | // called from the main loop when this connection has any | |||
// work to do. | // work to do. | |||
void on_send_data(error_code const& error | void on_send_data(error_code const& error | |||
, std::size_t bytes_transferred); | , std::size_t bytes_transferred); | |||
void on_receive_data(error_code const& error | void on_receive_data(error_code const& error | |||
, std::size_t bytes_transferred); | , std::size_t bytes_transferred); | |||
// this is the limit on the number of outstanding requests | ||||
// we have to this peer. This is initialized to the settings | ||||
// in the session_settings structure. But it may be lowered | ||||
// if the peer is known to require a smaller limit (like Bit | ||||
Comet). | ||||
// or if the extended handshake sets a limit. | ||||
// web seeds also has a limit on the queue size. | ||||
int m_max_out_request_queue; | ||||
// the average rate of receiving complete piece messages | // the average rate of receiving complete piece messages | |||
sliding_average<20> m_piece_rate; | sliding_average<20> m_piece_rate; | |||
sliding_average<20> m_send_rate; | sliding_average<20> m_send_rate; | |||
void set_timeout(int s) { m_timeout = s; } | ||||
#ifndef TORRENT_DISABLE_EXTENSIONS | ||||
typedef std::list<boost::shared_ptr<peer_plugin> > extension | ||||
_list_t; | ||||
extension_list_t m_extensions; | ||||
#endif | ||||
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES | ||||
// in case the session settings is set | ||||
// to resolve countries, this is set to | ||||
// the two character country code this | ||||
// peer resides in. | ||||
char m_country[2]; | ||||
#endif | ||||
boost::intrusive_ptr<peer_connection> self() | ||||
{ | ||||
TORRENT_ASSERT(!m_in_constructor); | ||||
return boost::intrusive_ptr<peer_connection>(this); | ||||
} | ||||
private: | private: | |||
std::pair<int, int> preferred_caching() const; | std::pair<int, int> preferred_caching() const; | |||
void fill_send_buffer(); | void fill_send_buffer(); | |||
void on_disk_read_complete(int ret, disk_io_job const& j, pe er_request r); | void on_disk_read_complete(int ret, disk_io_job const& j, pe er_request r); | |||
void on_disk_write_complete(int ret, disk_io_job const& j | void on_disk_write_complete(int ret, disk_io_job const& j | |||
, peer_request r, boost::shared_ptr<torrent> t); | , peer_request r, boost::shared_ptr<torrent> t); | |||
int request_upload_bandwidth( | int request_upload_bandwidth( | |||
bandwidth_channel* bwc1 | bandwidth_channel* bwc1 | |||
, bandwidth_channel* bwc2 = 0 | , bandwidth_channel* bwc2 = 0 | |||
skipping to change at line 801 | skipping to change at line 876 | |||
// the time we received the last | // the time we received the last | |||
// piece request from the peer | // piece request from the peer | |||
ptime m_last_incoming_request; | ptime m_last_incoming_request; | |||
// the time when we unchoked this peer | // the time when we unchoked this peer | |||
ptime m_last_unchoke; | ptime m_last_unchoke; | |||
// if we're unchoked by this peer, this | // if we're unchoked by this peer, this | |||
// was the time | // was the time | |||
ptime m_last_unchoked; | ptime m_last_unchoked; | |||
// the time we last choked this peer. min_time() in | ||||
// case we never unchoked it | ||||
ptime m_last_choke; | ||||
// timeouts | // timeouts | |||
ptime m_last_receive; | ptime m_last_receive; | |||
ptime m_last_sent; | ptime m_last_sent; | |||
// the time when the first entry in the | // the time when the first entry in the | |||
// request queue was requested, increased | // request queue was requested, increased | |||
// for each entry that is popped from the | // for each entry that is popped from the | |||
// download queue. Used for request timeout | // download queue. Used for request timeout | |||
ptime m_requested; | ptime m_requested; | |||
skipping to change at line 827 | skipping to change at line 906 | |||
ptime m_connect; | ptime m_connect; | |||
// the time when this peer sent us a not_interested message | // the time when this peer sent us a not_interested message | |||
// the last time. | // the last time. | |||
ptime m_became_uninterested; | ptime m_became_uninterested; | |||
// the time when we sent a not_interested message to | // the time when we sent a not_interested message to | |||
// this peer the last time. | // this peer the last time. | |||
ptime m_became_uninteresting; | ptime m_became_uninteresting; | |||
// the amount of data this peer has been given | ||||
// as free upload. This is distributed from | ||||
// peers from which we get free download | ||||
// this will be negative on a peer from which | ||||
// we get free download, and positive on peers | ||||
// that we give the free upload, to keep the balance. | ||||
size_type m_free_upload; | ||||
// the total payload download bytes | // the total payload download bytes | |||
// at the last unchoke round. This is used to | // at the last unchoke round. This is used to | |||
// measure the number of bytes transferred during | // measure the number of bytes transferred during | |||
// an unchoke cycle, to unchoke peers the more bytes | // an unchoke cycle, to unchoke peers the more bytes | |||
// they sent us | // they sent us | |||
size_type m_downloaded_at_last_round; | size_type m_downloaded_at_last_round; | |||
size_type m_uploaded_at_last_round; | size_type m_uploaded_at_last_round; | |||
// this is the number of bytes we had uploaded the | // this is the number of bytes we had uploaded the | |||
// last time this peer was unchoked. This does not | // last time this peer was unchoked. This does not | |||
// reset each unchoke interval/round. This is used to | // reset each unchoke interval/round. This is used to | |||
// track upload across rounds, for the full duration of | // track upload across rounds, for the full duration of | |||
// the peer being unchoked. Specifically, it's used | // the peer being unchoked. Specifically, it's used | |||
// for the round-robin unchoke algorithm. | // for the round-robin unchoke algorithm. | |||
size_type m_uploaded_at_last_unchoke; | size_type m_uploaded_at_last_unchoke; | |||
template <std::size_t Size> | ||||
struct handler_storage | ||||
{ | ||||
#ifdef TORRENT_DEBUG | ||||
handler_storage() | ||||
: used(false) | ||||
{} | ||||
bool used; | ||||
#else | ||||
handler_storage() {} | ||||
#endif | ||||
boost::aligned_storage<Size> bytes; | ||||
}; | ||||
handler_storage<TORRENT_READ_HANDLER_MAX_SIZE> m_read_handle | ||||
r_storage; | ||||
handler_storage<TORRENT_WRITE_HANDLER_MAX_SIZE> m_write_hand | ||||
ler_storage; | ||||
#ifndef TORRENT_DISABLE_GEO_IP | #ifndef TORRENT_DISABLE_GEO_IP | |||
std::string m_inet_as_name; | std::string m_inet_as_name; | |||
#endif | #endif | |||
buffer m_recv_buffer; | buffer m_recv_buffer; | |||
// if this peer is receiving a piece, this | // if this peer is receiving a piece, this | |||
// points to a disk buffer that the data is | // points to a disk buffer that the data is | |||
// read into. This eliminates a memcopy from | // read into. This eliminates a memcopy from | |||
// the receive buffer into the disk buffer | // the receive buffer into the disk buffer | |||
disk_buffer_holder m_disk_recv_buffer; | disk_buffer_holder m_disk_recv_buffer; | |||
chained_buffer m_send_buffer; | chained_buffer m_send_buffer; | |||
boost::shared_ptr<socket_type> m_socket; | boost::shared_ptr<socket_type> m_socket; | |||
// this is the peer we're actually talking to | ||||
// it may not necessarily be the peer we're | ||||
// connected to, in case we use a proxy | ||||
tcp::endpoint m_remote; | ||||
// this is the torrent this connection is | // this is the torrent this connection is | |||
// associated with. If the connection is an | // associated with. If the connection is an | |||
// incoming connection, this is set to zero | // incoming connection, this is set to zero | |||
// until the info_hash is received. Then it's | // until the info_hash is received. Then it's | |||
// set to the torrent it belongs to. | // set to the torrent it belongs to. | |||
boost::weak_ptr<torrent> m_torrent; | boost::weak_ptr<torrent> m_torrent; | |||
// remote peer's id | ||||
peer_id m_peer_id; | ||||
// the pieces the other end have | // the pieces the other end have | |||
bitfield m_have_piece; | bitfield m_have_piece; | |||
// the queue of requests we have got | // the queue of requests we have got | |||
// from this peer that haven't been issued | // from this peer that haven't been issued | |||
// to the disk thread yet | // to the disk thread yet | |||
std::vector<peer_request> m_requests; | std::vector<peer_request> m_requests; | |||
// the blocks we have reserved in the piece | // the blocks we have reserved in the piece | |||
// picker and will request from this peer. | // picker and will request from this peer. | |||
skipping to change at line 918 | skipping to change at line 1000 | |||
std::vector<int> m_allowed_fast; | std::vector<int> m_allowed_fast; | |||
// pieces that has been suggested to be | // pieces that has been suggested to be | |||
// downloaded from this peer | // downloaded from this peer | |||
std::vector<int> m_suggested_pieces; | std::vector<int> m_suggested_pieces; | |||
// a list of byte offsets inside the send buffer | // a list of byte offsets inside the send buffer | |||
// the piece requests | // the piece requests | |||
std::vector<int> m_requests_in_buffer; | std::vector<int> m_requests_in_buffer; | |||
// the block we're currently receiving. Or | // this peer's peer info struct. This may | |||
// (-1, -1) if we're not receiving one | // be 0, in case the connection is incoming | |||
piece_block m_receiving_block; | // and hasn't been added to a torrent yet. | |||
policy::peer* m_peer_info; | ||||
// the time when this peer last saw a complete copy | // the time when this peer last saw a complete copy | |||
// of this torrent | // of this torrent | |||
time_t m_last_seen_complete; | time_t m_last_seen_complete; | |||
// the block we're currently receiving. Or | ||||
// (-1, -1) if we're not receiving one | ||||
piece_block m_receiving_block; | ||||
// this is the peer we're actually talking to | ||||
// it may not necessarily be the peer we're | ||||
// connected to, in case we use a proxy | ||||
tcp::endpoint m_remote; | ||||
// the bandwidth channels, upload and download | ||||
// keeps track of the current quotas | ||||
bandwidth_channel m_bandwidth_channel[num_channels]; | ||||
// remote peer's id | ||||
peer_id m_peer_id; | ||||
// if the timeout is extended for the outstanding | // if the timeout is extended for the outstanding | |||
// requests, this is the number of seconds it was | // requests, this is the number of seconds it was | |||
// extended. | // extended. | |||
int m_timeout_extend; | int m_timeout_extend; | |||
// the number of bytes that the other | // the number of bytes that the other | |||
// end has to send us in order to respond | // end has to send us in order to respond | |||
// to all outstanding piece requests we | // to all outstanding piece requests we | |||
// have sent to it | // have sent to it | |||
int m_outstanding_bytes; | int m_outstanding_bytes; | |||
skipping to change at line 997 | skipping to change at line 1096 | |||
// by sending choke, unchoke. | // by sending choke, unchoke. | |||
int m_num_invalid_requests; | int m_num_invalid_requests; | |||
// this is the priority with which this peer gets | // this is the priority with which this peer gets | |||
// download bandwidth quota assigned to it. | // download bandwidth quota assigned to it. | |||
int m_priority; | int m_priority; | |||
int m_upload_limit; | int m_upload_limit; | |||
int m_download_limit; | int m_download_limit; | |||
// this peer's peer info struct. This may | ||||
// be 0, in case the connection is incoming | ||||
// and hasn't been added to a torrent yet. | ||||
policy::peer* m_peer_info; | ||||
// this is a measurement of how fast the peer | // this is a measurement of how fast the peer | |||
// it allows some variance without changing | // it allows some variance without changing | |||
// back and forth between states | // back and forth between states | |||
peer_speed_t m_speed; | peer_speed_t m_speed; | |||
// the ticket id from the connection queue. | // the ticket id from the connection queue. | |||
// This is used to identify the connection | // This is used to identify the connection | |||
// so that it can be removed from the queue | // so that it can be removed from the queue | |||
// once the connection completes | // once the connection completes | |||
int m_connection_ticket; | int m_connection_ticket; | |||
// if this is -1, superseeding is not active. If it is >= 0 | // if [0] is -1, superseeding is not active. If it is >= 0 | |||
// this is the piece that is available to this peer. Only | // this is the piece that is available to this peer. Only | |||
// this piece can be downloaded from us by this peer. | // these two pieces can be downloaded from us by this peer. | |||
// This will remain the current piece for this peer until | // This will remain the current piece for this peer until | |||
// another peer sends us a have message for this piece | // another peer sends us a have message for this piece | |||
int m_superseed_piece; | int m_superseed_piece[2]; | |||
// pieces downloaded since last second | // pieces downloaded since last second | |||
// timer timeout; used for determining | // timer timeout; used for determining | |||
// approx download rate | // approx download rate | |||
int m_remote_pieces_dled; | int m_remote_pieces_dled; | |||
// approximate peer download rate | // approximate peer download rate | |||
int m_remote_dl_rate; | int m_remote_dl_rate; | |||
// the number of bytes send to the disk-io | // the number of bytes send to the disk-io | |||
// thread that hasn't yet been completely written. | // thread that hasn't yet been completely written. | |||
int m_outstanding_writing_bytes; | int m_outstanding_writing_bytes; | |||
// max transfer rates seen on this peer | // max transfer rates seen on this peer | |||
int m_download_rate_peak; | int m_download_rate_peak; | |||
int m_upload_rate_peak; | int m_upload_rate_peak; | |||
// this is the limit on the number of outstanding requests | ||||
// we have to this peer. This is initialized to the settings | ||||
// in the session_settings structure. But it may be lowered | ||||
// if the peer is known to require a smaller limit (like Bit | ||||
Comet). | ||||
// or if the extended handshake sets a limit. | ||||
// web seeds also has a limit on the queue size. | ||||
int m_max_out_request_queue; | ||||
// when using the BitTyrant choker, this is our | // when using the BitTyrant choker, this is our | |||
// estimated reciprocation rate. i.e. the rate | // estimated reciprocation rate. i.e. the rate | |||
// we need to send to this peer for it to unchoke | // we need to send to this peer for it to unchoke | |||
// us | // us | |||
int m_est_reciprocation_rate; | int m_est_reciprocation_rate; | |||
// estimated round trip time to this peer | // estimated round trip time to this peer | |||
// based on the time from when async_connect | // based on the time from when async_connect | |||
// was called to when on_connection_complete | // was called to when on_connection_complete | |||
// was called. The rtt is specified in milliseconds | // was called. The rtt is specified in milliseconds | |||
boost::uint16_t m_rtt; | boost::uint16_t m_rtt; | |||
// the number of request we should queue up | #ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES | |||
// at the remote end. | // in case the session settings is set | |||
boost::uint16_t m_desired_queue_size; | // to resolve countries, this is set to | |||
// the two character country code this | ||||
// peer resides in. | ||||
char m_country[2]; | ||||
#endif | ||||
// if set to non-zero, this peer will always prefer | // if set to non-zero, this peer will always prefer | |||
// to request entire n pieces, rather than blocks. | // to request entire n pieces, rather than blocks. | |||
// where n is the value of this variable. | // where n is the value of this variable. | |||
// if it is 0, the download rate limit setting | // if it is 0, the download rate limit setting | |||
// will be used to determine if whole pieces | // will be used to determine if whole pieces | |||
// are preferred. | // are preferred. | |||
boost::uint8_t m_prefer_whole_pieces; | boost::uint8_t m_prefer_whole_pieces; | |||
// the number of piece requests we have rejected | // the number of request we should queue up | |||
// in a row because the peer is choked. This is | // at the remote end. | |||
// used to re-send the choked message in case the | boost::uint8_t m_desired_queue_size; | |||
// other end keeps requesting pieces while being | ||||
// choked, and eventuelly disconnect if it keeps | ||||
// requesting too many pieces while being choked | ||||
boost::uint8_t m_choke_rejects; | ||||
// if this is true, the disconnection | // if this is true, the disconnection | |||
// timestamp is not updated when the connection | // timestamp is not updated when the connection | |||
// is closed. This means the time until we can | // is closed. This means the time until we can | |||
// reconnect to this peer is shorter, and likely | // reconnect to this peer is shorter, and likely | |||
// immediate. | // immediate. | |||
bool m_fast_reconnect:1; | bool m_fast_reconnect:1; | |||
// is true if it was we that connected to the peer | // is true if it was we that connected to the peer | |||
// and false if we got an incoming connection | // and false if we got an incoming connection | |||
// could be considered: true = local, false = remote | // could be considered: true = local, false = remote | |||
bool m_outgoing:1; | bool m_outgoing:1; | |||
// is true if we learn the incoming connections listening | ||||
// during the extended handshake | ||||
bool m_received_listen_port:1; | ||||
// other side says that it's interested in downloading | ||||
// from us. | ||||
bool m_peer_interested:1; | ||||
// the other side has told us that it won't send anymore | ||||
// data to us for a while | ||||
bool m_peer_choked:1; | ||||
// the peer has pieces we are interested in | ||||
bool m_interesting:1; | ||||
// we have choked the upload to the peer | ||||
bool m_choked:1; | ||||
// this is set to true if the connection timed | ||||
// out or closed the connection. In that | ||||
// case we will not try to reconnect to | ||||
// this peer | ||||
bool m_failed:1; | ||||
// if this is set to true, the peer will not | // if this is set to true, the peer will not | |||
// request bandwidth from the limiter, but instead | // request bandwidth from the limiter, but instead | |||
// just send and receive as much as possible. | // just send and receive as much as possible. | |||
bool m_ignore_bandwidth_limits:1; | bool m_ignore_bandwidth_limits:1; | |||
// set to true if this peer controls its unchoke | // set to true if this peer controls its unchoke | |||
// state individually, regardless of the global | // state individually, regardless of the global | |||
// unchoker | // unchoker | |||
bool m_ignore_unchoke_slots:1; | bool m_ignore_unchoke_slots:1; | |||
// this is set to true when a have_all | ||||
// message is received. This information | ||||
// is used to fill the bitmask in init() | ||||
bool m_have_all:1; | ||||
// this is true if this connection has been added | ||||
// to the list of connections that will be closed. | ||||
bool m_disconnecting:1; | ||||
// this is true until this socket has become | // this is true until this socket has become | |||
// writable for the first time (i.e. the | // writable for the first time (i.e. the | |||
// connection completed). While connecting | // connection completed). While connecting | |||
// the timeout will not be triggered. This is | // the timeout will not be triggered. This is | |||
// because windows XP SP2 may delay connection | // because windows XP SP2 may delay connection | |||
// attempts, which means that the connection | // attempts, which means that the connection | |||
// may not even have been attempted when the | // may not even have been attempted when the | |||
// time out is reached. | // time out is reached. | |||
bool m_connecting:1; | bool m_connecting:1; | |||
skipping to change at line 1157 | skipping to change at line 1226 | |||
bool m_share_mode:1; | bool m_share_mode:1; | |||
// set to true when this peer is only uploading | // set to true when this peer is only uploading | |||
bool m_upload_only:1; | bool m_upload_only:1; | |||
// set to true when a piece request times out. The | // set to true when a piece request times out. The | |||
// result is that the desired pending queue size | // result is that the desired pending queue size | |||
// is set to 1 | // is set to 1 | |||
bool m_snubbed:1; | bool m_snubbed:1; | |||
// this is set to true once the bitfield is received | ||||
bool m_bitfield_received:1; | ||||
// if this is set to true, the client will not | // if this is set to true, the client will not | |||
// pick any pieces from this peer | // pick any pieces from this peer | |||
bool m_no_download:1; | bool m_no_download:1; | |||
// this is set to true if the last time we tried to | ||||
// pick a piece to download, we could only find | ||||
// blocks that were already requested from other | ||||
// peers. In this case, we should not try to pick | ||||
// another piece until the last one we requested is done | ||||
bool m_endgame_mode:1; | ||||
// set to true when we've sent the first round of suggests | ||||
bool m_sent_suggests:1; | ||||
// set to true while we're trying to holepunch | ||||
bool m_holepunch_mode:1; | ||||
// when this is set, the transfer stats for this connection | ||||
// is not included in the torrent or session stats | ||||
bool m_ignore_stats:1; | ||||
// when this is set, the peer_connection socket is | ||||
// corked, similar to the linux TCP feature TCP_CORK. | ||||
// we won't send anything to the actual socket, just | ||||
// buffer messages up in the application layer send | ||||
// buffer, and send it once we're uncorked. | ||||
bool m_corked:1; | ||||
// set to true if this peer has metadata, and false | ||||
// otherwise. | ||||
bool m_has_metadata:1; | ||||
template <std::size_t Size> | ||||
struct handler_storage | ||||
{ | ||||
#ifdef TORRENT_DEBUG | ||||
handler_storage() | ||||
: used(false) | ||||
{} | ||||
bool used; | ||||
#endif | ||||
boost::aligned_storage<Size> bytes; | ||||
}; | ||||
handler_storage<TORRENT_READ_HANDLER_MAX_SIZE> m_read_handle | ||||
r_storage; | ||||
handler_storage<TORRENT_WRITE_HANDLER_MAX_SIZE> m_write_hand | ||||
ler_storage; | ||||
template <class Handler, std::size_t Size> | template <class Handler, std::size_t Size> | |||
struct allocating_handler | struct allocating_handler | |||
{ | { | |||
allocating_handler( | allocating_handler( | |||
Handler const& h, handler_storage<Size>& s | Handler const& h, handler_storage<Size>& s | |||
) | ) | |||
: handler(h) | : handler(h) | |||
, storage(s) | , storage(s) | |||
{} | {} | |||
skipping to change at line 1277 | skipping to change at line 1299 | |||
template <class Handler> | template <class Handler> | |||
allocating_handler<Handler, TORRENT_WRITE_HANDLER_MAX_SIZE> | allocating_handler<Handler, TORRENT_WRITE_HANDLER_MAX_SIZE> | |||
make_write_handler(Handler const& handler) | make_write_handler(Handler const& handler) | |||
{ | { | |||
return allocating_handler<Handler, TORRENT_WRITE_HAN DLER_MAX_SIZE>( | return allocating_handler<Handler, TORRENT_WRITE_HAN DLER_MAX_SIZE>( | |||
handler, m_write_handler_storage | handler, m_write_handler_storage | |||
); | ); | |||
} | } | |||
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS | #if TORRENT_USE_ASSERTS | |||
public: | public: | |||
bool m_in_constructor:1; | bool m_in_constructor:1; | |||
bool m_disconnect_started:1; | bool m_disconnect_started:1; | |||
bool m_initialized:1; | bool m_initialized:1; | |||
int m_in_use; | int m_in_use; | |||
int m_received_in_piece; | int m_received_in_piece; | |||
#endif | #endif | |||
}; | }; | |||
struct cork | struct cork | |||
End of changes. 39 change blocks. | ||||
182 lines changed or deleted | 206 lines changed or added | |||
peer_id.hpp | peer_id.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2003, Arvid Norberg | Copyright (c) 2003-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 36 | skipping to change at line 36 | |||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 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 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||
POSSIBILITY OF SUCH DAMAGE. | POSSIBILITY OF SUCH DAMAGE. | |||
*/ | */ | |||
#ifndef TORRENT_PEER_ID_HPP_INCLUDED | #ifndef TORRENT_PEER_ID_HPP_INCLUDED | |||
#define TORRENT_PEER_ID_HPP_INCLUDED | #define TORRENT_PEER_ID_HPP_INCLUDED | |||
#include <cctype> | ||||
#include <algorithm> | ||||
#include <string> | ||||
#include <cstring> | ||||
#include "libtorrent/config.hpp" | #include "libtorrent/config.hpp" | |||
#include "libtorrent/assert.hpp" | #include "libtorrent/sha1_hash.hpp" | |||
#if TORRENT_USE_IOSTREAM | ||||
#include "libtorrent/escape_string.hpp" // to_hex, from_hex | ||||
#include <iostream> | ||||
#include <iomanip> | ||||
#endif | ||||
#ifdef max | ||||
#undef max | ||||
#endif | ||||
#ifdef min | ||||
#undef min | ||||
#endif | ||||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
typedef sha1_hash peer_id; | ||||
class TORRENT_EXPORT big_number | #ifndef TORRENT_NO_DEPRECATE | |||
{ | typedef sha1_hash big_number; | |||
// the number of bytes of the number | #endif | |||
enum { number_size = 20 }; | ||||
public: | ||||
enum { size = number_size }; | ||||
big_number() { clear(); } | ||||
static big_number max() | ||||
{ | ||||
big_number ret; | ||||
memset(ret.m_number, 0xff, size); | ||||
return ret; | ||||
} | ||||
static big_number min() | ||||
{ | ||||
big_number ret; | ||||
memset(ret.m_number, 0, size); | ||||
return ret; | ||||
} | ||||
explicit big_number(char const* s) | ||||
{ | ||||
if (s == 0) clear(); | ||||
else std::memcpy(m_number, s, size); | ||||
} | ||||
explicit big_number(std::string const& s) | ||||
{ | ||||
TORRENT_ASSERT(s.size() >= 20); | ||||
int sl = int(s.size()) < size ? int(s.size()) : size | ||||
; | ||||
std::memcpy(m_number, s.c_str(), sl); | ||||
} | ||||
void assign(std::string const& s) | ||||
{ | ||||
TORRENT_ASSERT(s.size() >= 20); | ||||
int sl = int(s.size()) < size ? int(s.size()) : size | ||||
; | ||||
std::memcpy(m_number, s.c_str(), sl); | ||||
} | ||||
void assign(char const* str) { std::memcpy(m_number, str, si | ||||
ze); } | ||||
void clear() { std::memset(m_number, 0, number_size); } | ||||
bool is_all_zeros() const | ||||
{ | ||||
for (const unsigned char* i = m_number; i < m_number | ||||
+number_size; ++i) | ||||
if (*i != 0) return false; | ||||
return true; | ||||
} | ||||
big_number& operator<<=(int n) | ||||
{ | ||||
TORRENT_ASSERT(n >= 0); | ||||
int num_bytes = n / 8; | ||||
if (num_bytes >= number_size) | ||||
{ | ||||
std::memset(m_number, 0, number_size); | ||||
return *this; | ||||
} | ||||
if (num_bytes > 0) | ||||
{ | ||||
std::memmove(m_number, m_number + num_bytes, | ||||
number_size - num_bytes); | ||||
std::memset(m_number + number_size - num_byt | ||||
es, 0, num_bytes); | ||||
n -= num_bytes * 8; | ||||
} | ||||
if (n > 0) | ||||
{ | ||||
for (int i = 0; i < number_size - 1; ++i) | ||||
{ | ||||
m_number[i] <<= n; | ||||
m_number[i] |= m_number[i+1] >> (8 - | ||||
n); | ||||
} | ||||
m_number[number_size-1] <<= n; | ||||
} | ||||
return *this; | ||||
} | ||||
big_number& operator>>=(int n) | ||||
{ | ||||
TORRENT_ASSERT(n >= 0); | ||||
int num_bytes = n / 8; | ||||
if (num_bytes >= number_size) | ||||
{ | ||||
std::memset(m_number, 0, number_size); | ||||
return *this; | ||||
} | ||||
if (num_bytes > 0) | ||||
{ | ||||
std::memmove(m_number + num_bytes, m_number, | ||||
number_size - num_bytes); | ||||
std::memset(m_number, 0, num_bytes); | ||||
n -= num_bytes * 8; | ||||
} | ||||
if (n > 0) | ||||
{ | ||||
for (int i = number_size - 1; i > 0; --i) | ||||
{ | ||||
m_number[i] >>= n; | ||||
m_number[i] |= m_number[i-1] << (8 - | ||||
n); | ||||
} | ||||
m_number[0] >>= n; | ||||
} | ||||
return *this; | ||||
} | ||||
bool operator==(big_number const& n) const | ||||
{ | ||||
return std::equal(n.m_number, n.m_number+number_size | ||||
, m_number); | ||||
} | ||||
bool operator!=(big_number const& n) const | ||||
{ | ||||
return !std::equal(n.m_number, n.m_number+number_siz | ||||
e, m_number); | ||||
} | ||||
bool operator<(big_number const& n) const | ||||
{ | ||||
for (int i = 0; i < number_size; ++i) | ||||
{ | ||||
if (m_number[i] < n.m_number[i]) return true | ||||
; | ||||
if (m_number[i] > n.m_number[i]) return fals | ||||
e; | ||||
} | ||||
return false; | ||||
} | ||||
big_number operator~() | ||||
{ | ||||
big_number ret; | ||||
for (int i = 0; i< number_size; ++i) | ||||
ret.m_number[i] = ~m_number[i]; | ||||
return ret; | ||||
} | ||||
big_number operator^ (big_number const& n) const | ||||
{ | ||||
big_number ret = *this; | ||||
ret ^= n; | ||||
return ret; | ||||
} | ||||
big_number operator& (big_number const& n) const | ||||
{ | ||||
big_number ret = *this; | ||||
ret &= n; | ||||
return ret; | ||||
} | ||||
big_number& operator &= (big_number const& n) | ||||
{ | ||||
for (int i = 0; i< number_size; ++i) | ||||
m_number[i] &= n.m_number[i]; | ||||
return *this; | ||||
} | ||||
big_number& operator |= (big_number const& n) | ||||
{ | ||||
for (int i = 0; i< number_size; ++i) | ||||
m_number[i] |= n.m_number[i]; | ||||
return *this; | ||||
} | ||||
big_number& operator ^= (big_number const& n) | ||||
{ | ||||
for (int i = 0; i< number_size; ++i) | ||||
m_number[i] ^= n.m_number[i]; | ||||
return *this; | ||||
} | ||||
unsigned char& operator[](int i) | ||||
{ TORRENT_ASSERT(i >= 0 && i < number_size); return m_number | ||||
[i]; } | ||||
unsigned char const& operator[](int i) const | ||||
{ TORRENT_ASSERT(i >= 0 && i < number_size); return m_number | ||||
[i]; } | ||||
typedef const unsigned char* const_iterator; | ||||
typedef unsigned char* iterator; | ||||
const_iterator begin() const { return m_number; } | ||||
const_iterator end() const { return m_number+number_size; } | ||||
iterator begin() { return m_number; } | ||||
iterator end() { return m_number+number_size; } | ||||
std::string to_string() const | ||||
{ return std::string((char const*)&m_number[0], number_size) | ||||
; } | ||||
private: | ||||
unsigned char m_number[number_size]; | ||||
}; | ||||
typedef big_number peer_id; | ||||
typedef big_number sha1_hash; | ||||
#if TORRENT_USE_IOSTREAM | ||||
inline std::ostream& operator<<(std::ostream& os, big_number const& | ||||
peer) | ||||
{ | ||||
char out[41]; | ||||
to_hex((char const*)&peer[0], big_number::size, out); | ||||
return os << out; | ||||
} | ||||
inline std::istream& operator>>(std::istream& is, big_number& peer) | ||||
{ | ||||
char hex[40]; | ||||
is.read(hex, 40); | ||||
if (!from_hex(hex, 40, (char*)&peer[0])) | ||||
is.setstate(std::ios_base::failbit); | ||||
return is; | ||||
} | ||||
#endif // TORRENT_USE_IOSTREAM | ||||
} | } | |||
#endif // TORRENT_PEER_ID_HPP_INCLUDED | #endif // TORRENT_PEER_ID_HPP_INCLUDED | |||
End of changes. 4 change blocks. | ||||
254 lines changed or deleted | 6 lines changed or added | |||
peer_info.hpp | peer_info.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2003, Arvid Norberg | Copyright (c) 2003-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 45 | skipping to change at line 45 | |||
#include "libtorrent/socket.hpp" | #include "libtorrent/socket.hpp" | |||
#include "libtorrent/deadline_timer.hpp" | #include "libtorrent/deadline_timer.hpp" | |||
#include "libtorrent/peer_id.hpp" | #include "libtorrent/peer_id.hpp" | |||
#include "libtorrent/size_type.hpp" | #include "libtorrent/size_type.hpp" | |||
#include "libtorrent/config.hpp" | #include "libtorrent/config.hpp" | |||
#include "libtorrent/bitfield.hpp" | #include "libtorrent/bitfield.hpp" | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
// holds information and statistics about one peer | ||||
// that libtorrent is connected to | ||||
struct TORRENT_EXPORT peer_info | struct TORRENT_EXPORT peer_info | |||
{ | { | |||
enum | // flags for the peer_info::flags field. Indicates various s | |||
tates | ||||
// the peer may be in. These flags are not mutually exclusiv | ||||
e, but | ||||
// not every combination of them makes sense either. | ||||
enum peer_flags_t | ||||
{ | { | |||
// **we** are interested in pieces from this peer. | ||||
interesting = 0x1, | interesting = 0x1, | |||
// **we** have choked this peer. | ||||
choked = 0x2, | choked = 0x2, | |||
// the peer is interested in **us** | ||||
remote_interested = 0x4, | remote_interested = 0x4, | |||
// the peer has choked **us**. | ||||
remote_choked = 0x8, | remote_choked = 0x8, | |||
// means that this peer supports the | ||||
// `extension protocol`__. | ||||
// | ||||
// __ extension_protocol.html | ||||
supports_extensions = 0x10, | supports_extensions = 0x10, | |||
// The connection was initiated by us, the peer has | ||||
a | ||||
// listen port open, and that port is the same as in | ||||
the | ||||
// address of this peer. If this flag is not set, th | ||||
is | ||||
// peer connection was opened by this peer connectin | ||||
g to | ||||
// us. | ||||
local_connection = 0x20, | local_connection = 0x20, | |||
// The connection is opened, and waiting for the | ||||
// handshake. Until the handshake is done, the peer | ||||
// cannot be identified. | ||||
handshake = 0x40, | handshake = 0x40, | |||
// The connection is in a half-open state (i.e. it i | ||||
s | ||||
// being connected). | ||||
connecting = 0x80, | connecting = 0x80, | |||
// The connection is currently queued for a connecti | ||||
on | ||||
// attempt. This may happen if there is a limit set | ||||
on | ||||
// the number of half-open TCP connections. | ||||
queued = 0x100, | queued = 0x100, | |||
// The peer has participated in a piece that failed | ||||
the | ||||
// hash check, and is now "on parole", which means w | ||||
e're | ||||
// only requesting whole pieces from this peer until | ||||
// it either fails that piece or proves that it does | ||||
n't | ||||
// send bad data. | ||||
on_parole = 0x200, | on_parole = 0x200, | |||
// This peer is a seed (it has all the pieces). | ||||
seed = 0x400, | seed = 0x400, | |||
// This peer is subject to an optimistic unchoke. It | ||||
has | ||||
// been unchoked for a while to see if it might unch | ||||
oke | ||||
// us in return an earn an upload/unchoke slot. If i | ||||
t | ||||
// doesn't within some period of time, it will be ch | ||||
oked | ||||
// and another peer will be optimistically unchoked. | ||||
optimistic_unchoke = 0x800, | optimistic_unchoke = 0x800, | |||
// This peer has recently failed to send a block wit | ||||
hin | ||||
// the request timeout from when the request was sen | ||||
t. | ||||
// We're currently picking one block at a time from | ||||
this | ||||
// peer. | ||||
snubbed = 0x1000, | snubbed = 0x1000, | |||
// This peer has either explicitly (with an extensio | ||||
n) | ||||
// or implicitly (by becoming a seed) told us that i | ||||
t | ||||
// will not downloading anything more, regardless of | ||||
// which pieces we have. | ||||
upload_only = 0x2000, | upload_only = 0x2000, | |||
// This means the last time this peer picket a piece | ||||
, | ||||
// it could not pick as many as it wanted because th | ||||
ere | ||||
// were not enough free ones. i.e. all pieces this p | ||||
eer | ||||
// has were already requested from other peers. | ||||
endgame_mode = 0x4000, | endgame_mode = 0x4000, | |||
// This flag is set if the peer was in holepunch mod | ||||
e | ||||
// when the connection succeeded. This typically onl | ||||
y | ||||
// happens if both peers are behind a NAT and the pe | ||||
ers | ||||
// connect via the NAT holepunch mechanism. | ||||
holepunched = 0x8000, | holepunched = 0x8000, | |||
// indicates that this socket is runnin on top of th | ||||
e | ||||
// I2P transport. | ||||
i2p_socket = 0x10000, | i2p_socket = 0x10000, | |||
utp_socket = 0x20000 | ||||
#ifndef TORRENT_DISABLE_ENCRYPTION | // indicates that this socket is a uTP socket | |||
, rc4_encrypted = 0x100000, | utp_socket = 0x20000, | |||
// indicates that this socket is running on top of a | ||||
n SSL | ||||
// (TLS) channel | ||||
ssl_socket = 0x40000, | ||||
// this connection is obfuscated with RC4 | ||||
rc4_encrypted = 0x100000, | ||||
// the handshake of this connection was obfuscated | ||||
// with a diffie-hellman exchange | ||||
plaintext_encrypted = 0x200000 | plaintext_encrypted = 0x200000 | |||
#endif | ||||
}; | }; | |||
unsigned int flags; | // tells you in which state the peer is in. It is set to | |||
// any combination of the peer_flags_t enum. | ||||
boost::uint32_t flags; | ||||
// the flags indicating which sources a peer can | ||||
// have come from. A peer may have been seen from | ||||
// multiple sources | ||||
enum peer_source_flags | enum peer_source_flags | |||
{ | { | |||
// The peer was received from the tracker. | ||||
tracker = 0x1, | tracker = 0x1, | |||
// The peer was received from the kademlia DHT. | ||||
dht = 0x2, | dht = 0x2, | |||
// The peer was received from the peer exchange | ||||
// extension. | ||||
pex = 0x4, | pex = 0x4, | |||
// The peer was received from the local service | ||||
// discovery (The peer is on the local network). | ||||
lsd = 0x8, | lsd = 0x8, | |||
// The peer was added from the fast resume data. | ||||
resume_data = 0x10, | resume_data = 0x10, | |||
// we received an incoming connection from this peer | ||||
incoming = 0x20 | incoming = 0x20 | |||
}; | }; | |||
// a combination of flags describing from which sources this | ||||
peer | ||||
// was received. | ||||
int source; | int source; | |||
// bw_idle: the channel is not used | // bits for the read_state and write_state | |||
// bw_limit: the channel is waiting for quota | enum bw_state | |||
// bw_network: the channel is waiting for an async write | { | |||
// for read operation to complete | // The peer is not waiting for any external events t | |||
// bw_disk: the peer is waiting for the disk io thread | o | |||
// this is a bitmask, a peer can wait for network and | // send or receive data. | |||
// disk at the same time! | bw_idle = 0, | |||
enum bw_state { bw_idle = 0, bw_limit = 1, bw_network = 2, b | ||||
w_disk = 4 }; | // The peer is waiting for the rate limiter. | |||
bw_limit = 1, | ||||
// The peer has quota and is currently waiting for a | ||||
// network read or write operation to complete. This | ||||
is | ||||
// the state all peers are in if there are no bandwi | ||||
dth | ||||
// limits. | ||||
bw_network = 2, | ||||
// The peer is waiting for the disk I/O thread to ca | ||||
tch | ||||
// up writing buffers to disk before downloading mor | ||||
e. | ||||
bw_disk = 4 | ||||
}; | ||||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
enum bw_state_deprecated { bw_torrent = bw_limit, bw_global = bw_limit }; | enum bw_state_deprecated { bw_torrent = bw_limit, bw_global = bw_limit }; | |||
#endif | #endif | |||
// bitmasks indicating what state this peer is in with regar | ||||
ds to sending | ||||
// and receiving data. The states are declared in the bw_sta | ||||
te enum. | ||||
char read_state; | char read_state; | |||
char write_state; | char write_state; | |||
// the IP-address to this peer. The type is an asio endpoint | ||||
. For | ||||
// more info, see the asio_ documentation. | ||||
// | ||||
// .. _asio: http://asio.sourceforge.net/asio-0.3.8/doc/asio | ||||
/reference.html | ||||
tcp::endpoint ip; | tcp::endpoint ip; | |||
// the current upload and download speed we have to and from | ||||
this peer | ||||
// (including any protocol messages). updated about once per | ||||
second | ||||
int up_speed; | int up_speed; | |||
int down_speed; | int down_speed; | |||
// The transfer rates of payload data only updated about onc | ||||
e per second | ||||
int payload_up_speed; | int payload_up_speed; | |||
int payload_down_speed; | int payload_down_speed; | |||
// the total number of bytes downloaded from and uploaded to | ||||
this peer. | ||||
// These numbers do not include the protocol chatter, but on | ||||
ly the | ||||
// payload data. | ||||
size_type total_download; | size_type total_download; | |||
size_type total_upload; | size_type total_upload; | |||
// the peer's id as used in the bit torrent protocol. This i | ||||
d can be used | ||||
// to extract 'fingerprints' from the peer. Sometimes it can | ||||
tell you | ||||
// which client the peer is using. See identify_client()_ | ||||
peer_id pid; | peer_id pid; | |||
// a bitfield, with one bit per piece in the torrent. | ||||
// Each bit tells you if the peer has that piece (if it's se | ||||
t to 1) | ||||
// or if the peer miss that piece (set to 0). | ||||
bitfield pieces; | bitfield pieces; | |||
// the number of bytes per second we are allowed to send to | ||||
or receive | ||||
// from this peer. It may be -1 if there's no local limit on | ||||
the peer. | ||||
// The global limit and the torrent limit may also be enforc | ||||
ed. | ||||
int upload_limit; | int upload_limit; | |||
int download_limit; | int download_limit; | |||
// time since last request | // the time since we last sent a request | |||
// to this peer and since any transfer occurred with this pe | ||||
er | ||||
time_duration last_request; | time_duration last_request; | |||
// time since last download or upload | ||||
time_duration last_active; | time_duration last_active; | |||
// the time until all blocks in the request | // the time until all blocks in the request | |||
// queue will be d | // queue will be d | |||
time_duration download_queue_time; | time_duration download_queue_time; | |||
int queue_bytes; | int queue_bytes; | |||
// the number of seconds until the current | // the number of seconds until the current front piece reque | |||
// pending request times out | st will time | |||
// out. This timeout can be adjusted through | ||||
// ``session_settings::request_timeout``. | ||||
// -1 means that there is not outstanding request. | ||||
int request_timeout; | int request_timeout; | |||
// the size of the send buffer for this peer, in bytes | // the number of bytes allocated | |||
// and used for the peer's send buffer, respectively. | ||||
int send_buffer_size; | int send_buffer_size; | |||
// the number bytes that's actually used of the send buffer | ||||
int used_send_buffer; | int used_send_buffer; | |||
// the number of bytes | ||||
// allocated and used as receive buffer, respectively. | ||||
int receive_buffer_size; | int receive_buffer_size; | |||
int used_receive_buffer; | int used_receive_buffer; | |||
// the number of failed hashes for this peer | // the number of pieces this peer has participated in | |||
// sending us that turned out to fail the hash check. | ||||
int num_hashfails; | int num_hashfails; | |||
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES | // the two letter `ISO 3166 country code`__ for the country | |||
// in case the session settings is set | the peer is | |||
// to resolve countries, this is set to | // connected from. If the country hasn't been resolved yet, | |||
// the two character country code this | both chars | |||
// peer resides in. | // are set to 0. If the resolution failed for some reason, t | |||
he field is | ||||
// set to "--". If the resolution service returns an invalid | ||||
country | ||||
// code, it is set to "!!". The ``countries.nerd.dk`` servic | ||||
e is used to | ||||
// look up countries. This field will remain set to 0 unless | ||||
the torrent | ||||
// is set to resolve countries, see `resolve_countries()`_. | ||||
// | ||||
// __ http://www.iso.org/iso/en/prods-services/iso3166ma/02i | ||||
so-3166-code-lists/list-en1.html | ||||
char country[2]; | char country[2]; | |||
#endif | ||||
#ifndef TORRENT_DISABLE_GEO_IP | // the name of the AS this peer is located in. This might be | |||
// atonomous system this peer belongs to | // an empty string if there is no name in the geo ip databas | |||
e. | ||||
std::string inet_as_name; | std::string inet_as_name; | |||
int inet_as; | ||||
#endif | ||||
size_type load_balancing; | // the AS number the peer is located in. | |||
int inet_as; | ||||
// this is the number of requests | // this is the number of requests | |||
// we have sent to this peer | // we have sent to this peer | |||
// that we haven't got a response | // that we haven't got a response | |||
// for yet | // for yet | |||
int download_queue_length; | int download_queue_length; | |||
// the number of block requests that have | // the number of block requests that have | |||
// timed out, and are still in the download | // timed out, and are still in the download | |||
// queue | // queue | |||
int timed_out_requests; | int timed_out_requests; | |||
// the number of busy requests in the download | // the number of busy requests in the download | |||
// queue. A budy request is a request for a block | // queue. A budy request is a request for a block | |||
// we've also requested from a different peer | // we've also requested from a different peer | |||
int busy_requests; | int busy_requests; | |||
// the number of request messages | // the number of requests messages that are currently in the | |||
// waiting to be sent inside the send buffer | // send buffer waiting to be sent. | |||
int requests_in_buffer; | int requests_in_buffer; | |||
// the number of requests that is | // the number of requests that is | |||
// tried to be maintained (this is | // tried to be maintained (this is | |||
// typically a function of download speed) | // typically a function of download speed) | |||
int target_dl_queue_length; | int target_dl_queue_length; | |||
// this is the number of requests | // the number of piece-requests we have received from this p | |||
// the peer has sent to us | eer | |||
// that we haven't sent yet | // that we haven't answered with a piece yet. | |||
int upload_queue_length; | int upload_queue_length; | |||
// the number of times this IP | // the number of times this peer has "failed". i.e. failed t | |||
// has failed to connect | o connect or | |||
// disconnected us. The failcount is decremented when we see | ||||
this peer in | ||||
// a tracker response or peer exchange message. | ||||
int failcount; | int failcount; | |||
// the currently downloading piece | // You can know which piece, and which part of that piece, t | |||
// if piece index is -1 all associated | hat is | |||
// members are just set to 0 | // currently being downloaded from a specific peer by lookin | |||
g at these | ||||
// four members. ``downloading_piece_index`` is the index of | ||||
the piece | ||||
// that is currently being downloaded. This may be set to -1 | ||||
if there's | ||||
// currently no piece downloading from this peer. If it is > | ||||
= 0, the | ||||
// other three members are valid. ``downloading_block_index` | ||||
` is the | ||||
// index of the block (or sub-piece) that is being downloade | ||||
d. | ||||
// ``downloading_progress`` is the number of bytes of this b | ||||
lock we have | ||||
// received from the peer, and ``downloading_total`` is the | ||||
total number | ||||
// of bytes in this block. | ||||
int downloading_piece_index; | int downloading_piece_index; | |||
int downloading_block_index; | int downloading_block_index; | |||
int downloading_progress; | int downloading_progress; | |||
int downloading_total; | int downloading_total; | |||
// a string describing the software at the other end of the | ||||
connection. | ||||
// In some cases this information is not available, then it | ||||
will contain | ||||
// a string that may give away something about which softwar | ||||
e is running | ||||
// in the other end. In the case of a web seed, the server t | ||||
ype and | ||||
// version will be a part of this string. | ||||
std::string client; | std::string client; | |||
enum | // the kind of connection this is. Used for the connection_t | |||
ype field. | ||||
enum connection_type_t | ||||
{ | { | |||
// Regular bittorrent connection over TCP | ||||
standard_bittorrent = 0, | standard_bittorrent = 0, | |||
// HTTP connection using the `BEP 19`_ protocol | ||||
web_seed = 1, | web_seed = 1, | |||
http_seed = 2, | ||||
bittorrent_utp = 3 | // HTTP connection using the `BEP 17`_ protocol | |||
http_seed = 2 | ||||
}; | }; | |||
// the kind of connection this peer uses. See connection_typ | ||||
e_t. | ||||
int connection_type; | int connection_type; | |||
// approximate peer download rate | // an estimate of the rate this peer is downloading at, in | |||
// bytes per second. | ||||
int remote_dl_rate; | int remote_dl_rate; | |||
// number of bytes this peer has in | // the number of bytes this peer has pending in the disk-io | |||
// the disk write queue | thread. | |||
// Downloaded and waiting to be written to disk. This is wha | ||||
t is capped | ||||
// by ``session_settings::max_queued_disk_bytes``. | ||||
int pending_disk_bytes; | int pending_disk_bytes; | |||
// numbers used for bandwidth limiting | // the number of bytes this peer has been assigned to be all | |||
owed to send | ||||
// and receive until it has to request more quota from the b | ||||
andwidth | ||||
// manager. | ||||
int send_quota; | int send_quota; | |||
int receive_quota; | int receive_quota; | |||
// estimated rtt to peer, in milliseconds | // an estimated round trip time to this peer, in millisecond | |||
s. It is | ||||
// estimated by timing the the tcp ``connect()``. It may be | ||||
0 for | ||||
// incoming connections. | ||||
int rtt; | int rtt; | |||
// the number of pieces this peer has | // the number of pieces this peer has. | |||
int num_pieces; | int num_pieces; | |||
// the highest transfer rates seen for this peer | // the highest download and upload rates seen on this connec | |||
tion. They | ||||
// are given in bytes per second. This number is reset to 0 | ||||
on reconnect. | ||||
int download_rate_peak; | int download_rate_peak; | |||
int upload_rate_peak; | int upload_rate_peak; | |||
// the peers progress | // the progress of the peer in the range [0, 1]. This is alw | |||
ays 0 when | ||||
// floating point operations are diabled, instead use ``prog | ||||
ress_ppm``. | ||||
float progress; // [0, 1] | float progress; // [0, 1] | |||
int progress_ppm; // [0, 1000000] | ||||
// indicates the download progress of the peer in the range | ||||
[0, 1000000] | ||||
// (parts per million). | ||||
int progress_ppm; | ||||
// this is an estimation of the upload rate, to this peer, w | ||||
here it will | ||||
// unchoke us. This is a coarse estimation based on the rate | ||||
at which | ||||
// we sent right before we were choked. This is primarily us | ||||
ed for the | ||||
// bittyrant choking algorithm. | ||||
int estimated_reciprocation_rate; | int estimated_reciprocation_rate; | |||
// the IP and port pair the socket is bound to locally. i.e. | ||||
the IP | ||||
// address of the interface it's going out over. This may be | ||||
useful for | ||||
// multi-homed clients with multiple interfaces to the inter | ||||
net. | ||||
tcp::endpoint local_endpoint; | tcp::endpoint local_endpoint; | |||
}; | }; | |||
// internal | ||||
struct TORRENT_EXPORT peer_list_entry | struct TORRENT_EXPORT peer_list_entry | |||
{ | { | |||
// internal | ||||
enum flags_t | enum flags_t | |||
{ | { | |||
banned = 1 | banned = 1 | |||
}; | }; | |||
// internal | ||||
tcp::endpoint ip; | tcp::endpoint ip; | |||
// internal | ||||
int flags; | int flags; | |||
// internal | ||||
boost::uint8_t failcount; | boost::uint8_t failcount; | |||
// internal | ||||
boost::uint8_t source; | boost::uint8_t source; | |||
}; | }; | |||
// defined in policy.cpp | // defined in policy.cpp | |||
int source_rank(int source_bitmask); | int source_rank(int source_bitmask); | |||
} | } | |||
#endif // TORRENT_PEER_INFO_HPP_INCLUDED | #endif // TORRENT_PEER_INFO_HPP_INCLUDED | |||
End of changes. 77 change blocks. | ||||
58 lines changed or deleted | 340 lines changed or added | |||
peer_request.hpp | peer_request.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2006, Arvid Norberg | Copyright (c) 2006-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 38 | skipping to change at line 38 | |||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||
POSSIBILITY OF SUCH DAMAGE. | POSSIBILITY OF SUCH DAMAGE. | |||
*/ | */ | |||
#ifndef TORRENT_PEER_REQUEST_HPP_INCLUDED | #ifndef TORRENT_PEER_REQUEST_HPP_INCLUDED | |||
#define TORRENT_PEER_REQUEST_HPP_INCLUDED | #define TORRENT_PEER_REQUEST_HPP_INCLUDED | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
struct TORRENT_EXTRA_EXPORT peer_request | ||||
// represents a byte range within a piece. Internally this is | ||||
// is used for incoming piece requests. | ||||
struct TORRENT_EXPORT peer_request | ||||
{ | { | |||
// the index of the piece in which the range starts. | ||||
int piece; | int piece; | |||
// the offset within that piece where the range starts. | ||||
int start; | int start; | |||
// the size of the range, in bytes. | ||||
int length; | int length; | |||
// returns true if the right hand side peer_request refers t | ||||
o the same | ||||
// range as this does. | ||||
bool operator==(peer_request const& r) const | bool operator==(peer_request const& r) const | |||
{ return piece == r.piece && start == r.start && length == r .length; } | { return piece == r.piece && start == r.start && length == r .length; } | |||
}; | }; | |||
} | } | |||
#endif // TORRENT_PEER_REQUEST_HPP_INCLUDED | #endif // TORRENT_PEER_REQUEST_HPP_INCLUDED | |||
End of changes. 6 change blocks. | ||||
2 lines changed or deleted | 12 lines changed or added | |||
piece_block_progress.hpp | piece_block_progress.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2003, Arvid Norberg | Copyright (c) 2003-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 40 | skipping to change at line 40 | |||
*/ | */ | |||
#ifndef TORRENT_PIECE_BLOCK_PROGRESS_HPP_INCLUDED | #ifndef TORRENT_PIECE_BLOCK_PROGRESS_HPP_INCLUDED | |||
#define TORRENT_PIECE_BLOCK_PROGRESS_HPP_INCLUDED | #define TORRENT_PIECE_BLOCK_PROGRESS_HPP_INCLUDED | |||
#include "libtorrent/config.hpp" | #include "libtorrent/config.hpp" | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
struct TORRENT_EXPORT piece_block_progress | struct piece_block_progress | |||
{ | { | |||
// the piece and block index | // the piece and block index | |||
// determines exactly which | // determines exactly which | |||
// part of the torrent that | // part of the torrent that | |||
// is currently being downloaded | // is currently being downloaded | |||
int piece_index; | int piece_index; | |||
int block_index; | int block_index; | |||
// the number of bytes we have received | // the number of bytes we have received | |||
// of this block | // of this block | |||
int bytes_downloaded; | int bytes_downloaded; | |||
End of changes. 2 change blocks. | ||||
2 lines changed or deleted | 2 lines changed or added | |||
piece_picker.hpp | piece_picker.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2003, Arvid Norberg | Copyright (c) 2003-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 56 | skipping to change at line 56 | |||
#ifdef _MSC_VER | #ifdef _MSC_VER | |||
#pragma warning(pop) | #pragma warning(pop) | |||
#endif | #endif | |||
#include "libtorrent/peer_id.hpp" | #include "libtorrent/peer_id.hpp" | |||
#include "libtorrent/config.hpp" | #include "libtorrent/config.hpp" | |||
#include "libtorrent/assert.hpp" | #include "libtorrent/assert.hpp" | |||
#include "libtorrent/time.hpp" | #include "libtorrent/time.hpp" | |||
// #define TORRENT_DEBUG_REFCOUNTS | ||||
#ifdef TORRENT_DEBUG_REFCOUNTS | ||||
#include <set> | ||||
#endif | ||||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
class torrent; | class torrent; | |||
class peer_connection; | class peer_connection; | |||
struct bitfield; | struct bitfield; | |||
struct TORRENT_EXTRA_EXPORT piece_block | struct TORRENT_EXTRA_EXPORT piece_block | |||
{ | { | |||
const static piece_block invalid; | const static piece_block invalid; | |||
skipping to change at line 90 | skipping to change at line 96 | |||
if (piece_index < b.piece_index) return true; | if (piece_index < b.piece_index) return true; | |||
if (piece_index == b.piece_index) return block_index < b.block_index; | if (piece_index == b.piece_index) return block_index < b.block_index; | |||
return false; | return false; | |||
} | } | |||
bool operator==(piece_block const& b) const | bool operator==(piece_block const& b) const | |||
{ return piece_index == b.piece_index && block_index == b.bl ock_index; } | { return piece_index == b.piece_index && block_index == b.bl ock_index; } | |||
bool operator!=(piece_block const& b) const | bool operator!=(piece_block const& b) const | |||
{ return piece_index != b.piece_index || block_index != b.bl ock_index; } | { return piece_index != b.piece_index || block_index != b.bl ock_index; } | |||
}; | }; | |||
class TORRENT_EXTRA_EXPORT piece_picker | class TORRENT_EXTRA_EXPORT piece_picker | |||
{ | { | |||
public: | public: | |||
struct piece_pos; | struct piece_pos; | |||
enum | enum | |||
{ | { | |||
skipping to change at line 120 | skipping to change at line 125 | |||
// the peer this block was requested or | // the peer this block was requested or | |||
// downloaded from. This is a pointer to | // downloaded from. This is a pointer to | |||
// a policy::peer object | // a policy::peer object | |||
void* peer; | void* peer; | |||
// the number of peers that has this block in their | // the number of peers that has this block in their | |||
// download or request queues | // download or request queues | |||
unsigned num_peers:14; | unsigned num_peers:14; | |||
// the state of this block | // the state of this block | |||
enum { state_none, state_requested, state_writing, s tate_finished }; | enum { state_none, state_requested, state_writing, s tate_finished }; | |||
unsigned state:2; | unsigned state:2; | |||
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS | #if TORRENT_USE_ASSERTS | |||
// to allow verifying the invariant of blocks belong ing to the right piece | // to allow verifying the invariant of blocks belong ing to the right piece | |||
int piece_index; | int piece_index; | |||
#endif | #endif | |||
}; | }; | |||
// the peers that are downloading this piece | // the peers that are downloading this piece | |||
// are considered fast peers or slow peers. | // are considered fast peers or slow peers. | |||
// none is set if the blocks were downloaded | // none is set if the blocks were downloaded | |||
// in a previous session | // in a previous session | |||
enum piece_state_t | enum piece_state_t | |||
skipping to change at line 148 | skipping to change at line 153 | |||
reverse = 2, | reverse = 2, | |||
// only pick pieces exclusively requested from this peer | // only pick pieces exclusively requested from this peer | |||
on_parole = 4, | on_parole = 4, | |||
// always pick partial pieces before any other piece | // always pick partial pieces before any other piece | |||
prioritize_partials = 8, | prioritize_partials = 8, | |||
// pick pieces in sequential order | // pick pieces in sequential order | |||
sequential = 16, | sequential = 16, | |||
// have affinity to pieces with the same speed categ ory | // have affinity to pieces with the same speed categ ory | |||
speed_affinity = 32, | speed_affinity = 32, | |||
// ignore the prefer_whole_pieces parameter | // ignore the prefer_whole_pieces parameter | |||
ignore_whole_pieces = 64 | ignore_whole_pieces = 64, | |||
// treat pieces with priority 6 and below as filtere | ||||
d | ||||
// to trigger end-game mode until all prio 7 pieces | ||||
are | ||||
// completed | ||||
time_critical_mode = 128 | ||||
}; | }; | |||
struct downloading_piece | struct downloading_piece | |||
{ | { | |||
downloading_piece(): state(none), index(-1), info(0) | downloading_piece(): info(NULL), index(-1) | |||
, finished(0), writing(0), requested(0) {} | , finished(0), writing(0), requested(0) | |||
, state(none) {} | ||||
bool operator<(downloading_piece const& rhs) const { return index < rhs.index; } | bool operator<(downloading_piece const& rhs) const { return index < rhs.index; } | |||
piece_state_t state; | ||||
// the index of the piece | ||||
int index; | ||||
// info about each block | // info about each block | |||
// this is a pointer into the m_block_info | // this is a pointer into the m_block_info | |||
// vector owned by the piece_picker | // vector owned by the piece_picker | |||
block_info* info; | block_info* info; | |||
// the index of the piece | ||||
int index; | ||||
// the number of blocks in the finished state | // the number of blocks in the finished state | |||
boost::int16_t finished; | boost::int16_t finished; | |||
// the number of blocks in the writing state | // the number of blocks in the writing state | |||
boost::int16_t writing; | boost::int16_t writing; | |||
// the number of blocks in the requested state | // the number of blocks in the requested state | |||
boost::int16_t requested; | boost::int16_t requested; | |||
// one of piece_state_t values | ||||
// really just needs 2 bits | ||||
boost::uint16_t state; | ||||
}; | }; | |||
piece_picker(); | piece_picker(); | |||
void get_availability(std::vector<int>& avail) const; | void get_availability(std::vector<int>& avail) const; | |||
// increases the peer count for the given piece | // increases the peer count for the given piece | |||
// (is used when a HAVE message is received) | // (is used when a HAVE message is received) | |||
void inc_refcount(int index); | void inc_refcount(int index, const void* peer); | |||
void dec_refcount(int index); | void dec_refcount(int index, const void* peer); | |||
// increases the peer count for the given piece | // increases the peer count for the given piece | |||
// (is used when a BITFIELD message is received) | // (is used when a BITFIELD message is received) | |||
void inc_refcount(bitfield const& bitmask); | void inc_refcount(bitfield const& bitmask, const void* peer) ; | |||
// decreases the peer count for the given piece | // decreases the peer count for the given piece | |||
// (used when a peer disconnects) | // (used when a peer disconnects) | |||
void dec_refcount(bitfield const& bitmask); | void dec_refcount(bitfield const& bitmask, const void* peer) ; | |||
// these will increase and decrease the peer count | // these will increase and decrease the peer count | |||
// of all pieces. They are used when seeds join | // of all pieces. They are used when seeds join | |||
// or leave the swarm. | // or leave the swarm. | |||
void inc_refcount_all(); | void inc_refcount_all(const void* peer); | |||
void dec_refcount_all(); | void dec_refcount_all(const void* peer); | |||
// This indicates that we just received this piece | // This indicates that we just received this piece | |||
// 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); | |||
void we_dont_have(int index); | void we_dont_have(int index); | |||
int cursor() const { return m_cursor; } | int cursor() const { return m_cursor; } | |||
int reverse_cursor() const { return m_reverse_cursor; } | int reverse_cursor() const { return m_reverse_cursor; } | |||
skipping to change at line 218 | skipping to change at line 230 | |||
void init(int blocks_per_piece, int blocks_in_last_piece, in t total_num_pieces); | void init(int blocks_per_piece, int blocks_in_last_piece, in t total_num_pieces); | |||
int num_pieces() const { return int(m_piece_map.size()); } | int num_pieces() const { return int(m_piece_map.size()); } | |||
bool have_piece(int index) const | bool have_piece(int index) const | |||
{ | { | |||
TORRENT_ASSERT(index >= 0); | TORRENT_ASSERT(index >= 0); | |||
TORRENT_ASSERT(index < int(m_piece_map.size())); | TORRENT_ASSERT(index < int(m_piece_map.size())); | |||
return m_piece_map[index].index == piece_pos::we_hav e_index; | return m_piece_map[index].index == piece_pos::we_hav e_index; | |||
} | } | |||
bool is_downloading(int index) const | ||||
{ | ||||
TORRENT_ASSERT(index >= 0); | ||||
TORRENT_ASSERT(index < int(m_piece_map.size())); | ||||
piece_pos const& p = m_piece_map[index]; | ||||
return p.downloading; | ||||
} | ||||
// sets the priority of a piece. | // sets the priority of a piece. | |||
// returns true if the priority was changed from 0 to non-0 | // returns true if the priority was changed from 0 to non-0 | |||
// or vice versa | // or vice versa | |||
bool set_piece_priority(int index, int prio); | bool set_piece_priority(int index, int prio); | |||
// returns the priority for the piece at 'index' | // returns the priority for the piece at 'index' | |||
int piece_priority(int index) const; | int piece_priority(int index) const; | |||
// returns the current piece priorities for all pieces | // returns the current piece priorities for all pieces | |||
void piece_priorities(std::vector<int>& pieces) const; | void piece_priorities(std::vector<int>& pieces) const; | |||
skipping to change at line 347 | skipping to change at line 368 | |||
int num_filtered() const { return m_num_filtered; } | int num_filtered() const { return m_num_filtered; } | |||
// the number of filtered pieces we already have | // the number of filtered pieces we already have | |||
int num_have_filtered() const { return m_num_have_filtered; } | int num_have_filtered() const { return m_num_have_filtered; } | |||
int num_have() const { return m_num_have; } | int num_have() const { return m_num_have; } | |||
// the number of pieces we want and don't have | // the number of pieces we want and don't have | |||
int num_want_left() const { return num_pieces() - m_num_have - m_num_filtered; } | int num_want_left() const { return num_pieces() - m_num_have - m_num_filtered; } | |||
#ifdef TORRENT_DEBUG | #if TORRENT_USE_INVARIANT_CHECKS | |||
// used in debug mode | // used in debug mode | |||
void verify_priority(int start, int end, int prio) const; | void verify_priority(int start, int end, int prio) const; | |||
void check_invariant(const torrent* t = 0) const; | ||||
void verify_pick(std::vector<piece_block> const& picked | void verify_pick(std::vector<piece_block> const& picked | |||
, bitfield const& bits) const; | , bitfield const& bits) const; | |||
void check_invariant(const torrent* t = 0) const; | ||||
#endif | #endif | |||
#if defined TORRENT_PICKER_LOG | #if defined TORRENT_PICKER_LOG | |||
void print_pieces() const; | void print_pieces() const; | |||
#endif | #endif | |||
// functor that compares indices on downloading_pieces | // functor that compares indices on downloading_pieces | |||
struct has_index | struct has_index | |||
{ | { | |||
has_index(int i): index(i) { TORRENT_ASSERT(i >= 0); } | has_index(int i): index(i) { TORRENT_ASSERT(i >= 0); } | |||
bool operator()(const downloading_piece& p) const | bool operator()(const downloading_piece& p) const | |||
skipping to change at line 423 | skipping to change at line 444 | |||
// 5 and 6 same priority as availability 1 (ignores availability) | // 5 and 6 same priority as availability 1 (ignores availability) | |||
// 7 is maximum priority (ignores availability) | // 7 is maximum priority (ignores availability) | |||
boost::uint32_t piece_priority : 3; | boost::uint32_t piece_priority : 3; | |||
// index in to the piece_info vector | // index in to the piece_info vector | |||
#if TORRENT_COMPACT_PICKER | #if TORRENT_COMPACT_PICKER | |||
boost::uint32_t index : 18; | boost::uint32_t index : 18; | |||
#else | #else | |||
boost::uint32_t index; | boost::uint32_t index; | |||
#endif | #endif | |||
#ifdef TORRENT_DEBUG_REFCOUNTS | ||||
// all the peers that have this piece | ||||
std::set<const void*> have_peers; | ||||
#endif | ||||
enum | enum | |||
{ | { | |||
// index is set to this to indicate that we have the | // index is set to this to indicate that we have the | |||
// piece. There is no entry for the piece in the | // piece. There is no entry for the piece in the | |||
// buckets if this is the case. | // buckets if this is the case. | |||
#if TORRENT_COMPACT_PICKER | #if TORRENT_COMPACT_PICKER | |||
we_have_index = 0x3ffff, | we_have_index = 0x3ffff, | |||
#else | #else | |||
we_have_index = 0xffffffff, | we_have_index = 0xffffffff, | |||
#endif | #endif | |||
skipping to change at line 491 | skipping to change at line 516 | |||
if (downloading) return availability * prio_ factor; | if (downloading) return availability * prio_ factor; | |||
return availability * prio_factor + (priorit y_levels / 2) - p; | return availability * prio_factor + (priorit y_levels / 2) - p; | |||
} | } | |||
bool operator!=(piece_pos p) const | bool operator!=(piece_pos p) const | |||
{ return index != p.index || peer_count != p.peer_co unt; } | { return index != p.index || peer_count != p.peer_co unt; } | |||
bool operator==(piece_pos p) const | bool operator==(piece_pos p) const | |||
{ return index == p.index && peer_count == p.peer_co unt; } | { return index == p.index && peer_count == p.peer_co unt; } | |||
}; | }; | |||
void set_num_pad_files(int n) { m_num_pad_files = n; } | ||||
private: | private: | |||
#ifndef TORRENT_DEBUG_REFCOUNTS | ||||
#if TORRENT_COMPACT_PICKER | #if TORRENT_COMPACT_PICKER | |||
BOOST_STATIC_ASSERT(sizeof(piece_pos) == sizeof(char) * 4); | BOOST_STATIC_ASSERT(sizeof(piece_pos) == sizeof(char) * 4); | |||
#else | #else | |||
BOOST_STATIC_ASSERT(sizeof(piece_pos) == sizeof(char) * 8); | BOOST_STATIC_ASSERT(sizeof(piece_pos) == sizeof(char) * 8); | |||
#endif | #endif | |||
#endif | ||||
void break_one_seed(); | ||||
void update_pieces() const; | void update_pieces() const; | |||
// fills in the range [start, end) of pieces in | // fills in the range [start, end) of pieces in | |||
// m_pieces that have priority 'prio' | // m_pieces that have priority 'prio' | |||
void priority_range(int prio, int* start, int* end); | void priority_range(int prio, int* start, int* end); | |||
// adds the piece 'index' to m_pieces | // adds the piece 'index' to m_pieces | |||
void add(int index); | void add(int index); | |||
// removes the piece with the given priority and the | // removes the piece with the given priority and the | |||
skipping to change at line 574 | skipping to change at line 604 | |||
// this holds the information of the | // this holds the information of the | |||
// blocks in partially downloaded pieces. | // blocks in partially downloaded pieces. | |||
// the first m_blocks_per_piece entries | // the first m_blocks_per_piece entries | |||
// in the vector belongs to the first | // in the vector belongs to the first | |||
// entry in m_downloads, the second | // entry in m_downloads, the second | |||
// m_blocks_per_piece entries to the | // m_blocks_per_piece entries to the | |||
// second entry in m_downloads and so on. | // second entry in m_downloads and so on. | |||
std::vector<block_info> m_block_info; | std::vector<block_info> m_block_info; | |||
int m_blocks_per_piece; | boost::uint16_t m_blocks_per_piece; | |||
int m_blocks_in_last_piece; | boost::uint16_t m_blocks_in_last_piece; | |||
// the number of filtered pieces that we don't already | // the number of filtered pieces that we don't already | |||
// have. total_number_of_pieces - number_of_pieces_we_have | // have. total_number_of_pieces - number_of_pieces_we_have | |||
// - num_filtered is supposed to the number of pieces | // - num_filtered is supposed to the number of pieces | |||
// we still want to download | // we still want to download | |||
int m_num_filtered; | int m_num_filtered; | |||
// the number of pieces we have that also are filtered | // the number of pieces we have that also are filtered | |||
int m_num_have_filtered; | int m_num_have_filtered; | |||
skipping to change at line 601 | skipping to change at line 631 | |||
int m_cursor; | int m_cursor; | |||
// we have all pieces in the range [m_reverse_cursor, end) | // we have all pieces in the range [m_reverse_cursor, end) | |||
// m_reverse_cursor is the first piece where we also have | // m_reverse_cursor is the first piece where we also have | |||
// all the subsequent pieces | // all the subsequent pieces | |||
int m_reverse_cursor; | int m_reverse_cursor; | |||
// the number of regions of pieces we don't have. | // the number of regions of pieces we don't have. | |||
int m_sparse_regions; | int m_sparse_regions; | |||
// this is the number of partial download pieces | ||||
// that may be caused by pad files. We raise the limit | ||||
// of number of partial pieces by this amount, to not | ||||
// prioritize pieces that intersect pad files for no | ||||
// apparent reason | ||||
int m_num_pad_files; | ||||
// if this is set to true, it means update_pieces() | // if this is set to true, it means update_pieces() | |||
// has to be called before accessing m_pieces. | // has to be called before accessing m_pieces. | |||
mutable bool m_dirty; | mutable bool m_dirty; | |||
public: | public: | |||
#if TORRENT_COMPACT_PICKER | #if TORRENT_COMPACT_PICKER | |||
enum { max_pieces = piece_pos::we_have_index - 1 }; | enum { max_pieces = piece_pos::we_have_index - 1 }; | |||
#else | #else | |||
// still limited by piece_block | // still limited by piece_block | |||
enum { max_pieces = (1 << 19) - 2 }; | enum { max_pieces = (1 << 19) - 2 }; | |||
End of changes. 24 change blocks. | ||||
21 lines changed or deleted | 60 lines changed or added | |||
policy.hpp | policy.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2003, Arvid Norberg | Copyright (c) 2003-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 53 | skipping to change at line 53 | |||
#include "libtorrent/address.hpp" | #include "libtorrent/address.hpp" | |||
#include "libtorrent/size_type.hpp" | #include "libtorrent/size_type.hpp" | |||
#include "libtorrent/invariant_check.hpp" | #include "libtorrent/invariant_check.hpp" | |||
#include "libtorrent/config.hpp" | #include "libtorrent/config.hpp" | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
class torrent; | class torrent; | |||
class peer_connection; | class peer_connection; | |||
struct external_ip; | ||||
// this is compressed as an unsigned floating point value | // this is compressed as an unsigned floating point value | |||
// the top 13 bits are the mantissa and the low | // the top 13 bits are the mantissa and the low | |||
// 3 bits is the unsigned exponent. The exponent | // 3 bits is the unsigned exponent. The exponent | |||
// has an implicit + 4 as well. | // has an implicit + 4 as well. | |||
// This means that the resolution is no less than 16 | // This means that the resolution is no less than 16 | |||
// The actual rate is: (upload_rate >> 4) << ((upload_rate & 0xf) + 4) | // The actual rate is: (upload_rate >> 4) << ((upload_rate & 0xf) + 4) | |||
// the resolution gets worse the higher the value is | // the resolution gets worse the higher the value is | |||
// min value is 0, max value is 16775168 | // min value is 0, max value is 16775168 | |||
struct ufloat16 | struct ufloat16 | |||
skipping to change at line 97 | skipping to change at line 98 | |||
} | } | |||
return *this; | return *this; | |||
} | } | |||
private: | private: | |||
boost::uint16_t m_val; | boost::uint16_t m_val; | |||
}; | }; | |||
enum | enum | |||
{ | { | |||
// the limits of the download queue size | // the limits of the download queue size | |||
min_request_queue = 2, | min_request_queue = 2 | |||
// the amount of free upload allowed before | ||||
// the peer is choked | ||||
free_upload_amount = 4 * 16 * 1024 | ||||
}; | }; | |||
// calculate the priority of a peer based on its address. One of the | ||||
// endpoint should be our own. The priority is symmetric, so it does | ||||
n't | ||||
// matter which is which | ||||
TORRENT_EXTRA_EXPORT boost::uint32_t peer_priority( | ||||
tcp::endpoint e1, tcp::endpoint e2); | ||||
void request_a_block(torrent& t, peer_connection& c); | void request_a_block(torrent& t, peer_connection& c); | |||
class TORRENT_EXTRA_EXPORT policy | class TORRENT_EXTRA_EXPORT policy | |||
{ | { | |||
public: | public: | |||
policy(torrent* t); | policy(torrent* t); | |||
struct peer; | struct peer; | |||
skipping to change at line 144 | skipping to change at line 147 | |||
void set_connection(policy::peer* p, peer_connection* c); | void set_connection(policy::peer* p, peer_connection* c); | |||
void set_failcount(policy::peer* p, int f); | void set_failcount(policy::peer* p, int f); | |||
// the peer has got at least one interesting piece | // the peer has got at least one interesting piece | |||
void peer_is_interesting(peer_connection& c); | void peer_is_interesting(peer_connection& c); | |||
void ip_filter_updated(); | void ip_filter_updated(); | |||
void set_seed(policy::peer* p, bool s); | void set_seed(policy::peer* p, bool s); | |||
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS | // this clears all cached peer priorities. It's called when | |||
// our external IP changes | ||||
void clear_peer_prio(); | ||||
#if TORRENT_USE_ASSERTS | ||||
bool has_connection(const peer_connection* p); | bool has_connection(const peer_connection* p); | |||
#endif | #endif | |||
#ifdef TORRENT_DEBUG | #if TORRENT_USE_INVARIANT_CHECKS | |||
void check_invariant() const; | void check_invariant() const; | |||
#endif | #endif | |||
// intended struct layout (on 32 bit architectures) | ||||
// offset size alignment field | ||||
// 0 8 4 prev_amount_upload, prev_amount_download | ||||
// 8 4 4 connection | ||||
// 12 2 2 last_optimistically_unchoked | ||||
// 14 2 2 last_connected | ||||
// 16 16 1 addr | ||||
// 32 2 2 port | ||||
// 34 2 2 upload_rate_limit | ||||
// 36 2 2 download_rate_limit | ||||
// 38 1 1 hashfails | ||||
// 39 1 1 failcount, connectable, optimistically_unchoked, | ||||
seed | ||||
// 40 1 1 fast_reconnects, trust_points | ||||
// 41 1 1 source, pe_support, is_v6_addr | ||||
// 42 1 1 on_parole, banned, added_to_dht, supports_utp, | ||||
// supports_holepunch, web_seed | ||||
// 43 1 1 <padding> | ||||
// 44 | ||||
struct TORRENT_EXTRA_EXPORT peer | struct TORRENT_EXTRA_EXPORT peer | |||
{ | { | |||
peer(boost::uint16_t port, bool connectable, int src ); | peer(boost::uint16_t port, bool connectable, int src ); | |||
size_type total_download() const; | size_type total_download() const; | |||
size_type total_upload() const; | size_type total_upload() const; | |||
boost::uint32_t rank(external_ip const& external, in | ||||
t external_port) const; | ||||
libtorrent::address address() const; | libtorrent::address address() const; | |||
char const* dest() const; | char const* dest() const; | |||
tcp::endpoint ip() const { return tcp::endpoint(addr ess(), port); } | tcp::endpoint ip() const { return tcp::endpoint(addr ess(), port); } | |||
// this is the accumulated amount of | // this is the accumulated amount of | |||
// uploaded and downloaded data to this | // uploaded and downloaded data to this | |||
// peer. It only accounts for what was | // peer. It only accounts for what was | |||
// shared during the last connection to | // shared during the last connection to | |||
// this peer. i.e. These are only updated | // this peer. i.e. These are only updated | |||
skipping to change at line 211 | skipping to change at line 202 | |||
#ifndef TORRENT_DISABLE_GEO_IP | #ifndef TORRENT_DISABLE_GEO_IP | |||
#ifdef TORRENT_DEBUG | #ifdef TORRENT_DEBUG | |||
// only used in debug mode to assert that | // only used in debug mode to assert that | |||
// the first entry in the AS pair keeps the same | // the first entry in the AS pair keeps the same | |||
boost::uint16_t inet_as_num; | boost::uint16_t inet_as_num; | |||
#endif | #endif | |||
// The AS this peer belongs to | // The AS this peer belongs to | |||
std::pair<const int, int>* inet_as; | std::pair<const int, int>* inet_as; | |||
#endif | #endif | |||
// as computed by hashing our IP with the remote | ||||
// IP of this peer | ||||
// calculated lazily | ||||
mutable boost::uint32_t peer_rank; | ||||
// the time when this peer was optimistically unchok ed | // the time when this peer was optimistically unchok ed | |||
// the last time. in seconds since session was creat ed | // the last time. in seconds since session was creat ed | |||
// 16 bits is enough to last for 18.2 hours | // 16 bits is enough to last for 18.2 hours | |||
// when the session time reaches 18 hours, it jumps back by | // when the session time reaches 18 hours, it jumps back by | |||
// 9 hours, and all peers' times are updated to be | // 9 hours, and all peers' times are updated to be | |||
// relative to that new time offset | // relative to that new time offset | |||
boost::uint16_t last_optimistically_unchoked; | boost::uint16_t last_optimistically_unchoked; | |||
// the time when the peer connected to us | // the time when the peer connected to us | |||
// or disconnected if it isn't connected right now | // or disconnected if it isn't connected right now | |||
skipping to change at line 321 | skipping to change at line 317 | |||
bool supports_utp:1; | bool supports_utp:1; | |||
// we have been connected via uTP at least once | // we have been connected via uTP at least once | |||
bool confirmed_supports_utp:1; | bool confirmed_supports_utp:1; | |||
bool supports_holepunch:1; | bool supports_holepunch:1; | |||
// this is set to one for web seeds. Web seeds | // this is set to one for web seeds. Web seeds | |||
// are not stored in the policy m_peers list, | // are not stored in the policy m_peers list, | |||
// and are excempt from connect candidate bookkeepin g | // and are excempt from connect candidate bookkeepin g | |||
// so, any peer with the web_seed bit set, is | // so, any peer with the web_seed bit set, is | |||
// never considered a connect candidate | // never considered a connect candidate | |||
bool web_seed:1; | bool web_seed:1; | |||
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS | #if TORRENT_USE_ASSERTS | |||
bool in_use:1; | bool in_use:1; | |||
#endif | #endif | |||
}; | }; | |||
struct TORRENT_EXTRA_EXPORT ipv4_peer : peer | struct TORRENT_EXTRA_EXPORT ipv4_peer : peer | |||
{ | { | |||
ipv4_peer(tcp::endpoint const& ip, bool connectable, int src); | ipv4_peer(tcp::endpoint const& ip, bool connectable, int src); | |||
const address_v4 addr; | address_v4 addr; | |||
}; | }; | |||
#if TORRENT_USE_I2P | #if TORRENT_USE_I2P | |||
struct TORRENT_EXTRA_EXPORT i2p_peer : peer | struct TORRENT_EXTRA_EXPORT i2p_peer : peer | |||
{ | { | |||
i2p_peer(char const* destination, bool connectable, int src); | i2p_peer(char const* destination, bool connectable, int src); | |||
~i2p_peer(); | ~i2p_peer(); | |||
char* destination; | char* destination; | |||
}; | }; | |||
skipping to change at line 433 | skipping to change at line 429 | |||
void erase_peer(iterator i); | void erase_peer(iterator i); | |||
private: | private: | |||
void update_peer(policy::peer* p, int src, int flags | void update_peer(policy::peer* p, int src, int flags | |||
, tcp::endpoint const& remote, char const* destination); | , tcp::endpoint const& remote, char const* destination); | |||
bool insert_peer(policy::peer* p, iterator iter, int flags); | bool insert_peer(policy::peer* p, iterator iter, int flags); | |||
bool compare_peer_erase(policy::peer const& lhs, policy::pee r const& rhs) const; | bool compare_peer_erase(policy::peer const& lhs, policy::pee r const& rhs) const; | |||
bool compare_peer(policy::peer const& lhs, policy::peer cons t& rhs | bool compare_peer(policy::peer const& lhs, policy::peer cons t& rhs | |||
, address const& external_ip) const; | , external_ip const& external, int source_port) cons t; | |||
iterator find_connect_candidate(int session_time); | iterator find_connect_candidate(int session_time); | |||
bool is_connect_candidate(peer const& p, bool finished) cons t; | bool is_connect_candidate(peer const& p, bool finished) cons t; | |||
bool is_erase_candidate(peer const& p, bool finished) const; | bool is_erase_candidate(peer const& p, bool finished) const; | |||
bool is_force_erase_candidate(peer const& pe) const; | bool is_force_erase_candidate(peer const& pe) const; | |||
bool should_erase_immediately(peer const& p) const; | bool should_erase_immediately(peer const& p) const; | |||
enum flags_t { force_erase = 1 }; | enum flags_t { force_erase = 1 }; | |||
void erase_peers(int flags = 0); | void erase_peers(int flags = 0); | |||
End of changes. 12 change blocks. | ||||
30 lines changed or deleted | 27 lines changed or added | |||
proxy_base.hpp | proxy_base.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2007, Arvid Norberg | Copyright (c) 2007-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 137 | skipping to change at line 137 | |||
} | } | |||
#endif | #endif | |||
template <class SettableSocketOption> | template <class SettableSocketOption> | |||
error_code set_option(SettableSocketOption const& opt, error_code& e c) | error_code set_option(SettableSocketOption const& opt, error_code& e c) | |||
{ | { | |||
return m_sock.set_option(opt, ec); | return m_sock.set_option(opt, ec); | |||
} | } | |||
#ifndef BOOST_NO_EXCEPTIONS | #ifndef BOOST_NO_EXCEPTIONS | |||
template <class GettableSocketOption> | ||||
void get_option(GettableSocketOption& opt) | ||||
{ | ||||
m_sock.get_option(opt); | ||||
} | ||||
#endif | ||||
template <class GettableSocketOption> | ||||
error_code get_option(GettableSocketOption& opt, error_code& ec) | ||||
{ | ||||
return m_sock.get_option(opt, ec); | ||||
} | ||||
#ifndef BOOST_NO_EXCEPTIONS | ||||
void bind(endpoint_type const& endpoint) | void bind(endpoint_type const& endpoint) | |||
{ | { | |||
// m_sock.bind(endpoint); | // m_sock.bind(endpoint); | |||
} | } | |||
#endif | #endif | |||
void bind(endpoint_type const& endpoint, error_code& ec) | void bind(endpoint_type const& endpoint, error_code& ec) | |||
{ | { | |||
// the reason why we ignore binds here is because we don't | // the reason why we ignore binds here is because we don't | |||
// (necessarily) yet know what address family the proxy | // (necessarily) yet know what address family the proxy | |||
End of changes. 2 change blocks. | ||||
1 lines changed or deleted | 15 lines changed or added | |||
ptime.hpp | ptime.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2009, Arvid Norberg | Copyright (c) 2009-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 58 | skipping to change at line 58 | |||
typedef boost::posix_time::time_duration time_duration; | typedef boost::posix_time::time_duration time_duration; | |||
} | } | |||
#else // TORRENT_USE_BOOST_DATE_TIME | #else // TORRENT_USE_BOOST_DATE_TIME | |||
#include <boost/cstdint.hpp> | #include <boost/cstdint.hpp> | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
// libtorrent time_duration type | // libtorrent time_duration type | |||
struct time_duration | struct TORRENT_EXPORT time_duration | |||
{ | { | |||
// hidden | ||||
time_duration() {} | time_duration() {} | |||
// all operators have the same semantics as a 64 bit signed | ||||
integer | ||||
time_duration operator/(int rhs) const { return time_duratio n(diff / rhs); } | time_duration operator/(int rhs) const { return time_duratio n(diff / rhs); } | |||
explicit time_duration(boost::int64_t d) : diff(d) {} | explicit time_duration(boost::int64_t d) : diff(d) {} | |||
time_duration& operator-=(time_duration const& c) { diff -= | time_duration& operator-=(time_duration const& c) | |||
c.diff; return *this; } | { diff -= c.diff; return *this; } | |||
time_duration& operator+=(time_duration const& c) { diff += | time_duration& operator+=(time_duration const& c) | |||
c.diff; return *this; } | { diff += c.diff; return *this; } | |||
time_duration& operator*=(int v) { diff *= v; return *this; } | time_duration& operator*=(int v) { diff *= v; return *this; } | |||
time_duration operator+(time_duration const& c) { return tim | time_duration operator+(time_duration const& c) | |||
e_duration(diff + c.diff); } | { return time_duration(diff + c.diff); } | |||
time_duration operator-(time_duration const& c) { return tim | time_duration operator-(time_duration const& c) | |||
e_duration(diff - c.diff); } | { return time_duration(diff - c.diff); } | |||
// internal | ||||
boost::int64_t diff; | boost::int64_t diff; | |||
}; | }; | |||
// libtorrent time type | // This type represents a point in time. | |||
struct ptime | struct TORRENT_EXPORT ptime | |||
{ | { | |||
// hidden | ||||
ptime() {} | ptime() {} | |||
explicit ptime(boost::uint64_t t): time(t) {} | explicit ptime(boost::uint64_t t): time(t) {} | |||
// these operators have the same semantics as signed 64 bit | ||||
integers | ||||
ptime& operator+=(time_duration rhs) { time += rhs.diff; ret urn *this; } | ptime& operator+=(time_duration rhs) { time += rhs.diff; ret urn *this; } | |||
ptime& operator-=(time_duration rhs) { time -= rhs.diff; ret urn *this; } | ptime& operator-=(time_duration rhs) { time -= rhs.diff; ret urn *this; } | |||
// internal | ||||
boost::uint64_t time; | boost::uint64_t time; | |||
}; | }; | |||
// returns true of the time duration is less than 0 | ||||
inline bool is_negative(time_duration dt) { return dt.diff < 0; } | ||||
// all operators have the same semantics as signed 64 bit integers | ||||
inline bool operator>(ptime lhs, ptime rhs) | inline bool operator>(ptime lhs, ptime rhs) | |||
{ return lhs.time > rhs.time; } | { return lhs.time > rhs.time; } | |||
inline bool operator>=(ptime lhs, ptime rhs) | inline bool operator>=(ptime lhs, ptime rhs) | |||
{ return lhs.time >= rhs.time; } | { return lhs.time >= rhs.time; } | |||
inline bool operator<=(ptime lhs, ptime rhs) | inline bool operator<=(ptime lhs, ptime rhs) | |||
{ return lhs.time <= rhs.time; } | { return lhs.time <= rhs.time; } | |||
inline bool operator<(ptime lhs, ptime rhs) | inline bool operator<(ptime lhs, ptime rhs) | |||
{ return lhs.time < rhs.time; } | { return lhs.time < rhs.time; } | |||
inline bool operator!=(ptime lhs, ptime rhs) | inline bool operator!=(ptime lhs, ptime rhs) | |||
{ return lhs.time != rhs.time;} | { return lhs.time != rhs.time;} | |||
inline bool operator==(ptime lhs, ptime rhs) | inline bool operator==(ptime lhs, ptime rhs) | |||
{ return lhs.time == rhs.time;} | { return lhs.time == rhs.time;} | |||
inline bool is_negative(time_duration dt) { return dt.diff < 0; } | ||||
inline bool operator==(time_duration lhs, time_duration rhs) | inline bool operator==(time_duration lhs, time_duration rhs) | |||
{ return lhs.diff == rhs.diff; } | { return lhs.diff == rhs.diff; } | |||
inline bool operator<(time_duration lhs, time_duration rhs) | inline bool operator<(time_duration lhs, time_duration rhs) | |||
{ return lhs.diff < rhs.diff; } | { return lhs.diff < rhs.diff; } | |||
inline bool operator<=(time_duration lhs, time_duration rhs) | inline bool operator<=(time_duration lhs, time_duration rhs) | |||
{ return lhs.diff <= rhs.diff; } | { return lhs.diff <= rhs.diff; } | |||
inline bool operator>(time_duration lhs, time_duration rhs) | inline bool operator>(time_duration lhs, time_duration rhs) | |||
{ return lhs.diff > rhs.diff; } | { return lhs.diff > rhs.diff; } | |||
inline bool operator>=(time_duration lhs, time_duration rhs) | inline bool operator>=(time_duration lhs, time_duration rhs) | |||
{ return lhs.diff >= rhs.diff; } | { return lhs.diff >= rhs.diff; } | |||
inline time_duration operator*(time_duration lhs, int rhs) | inline time_duration operator*(time_duration lhs, int rhs) | |||
{ return time_duration(boost::int64_t(lhs.diff * rhs)); } | { return time_duration(boost::int64_t(lhs.diff * rhs)); } | |||
inline time_duration operator*(int lhs, time_duration rhs) | inline time_duration operator*(int lhs, time_duration rhs) | |||
{ return time_duration(boost::int64_t(lhs * rhs.diff)); } | { return time_duration(boost::int64_t(lhs * rhs.diff)); } | |||
inline time_duration operator-(ptime lhs, ptime rhs) | inline time_duration operator-(ptime lhs, ptime rhs) | |||
{ return time_duration(lhs.time - rhs.time); } | { return time_duration(lhs.time - rhs.time); } | |||
inline ptime operator+(ptime lhs, time_duration rhs) | inline ptime operator+(ptime lhs, time_duration rhs) | |||
{ return ptime(lhs.time + rhs.diff); } | { return ptime(lhs.time + rhs.diff); } | |||
inline ptime operator+(time_duration lhs, ptime rhs) | inline ptime operator+(time_duration lhs, ptime rhs) | |||
{ return ptime(rhs.time + lhs.diff); } | { return ptime(rhs.time + lhs.diff); } | |||
inline ptime operator-(ptime lhs, time_duration rhs) | inline ptime operator-(ptime lhs, time_duration rhs) | |||
{ return ptime(lhs.time - rhs.diff); } | { return ptime(lhs.time - rhs.diff); } | |||
} | } | |||
#endif // TORRENT_USE_BOOST_DATE_TIME | #endif // TORRENT_USE_BOOST_DATE_TIME | |||
namespace libtorrent | ||||
{ | ||||
TORRENT_EXPORT ptime time_now_hires(); | ||||
TORRENT_EXPORT ptime min_time(); | ||||
TORRENT_EXPORT ptime max_time(); | ||||
TORRENT_EXPORT char const* time_now_string(); | ||||
TORRENT_EXPORT std::string log_time(); | ||||
TORRENT_EXPORT ptime const& time_now(); | ||||
} | ||||
#endif | #endif | |||
End of changes. 14 change blocks. | ||||
27 lines changed or deleted | 28 lines changed or added | |||
random.hpp | random.hpp | |||
---|---|---|---|---|
/* | ||||
Copyright (c) 2011-2014, 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 distributi | ||||
on. | ||||
* 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. | ||||
*/ | ||||
#include "libtorrent/config.hpp" | #include "libtorrent/config.hpp" | |||
#include <boost/cstdint.hpp> | #include <boost/cstdint.hpp> | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
TORRENT_EXTRA_EXPORT void random_seed(boost::uint32_t v); | void random_seed(boost::uint32_t v); | |||
boost::uint32_t random(); | boost::uint32_t TORRENT_EXTRA_EXPORT random(); | |||
} | } | |||
End of changes. 2 change blocks. | ||||
2 lines changed or deleted | 35 lines changed or added | |||
refresh.hpp | refresh.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2006, Arvid Norberg & Daniel Wallin | Copyright (c) 2006-2014, Arvid Norberg & Daniel Wallin | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 38 | skipping to change at line 38 | |||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||
POSSIBILITY OF SUCH DAMAGE. | POSSIBILITY OF SUCH DAMAGE. | |||
*/ | */ | |||
#ifndef REFRESH_050324_HPP | #ifndef REFRESH_050324_HPP | |||
#define REFRESH_050324_HPP | #define REFRESH_050324_HPP | |||
#include <libtorrent/kademlia/traversal_algorithm.hpp> | #include <libtorrent/kademlia/traversal_algorithm.hpp> | |||
#include <libtorrent/kademlia/node_id.hpp> | #include <libtorrent/kademlia/node_id.hpp> | |||
#include <libtorrent/kademlia/find_data.hpp> | #include <libtorrent/kademlia/get_peers.hpp> | |||
namespace libtorrent { namespace dht | namespace libtorrent { namespace dht | |||
{ | { | |||
class routing_table; | class routing_table; | |||
class rpc_manager; | class rpc_manager; | |||
class refresh : public find_data | class refresh : public get_peers | |||
{ | { | |||
public: | public: | |||
typedef find_data::nodes_callback done_callback; | typedef get_peers::nodes_callback done_callback; | |||
refresh(node_impl& node, node_id target | refresh(node_impl& node, node_id target | |||
, done_callback const& callback); | , done_callback const& callback); | |||
virtual char const* name() const; | virtual char const* name() const; | |||
protected: | protected: | |||
observer_ptr new_observer(void* ptr, udp::endpoint const& ep, node_i | observer_ptr new_observer(void* ptr, udp::endpoint const& ep | |||
d const& id); | , node_id const& id); | |||
virtual bool invoke(observer_ptr o); | virtual bool invoke(observer_ptr o); | |||
}; | }; | |||
class bootstrap : public refresh | class bootstrap : public refresh | |||
{ | { | |||
public: | public: | |||
bootstrap(node_impl& node, node_id target | bootstrap(node_impl& node, node_id target | |||
, done_callback const& callback); | , done_callback const& callback); | |||
virtual char const* name() const; | virtual char const* name() const; | |||
End of changes. 5 change blocks. | ||||
6 lines changed or deleted | 6 lines changed or added | |||
routing_table.hpp | routing_table.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2006, Arvid Norberg | Copyright (c) 2006-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 43 | skipping to change at line 43 | |||
#ifndef ROUTING_TABLE_HPP | #ifndef ROUTING_TABLE_HPP | |||
#define ROUTING_TABLE_HPP | #define ROUTING_TABLE_HPP | |||
#include <vector> | #include <vector> | |||
#include <boost/cstdint.hpp> | #include <boost/cstdint.hpp> | |||
#include <boost/utility.hpp> | #include <boost/utility.hpp> | |||
#include <boost/tuple/tuple.hpp> | #include <boost/tuple/tuple.hpp> | |||
#include <boost/array.hpp> | #include <boost/array.hpp> | |||
#include <set> | #include <set> | |||
#include <list> | ||||
#include <libtorrent/kademlia/logging.hpp> | #include <libtorrent/kademlia/logging.hpp> | |||
#include <libtorrent/kademlia/node_id.hpp> | #include <libtorrent/kademlia/node_id.hpp> | |||
#include <libtorrent/kademlia/node_entry.hpp> | #include <libtorrent/kademlia/node_entry.hpp> | |||
#include <libtorrent/session_settings.hpp> | #include <libtorrent/session_settings.hpp> | |||
#include <libtorrent/size_type.hpp> | #include <libtorrent/size_type.hpp> | |||
#include <libtorrent/assert.hpp> | #include <libtorrent/assert.hpp> | |||
#include <libtorrent/ptime.hpp> | #include <libtorrent/ptime.hpp> | |||
skipping to change at line 106 | skipping to change at line 105 | |||
// adds an endpoint that will never be added to | // adds an endpoint that will never be added to | |||
// the routing table | // the routing table | |||
void add_router_node(udp::endpoint router); | void add_router_node(udp::endpoint router); | |||
// iterates over the router nodes added | // iterates over the router nodes added | |||
typedef std::set<udp::endpoint>::const_iterator router_iterator; | typedef std::set<udp::endpoint>::const_iterator router_iterator; | |||
router_iterator router_begin() const { return m_router_nodes.begin() ; } | router_iterator router_begin() const { return m_router_nodes.begin() ; } | |||
router_iterator router_end() const { return m_router_nodes.end(); } | router_iterator router_end() const { return m_router_nodes.end(); } | |||
bool add_node(node_entry const& e); | bool add_node(node_entry e); | |||
// this function is called every time the node sees | // this function is called every time the node sees | |||
// a sign of a node being alive. This node will either | // a sign of a node being alive. This node will either | |||
// be inserted in the k-buckets or be moved to the top | // be inserted in the k-buckets or be moved to the top | |||
// of its bucket. | // of its bucket. | |||
bool node_seen(node_id const& id, udp::endpoint ep); | bool node_seen(node_id const& id, udp::endpoint ep, int rtt); | |||
// this may add a node to the routing table and mark it as | // this may add a node to the routing table and mark it as | |||
// not pinged. If the bucket the node falls into is full, | // not pinged. If the bucket the node falls into is full, | |||
// the node will be ignored. | // the node will be ignored. | |||
void heard_about(node_id const& id, udp::endpoint const& ep); | void heard_about(node_id const& id, udp::endpoint const& ep); | |||
// if any bucket in the routing table needs to be refreshed | // if any bucket in the routing table needs to be refreshed | |||
// this function will return true and set the target to an | // this function will return true and set the target to an | |||
// appropriate target inside that bucket | // appropriate target inside that bucket | |||
bool need_refresh(node_id& target) const; | bool need_refresh(node_id& target) const; | |||
skipping to change at line 135 | skipping to change at line 134 | |||
{ | { | |||
include_failed = 1 | include_failed = 1 | |||
}; | }; | |||
// fills the vector with the count nodes from our buckets that | // fills the vector with the count nodes from our buckets that | |||
// are nearest to the given id. | // are nearest to the given id. | |||
void find_node(node_id const& id, std::vector<node_entry>& l | void find_node(node_id const& id, std::vector<node_entry>& l | |||
, int options, int count = 0); | , int options, int count = 0); | |||
void remove_node(node_entry* n | void remove_node(node_entry* n | |||
, table_t::iterator bucket) ; | , table_t::iterator bucket) ; | |||
int bucket_size(int bucket) | int bucket_size(int bucket) const | |||
{ | { | |||
int num_buckets = m_buckets.size(); | int num_buckets = m_buckets.size(); | |||
if (num_buckets == 0) return 0; | if (num_buckets == 0) return 0; | |||
if (bucket < num_buckets) bucket = num_buckets - 1; | if (bucket < num_buckets) bucket = num_buckets - 1; | |||
table_t::iterator i = m_buckets.begin(); | table_t::const_iterator i = m_buckets.begin(); | |||
std::advance(i, bucket); | std::advance(i, bucket); | |||
return (int)i->live_nodes.size(); | return (int)i->live_nodes.size(); | |||
} | } | |||
void for_each_node(void (*)(void*, node_entry const&) | void for_each_node(void (*)(void*, node_entry const&) | |||
, void (*)(void*, node_entry const&), void* userdata) const; | , void (*)(void*, node_entry const&), void* userdata) const; | |||
int bucket_size() const { return m_bucket_size; } | int bucket_size() const { return m_bucket_size; } | |||
boost::tuple<int, int> size() const; | boost::tuple<int, int> size() const; | |||
size_type num_global_nodes() const; | size_type num_global_nodes() const; | |||
// the number of bits down we have full buckets | ||||
// i.e. essentially the number of full buckets | ||||
// we have | ||||
int depth() const; | ||||
// returns true if there are no working nodes | // returns true if there are no working nodes | |||
// in the routing table | // in the routing table | |||
bool need_bootstrap() const; | bool need_bootstrap() const; | |||
int num_active_buckets() const { return m_buckets.size(); } | int num_active_buckets() const { return m_buckets.size(); } | |||
void replacement_cache(bucket_t& nodes) const; | void replacement_cache(bucket_t& nodes) const; | |||
#if defined TORRENT_DHT_VERBOSE_LOGGING || defined TORRENT_DEBUG | #if defined TORRENT_DHT_VERBOSE_LOGGING || defined TORRENT_DEBUG | |||
// used for debug and monitoring purposes. This will print out | // used for debug and monitoring purposes. This will print out | |||
// the state of the routing table to the given stream | // the state of the routing table to the given stream | |||
void print_state(std::ostream& os) const; | void print_state(std::ostream& os) const; | |||
#endif | #endif | |||
void touch_bucket(node_id const& target); | void touch_bucket(node_id const& target); | |||
int bucket_limit(int bucket) const; | ||||
#if TORRENT_USE_INVARIANT_CHECKS | ||||
void check_invariant() const; | ||||
#endif | ||||
private: | private: | |||
table_t::iterator find_bucket(node_id const& id); | table_t::iterator find_bucket(node_id const& id); | |||
void split_bucket(); | ||||
// return a pointer the node_entry with the given endpoint | // return a pointer the node_entry with the given endpoint | |||
// or 0 if we don't have such a node. Both the address and the | // or 0 if we don't have such a node. Both the address and the | |||
// port has to match | // port has to match | |||
node_entry* find_node(udp::endpoint const& ep, routing_table::table_ | node_entry* find_node(udp::endpoint const& ep | |||
t::iterator* bucket); | , routing_table::table_t::iterator* bucket); | |||
dht_settings const& m_settings; | ||||
// constant called k in paper | // constant called k in paper | |||
int m_bucket_size; | int m_bucket_size; | |||
dht_settings const& m_settings; | ||||
// (k-bucket, replacement cache) pairs | // (k-bucket, replacement cache) pairs | |||
// the first entry is the bucket the furthest | // the first entry is the bucket the furthest | |||
// away from our own ID. Each time the bucket | // away from our own ID. Each time the bucket | |||
// closest to us (m_buckets.back()) has more than | // closest to us (m_buckets.back()) has more than | |||
// bucket size nodes in it, another bucket is | // bucket size nodes in it, another bucket is | |||
// added to the end and it's split up between them | // added to the end and it's split up between them | |||
table_t m_buckets; | table_t m_buckets; | |||
node_id m_id; // our own node id | node_id m_id; // our own node id | |||
// the last seen depth (i.e. levels in the routing table) | ||||
// it's mutable because it's updated by depth(), which is const | ||||
mutable int m_depth; | ||||
// the last time need_bootstrap() returned true | // the last time need_bootstrap() returned true | |||
mutable ptime m_last_bootstrap; | mutable ptime m_last_bootstrap; | |||
// the last time the routing table was refreshed. | // the last time the routing table was refreshed. | |||
// this is used to stagger buckets needing refresh | // this is used to stagger buckets needing refresh | |||
// to be at least 45 seconds apart. | // to be at least 45 seconds apart. | |||
mutable ptime m_last_refresh; | mutable ptime m_last_refresh; | |||
// the last time we refreshed our own bucket | // the last time we refreshed our own bucket | |||
// refreshed every 15 minutes | // refreshed every 15 minutes | |||
End of changes. 12 change blocks. | ||||
10 lines changed or deleted | 26 lines changed or added | |||
rpc_manager.hpp | rpc_manager.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2006, Arvid Norberg | Copyright (c) 2006-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 37 | skipping to change at line 37 | |||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 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 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||
POSSIBILITY OF SUCH DAMAGE. | POSSIBILITY OF SUCH DAMAGE. | |||
*/ | */ | |||
#ifndef RPC_MANAGER_HPP | #ifndef RPC_MANAGER_HPP | |||
#define RPC_MANAGER_HPP | #define RPC_MANAGER_HPP | |||
#include <vector> | #include <vector> | |||
#include <deque> | ||||
#include <map> | #include <map> | |||
#include <boost/cstdint.hpp> | #include <boost/cstdint.hpp> | |||
#include <boost/pool/pool.hpp> | #include <boost/pool/pool.hpp> | |||
#include <boost/function/function3.hpp> | #include <boost/function/function3.hpp> | |||
#include <libtorrent/socket.hpp> | #include <libtorrent/socket.hpp> | |||
#include <libtorrent/entry.hpp> | #include <libtorrent/entry.hpp> | |||
#include <libtorrent/kademlia/node_id.hpp> | #include <libtorrent/kademlia/node_id.hpp> | |||
#include <libtorrent/kademlia/logging.hpp> | #include <libtorrent/kademlia/logging.hpp> | |||
#include <libtorrent/kademlia/observer.hpp> | #include <libtorrent/kademlia/observer.hpp> | |||
#include "libtorrent/ptime.hpp" | #include "libtorrent/ptime.hpp" | |||
namespace libtorrent { namespace aux { struct session_impl; } } | namespace libtorrent { namespace aux { struct session_impl; } } | |||
namespace libtorrent { struct dht_settings; } | ||||
namespace libtorrent { namespace dht | namespace libtorrent { namespace dht | |||
{ | { | |||
#ifdef TORRENT_DHT_VERBOSE_LOGGING | #ifdef TORRENT_DHT_VERBOSE_LOGGING | |||
TORRENT_DECLARE_LOG(rpc); | TORRENT_DECLARE_LOG(rpc); | |||
#endif | #endif | |||
struct udp_socket_interface; | ||||
struct null_observer : public observer | struct null_observer : public observer | |||
{ | { | |||
null_observer(boost::intrusive_ptr<traversal_algorithm> const& a | null_observer(boost::intrusive_ptr<traversal_algorithm> const& a | |||
, udp::endpoint const& ep, node_id const& id): observer(a, e p, id) {} | , udp::endpoint const& ep, node_id const& id): observer(a, e p, id) {} | |||
virtual void reply(msg const&) { flags |= flag_done; } | virtual void reply(msg const&) { flags |= flag_done; } | |||
}; | }; | |||
class routing_table; | class routing_table; | |||
class TORRENT_EXTRA_EXPORT rpc_manager | class TORRENT_EXTRA_EXPORT rpc_manager | |||
{ | { | |||
public: | public: | |||
typedef bool (*send_fun)(void* userdata, entry&, udp::endpoint const &, int); | ||||
rpc_manager(node_id const& our_id | rpc_manager(node_id const& our_id | |||
, routing_table& table, send_fun const& sf | , routing_table& table, udp_socket_interface* sock); | |||
, void* userdata); | ||||
~rpc_manager(); | ~rpc_manager(); | |||
void unreachable(udp::endpoint const& ep); | void unreachable(udp::endpoint const& ep); | |||
// returns true if the node needs a refresh | // returns true if the node needs a refresh | |||
// if so, id is assigned the node id to refresh | // if so, id is assigned the node id to refresh | |||
bool incoming(msg const&, node_id* id); | bool incoming(msg const&, node_id* id, libtorrent::dht_settings cons t& settings); | |||
time_duration tick(); | time_duration tick(); | |||
bool invoke(entry& e, udp::endpoint target | bool invoke(entry& e, udp::endpoint target | |||
, observer_ptr o); | , observer_ptr o); | |||
void add_our_id(entry& e); | void add_our_id(entry& e); | |||
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS | #if TORRENT_USE_ASSERTS | |||
size_t allocation_size() const; | size_t allocation_size() const; | |||
#endif | #endif | |||
#ifdef TORRENT_DEBUG | #if TORRENT_USE_INVARIANT_CHECKS | |||
void check_invariant() const; | void check_invariant() const; | |||
#endif | #endif | |||
void* allocate_observer(); | void* allocate_observer(); | |||
void free_observer(void* ptr); | void free_observer(void* ptr); | |||
int num_allocated_observers() const { return m_allocated_observers; } | int num_allocated_observers() const { return m_allocated_observers; } | |||
private: | private: | |||
boost::uint32_t calc_connection_id(udp::endpoint addr); | boost::uint32_t calc_connection_id(udp::endpoint addr); | |||
mutable boost::pool<> m_pool_allocator; | mutable boost::pool<> m_pool_allocator; | |||
typedef std::list<observer_ptr> transactions_t; | typedef std::deque<observer_ptr> transactions_t; | |||
transactions_t m_transactions; | transactions_t m_transactions; | |||
send_fun m_send; | udp_socket_interface* m_sock; | |||
void* m_userdata; | ||||
node_id m_our_id; | ||||
routing_table& m_table; | routing_table& m_table; | |||
ptime m_timer; | ptime m_timer; | |||
node_id m_random_number; | node_id m_our_id; | |||
int m_allocated_observers; | int m_allocated_observers; | |||
bool m_destructing; | bool m_destructing; | |||
}; | }; | |||
} } // namespace libtorrent::dht | } } // namespace libtorrent::dht | |||
#endif | #endif | |||
End of changes. 12 change blocks. | ||||
12 lines changed or deleted | 13 lines changed or added | |||
rss.hpp | rss.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2010, Arvid Norberg | Copyright (c) 2010-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 48 | skipping to change at line 48 | |||
#include "libtorrent/size_type.hpp" | #include "libtorrent/size_type.hpp" | |||
#include <boost/enable_shared_from_this.hpp> | #include <boost/enable_shared_from_this.hpp> | |||
#include <string> | #include <string> | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
namespace aux | namespace aux | |||
{ struct session_impl; } | { struct session_impl; } | |||
// represents one item from an RSS feed. Specifically | ||||
// a feed of torrents. | ||||
// | ||||
struct TORRENT_EXPORT feed_item | struct TORRENT_EXPORT feed_item | |||
{ | { | |||
feed_item(); | feed_item(); | |||
~feed_item(); | ~feed_item(); | |||
// these are self explanatory and may be empty if the feed d | ||||
oes not specify | ||||
// those fields. | ||||
std::string url; | std::string url; | |||
std::string uuid; | std::string uuid; | |||
std::string title; | std::string title; | |||
std::string description; | std::string description; | |||
std::string comment; | std::string comment; | |||
std::string category; | std::string category; | |||
// the total size of the content the torrent refers to, or - | ||||
1 | ||||
// if no size was specified by the feed. | ||||
size_type size; | size_type size; | |||
// the handle to the torrent, if the session is already down | ||||
loading | ||||
// this torrent. | ||||
torrent_handle handle; | torrent_handle handle; | |||
// the info-hash of the torrent, or cleared (i.e. all zeroes | ||||
) if | ||||
// the feed does not specify the info-hash. | ||||
sha1_hash info_hash; | sha1_hash info_hash; | |||
}; | }; | |||
// given a feed_item ``f``, add the torrent it refers to to session ``s``. | ||||
#ifndef BOOST_NO_EXCEPTIONS | #ifndef BOOST_NO_EXCEPTIONS | |||
torrent_handle TORRENT_EXPORT add_feed_item(session& s, feed_item co nst& fi | torrent_handle TORRENT_EXPORT add_feed_item(session& s, feed_item co nst& fi | |||
, add_torrent_params const& p); | , add_torrent_params const& p); | |||
#endif | #endif | |||
torrent_handle TORRENT_EXPORT add_feed_item(session& s, feed_item co nst& fi | torrent_handle TORRENT_EXPORT add_feed_item(session& s, feed_item co nst& fi | |||
, add_torrent_params const& p, error_code& ec); | , add_torrent_params const& p, error_code& ec); | |||
// the feed_settings object is all the information | // the feed_settings object is all the information | |||
// and configuration for a specific feed. All of | // and configuration for a specific feed. All of | |||
// these settings can be changed by the user | // these settings can be changed by the user | |||
// after adding the feed | // after adding the feed | |||
struct feed_settings | struct TORRENT_EXPORT feed_settings | |||
{ | { | |||
feed_settings() | feed_settings() | |||
: auto_download(true) | : auto_download(true) | |||
, auto_map_handles(true) | , auto_map_handles(true) | |||
, default_ttl(30) | , default_ttl(30) | |||
{} | {} | |||
std::string url; | std::string url; | |||
// automatically add torrents to session from | // By default ``auto_download`` is true, which means all tor | |||
rents in | ||||
// the feed will be downloaded. Set this to false in order t | ||||
o manually | ||||
// add torrents to the session. You may react to the rss_ale | ||||
rt when | ||||
// a feed has been updated to poll it for the new items in t | ||||
he feed | ||||
// when adding torrents manually. When torrents are added au | ||||
tomatically, | ||||
// an add_torrent_alert is posted which includes the torrent | ||||
handle | ||||
// as well as the error code if it failed to be added. You m | ||||
ay also call | ||||
// ``session::get_torrents()`` to get the handles to the new | ||||
torrents. | ||||
bool auto_download; | bool auto_download; | |||
// automatically find existing torrents and set | // ``auto_map_handles`` defaults to true and determines whet | |||
// the torrent_handle in the feed item | her or | |||
// not to set the ``handle`` field in the feed_item, returne | ||||
d | ||||
// as the feed status. If auto-download is enabled, this set | ||||
ting | ||||
// is ignored. If auto-download is not set, setting this to | ||||
false | ||||
// will save one pass through all the feed items trying to f | ||||
ind | ||||
// corresponding torrents in the session. | ||||
bool auto_map_handles; | bool auto_map_handles; | |||
// in minutes | // The ``default_ttl`` is the default interval for refreshin | |||
g a feed. | ||||
// This may be overridden by the feed itself (by specifying | ||||
the ``<ttl>`` | ||||
// tag) and defaults to 30 minutes. The field specifies the | ||||
number of | ||||
// minutes between refreshes. | ||||
int default_ttl; | int default_ttl; | |||
// used when adding torrents | // If torrents are added automatically, you may want to set | |||
the | ||||
// ``add_args`` to appropriate values for download directory | ||||
etc. | ||||
// This object is used as a template for adding torrents fro | ||||
m feeds, | ||||
// but some torrent specific fields will be overridden by th | ||||
e | ||||
// individual torrent being added. For more information on t | ||||
he | ||||
// add_torrent_params, see async_add_torrent() and add_torre | ||||
nt(). | ||||
add_torrent_params add_args; | add_torrent_params add_args; | |||
}; | }; | |||
struct feed_status | // holds information about the status of an RSS feed. Retrieved by | |||
// calling get_feed_status() on feed_handle. | ||||
struct TORRENT_EXPORT feed_status | ||||
{ | { | |||
feed_status(): last_update(0), next_update(0) | feed_status(): last_update(0), next_update(0) | |||
, updating(false), ttl(0) {} | , updating(false), ttl(0) {} | |||
// the URL of the feed. | ||||
std::string url; | std::string url; | |||
// the name of the feed (as specified by the feed itself). T | ||||
his | ||||
// may be empty if we have not recevied a response from the | ||||
RSS server yet, | ||||
// or if the feed does not specify a title. | ||||
std::string title; | std::string title; | |||
// the feed description (as specified by the feed itself). | ||||
// This may be empty if we have not received a response from | ||||
the RSS server | ||||
// yet, or if the feed does not specify a description. | ||||
std::string description; | std::string description; | |||
// the posix time of the last successful response from the f | ||||
eed. | ||||
time_t last_update; | time_t last_update; | |||
// the number of seconds, from now, when the feed will be | ||||
// updated again. | ||||
int next_update; | int next_update; | |||
// true if the feed is currently being updated (i.e. waiting | ||||
for | ||||
// DNS resolution, connecting to the server or waiting for t | ||||
he response to the | ||||
// HTTP request, or receiving the response). | ||||
bool updating; | bool updating; | |||
// a vector of all items that we have received from the feed | ||||
. See | ||||
// feed_item for more information. | ||||
std::vector<feed_item> items; | std::vector<feed_item> items; | |||
// set to the appropriate error code if the feed encountered | ||||
an | ||||
// error. See error_code for more info. | ||||
error_code error; | error_code error; | |||
// the current refresh time (in minutes). It's either the co | ||||
nfigured | ||||
// default ttl, or the ttl specified by the feed. | ||||
int ttl; | int ttl; | |||
}; | }; | |||
struct feed; | struct feed; | |||
// The ``feed_handle`` refers to a specific RSS feed that is watched by the session. | ||||
struct TORRENT_EXPORT feed_handle | struct TORRENT_EXPORT feed_handle | |||
{ | { | |||
feed_handle() {} | feed_handle() {} | |||
// Forces an update/refresh of the feed. Regular updates of | ||||
the feed is managed | ||||
// by libtorrent, be careful to not call this too frequently | ||||
since it may | ||||
// overload the RSS server. | ||||
void update_feed(); | void update_feed(); | |||
// Queries the RSS feed for information, including all the i | ||||
tems in the feed. | ||||
// see feed_status. | ||||
feed_status get_feed_status() const; | feed_status get_feed_status() const; | |||
// Sets and gets settings for this feed. For more informatio | ||||
n on the | ||||
// available settings, see add_feed(). | ||||
void set_settings(feed_settings const& s); | void set_settings(feed_settings const& s); | |||
feed_settings settings() const; | feed_settings settings() const; | |||
private: | private: | |||
friend struct aux::session_impl; | friend struct aux::session_impl; | |||
friend struct feed; | friend struct feed; | |||
feed_handle(boost::weak_ptr<feed> const& p); | feed_handle(boost::weak_ptr<feed> const& p); | |||
boost::weak_ptr<feed> m_feed_ptr; | boost::weak_ptr<feed> m_feed_ptr; | |||
}; | }; | |||
struct feed_state; | struct feed_state; | |||
class http_parser; | class http_parser; | |||
boost::shared_ptr<feed> new_feed(aux::session_impl& ses, feed_settin gs const& sett); | boost::shared_ptr<feed> TORRENT_EXPORT new_feed(aux::session_impl& s es, feed_settings const& sett); | |||
// this is the internal object holding all state about an | // this is the internal object holding all state about an | |||
// RSS feed. All user interaction with this object | // RSS feed. All user interaction with this object | |||
// goes through the feed_handle, which makes sure all calls | // goes through the feed_handle, which makes sure all calls | |||
// are posted to the network thread | // are posted to the network thread | |||
struct TORRENT_EXTRA_EXPORT feed : boost::enable_shared_from_this<fe ed> | struct TORRENT_EXTRA_EXPORT feed : boost::enable_shared_from_this<fe ed> | |||
{ | { | |||
friend void parse_feed(feed_state& f, int token, char const* name, char const* val); | friend void parse_feed(feed_state& f, int token, char const* name, char const* val); | |||
feed(aux::session_impl& ses, feed_settings const& feed); | feed(aux::session_impl& ses, feed_settings const& feed); | |||
skipping to change at line 199 | skipping to change at line 274 | |||
int m_ttl; | int m_ttl; | |||
// the number of update failures in a row | // the number of update failures in a row | |||
int m_failures; | int m_failures; | |||
// true while waiting for the server to respond | // true while waiting for the server to respond | |||
bool m_updating; | bool m_updating; | |||
feed_settings m_settings; | feed_settings m_settings; | |||
aux::session_impl& m_ses; | aux::session_impl& m_ses; | |||
}; | }; | |||
}; | } | |||
#endif | #endif | |||
End of changes. 29 change blocks. | ||||
11 lines changed or deleted | 125 lines changed or added | |||
session.hpp | session.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2006, Arvid Norberg | Copyright (c) 2006-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 83 | skipping to change at line 83 | |||
#endif | #endif | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
struct plugin; | struct plugin; | |||
struct torrent_plugin; | struct torrent_plugin; | |||
class torrent; | class torrent; | |||
struct ip_filter; | struct ip_filter; | |||
class port_filter; | class port_filter; | |||
class connection_queue; | class connection_queue; | |||
class natpmp; | ||||
class upnp; | ||||
class alert; | class alert; | |||
// The default values of the session settings are set for a regular | ||||
// bittorrent client running on a desktop system. There are function | ||||
s that | ||||
// can set the session settings to pre set settings for other enviro | ||||
nments. | ||||
// These can be used for the basis, and should be tweaked to fit you | ||||
r needs | ||||
// better. | ||||
// | ||||
// ``min_memory_usage`` returns settings that will use the minimal a | ||||
mount of | ||||
// RAM, at the potential expense of upload and download performance. | ||||
It | ||||
// adjusts the socket buffer sizes, disables the disk cache, lowers | ||||
the send | ||||
// buffer watermarks so that each connection only has at most one bl | ||||
ock in | ||||
// use at any one time. It lowers the outstanding blocks send to the | ||||
disk | ||||
// I/O thread so that connections only have one block waiting to be | ||||
flushed | ||||
// to disk at any given time. It lowers the max number of peers in t | ||||
he peer | ||||
// list for torrents. It performs multiple smaller reads when it has | ||||
hes | ||||
// pieces, instead of reading it all into memory before hashing. | ||||
// | ||||
// This configuration is inteded to be the starting point for embedd | ||||
ed | ||||
// devices. It will significantly reduce memory usage. | ||||
// | ||||
// ``high_performance_seed`` returns settings optimized for a seed b | ||||
ox, | ||||
// serving many peers and that doesn't do any downloading. It has a | ||||
128 MB | ||||
// disk cache and has a limit of 400 files in its file pool. It supp | ||||
ort fast | ||||
// upload rates by allowing large send buffers. | ||||
TORRENT_EXPORT session_settings min_memory_usage(); | TORRENT_EXPORT session_settings min_memory_usage(); | |||
TORRENT_EXPORT session_settings high_performance_seed(); | TORRENT_EXPORT session_settings high_performance_seed(); | |||
#ifndef TORRENT_CFG | #ifndef TORRENT_CFG | |||
#error TORRENT_CFG is not defined! | #error TORRENT_CFG is not defined! | |||
#endif | #endif | |||
void TORRENT_EXPORT TORRENT_CFG(); | void TORRENT_EXPORT TORRENT_CFG(); | |||
namespace aux | namespace aux | |||
{ | { | |||
// workaround for microsofts | ||||
// hardware exceptions that makes | ||||
// it hard to debug stuff | ||||
#ifdef _MSC_VER | ||||
struct TORRENT_EXPORT eh_initializer | ||||
{ | ||||
eh_initializer(); | ||||
static void straight_to_debugger(unsigned int, _EXCE | ||||
PTION_POINTERS*) | ||||
{ throw; } | ||||
}; | ||||
#else | ||||
struct eh_initializer {}; | ||||
#endif | ||||
struct session_impl; | struct session_impl; | |||
} | } | |||
// this is a holder for the internal session implementation object. | ||||
Once the | ||||
// session destruction is explicitly initiated, this holder is used | ||||
to | ||||
// synchronize the completion of the shutdown. The lifetime of this | ||||
object | ||||
// may outlive session, causing the session destructor to not block. | ||||
The | ||||
// session_proxy destructor will block however, until the underlying | ||||
session | ||||
// is done shutting down. | ||||
class TORRENT_EXPORT session_proxy | class TORRENT_EXPORT session_proxy | |||
{ | { | |||
friend class session; | friend class session; | |||
public: | public: | |||
// default constructor, does not refer to any session | ||||
// implementation object. | ||||
session_proxy() {} | session_proxy() {} | |||
private: | private: | |||
session_proxy(boost::shared_ptr<aux::session_impl> impl) | session_proxy(boost::shared_ptr<aux::session_impl> impl) | |||
: m_impl(impl) {} | : m_impl(impl) {} | |||
boost::shared_ptr<aux::session_impl> m_impl; | boost::shared_ptr<aux::session_impl> m_impl; | |||
}; | }; | |||
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T ORRENT_ERROR_LOGGING | #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T ORRENT_ERROR_LOGGING | |||
#define TORRENT_LOGPATH_ARG_DEFAULT , std::string logpath = "." | #define TORRENT_LOGPATH_ARG_DEFAULT , std::string logpath = "." | |||
#define TORRENT_LOGPATH_ARG , std::string logpath | ||||
#define TORRENT_LOGPATH , logpath | ||||
#else | #else | |||
#define TORRENT_LOGPATH_ARG_DEFAULT | #define TORRENT_LOGPATH_ARG_DEFAULT | |||
#define TORRENT_LOGPATH_ARG | ||||
#define TORRENT_LOGPATH | ||||
#endif | #endif | |||
class TORRENT_EXPORT session: public boost::noncopyable, aux::eh_ini | // The session holds all state that spans multiple torrents. Among o | |||
tializer | ther | |||
// things it runs the network loop and manages all torrents. Once it | ||||
's | ||||
// created, the session object will spawn the main thread that will | ||||
do all | ||||
// the work. The main thread will be idle as long it doesn't have an | ||||
y | ||||
// torrents to participate in. | ||||
class TORRENT_EXPORT session: public boost::noncopyable | ||||
{ | { | |||
public: | public: | |||
// If the fingerprint in the first overload is omited, the c | ||||
lient will | ||||
// get a default fingerprint stating the version of libtorre | ||||
nt. The | ||||
// fingerprint is a short string that will be used in the pe | ||||
er-id to | ||||
// identify the client and the client's version. For more de | ||||
tails see the | ||||
// fingerprint class. The constructor that only takes a fing | ||||
erprint will | ||||
// not open a listen port for the session, to get it running | ||||
you'll have | ||||
// to call ``session::listen_on()``. The other constructor, | ||||
that takes a | ||||
// port range and an interface as well as the fingerprint wi | ||||
ll | ||||
// automatically try to listen on a port on the given interf | ||||
ace. For more | ||||
// information about the parameters, see ``listen_on()`` fun | ||||
ction. | ||||
// | ||||
// The flags paramater can be used to start default features | ||||
(upnp & | ||||
// nat-pmp) and default plugins (ut_metadata, ut_pex and sma | ||||
rt_ban). The | ||||
// default is to start those things. If you do not want them | ||||
to start, | ||||
// pass 0 as the flags parameter. | ||||
// | ||||
// The ``alert_mask`` is the same mask that you would send t | ||||
o | ||||
// set_alert_mask(). | ||||
session(fingerprint const& print = fingerprint("LT" | session(fingerprint const& print = fingerprint("LT" | |||
, LIBTORRENT_VERSION_MAJOR, LIBTORRENT_VERSION_MINOR , 0, 0) | , LIBTORRENT_VERSION_MAJOR, LIBTORRENT_VERSION_MINOR , 0, 0) | |||
, int flags = start_default_features | add_default_p lugins | , int flags = start_default_features | add_default_p lugins | |||
, boost::uint32_t alert_mask = alert::error_notifica tion | , boost::uint32_t alert_mask = alert::error_notifica tion | |||
TORRENT_LOGPATH_ARG_DEFAULT) | TORRENT_LOGPATH_ARG_DEFAULT) | |||
{ | { | |||
TORRENT_CFG(); | TORRENT_CFG(); | |||
init(std::make_pair(0, 0), "0.0.0.0", print, flags, | init(std::make_pair(0, 0), "0.0.0.0", print, alert_m | |||
alert_mask TORRENT_LOGPATH); | ask); | |||
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T | ||||
ORRENT_ERROR_LOGGING | ||||
set_log_path(logpath); | ||||
#endif | ||||
start(flags); | ||||
} | } | |||
session(fingerprint const& print | ||||
session( | ||||
fingerprint const& print | ||||
, std::pair<int, int> listen_port_range | , std::pair<int, int> listen_port_range | |||
, char const* listen_interface = "0.0.0.0" | , char const* listen_interface = "0.0.0.0" | |||
, int flags = start_default_features | add_default_p lugins | , int flags = start_default_features | add_default_p lugins | |||
, int alert_mask = alert::error_notification | , int alert_mask = alert::error_notification | |||
TORRENT_LOGPATH_ARG_DEFAULT) | TORRENT_LOGPATH_ARG_DEFAULT) | |||
{ | { | |||
TORRENT_CFG(); | TORRENT_CFG(); | |||
TORRENT_ASSERT(listen_port_range.first > 0); | TORRENT_ASSERT(listen_port_range.first > 0); | |||
TORRENT_ASSERT(listen_port_range.first < listen_port _range.second); | TORRENT_ASSERT(listen_port_range.first < listen_port _range.second); | |||
init(listen_port_range, listen_interface, print, fla | init(listen_port_range, listen_interface, print, ale | |||
gs, alert_mask TORRENT_LOGPATH); | rt_mask); | |||
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T | ||||
ORRENT_ERROR_LOGGING | ||||
set_log_path(logpath); | ||||
#endif | ||||
start(flags); | ||||
} | } | |||
// The destructor of session will notify all trackers that o | ||||
ur torrents | ||||
// have been shut down. If some trackers are down, they will | ||||
time out. | ||||
// All this before the destructor of session returns. So, it | ||||
's advised | ||||
// that any kind of interface (such as windows) are closed b | ||||
efore | ||||
// destructing the session object. Because it can take a few | ||||
second for | ||||
// it to finish. The timeout can be set with ``set_settings( | ||||
)``. | ||||
~session(); | ~session(); | |||
// flags that determines which aspects of the session should | ||||
be | ||||
// saved when calling save_state(). | ||||
enum save_state_flags_t | enum save_state_flags_t | |||
{ | { | |||
// saves settings (i.e. the session_settings) | ||||
save_settings = 0x001, | save_settings = 0x001, | |||
// saves dht_settings | ||||
save_dht_settings = 0x002, | save_dht_settings = 0x002, | |||
// saves dht state such as nodes and node-id, possib | ||||
ly accelerating | ||||
// joining the DHT if provided at next session start | ||||
up. | ||||
save_dht_state = 0x004, | save_dht_state = 0x004, | |||
// save proxy_settings | ||||
save_proxy = 0x008, | save_proxy = 0x008, | |||
// save i2p_proxy settings | ||||
save_i2p_proxy = 0x010, | save_i2p_proxy = 0x010, | |||
// save pe_settings | ||||
save_encryption_settings = 0x020, | save_encryption_settings = 0x020, | |||
// internal | ||||
save_as_map = 0x040, | save_as_map = 0x040, | |||
// saves RSS feeds | ||||
save_feeds = 0x080 | save_feeds = 0x080 | |||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
, | , | |||
save_dht_proxy = save_proxy, | save_dht_proxy = save_proxy, | |||
save_peer_proxy = save_proxy, | save_peer_proxy = save_proxy, | |||
save_web_proxy = save_proxy, | save_web_proxy = save_proxy, | |||
save_tracker_proxy = save_proxy | save_tracker_proxy = save_proxy | |||
#endif | #endif | |||
}; | }; | |||
// loads and saves all session settings, including dht_setti | ||||
ngs, | ||||
// encryption settings and proxy settings. ``save_state`` wr | ||||
ites all keys | ||||
// to the ``entry`` that's passed in, which needs to either | ||||
not be | ||||
// initialized, or initialized as a dictionary. | ||||
// | ||||
// ``load_state`` expects a lazy_entry which can be built fr | ||||
om a bencoded | ||||
// buffer with lazy_bdecode(). | ||||
// | ||||
// The ``flags`` arguments passed in to ``save_state`` can b | ||||
e used to | ||||
// filter which parts of the session state to save. By defau | ||||
lt, all state | ||||
// is saved (except for the individual torrents). see save_s | ||||
tate_flags_t | ||||
void save_state(entry& e, boost::uint32_t flags = 0xffffffff ) const; | void save_state(entry& e, boost::uint32_t flags = 0xffffffff ) const; | |||
void load_state(lazy_entry const& e); | void load_state(lazy_entry const& e); | |||
// .. note:: | ||||
// these calls are potentially expensive and won't scal | ||||
e well with | ||||
// lots of torrents. If you're concerned about performa | ||||
nce, consider | ||||
// using ``post_torrent_updates()`` instead. | ||||
// | ||||
// ``get_torrent_status`` returns a vector of the torrent_st | ||||
atus for | ||||
// every torrent which satisfies ``pred``, which is a predic | ||||
ate function | ||||
// which determines if a torrent should be included in the r | ||||
eturned set | ||||
// or not. Returning true means it should be included and fa | ||||
lse means | ||||
// excluded. The ``flags`` argument is the same as to | ||||
// ``torrent_handle::status()``. Since ``pred`` is guarantee | ||||
d to be | ||||
// called for every torrent, it may be used to count the num | ||||
ber of | ||||
// torrents of different categories as well. | ||||
// | ||||
// ``refresh_torrent_status`` takes a vector of torrent_stat | ||||
us structs | ||||
// (for instance the same vector that was returned by | ||||
// get_torrent_status() ) and refreshes the status based on | ||||
the | ||||
// ``handle`` member. It is possible to use this function by | ||||
first | ||||
// setting up a vector of default constructed ``torrent_stat | ||||
us`` objects, | ||||
// only initializing the ``handle`` member, in order to requ | ||||
est the | ||||
// torrent status for multiple torrents in a single call. Th | ||||
is can save a | ||||
// significant amount of time if you have a lot of torrents. | ||||
// | ||||
// Any torrent_status object whose ``handle`` member is not | ||||
referring to | ||||
// a valid torrent are ignored. | ||||
void get_torrent_status(std::vector<torrent_status>* ret | void get_torrent_status(std::vector<torrent_status>* ret | |||
, boost::function<bool(torrent_status const&)> const & pred | , boost::function<bool(torrent_status const&)> const & pred | |||
, boost::uint32_t flags = 0) const; | , boost::uint32_t flags = 0) const; | |||
void refresh_torrent_status(std::vector<torrent_status>* ret | void refresh_torrent_status(std::vector<torrent_status>* ret | |||
, boost::uint32_t flags = 0) const; | , boost::uint32_t flags = 0) const; | |||
void post_torrent_updates(); | ||||
// returns a list of all torrents in this session | // This functions instructs the session to post the state_up | |||
std::vector<torrent_handle> get_torrents() const; | date_alert, | |||
// containing the status of all torrents whose state changed | ||||
since the | ||||
// last time this function was called. | ||||
// | ||||
// Only torrents who has the state subscription flag set wil | ||||
l be | ||||
// included. This flag is on by default. See add_torrent_par | ||||
ams. | ||||
void post_torrent_updates(); | ||||
// internal | ||||
io_service& get_io_service(); | io_service& get_io_service(); | |||
// returns an invalid handle in case the torrent doesn't exi | // ``find_torrent()`` looks for a torrent with the given inf | |||
st | o-hash. In | |||
// case there is such a torrent in the session, a torrent_ha | ||||
ndle to that | ||||
// torrent is returned. In case the torrent cannot be found, | ||||
an invalid | ||||
// torrent_handle is returned. | ||||
// | ||||
// See ``torrent_handle::is_valid()`` to know if the torrent | ||||
was found or | ||||
// not. | ||||
// | ||||
// ``get_torrents()`` returns a vector of torrent_handles to | ||||
all the | ||||
// torrents currently in the session. | ||||
torrent_handle find_torrent(sha1_hash const& info_hash) cons t; | torrent_handle find_torrent(sha1_hash const& info_hash) cons t; | |||
std::vector<torrent_handle> get_torrents() const; | ||||
// You add torrents through the add_torrent() function where | ||||
you give an | ||||
// object with all the parameters. The add_torrent() overloa | ||||
ds will block | ||||
// until the torrent has been added (or failed to be added) | ||||
and returns | ||||
// an error code and a torrent_handle. In order to add torre | ||||
nts more | ||||
// efficiently, consider using async_add_torrent() which ret | ||||
urns | ||||
// immediately, without waiting for the torrent to add. Noti | ||||
fication of | ||||
// the torrent being added is sent as add_torrent_alert. | ||||
// | ||||
// The overload that does not take an error_code throws an e | ||||
xception on | ||||
// error and is not available when building without exceptio | ||||
n support. | ||||
// The torrent_handle returned by add_torrent() can be used | ||||
to retrieve | ||||
// information about the torrent's progress, its peers etc. | ||||
It is also | ||||
// used to abort a torrent. | ||||
// | ||||
// If the torrent you are trying to add already exists in th | ||||
e session (is | ||||
// either queued for checking, being checked or downloading) | ||||
// ``add_torrent()`` will throw libtorrent_exception which d | ||||
erives from | ||||
// ``std::exception`` unless duplicate_is_error is set to fa | ||||
lse. In that | ||||
// case, add_torrent() will return the handle to the existin | ||||
g torrent. | ||||
// | ||||
// all torrent_handles must be destructed before the session is destructed! | // all torrent_handles must be destructed before the session is destructed! | |||
#ifndef BOOST_NO_EXCEPTIONS | #ifndef BOOST_NO_EXCEPTIONS | |||
torrent_handle add_torrent(add_torrent_params const& params) ; | torrent_handle add_torrent(add_torrent_params const& params) ; | |||
#endif | #endif | |||
torrent_handle add_torrent(add_torrent_params const& params, error_code& ec); | torrent_handle add_torrent(add_torrent_params const& params, error_code& ec); | |||
void async_add_torrent(add_torrent_params const& params); | void async_add_torrent(add_torrent_params const& params); | |||
#ifndef BOOST_NO_EXCEPTIONS | #ifndef BOOST_NO_EXCEPTIONS | |||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
// deprecated in 0.14 | // deprecated in 0.14 | |||
skipping to change at line 247 | skipping to change at line 384 | |||
, char const* name | , char const* name | |||
, std::string const& save_path | , std::string const& save_path | |||
, entry const& resume_data = entry() | , entry const& resume_data = entry() | |||
, storage_mode_t storage_mode = storage_mode_sparse | , storage_mode_t storage_mode = storage_mode_sparse | |||
, bool paused = false | , bool paused = false | |||
, storage_constructor_type sc = default_storage_cons tructor | , storage_constructor_type sc = default_storage_cons tructor | |||
, void* userdata = 0) TORRENT_DEPRECATED; | , void* userdata = 0) TORRENT_DEPRECATED; | |||
#endif | #endif | |||
#endif | #endif | |||
// In case you want to destruct the session asynchrounously, | ||||
you can | ||||
// request a session destruction proxy. If you don't do this | ||||
, the | ||||
// destructor of the session object will block while the tra | ||||
ckers are | ||||
// contacted. If you keep one ``session_proxy`` to the sessi | ||||
on when | ||||
// destructing it, the destructor will not block, but start | ||||
to close down | ||||
// the session, the destructor of the proxy will then synchr | ||||
onize the | ||||
// threads. So, the destruction of the session is performed | ||||
from the | ||||
// ``session`` destructor call until the ``session_proxy`` d | ||||
estructor | ||||
// call. The ``session_proxy`` does not have any operations | ||||
on it (since | ||||
// the session is being closed down, no operations are allow | ||||
ed on it). | ||||
// The only valid operation is calling the destructor:: | ||||
// | ||||
// class session_proxy | ||||
// { | ||||
// public: | ||||
// session_proxy(); | ||||
// ~session_proxy() | ||||
// }; | ||||
session_proxy abort() { return session_proxy(m_impl); } | session_proxy abort() { return session_proxy(m_impl); } | |||
// Pausing the session has the same effect as pausing every | ||||
torrent in | ||||
// it, except that torrents will not be resumed by the auto- | ||||
manage | ||||
// mechanism. Resuming will restore the torrents to their pr | ||||
evious paused | ||||
// state. i.e. the session pause state is separate from the | ||||
torrent pause | ||||
// state. A torrent is inactive if it is paused or if the se | ||||
ssion is | ||||
// paused. | ||||
void pause(); | void pause(); | |||
void resume(); | void resume(); | |||
bool is_paused() const; | bool is_paused() const; | |||
// returns session wide-statistics and status. For more info | ||||
rmation, see | ||||
// the ``session_status`` struct. | ||||
session_status status() const; | session_status status() const; | |||
// Returns status of the disk cache for this session. For mo | ||||
re | ||||
// information, see the cache_status type. | ||||
cache_status get_cache_status() const; | cache_status get_cache_status() const; | |||
// fills out the supplied vector with information for | ||||
// each piece that is currently in the disk cache for the to | ||||
rrent with the | ||||
// specified info-hash (``ih``). | ||||
void get_cache_info(sha1_hash const& ih | void get_cache_info(sha1_hash const& ih | |||
, std::vector<cached_piece_info>& ret) const; | , std::vector<cached_piece_info>& ret) const; | |||
// This adds an RSS feed to the session. The feed will be re | ||||
freshed | ||||
// regularly and optionally add all torrents from the feed, | ||||
as they | ||||
// appear. | ||||
// | ||||
// Before adding the feed, you must set the ``url`` field to | ||||
the feed's | ||||
// url. It may point to an RSS or an atom feed. The returned | ||||
feed_handle | ||||
// is a handle which is used to interact with the feed, thin | ||||
gs like | ||||
// forcing a refresh or querying for information about the i | ||||
tems in the | ||||
// feed. For more information, see feed_handle. | ||||
feed_handle add_feed(feed_settings const& feed); | feed_handle add_feed(feed_settings const& feed); | |||
// Removes a feed from being watched by the session. When th | ||||
is | ||||
// call returns, the feed handle is invalid and won't refer | ||||
// to any feed. | ||||
void remove_feed(feed_handle h); | void remove_feed(feed_handle h); | |||
// Returns a list of all RSS feeds that are being watched by | ||||
the session. | ||||
void get_feeds(std::vector<feed_handle>& f) const; | void get_feeds(std::vector<feed_handle>& f) const; | |||
#ifndef TORRENT_DISABLE_DHT | // starts/stops UPnP, NATPMP or LSD port mappers they are st | |||
opped by | ||||
// default These functions are not available in case | ||||
// ``TORRENT_DISABLE_DHT`` is defined. ``start_dht`` starts | ||||
the dht node | ||||
// and makes the trackerless service available to torrents. | ||||
The startup | ||||
// state is optional and can contain nodes and the node id f | ||||
rom the | ||||
// previous session. The dht node state is a bencoded dictio | ||||
nary with the | ||||
// following entries: | ||||
// | ||||
// nodes | ||||
// A list of strings, where each string is a node endpo | ||||
int encoded in | ||||
// binary. If the string is 6 bytes long, it is an IPv4 | ||||
address of 4 | ||||
// bytes, encoded in network byte order (big endian), f | ||||
ollowed by a 2 | ||||
// byte port number (also network byte order). If the s | ||||
tring is 18 | ||||
// bytes long, it is 16 bytes of IPv6 address followed | ||||
by a 2 bytes | ||||
// port number (also network byte order). | ||||
// | ||||
// node-id | ||||
// The node id written as a readable string as a hexade | ||||
cimal number. | ||||
// | ||||
// ``dht_state`` will return the current state of the dht no | ||||
de, this can | ||||
// be used to start up the node again, passing this entry to | ||||
// ``start_dht``. It is a good idea to save this to disk whe | ||||
n the session | ||||
// is closed, and read it up again when starting. | ||||
// | ||||
// If the port the DHT is supposed to listen on is already i | ||||
n use, and | ||||
// exception is thrown, ``asio::error``. | ||||
// | ||||
// ``stop_dht`` stops the dht node. | ||||
// | ||||
// ``add_dht_node`` adds a node to the routing table. This c | ||||
an be used if | ||||
// your client has its own source of bootstrapping nodes. | ||||
// | ||||
// ``set_dht_settings`` sets some parameters availavle to th | ||||
e dht node. | ||||
// See dht_settings for more information. | ||||
// | ||||
// ``is_dht_running()`` returns true if the DHT support has | ||||
been started | ||||
// and false | ||||
// otherwise. | ||||
void start_dht(); | void start_dht(); | |||
void stop_dht(); | void stop_dht(); | |||
void set_dht_settings(dht_settings const& settings); | void set_dht_settings(dht_settings const& settings); | |||
bool is_dht_running() const; | ||||
// ``add_dht_node`` takes a host name and port pair. That en | ||||
dpoint will be | ||||
// pinged, and if a valid DHT reply is received, the node wi | ||||
ll be added to | ||||
// the routing table. | ||||
// | ||||
// ``add_dht_router`` adds the given endpoint to a list of D | ||||
HT router nodes. | ||||
// If a search is ever made while the routing table is empty | ||||
, those nodes will | ||||
// be used as backups. Nodes in the router node list will al | ||||
so never be added | ||||
// to the regular routing table, which effectively means the | ||||
y are only used | ||||
// for bootstrapping, to keep the load off them. | ||||
// | ||||
// An example routing node that you could typically add is | ||||
// ``router.bittorrent.com``. | ||||
void add_dht_node(std::pair<std::string, int> const& node); | ||||
void add_dht_router(std::pair<std::string, int> const& node) | ||||
; | ||||
// query the DHT for an immutable item at the ``target`` has | ||||
h. | ||||
// the result is posted as a dht_immutable_item_alert. | ||||
void dht_get_item(sha1_hash const& target); | ||||
// query the DHT for a mutable item under the public key ``k | ||||
ey``. | ||||
// this is an ed25519 key. ``salt`` is optional and may be l | ||||
eft | ||||
// as an empty string if no salt is to be used. | ||||
// if the item is found in the DHT, a dht_mutable_item_alert | ||||
is | ||||
// posted. | ||||
void dht_get_item(boost::array<char, 32> key | ||||
, std::string salt = std::string()); | ||||
// store the given bencoded data as an immutable item in the | ||||
DHT. | ||||
// the returned hash is the key that is to be used to look t | ||||
he item | ||||
// up agan. It's just the sha-1 hash of the bencoded form of | ||||
the | ||||
// structure. | ||||
sha1_hash dht_put_item(entry data); | ||||
// store an immutable item. The ``key`` is the public key th | ||||
e blob is | ||||
// to be stored under. The optional ``salt`` argument is a s | ||||
tring that | ||||
// is to be mixed in with the key when determining where in | ||||
the DHT | ||||
// the value is to be stored. The callback function is calle | ||||
d from within | ||||
// the libtorrent network thread once we've found where to s | ||||
tore the blob, | ||||
// possibly with the current value stored under the key. | ||||
// The values passed to the callback functions are: | ||||
// | ||||
// entry& value | ||||
// the current value stored under the key (may be empty | ||||
). Also expected | ||||
// to be set to the value to be stored by the function. | ||||
// | ||||
// boost::array<char,64>& signature | ||||
// the signature authenticating the current value. This | ||||
may be zeroes | ||||
// if there is currently no value stored. The functon i | ||||
s expected to | ||||
// fill in this buffer with the signature of the new va | ||||
lue to store. | ||||
// To generate the signature, you may want to use the | ||||
// ``sign_mutable_item`` function. | ||||
// | ||||
// boost::uint64_t& seq | ||||
// current sequence number. May be zero if there is no | ||||
current value. | ||||
// The function is expected to set this to the new sequ | ||||
ence number of | ||||
// the value that is to be stored. Sequence numbers mus | ||||
t be monotonically | ||||
// increasing. Attempting to overwrite a value with a l | ||||
ower or equal | ||||
// sequence number will fail, even if the signature is | ||||
correct. | ||||
// | ||||
// std::string const& salt | ||||
// this is the salt that was used for this put call. | ||||
// | ||||
// Since the callback function ``cb`` is called from within | ||||
libtorrent, | ||||
// it is critical to not perform any blocking operations. Id | ||||
eally not | ||||
// even locking a mutex. Pass any data required for this fun | ||||
ction along | ||||
// with the function object's context and make the function | ||||
entirely | ||||
// self-contained. The only reason data blobs' values are co | ||||
mputed | ||||
// via a function instead of just passing in the new value i | ||||
s to avoid | ||||
// race conditions. If you want to *update* the value in the | ||||
DHT, you | ||||
// must first retrieve it, then modify it, then write it bac | ||||
k. The way | ||||
// the DHT works, it is natural to always do a lookup before | ||||
storing and | ||||
// calling the callback in between is convenient. | ||||
void dht_put_item(boost::array<char, 32> key | ||||
, boost::function<void(entry&, boost::array<char,64> | ||||
& | ||||
, boost::uint64_t&, std::string const&)> cb | ||||
, std::string salt = std::string()); | ||||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
// deprecated in 0.15 | // deprecated in 0.15 | |||
// use save_state and load_state instead | // use save_state and load_state instead | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
entry dht_state() const TORRENT_DEPRECATED; | entry dht_state() const TORRENT_DEPRECATED; | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
void start_dht(entry const& startup_state) TORRENT_DEPRECATE D; | void start_dht(entry const& startup_state) TORRENT_DEPRECATE D; | |||
#endif | #endif | |||
void add_dht_node(std::pair<std::string, int> const& node); | ||||
void add_dht_router(std::pair<std::string, int> const& node) | ||||
; | ||||
bool is_dht_running() const; | ||||
#endif | ||||
#ifndef TORRENT_DISABLE_ENCRYPTION | ||||
void set_pe_settings(pe_settings const& settings); | ||||
pe_settings get_pe_settings() const; | ||||
#endif | ||||
#ifndef TORRENT_DISABLE_EXTENSIONS | // This function adds an extension to this session. The argu | |||
void add_extension(boost::function<boost::shared_ptr<torrent | ment is a | |||
_plugin>(torrent*, void*)> ext); | // function object that is called with a ``torrent*`` and wh | |||
ich should | ||||
// return a ``boost::shared_ptr<torrent_plugin>``. To write | ||||
custom | ||||
// plugins, see `libtorrent plugins`_. For the typical bitto | ||||
rrent client | ||||
// all of these extensions should be added. The main plugins | ||||
implemented | ||||
// in libtorrent are: | ||||
// | ||||
// metadata extension | ||||
// Allows peers to download the metadata (.torren files | ||||
) from the swarm | ||||
// directly. Makes it possible to join a swarm with jus | ||||
t a tracker and | ||||
// info-hash. | ||||
// | ||||
// :: | ||||
// | ||||
// #include <libtorrent/extensions/metadata_transfer.hp | ||||
p> | ||||
// ses.add_extension(&libtorrent::create_metadata_plugi | ||||
n); | ||||
// | ||||
// uTorrent metadata | ||||
// Same as ``metadata extension`` but compatible with u | ||||
Torrent. | ||||
// | ||||
// :: | ||||
// | ||||
// #include <libtorrent/extensions/ut_metadata.hpp> | ||||
// ses.add_extension(&libtorrent::create_ut_metadata_pl | ||||
ugin); | ||||
// | ||||
// uTorrent peer exchange | ||||
// Exchanges peers between clients. | ||||
// | ||||
// :: | ||||
// | ||||
// #include <libtorrent/extensions/ut_pex.hpp> | ||||
// ses.add_extension(&libtorrent::create_ut_pex_plugin) | ||||
; | ||||
// | ||||
// smart ban plugin | ||||
// A plugin that, with a small overhead, can ban peers | ||||
// that sends bad data with very high accuracy. Should | ||||
// eliminate most problems on poisoned torrents. | ||||
// | ||||
// :: | ||||
// | ||||
// #include <libtorrent/extensions/smart_ban.hpp> | ||||
// ses.add_extension(&libtorrent::create_smart_ban_plug | ||||
in); | ||||
// | ||||
// | ||||
// .. _`libtorrent plugins`: libtorrent_plugins.html | ||||
void add_extension(boost::function<boost::shared_ptr<torrent | ||||
_plugin>( | ||||
torrent*, void*)> ext); | ||||
void add_extension(boost::shared_ptr<plugin> ext); | void add_extension(boost::shared_ptr<plugin> ext); | |||
#endif | ||||
#ifndef TORRENT_DISABLE_GEO_IP | // These functions are not available if ``TORRENT_DISABLE_GE | |||
int as_for_ip(address const& addr); | O_IP`` is | |||
// defined. They expects a path to the `MaxMind ASN database | ||||
`_ and | ||||
// `MaxMind GeoIP database`_ respectively. This will be used | ||||
to look up | ||||
// which AS and country peers belong to. | ||||
// | ||||
// ``as_for_ip`` returns the AS number for the IP address sp | ||||
ecified. If | ||||
// the IP is not in the database or the ASN database is not | ||||
loaded, 0 is | ||||
// returned. | ||||
// | ||||
// .. _`MaxMind ASN database`: http://www.maxmind.com/app/as | ||||
num | ||||
// .. _`MaxMind GeoIP database`: http://www.maxmind.com/app/ | ||||
geolitecountry | ||||
void load_asnum_db(char const* file); | void load_asnum_db(char const* file); | |||
void load_country_db(char const* file); | void load_country_db(char const* file); | |||
int as_for_ip(address const& addr); | ||||
#ifndef TORRENT_NO_DEPRECATE | ||||
#if TORRENT_USE_WSTRING | #if TORRENT_USE_WSTRING | |||
// all wstring APIs are deprecated since 0.16.11 | // all wstring APIs are deprecated since 0.16.11 | |||
// instead, use the wchar -> utf8 conversion functions | // instead, use the wchar -> utf8 conversion functions | |||
// and pass in utf8 strings | // and pass in utf8 strings | |||
#ifndef TORRENT_NO_DEPRECATE | ||||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
void load_country_db(wchar_t const* file) TORRENT_DEPRECATED ; | void load_country_db(wchar_t const* file) TORRENT_DEPRECATED ; | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
void load_asnum_db(wchar_t const* file) TORRENT_DEPRECATED; | void load_asnum_db(wchar_t const* file) TORRENT_DEPRECATED; | |||
#endif // TORRENT_NO_DEPRECATE | ||||
#endif // TORRENT_USE_WSTRING | #endif // TORRENT_USE_WSTRING | |||
#endif // TORRENT_DISABLE_GEO_IP | #endif // TORRENT_NO_DEPRECATE | |||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
// deprecated in 0.15 | // deprecated in 0.15 | |||
// use load_state and save_state instead | // use load_state and save_state instead | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
void load_state(entry const& ses_state) TORRENT_DEPRECATED; | void load_state(entry const& ses_state) TORRENT_DEPRECATED; | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
entry state() const TORRENT_DEPRECATED; | entry state() const TORRENT_DEPRECATED; | |||
#endif | #endif | |||
// Sets a filter that will be used to reject and accept inco | ||||
ming as well | ||||
// as outgoing connections based on their originating ip add | ||||
ress. The | ||||
// default filter will allow connections to any ip address. | ||||
To build a | ||||
// set of rules for which addresses are accepted and not, se | ||||
e ip_filter. | ||||
// | ||||
// Each time a peer is blocked because of the IP filter, a | ||||
// peer_blocked_alert is generated. ``get_ip_filter()`` Retu | ||||
rns the | ||||
// ip_filter currently in the session. See ip_filter. | ||||
void set_ip_filter(ip_filter const& f); | void set_ip_filter(ip_filter const& f); | |||
ip_filter get_ip_filter() const; | ip_filter get_ip_filter() const; | |||
// apply port_filter ``f`` to incoming and outgoing peers. a | ||||
port filter | ||||
// will reject making outgoing peer connections to certain r | ||||
emote ports. | ||||
// The main intention is to be able to avoid triggering cert | ||||
ain | ||||
// anti-virus software by connecting to SMTP, FTP ports. | ||||
void set_port_filter(port_filter const& f); | void set_port_filter(port_filter const& f); | |||
// sets and gets the raw peer ID used by libtorrent. When an | ||||
onymous | ||||
// mode is set the peer ID is randomized per peer anyway. | ||||
void set_peer_id(peer_id const& pid); | void set_peer_id(peer_id const& pid); | |||
void set_key(int key); | ||||
peer_id id() const; | peer_id id() const; | |||
// sets the key sent to trackers. If it's not set, it is ini | ||||
tialized | ||||
// by libtorrent. The key may be used by the tracker to iden | ||||
tify the | ||||
// peer potentially across you changing your IP. | ||||
void set_key(int key); | ||||
// ``is_listening()`` will tell you whether or not the sessi | ||||
on has | ||||
// successfully opened a listening port. If it hasn't, this | ||||
function will | ||||
// return false, and then you can use ``listen_on()`` to mak | ||||
e another | ||||
// attempt. | ||||
// | ||||
// ``listen_port()`` returns the port we ended up listening | ||||
on. Since you | ||||
// just pass a port-range to the constructor and to ``listen | ||||
_on()``, to | ||||
// know which port it ended up using, you have to ask the se | ||||
ssion using | ||||
// this function. | ||||
// | ||||
// ``listen_on()`` will change the listen port and/or the li | ||||
sten | ||||
// interface. If the session is already listening on a port, | ||||
this socket | ||||
// will be closed and a new socket will be opened with these | ||||
new | ||||
// settings. The port range is the ports it will try to list | ||||
en on, if the | ||||
// first port fails, it will continue trying the next port w | ||||
ithin the | ||||
// range and so on. The interface parameter can be left as 0 | ||||
, in that | ||||
// case the os will decide which interface to listen on, oth | ||||
erwise it | ||||
// should be the ip-address of the interface you want the li | ||||
stener socket | ||||
// bound to. ``listen_on()`` returns the error code of the o | ||||
peration in | ||||
// ``ec``. If this indicates success, the session is listeni | ||||
ng on a port | ||||
// within the specified range. If it fails, it will also gen | ||||
erate an | ||||
// appropriate alert (listen_failed_alert). | ||||
// | ||||
// If all ports in the specified range fails to be opened fo | ||||
r listening, | ||||
// libtorrent will try to use port 0 (which tells the operat | ||||
ing system to | ||||
// pick a port that's free). If that still fails you may see | ||||
a | ||||
// listen_failed_alert with port 0 even if you didn't ask to | ||||
listen on | ||||
// it. | ||||
// | ||||
// It is possible to prevent libtorrent from binding to port | ||||
0 by passing | ||||
// in the flag ``session::no_system_port`` in the ``flags`` | ||||
argument. | ||||
// | ||||
// The interface parameter can also be a hostname that will | ||||
resolve to | ||||
// the device you want to listen on. If you don't specify an | ||||
interface, | ||||
// libtorrent may attempt to listen on multiple interfaces ( | ||||
typically | ||||
// 0.0.0.0 and ::). This means that if your IPv6 interface d | ||||
oesn't work, | ||||
// you may still see a listen_failed_alert, even though the | ||||
IPv4 port | ||||
// succeeded. | ||||
// | ||||
// The ``flags`` parameter can either be 0 or | ||||
// ``session::listen_reuse_address``, which will set the reu | ||||
se address | ||||
// socket option on the listen socket(s). By default, the li | ||||
sten socket | ||||
// does not use reuse address. If you're running a service t | ||||
hat needs to | ||||
// run on a specific port no matter if it's in use, set this | ||||
flag. | ||||
// | ||||
// If you're also starting the DHT, it is a good idea to do | ||||
that after | ||||
// you've called ``listen_on()``, since the default listen p | ||||
ort for the | ||||
// DHT is the same as the tcp listen socket. If you start th | ||||
e DHT first, | ||||
// it will assume the tcp port is free and open the udp sock | ||||
et on that | ||||
// port, then later, when ``listen_on()`` is called, it may | ||||
turn out that | ||||
// the tcp port is in use. That results in the DHT and the b | ||||
ittorrent | ||||
// socket listening on different ports. If the DHT is active | ||||
when | ||||
// ``listen_on`` is called, the udp port will be rebound to | ||||
the new port, | ||||
// if it was configured to use the same port as the tcp sock | ||||
et, and if | ||||
// the listen_on call failed to bind to the same port that t | ||||
he udp uses. | ||||
// | ||||
// If you want the OS to pick a port for you, pass in 0 as b | ||||
oth first and | ||||
// second. | ||||
// | ||||
// The reason why it's a good idea to run the DHT and the bi | ||||
ttorrent | ||||
// socket on the same port is because that is an assumption | ||||
that may be | ||||
// used to increase performance. One way to accelerate the c | ||||
onnecting of | ||||
// peers on windows may be to first ping all peers with a DH | ||||
T ping | ||||
// packet, and connect to those that responds first. On wind | ||||
ows one can | ||||
// only connect to a few peers at a time because of a built | ||||
in limitation | ||||
// (in XP Service pack 2). | ||||
void listen_on( | ||||
std::pair<int, int> const& port_range | ||||
, error_code& ec | ||||
, const char* net_interface = 0 | ||||
, int flags = 0); | ||||
unsigned short listen_port() const; | ||||
unsigned short ssl_listen_port() const; | ||||
bool is_listening() const; | bool is_listening() const; | |||
// if the listen port failed in some way | // if the listen port failed in some way you can retry to li | |||
// you can retry to listen on another port- | sten on | |||
// range with this function. If the listener | // another port- range with this function. If the listener s | |||
// succeeded and is currently listening, | ucceeded and | |||
// a call to this function will shut down the | // is currently listening, a call to this function will shut | |||
// listen port and reopen it using these new | down the | |||
// properties (the given interface and port range). | // listen port and reopen it using these new properties (the | |||
// As usual, if the interface is left as 0 | given | |||
// this function will return false on failure. | // interface and port range). As usual, if the interface is | |||
// If it fails, it will also generate alerts describing | left as 0 | |||
// the error. It will return true on success. | // this function will return false on failure. If it fails, | |||
it will also | ||||
// generate alerts describing the error. It will return true | ||||
on success. | ||||
enum listen_on_flags_t | enum listen_on_flags_t | |||
{ | { | |||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
// this is always on starting with 0.16.2 | // this is always on starting with 0.16.2 | |||
listen_reuse_address = 0x01, | listen_reuse_address = 0x01, | |||
#endif | #endif | |||
listen_no_system_port = 0x02 | listen_no_system_port = 0x02 | |||
}; | }; | |||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
// deprecated in 0.16 | // deprecated in 0.16 | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
bool listen_on( | bool listen_on( | |||
std::pair<int, int> const& port_range | std::pair<int, int> const& port_range | |||
, const char* net_interface = 0 | , const char* net_interface = 0 | |||
, int flags = 0) TORRENT_DEPRECATED; | , int flags = 0) TORRENT_DEPRECATED; | |||
#endif | #endif | |||
void listen_on( | // flags to be passed in to remove_torrent(). | |||
std::pair<int, int> const& port_range | ||||
, error_code& ec | ||||
, const char* net_interface = 0 | ||||
, int flags = 0); | ||||
// returns the port we ended up listening on | ||||
unsigned short listen_port() const; | ||||
unsigned short ssl_listen_port() const; | ||||
enum options_t | enum options_t | |||
{ | { | |||
none = 0, | // delete the files belonging to the torrent from di sk. | |||
delete_files = 1 | delete_files = 1 | |||
}; | }; | |||
// flags to be passed in to the session constructor | ||||
enum session_flags_t | enum session_flags_t | |||
{ | { | |||
// this will add common extensions like ut_pex, ut_m | ||||
etadata, lt_tex | ||||
// smart_ban and possibly others. | ||||
add_default_plugins = 1, | add_default_plugins = 1, | |||
// this will start features like DHT, local service | ||||
discovery, UPnP | ||||
// and NAT-PMP. | ||||
start_default_features = 2 | start_default_features = 2 | |||
}; | }; | |||
void remove_torrent(const torrent_handle& h, int options = n | // ``remove_torrent()`` will close all peer connections asso | |||
one); | ciated with | |||
// the torrent and tell the tracker that we've stopped parti | ||||
cipating in | ||||
// the swarm. This operation cannot fail. When it completes, | ||||
you will | ||||
// receive a torrent_removed_alert. | ||||
// | ||||
// The optional second argument ``options`` can be used to d | ||||
elete all the | ||||
// files downloaded by this torrent. To do so, pass in the v | ||||
alue | ||||
// ``session::delete_files``. The removal of the torrent is | ||||
asyncronous, | ||||
// there is no guarantee that adding the same torrent immedi | ||||
ately after | ||||
// it was removed will not throw a libtorrent_exception exce | ||||
ption. Once | ||||
// the torrent is deleted, a torrent_deleted_alert is posted | ||||
. | ||||
void remove_torrent(const torrent_handle& h, int options = 0 | ||||
); | ||||
// Sets the session settings and the packet encryption setti | ||||
ngs | ||||
// respectively. See session_settings and pe_settings for mo | ||||
re | ||||
// information on available options. | ||||
void set_settings(session_settings const& s); | void set_settings(session_settings const& s); | |||
session_settings settings() const; | session_settings settings() const; | |||
void set_pe_settings(pe_settings const& settings); | ||||
pe_settings get_pe_settings() const; | ||||
// These functions sets and queries the proxy settings to be | ||||
used for the | ||||
// session. | ||||
// | ||||
// For more information on what settings are available for p | ||||
roxies, see | ||||
// proxy_settings. If the session is not in anonymous mode, | ||||
proxies that | ||||
// aren't working or fail, will automatically be disabled an | ||||
d packets | ||||
// will flow without using any proxy. If you want to enforce | ||||
using a | ||||
// proxy, even when the proxy doesn't work, enable anonymous | ||||
_mode in | ||||
// session_settings. | ||||
void set_proxy(proxy_settings const& s); | void set_proxy(proxy_settings const& s); | |||
proxy_settings proxy() const; | proxy_settings proxy() const; | |||
#ifdef TORRENT_STATS | #ifdef TORRENT_STATS | |||
// internal | ||||
void enable_stats_logging(bool s); | void enable_stats_logging(bool s); | |||
#endif | #endif | |||
// ``set_i2p_proxy`` sets the i2p_ proxy, and tries to open | ||||
a persistant | ||||
// connection to it. The only used fields in the proxy setti | ||||
ngs structs | ||||
// are ``hostname`` and ``port``. | ||||
// | ||||
// ``i2p_proxy`` returns the current i2p proxy in use. | ||||
// | ||||
// .. _i2p: http://www.i2p2.de | ||||
void set_i2p_proxy(proxy_settings const& s); | ||||
proxy_settings i2p_proxy() const; | ||||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
// deprecated in 0.16 | // deprecated in 0.16 | |||
// Get the number of uploads. | // Get the number of uploads. | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
int num_uploads() const TORRENT_DEPRECATED; | int num_uploads() const TORRENT_DEPRECATED; | |||
// Get the number of connections. This number also contains the | // Get the number of connections. This number also contains the | |||
// number of half open connections. | // number of half open connections. | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
int num_connections() const TORRENT_DEPRECATED; | int num_connections() const TORRENT_DEPRECATED; | |||
skipping to change at line 415 | skipping to change at line 880 | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
void set_tracker_proxy(proxy_settings const& s) TORRENT_DEPR ECATED; | void set_tracker_proxy(proxy_settings const& s) TORRENT_DEPR ECATED; | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
proxy_settings peer_proxy() const TORRENT_DEPRECATED; | proxy_settings peer_proxy() const TORRENT_DEPRECATED; | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
proxy_settings web_seed_proxy() const TORRENT_DEPRECATED; | proxy_settings web_seed_proxy() const TORRENT_DEPRECATED; | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
proxy_settings tracker_proxy() const TORRENT_DEPRECATED; | proxy_settings tracker_proxy() const TORRENT_DEPRECATED; | |||
#ifndef TORRENT_DISABLE_DHT | ||||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
void set_dht_proxy(proxy_settings const& s) TORRENT_DEPRECAT ED; | void set_dht_proxy(proxy_settings const& s) TORRENT_DEPRECAT ED; | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
proxy_settings dht_proxy() const TORRENT_DEPRECATED; | proxy_settings dht_proxy() const TORRENT_DEPRECATED; | |||
#endif | ||||
#endif // TORRENT_NO_DEPRECATE | ||||
#if TORRENT_USE_I2P | ||||
void set_i2p_proxy(proxy_settings const& s); | ||||
proxy_settings i2p_proxy() const; | ||||
#endif | ||||
#ifndef TORRENT_NO_DEPRECATE | ||||
// deprecated in 0.16 | // deprecated in 0.16 | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
int upload_rate_limit() const TORRENT_DEPRECATED; | int upload_rate_limit() const TORRENT_DEPRECATED; | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
int download_rate_limit() const TORRENT_DEPRECATED; | int download_rate_limit() const TORRENT_DEPRECATED; | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
int local_upload_rate_limit() const TORRENT_DEPRECATED; | int local_upload_rate_limit() const TORRENT_DEPRECATED; | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
int local_download_rate_limit() const TORRENT_DEPRECATED; | int local_download_rate_limit() const TORRENT_DEPRECATED; | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
skipping to change at line 462 | skipping to change at line 918 | |||
void set_max_connections(int limit) TORRENT_DEPRECATED; | void set_max_connections(int limit) TORRENT_DEPRECATED; | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
void set_max_half_open_connections(int limit) TORRENT_DEPREC ATED; | void set_max_half_open_connections(int limit) TORRENT_DEPREC ATED; | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
int max_connections() const TORRENT_DEPRECATED; | int max_connections() const TORRENT_DEPRECATED; | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
int max_uploads() const TORRENT_DEPRECATED; | int max_uploads() const TORRENT_DEPRECATED; | |||
#endif | #endif | |||
// pop one alert from the alert queue, or do nothing | // ``pop_alert()`` is used to ask the session if any errors | |||
// and return a NULL pointer if there are no alerts | or events has | |||
// in the queue | // occurred. With set_alert_mask() you can filter which aler | |||
ts to receive | ||||
// through ``pop_alert()``. For information about the alert | ||||
categories, | ||||
// see alerts_. | ||||
// | ||||
// ``pop_alerts()`` pops all pending alerts in a single call | ||||
. In high | ||||
// performance environments with a very high alert churn rat | ||||
e, this can | ||||
// save significant amount of time compared to popping alert | ||||
s one at a | ||||
// time. Each call requires one round-trip to the network th | ||||
read. If | ||||
// alerts are produced in a higher rate than they can be pop | ||||
ped (when | ||||
// popped one at a time) it's easy to get stuck in an infini | ||||
te loop, | ||||
// trying to drain the alert queue. Popping the entire queue | ||||
at once | ||||
// avoids this problem. | ||||
// | ||||
// However, the ``pop_alerts`` function comes with significa | ||||
ntly more | ||||
// responsibility. You pass in an *empty* ``std::dequeue<ale | ||||
rt*>`` to it. | ||||
// If it's not empty, all elements in it will be deleted and | ||||
then | ||||
// cleared. All currently pending alerts are returned by bei | ||||
ng swapped | ||||
// into the passed in container. The responsibility of delet | ||||
ing the | ||||
// alerts is transferred to the caller. This means you need | ||||
to call | ||||
// delete for each item in the returned dequeue. It's probab | ||||
ly a good | ||||
// idea to delete the alerts as you handle them, to save one | ||||
extra pass | ||||
// over the dequeue. | ||||
// | ||||
// Alternatively, you can pass in the same container the nex | ||||
t time you | ||||
// call ``pop_alerts``. | ||||
// | ||||
// ``wait_for_alert`` blocks until an alert is available, or | ||||
for no more | ||||
// than ``max_wait`` time. If ``wait_for_alert`` returns bec | ||||
ause of the | ||||
// time-out, and no alerts are available, it returns 0. If a | ||||
t least one | ||||
// alert was generated, a pointer to that alert is returned. | ||||
The alert is | ||||
// not popped, any subsequent calls to ``wait_for_alert`` wi | ||||
ll return the | ||||
// same pointer until the alert is popped by calling ``pop_a | ||||
lert``. This | ||||
// is useful for leaving any alert dispatching mechanism ind | ||||
ependent of | ||||
// this blocking call, the dispatcher can be called and it c | ||||
an pop the | ||||
// alert independently. | ||||
// | ||||
// .. note:: | ||||
// Although these functions are all thread-safe, poppin | ||||
g alerts from | ||||
// multiple separate threads may introduce race conditi | ||||
ons in that | ||||
// the thread issuing an asynchronous operation may not | ||||
be the one | ||||
// receiving the alert with the result. | ||||
// | ||||
// In the python binding, ``wait_for_alert`` takes the numbe | ||||
r of | ||||
// milliseconds to wait as an integer. | ||||
// | ||||
// To control the max number of alerts that's queued by the | ||||
session, see | ||||
// ``session_settings::alert_queue_size``. | ||||
// | ||||
// save_resume_data_alert and save_resume_data_failed_alert | ||||
are always | ||||
// posted, regardelss of the alert mask. | ||||
std::auto_ptr<alert> pop_alert(); | std::auto_ptr<alert> pop_alert(); | |||
// pop all alerts in the alert queue and returns them | ||||
// in the supplied dequeue 'alerts'. The passed in | ||||
// queue must be empty when passed in. | ||||
// the responsibility of individual alerts returned | ||||
// in the dequeue is passed on to the caller of this functio | ||||
n. | ||||
// when you're done with reacting to the alerts, you need to | ||||
// delete them all. | ||||
void pop_alerts(std::deque<alert*>* alerts); | void pop_alerts(std::deque<alert*>* alerts); | |||
alert const* wait_for_alert(time_duration max_wait); | ||||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
void set_severity_level(alert::severity_t s) TORRENT_DEPRECA TED; | void set_severity_level(alert::severity_t s) TORRENT_DEPRECA TED; | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
size_t set_alert_queue_size_limit(size_t queue_size_limit_) TORRENT_DEPRECATED; | size_t set_alert_queue_size_limit(size_t queue_size_limit_) TORRENT_DEPRECATED; | |||
#endif | #endif | |||
// Changes the mask of which alerts to receive. By default o | ||||
nly errors | ||||
// are reported. ``m`` is a bitmask where each bit represent | ||||
s a category | ||||
// of alerts. | ||||
// | ||||
// See category_t enum for options. | ||||
void set_alert_mask(boost::uint32_t m); | void set_alert_mask(boost::uint32_t m); | |||
alert const* wait_for_alert(time_duration max_wait); | // This sets a function to be called (from within libtorrent | |||
's netowrk | ||||
// thread) every time an alert is posted. Since the function | ||||
(``fun``) is | ||||
// run in libtorrent's internal thread, it may not call any | ||||
of | ||||
// libtorrent's external API functions. Doing so results in | ||||
a dead lock. | ||||
// | ||||
// The main intention with this function is to support integ | ||||
ration with | ||||
// platform-dependent message queues or signalling systems. | ||||
For instance, | ||||
// on windows, one could post a message to an HNWD or on lin | ||||
ux, write to | ||||
// a pipe or an eventfd. | ||||
void set_alert_dispatch(boost::function<void(std::auto_ptr<a lert>)> const& fun); | void set_alert_dispatch(boost::function<void(std::auto_ptr<a lert>)> const& fun); | |||
// internal | ||||
connection_queue& get_connection_queue(); | connection_queue& get_connection_queue(); | |||
// starts/stops UPnP, NATPMP or LSD port mappers | // Starts and stops Local Service Discovery. This service wi | |||
// they are stopped by default | ll broadcast | |||
// the infohashes of all the non-private torrents on the loc | ||||
al network to | ||||
// look for peers on the same swarm within multicast reach. | ||||
// | ||||
// It is turned off by default. | ||||
void start_lsd(); | void start_lsd(); | |||
natpmp* start_natpmp(); | ||||
upnp* start_upnp(); | ||||
void stop_lsd(); | void stop_lsd(); | |||
void stop_natpmp(); | ||||
// Starts and stops the UPnP service. When started, the list | ||||
en port and | ||||
// the DHT port are attempted to be forwarded on local UPnP | ||||
router | ||||
// devices. | ||||
// | ||||
// The upnp object returned by ``start_upnp()`` can be used | ||||
to add and | ||||
// remove arbitrary port mappings. Mapping status is returne | ||||
d through the | ||||
// portmap_alert and the portmap_error_alert. The object wil | ||||
l be valid | ||||
// until ``stop_upnp()`` is called. See upnp-and-nat-pmp_. | ||||
// | ||||
// It is off by default. | ||||
void start_upnp(); | ||||
void stop_upnp(); | void stop_upnp(); | |||
// protocols used by add_port_mapping() | ||||
enum protocol_type { udp = 1, tcp = 2 }; | ||||
// add_port_mapping adds a port forwarding on UPnP and/or NA | ||||
T-PMP, | ||||
// whichever is enabled. The return value is a handle referr | ||||
ing to the | ||||
// port mapping that was just created. Pass it to delete_por | ||||
t_mapping() | ||||
// to remove it. | ||||
int add_port_mapping(protocol_type t, int external_port, int | ||||
local_port); | ||||
void delete_port_mapping(int handle); | ||||
// Starts and stops the NAT-PMP service. When started, the l | ||||
isten port | ||||
// and the DHT port are attempted to be forwarded on the rou | ||||
ter through | ||||
// NAT-PMP. | ||||
// | ||||
// The natpmp object returned by ``start_natpmp()`` can be u | ||||
sed to add | ||||
// and remove arbitrary port mappings. Mapping status is ret | ||||
urned through | ||||
// the portmap_alert and the portmap_error_alert. The object | ||||
will be | ||||
// valid until ``stop_natpmp()`` is called. See upnp-and-nat | ||||
-pmp_. | ||||
// | ||||
// It is off by default. | ||||
void start_natpmp(); | ||||
void stop_natpmp(); | ||||
private: | private: | |||
void init(std::pair<int, int> listen_range, char const* list en_interface | void init(std::pair<int, int> listen_range, char const* list en_interface | |||
, fingerprint const& id, int flags, boost::uint32_t | , fingerprint const& id, boost::uint32_t alert_mask) | |||
alert_mask TORRENT_LOGPATH_ARG); | ; | |||
void set_log_path(std::string const& p); | ||||
void start(int flags); | ||||
// data shared between the main thread | // data shared between the main thread | |||
// and the working thread | // and the working thread | |||
boost::shared_ptr<aux::session_impl> m_impl; | boost::shared_ptr<aux::session_impl> m_impl; | |||
}; | }; | |||
} | } | |||
#endif // TORRENT_SESSION_HPP_INCLUDED | #endif // TORRENT_SESSION_HPP_INCLUDED | |||
End of changes. 79 change blocks. | ||||
111 lines changed or deleted | 996 lines changed or added | |||
session_impl.hpp | session_impl.hpp | |||
---|---|---|---|---|
skipping to change at line 60 | skipping to change at line 60 | |||
#ifdef _MSC_VER | #ifdef _MSC_VER | |||
#pragma warning(push, 1) | #pragma warning(push, 1) | |||
#endif | #endif | |||
#include <boost/pool/object_pool.hpp> | #include <boost/pool/object_pool.hpp> | |||
#ifdef _MSC_VER | #ifdef _MSC_VER | |||
#pragma warning(pop) | #pragma warning(pop) | |||
#endif | #endif | |||
#include "libtorrent/ip_voter.hpp" | ||||
#include "libtorrent/torrent_handle.hpp" | #include "libtorrent/torrent_handle.hpp" | |||
#include "libtorrent/entry.hpp" | #include "libtorrent/entry.hpp" | |||
#include "libtorrent/socket.hpp" | #include "libtorrent/socket.hpp" | |||
#include "libtorrent/peer_id.hpp" | #include "libtorrent/peer_id.hpp" | |||
#include "libtorrent/tracker_manager.hpp" | #include "libtorrent/tracker_manager.hpp" | |||
#include "libtorrent/debug.hpp" | #include "libtorrent/debug.hpp" | |||
#include "libtorrent/piece_block_progress.hpp" | #include "libtorrent/piece_block_progress.hpp" | |||
#include "libtorrent/ip_filter.hpp" | #include "libtorrent/ip_filter.hpp" | |||
#include "libtorrent/config.hpp" | #include "libtorrent/config.hpp" | |||
#include "libtorrent/session_settings.hpp" | #include "libtorrent/session_settings.hpp" | |||
skipping to change at line 82 | skipping to change at line 83 | |||
#include "libtorrent/stat.hpp" | #include "libtorrent/stat.hpp" | |||
#include "libtorrent/file_pool.hpp" | #include "libtorrent/file_pool.hpp" | |||
#include "libtorrent/bandwidth_manager.hpp" | #include "libtorrent/bandwidth_manager.hpp" | |||
#include "libtorrent/socket_type.hpp" | #include "libtorrent/socket_type.hpp" | |||
#include "libtorrent/connection_queue.hpp" | #include "libtorrent/connection_queue.hpp" | |||
#include "libtorrent/disk_io_thread.hpp" | #include "libtorrent/disk_io_thread.hpp" | |||
#include "libtorrent/udp_socket.hpp" | #include "libtorrent/udp_socket.hpp" | |||
#include "libtorrent/assert.hpp" | #include "libtorrent/assert.hpp" | |||
#include "libtorrent/thread.hpp" | #include "libtorrent/thread.hpp" | |||
#include "libtorrent/policy.hpp" // for policy::peer | #include "libtorrent/policy.hpp" // for policy::peer | |||
#include "libtorrent/alert.hpp" // for alert_manager | #include "libtorrent/alert_manager.hpp" // for alert_manager | |||
#include "libtorrent/deadline_timer.hpp" | #include "libtorrent/deadline_timer.hpp" | |||
#include "libtorrent/socket_io.hpp" // for print_address | #include "libtorrent/socket_io.hpp" // for print_address | |||
#include "libtorrent/address.hpp" | #include "libtorrent/address.hpp" | |||
#include "libtorrent/utp_socket_manager.hpp" | #include "libtorrent/utp_socket_manager.hpp" | |||
#include "libtorrent/bloom_filter.hpp" | #include "libtorrent/bloom_filter.hpp" | |||
#include "libtorrent/rss.hpp" | #include "libtorrent/rss.hpp" | |||
#include "libtorrent/alert_dispatcher.hpp" | ||||
#include "libtorrent/kademlia/dht_observer.hpp" | ||||
#if TORRENT_COMPLETE_TYPES_REQUIRED | #if TORRENT_COMPLETE_TYPES_REQUIRED | |||
#include "libtorrent/peer_connection.hpp" | #include "libtorrent/peer_connection.hpp" | |||
#endif | #endif | |||
#ifdef TORRENT_USE_OPENSSL | #ifdef TORRENT_USE_OPENSSL | |||
#include <boost/asio/ssl/context.hpp> | #include <boost/asio/ssl/context.hpp> | |||
#endif | #endif | |||
#if defined TORRENT_STATS && defined __MACH__ | #if defined TORRENT_STATS && defined __MACH__ | |||
skipping to change at line 119 | skipping to change at line 122 | |||
class upnp; | class upnp; | |||
class natpmp; | class natpmp; | |||
class lsd; | class lsd; | |||
struct fingerprint; | struct fingerprint; | |||
class torrent; | class torrent; | |||
class alert; | class alert; | |||
namespace dht | namespace dht | |||
{ | { | |||
struct dht_tracker; | struct dht_tracker; | |||
class item; | ||||
} | } | |||
struct bencode_map_entry; | struct bencode_map_entry; | |||
struct listen_socket_t | struct listen_socket_t | |||
{ | { | |||
listen_socket_t(): external_port(0), ssl(false) {} | listen_socket_t(): external_port(0), ssl(false) {} | |||
// this is typically empty but can be set | // this is typically empty but can be set | |||
// to the WAN IP address of NAT-PMP or UPnP router | // to the WAN IP address of NAT-PMP or UPnP router | |||
skipping to change at line 185 | skipping to change at line 189 | |||
// anything else | // anything else | |||
struct initialize_timer | struct initialize_timer | |||
{ | { | |||
initialize_timer(); | initialize_timer(); | |||
}; | }; | |||
TORRENT_EXPORT std::pair<bencode_map_entry*, int> settings_m ap(); | TORRENT_EXPORT std::pair<bencode_map_entry*, int> settings_m ap(); | |||
// this is the link between the main thread and the | // this is the link between the main thread and the | |||
// thread started to run the main downloader loop | // thread started to run the main downloader loop | |||
struct TORRENT_EXTRA_EXPORT session_impl: boost::noncopyable | struct TORRENT_EXTRA_EXPORT session_impl | |||
, initialize_timer | : alert_dispatcher | |||
, boost::enable_shared_from_this<session_impl> | , dht::dht_observer | |||
, boost::noncopyable | ||||
, initialize_timer | ||||
, udp_socket_observer | ||||
{ | { | |||
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T ORRENT_ERROR_LOGGING | #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T ORRENT_ERROR_LOGGING | |||
// this needs to be destructed last, since other com ponents may log | // this needs to be destructed last, since other com ponents may log | |||
// things as they are being destructed. That's why i t's declared at | // things as they are being destructed. That's why i t's declared at | |||
// the top of session_impl | // the top of session_impl | |||
boost::shared_ptr<logger> m_logger; | boost::shared_ptr<logger> m_logger; | |||
#endif | #endif | |||
// the size of each allocation that is chained in th e send buffer | // the size of each allocation that is chained in th e send buffer | |||
enum { send_buffer_size = 128 }; | enum { send_buffer_size = 128 }; | |||
skipping to change at line 210 | skipping to change at line 218 | |||
#endif | #endif | |||
friend struct checker_impl; | friend struct checker_impl; | |||
friend class invariant_access; | friend class invariant_access; | |||
typedef std::set<boost::intrusive_ptr<peer_connectio n> > connection_map; | typedef std::set<boost::intrusive_ptr<peer_connectio n> > connection_map; | |||
typedef std::map<sha1_hash, boost::shared_ptr<torren t> > torrent_map; | typedef std::map<sha1_hash, boost::shared_ptr<torren t> > torrent_map; | |||
session_impl( | session_impl( | |||
std::pair<int, int> listen_port_range | std::pair<int, int> listen_port_range | |||
, fingerprint const& cl_fprint | , fingerprint const& cl_fprint | |||
, char const* listen_interface | , char const* listen_interface | |||
, boost::uint32_t alert_mask | , boost::uint32_t alert_mask); | |||
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T | virtual ~session_impl(); | |||
ORRENT_ERROR_LOGGING | void update_dht_announce_interval(); | |||
, std::string const& logpath | ||||
#endif | ||||
); | ||||
~session_impl(); | ||||
void init(); | void init(); | |||
void start_session(); | void start_session(); | |||
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T | ||||
ORRENT_ERROR_LOGGING | ||||
void set_log_path(std::string const& p) { m_logpath | ||||
= p; } | ||||
#endif | ||||
#ifndef TORRENT_DISABLE_EXTENSIONS | #ifndef TORRENT_DISABLE_EXTENSIONS | |||
void add_extension(boost::function<boost::shared_ptr <torrent_plugin>( | void add_extension(boost::function<boost::shared_ptr <torrent_plugin>( | |||
torrent*, void*)> ext); | torrent*, void*)> ext); | |||
void add_ses_extension(boost::shared_ptr<plugin> ext ); | void add_ses_extension(boost::shared_ptr<plugin> ext ); | |||
#endif | #endif | |||
#ifdef TORRENT_DEBUG | #if TORRENT_USE_ASSERTS | |||
bool has_peer(peer_connection const* p) const | bool has_peer(peer_connection const* p) const | |||
{ | { | |||
TORRENT_ASSERT(is_network_thread()); | TORRENT_ASSERT(is_network_thread()); | |||
return std::find_if(m_connections.begin(), m _connections.end() | return std::find_if(m_connections.begin(), m _connections.end() | |||
, boost::bind(&boost::intrusive_ptr< peer_connection>::get, _1) == p) | , boost::bind(&boost::intrusive_ptr< peer_connection>::get, _1) == p) | |||
!= m_connections.end(); | != m_connections.end(); | |||
} | } | |||
// this is set while the session is building the | ||||
// torrent status update message | ||||
bool m_posting_torrent_updates; | ||||
#endif | #endif | |||
void main_thread(); | void main_thread(); | |||
void open_listen_port(int flags, error_code& ec); | void open_listen_port(int flags, error_code& ec); | |||
// prioritize this torrent to be allocated some conn | ||||
ection | ||||
// attempts, because this torrent needs more peers. | ||||
// this is typically done when a torrent starts out | ||||
and | ||||
// need the initial push to connect peers | ||||
void prioritize_connections(boost::weak_ptr<torrent> | ||||
t); | ||||
// if we are listening on an IPv6 interface | // if we are listening on an IPv6 interface | |||
// this will return one of the IPv6 addresses on thi s | // this will return one of the IPv6 addresses on thi s | |||
// machine, otherwise just an empty endpoint | // machine, otherwise just an empty endpoint | |||
tcp::endpoint get_ipv6_interface() const; | tcp::endpoint get_ipv6_interface() const; | |||
tcp::endpoint get_ipv4_interface() const; | tcp::endpoint get_ipv4_interface() const; | |||
void async_accept(boost::shared_ptr<socket_acceptor> const& listener, bool ssl); | void async_accept(boost::shared_ptr<socket_acceptor> const& listener, bool ssl); | |||
void on_accept_connection(boost::shared_ptr<socket_t ype> const& s | void on_accept_connection(boost::shared_ptr<socket_t ype> const& s | |||
, boost::weak_ptr<socket_acceptor> listener, error_code const& e, bool ssl); | , boost::weak_ptr<socket_acceptor> listener, error_code const& e, bool ssl); | |||
void on_socks_accept(boost::shared_ptr<socket_type> const& s | void on_socks_accept(boost::shared_ptr<socket_type> const& s | |||
, error_code const& e); | , error_code const& e); | |||
void incoming_connection(boost::shared_ptr<socket_ty pe> const& s); | void incoming_connection(boost::shared_ptr<socket_ty pe> const& s); | |||
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS | #if TORRENT_USE_ASSERTS | |||
bool is_network_thread() const | bool is_network_thread() const | |||
{ | { | |||
#if defined BOOST_HAS_PTHREADS | #if defined BOOST_HAS_PTHREADS | |||
if (m_network_thread == 0) return true; | if (m_network_thread == 0) return true; | |||
return m_network_thread == pthread_self(); | return m_network_thread == pthread_self(); | |||
#endif | #endif | |||
return true; | return true; | |||
} | } | |||
bool is_not_network_thread() const | ||||
{ | ||||
#if defined BOOST_HAS_PTHREADS | ||||
if (m_network_thread == 0) return true; | ||||
return m_network_thread != pthread_self(); | ||||
#endif | ||||
return true; | ||||
} | ||||
#endif | #endif | |||
feed_handle add_feed(feed_settings const& feed); | feed_handle add_feed(feed_settings const& feed); | |||
void remove_feed(feed_handle h); | void remove_feed(feed_handle h); | |||
void get_feeds(std::vector<feed_handle>* f) const; | void get_feeds(std::vector<feed_handle>* f) const; | |||
boost::weak_ptr<torrent> find_torrent(sha1_hash cons | boost::weak_ptr<torrent> find_torrent(sha1_hash cons | |||
t& info_hash); | t& info_hash) const; | |||
boost::weak_ptr<torrent> find_torrent(std::string co | boost::weak_ptr<torrent> find_torrent(std::string co | |||
nst& uuid); | nst& uuid) const; | |||
boost::weak_ptr<torrent> find_disconnect_candidate_t | ||||
orrent() const; | ||||
peer_id const& get_peer_id() const { return m_peer_i d; } | peer_id const& get_peer_id() const { return m_peer_i d; } | |||
void close_connection(peer_connection const* p, erro r_code const& ec); | void close_connection(peer_connection const* p, erro r_code const& ec); | |||
void set_settings(session_settings const& s); | void set_settings(session_settings const& s); | |||
session_settings const& settings() const { return m_ settings; } | session_settings const& settings() const { return m_ settings; } | |||
#ifndef TORRENT_DISABLE_DHT | #ifndef TORRENT_DISABLE_DHT | |||
void add_dht_node_name(std::pair<std::string, int> c onst& node); | void add_dht_node_name(std::pair<std::string, int> c onst& node); | |||
void add_dht_node(udp::endpoint n); | void add_dht_node(udp::endpoint n); | |||
void add_dht_router(std::pair<std::string, int> cons t& node); | void add_dht_router(std::pair<std::string, int> cons t& node); | |||
void set_dht_settings(dht_settings const& s); | void set_dht_settings(dht_settings const& s); | |||
dht_settings const& get_dht_settings() const { retur n m_dht_settings; } | dht_settings const& get_dht_settings() const { retur n m_dht_settings; } | |||
void start_dht(); | void start_dht(); | |||
void stop_dht(); | void stop_dht(); | |||
void start_dht(entry const& startup_state); | void start_dht(entry const& startup_state); | |||
// this is called for torrents when they are started | ||||
// it will prioritize them for announcing to | ||||
// the DHT, to get the initial peers quickly | ||||
void prioritize_dht(boost::weak_ptr<torrent> t); | ||||
void get_immutable_callback(sha1_hash target | ||||
, dht::item const& i); | ||||
void get_mutable_callback(dht::item const& i); | ||||
void dht_get_immutable_item(sha1_hash const& target) | ||||
; | ||||
void dht_get_mutable_item(boost::array<char, 32> key | ||||
, std::string salt = std::string()); | ||||
void dht_put_item(entry data, sha1_hash target); | ||||
void dht_put_mutable_item(boost::array<char, 32> key | ||||
, boost::function<void(entry&, boost::array< | ||||
char,64>& | ||||
, boost::uint64_t&, std::string cons | ||||
t&)> cb | ||||
, std::string salt = std::string()); | ||||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
entry dht_state() const; | entry dht_state() const; | |||
#endif | #endif | |||
void on_dht_announce(error_code const& e); | void on_dht_announce(error_code const& e); | |||
void on_dht_router_name_lookup(error_code const& e | void on_dht_router_name_lookup(error_code const& e | |||
, tcp::resolver::iterator host); | , tcp::resolver::iterator host); | |||
#endif | #endif | |||
void maybe_update_udp_mapping(int nat, int local_por t, int external_port); | void maybe_update_udp_mapping(int nat, int local_por t, int external_port); | |||
skipping to change at line 329 | skipping to change at line 376 | |||
void set_port_filter(port_filter const& f); | void set_port_filter(port_filter const& f); | |||
void listen_on( | void listen_on( | |||
std::pair<int, int> const& port_range | std::pair<int, int> const& port_range | |||
, error_code& ec | , error_code& ec | |||
, const char* net_interface = 0 | , const char* net_interface = 0 | |||
, int flags = 0); | , int flags = 0); | |||
bool is_listening() const; | bool is_listening() const; | |||
torrent_handle add_torrent(add_torrent_params const& , error_code& ec); | torrent_handle add_torrent(add_torrent_params const& , error_code& ec); | |||
torrent_handle add_torrent_impl(add_torrent_params c onst&, error_code& ec); | ||||
void async_add_torrent(add_torrent_params* params); | void async_add_torrent(add_torrent_params* params); | |||
void remove_torrent(torrent_handle const& h, int opt ions); | void remove_torrent(torrent_handle const& h, int opt ions); | |||
void remove_torrent_impl(boost::shared_ptr<torrent> tptr, int options); | void remove_torrent_impl(boost::shared_ptr<torrent> tptr, int options); | |||
void get_torrent_status(std::vector<torrent_status>* ret | void get_torrent_status(std::vector<torrent_status>* ret | |||
, boost::function<bool(torrent_status const& )> const& pred | , boost::function<bool(torrent_status const& )> const& pred | |||
, boost::uint32_t flags) const; | , boost::uint32_t flags) const; | |||
void refresh_torrent_status(std::vector<torrent_stat us>* ret | void refresh_torrent_status(std::vector<torrent_stat us>* ret | |||
, boost::uint32_t flags) const; | , boost::uint32_t flags) const; | |||
skipping to change at line 416 | skipping to change at line 464 | |||
proxy_settings const& web_seed_proxy() const { retur n proxy(); } | proxy_settings const& web_seed_proxy() const { retur n proxy(); } | |||
proxy_settings const& tracker_proxy() const { return proxy(); } | proxy_settings const& tracker_proxy() const { return proxy(); } | |||
#ifndef TORRENT_DISABLE_DHT | #ifndef TORRENT_DISABLE_DHT | |||
void set_dht_proxy(proxy_settings const& s) { set_pr oxy(s); } | void set_dht_proxy(proxy_settings const& s) { set_pr oxy(s); } | |||
proxy_settings const& dht_proxy() const { return pro xy(); } | proxy_settings const& dht_proxy() const { return pro xy(); } | |||
#endif | #endif | |||
#endif // TORRENT_NO_DEPRECATE | #endif // TORRENT_NO_DEPRECATE | |||
#ifndef TORRENT_DISABLE_DHT | #ifndef TORRENT_DISABLE_DHT | |||
bool is_dht_running() const { return m_dht.get(); } | bool is_dht_running() const { return (m_dht.get() != NULL); } | |||
#endif | #endif | |||
#if TORRENT_USE_I2P | #if TORRENT_USE_I2P | |||
void set_i2p_proxy(proxy_settings const& s); | void set_i2p_proxy(proxy_settings const& s); | |||
void on_i2p_open(error_code const& ec); | void on_i2p_open(error_code const& ec); | |||
proxy_settings const& i2p_proxy() const | proxy_settings const& i2p_proxy() const | |||
{ return m_i2p_conn.proxy(); } | { return m_i2p_conn.proxy(); } | |||
void open_new_incoming_i2p_connection(); | void open_new_incoming_i2p_connection(); | |||
void on_i2p_accept(boost::shared_ptr<socket_type> co nst& s | void on_i2p_accept(boost::shared_ptr<socket_type> co nst& s | |||
, error_code const& e); | , error_code const& e); | |||
skipping to change at line 456 | skipping to change at line 504 | |||
#endif // TORRENT_DISABLE_GEO_IP | #endif // TORRENT_DISABLE_GEO_IP | |||
void start_lsd(); | void start_lsd(); | |||
natpmp* start_natpmp(); | natpmp* start_natpmp(); | |||
upnp* start_upnp(); | upnp* start_upnp(); | |||
void stop_lsd(); | void stop_lsd(); | |||
void stop_natpmp(); | void stop_natpmp(); | |||
void stop_upnp(); | void stop_upnp(); | |||
int add_port_mapping(int t, int external_port | ||||
, int local_port); | ||||
void delete_port_mapping(int handle); | ||||
int next_port(); | int next_port(); | |||
void add_redundant_bytes(size_type b, int reason) | void add_redundant_bytes(size_type b, int reason) | |||
{ | { | |||
TORRENT_ASSERT(b > 0); | TORRENT_ASSERT(b > 0); | |||
m_total_redundant_bytes += b; | m_total_redundant_bytes += b; | |||
m_redundant_bytes[reason] += b; | m_redundant_bytes[reason] += b; | |||
} | } | |||
void add_failed_bytes(size_type b) | void add_failed_bytes(size_type b) | |||
skipping to change at line 485 | skipping to change at line 537 | |||
void free_disk_buffer(char* buf); | void free_disk_buffer(char* buf); | |||
enum | enum | |||
{ | { | |||
source_dht = 1, | source_dht = 1, | |||
source_peer = 2, | source_peer = 2, | |||
source_tracker = 4, | source_tracker = 4, | |||
source_router = 8 | source_router = 8 | |||
}; | }; | |||
// implements dht_observer | ||||
virtual void set_external_address(address const& ip | ||||
, address const& source); | ||||
void set_external_address(address const& ip | void set_external_address(address const& ip | |||
, int source_type, address const& source); | , int source_type, address const& source); | |||
address const& external_address() const { return m_e | ||||
xternal_address; } | external_ip const& external_address() const; | |||
bool can_write_to_disk() const | bool can_write_to_disk() const | |||
{ return m_disk_thread.can_write(); } | { return m_disk_thread.can_write(); } | |||
// used when posting synchronous function | // used when posting synchronous function | |||
// calls to session_impl and torrent objects | // calls to session_impl and torrent objects | |||
mutable libtorrent::mutex mut; | mutable libtorrent::mutex mut; | |||
mutable libtorrent::condition cond; | mutable libtorrent::condition_variable cond; | |||
void inc_disk_queue(int channel) | void inc_disk_queue(int channel) | |||
{ | { | |||
TORRENT_ASSERT(channel >= 0 && channel < 2); | TORRENT_ASSERT(channel >= 0 && channel < 2); | |||
++m_disk_queues[channel]; | ++m_disk_queues[channel]; | |||
} | } | |||
void dec_disk_queue(int channel) | void dec_disk_queue(int channel) | |||
{ | { | |||
TORRENT_ASSERT(channel >= 0 && channel < 2); | TORRENT_ASSERT(channel >= 0 && channel < 2); | |||
TORRENT_ASSERT(m_disk_queues[channel] > 0); | TORRENT_ASSERT(m_disk_queues[channel] > 0); | |||
--m_disk_queues[channel]; | --m_disk_queues[channel]; | |||
} | } | |||
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS | void inc_active_downloading() { ++m_num_active_downl | |||
oading; } | ||||
void dec_active_downloading() | ||||
{ | ||||
TORRENT_ASSERT(m_num_active_downloading > 0) | ||||
; | ||||
--m_num_active_downloading; | ||||
} | ||||
void inc_active_finished() { ++m_num_active_finished | ||||
; } | ||||
void dec_active_finished() | ||||
{ | ||||
TORRENT_ASSERT(m_num_active_finished > 0); | ||||
--m_num_active_finished; | ||||
} | ||||
#if TORRENT_USE_ASSERTS | ||||
bool in_state_updates(boost::shared_ptr<torrent> t) | bool in_state_updates(boost::shared_ptr<torrent> t) | |||
{ | { | |||
return std::find_if(m_state_updates.begin(), m_state_updates.end() | return std::find_if(m_state_updates.begin(), m_state_updates.end() | |||
, boost::bind(&boost::weak_ptr<torre nt>::lock, _1) == t) != m_state_updates.end(); | , boost::bind(&boost::weak_ptr<torre nt>::lock, _1) == t) != m_state_updates.end(); | |||
} | } | |||
#endif | #endif | |||
void add_to_update_queue(boost::weak_ptr<torrent> t) | void add_to_update_queue(boost::weak_ptr<torrent> t) | |||
{ | { | |||
TORRENT_ASSERT(std::find_if(m_state_updates. begin(), m_state_updates.end() | TORRENT_ASSERT(std::find_if(m_state_updates. begin(), m_state_updates.end() | |||
, boost::bind(&boost::weak_ptr<torre nt>::lock, _1) == t.lock()) == m_state_updates.end()); | , boost::bind(&boost::weak_ptr<torre nt>::lock, _1) == t.lock()) == m_state_updates.end()); | |||
m_state_updates.push_back(t); | m_state_updates.push_back(t); | |||
} | } | |||
// private: | // private: | |||
void trigger_auto_manage(); | // implements alert_dispatcher | |||
virtual bool post_alert(alert* a); | ||||
void update_connections_limit(); | void update_connections_limit(); | |||
void update_unchoke_limit(); | void update_unchoke_limit(); | |||
void trigger_auto_manage(); | ||||
void on_trigger_auto_manage(); | ||||
void update_rate_settings(); | void update_rate_settings(); | |||
void update_disk_thread_settings(); | void update_disk_thread_settings(); | |||
void on_lsd_peer(tcp::endpoint peer, sha1_hash const & ih); | void on_lsd_peer(tcp::endpoint peer, sha1_hash const & ih); | |||
void setup_socket_buffers(socket_type& s); | void setup_socket_buffers(socket_type& s); | |||
// the settings for the client | // the settings for the client | |||
session_settings m_settings; | session_settings m_settings; | |||
// this is a shared pool where policy_peer objects | // this is a shared pool where policy_peer objects | |||
skipping to change at line 675 | skipping to change at line 748 | |||
// the number of peer connections that are waiting | // the number of peer connections that are waiting | |||
// for the disk. one for each channel. | // for the disk. one for each channel. | |||
// upload_channel means waiting to read from disk | // upload_channel means waiting to read from disk | |||
// and download_channel is waiting to write to disk | // and download_channel is waiting to write to disk | |||
int m_disk_queues[2]; | int m_disk_queues[2]; | |||
tracker_manager m_tracker_manager; | tracker_manager m_tracker_manager; | |||
torrent_map m_torrents; | torrent_map m_torrents; | |||
std::map<std::string, boost::shared_ptr<torrent> > m _uuids; | std::map<std::string, boost::shared_ptr<torrent> > m _uuids; | |||
// counters of how many of the active (non-paused) t | ||||
orrents | ||||
// are finished and downloading. This is used to wei | ||||
gh the | ||||
// priority of downloading and finished torrents whe | ||||
n connecting | ||||
// more peers. | ||||
int m_num_active_downloading; | ||||
int m_num_active_finished; | ||||
typedef std::list<boost::shared_ptr<torrent> > check _queue_t; | typedef std::list<boost::shared_ptr<torrent> > check _queue_t; | |||
// this has all torrents that wants to be checked in it | // this has all torrents that wants to be checked in it | |||
check_queue_t m_queued_for_checking; | check_queue_t m_queued_for_checking; | |||
// this maps sockets to their peer_connection | // this maps sockets to their peer_connection | |||
// object. It is the complete list of all connected | // object. It is the complete list of all connected | |||
// peers. | // peers. | |||
connection_map m_connections; | connection_map m_connections; | |||
// this list holds incoming connections while they | ||||
// are performing SSL handshake. When we shut down | ||||
// the session, all of these are disconnected, other | ||||
wise | ||||
// they would linger and stall or hang session shutd | ||||
own | ||||
std::set<boost::shared_ptr<socket_type> > m_incoming | ||||
_sockets; | ||||
// peer connections are put here when disconnected t | ||||
o avoid | ||||
// race conditions with the disk thread. It's import | ||||
ant that | ||||
// peer connections are destructed from the network | ||||
thread, | ||||
// once a peer is disconnected, it's put in this lis | ||||
t and | ||||
// every second their refcount is checked, and if it | ||||
's 1, | ||||
// they are deleted (from the network thread) | ||||
std::vector<boost::intrusive_ptr<peer_connection> > | ||||
m_undead_peers; | ||||
// filters incoming connections | // filters incoming connections | |||
ip_filter m_ip_filter; | ip_filter m_ip_filter; | |||
// filters outgoing connections | // filters outgoing connections | |||
port_filter m_port_filter; | port_filter m_port_filter; | |||
// the peer id that is generated at the start of the session | // the peer id that is generated at the start of the session | |||
peer_id m_peer_id; | peer_id m_peer_id; | |||
// the key is an id that is used to identify the | // the key is an id that is used to identify the | |||
skipping to change at line 721 | skipping to change at line 815 | |||
// if we're listening on an IPv6 interface | // if we're listening on an IPv6 interface | |||
// this is one of the non local IPv6 interfaces | // this is one of the non local IPv6 interfaces | |||
// on this machine | // on this machine | |||
tcp::endpoint m_ipv6_interface; | tcp::endpoint m_ipv6_interface; | |||
tcp::endpoint m_ipv4_interface; | tcp::endpoint m_ipv4_interface; | |||
// since we might be listening on multiple interface s | // since we might be listening on multiple interface s | |||
// we might need more than one listen socket | // we might need more than one listen socket | |||
std::list<listen_socket_t> m_listen_sockets; | std::list<listen_socket_t> m_listen_sockets; | |||
#if TORRENT_USE_I2P | ||||
i2p_connection m_i2p_conn; | ||||
boost::shared_ptr<socket_type> m_i2p_listen_socket; | ||||
#endif | ||||
#ifdef TORRENT_USE_OPENSSL | #ifdef TORRENT_USE_OPENSSL | |||
void ssl_handshake(error_code const& ec, boost::shar ed_ptr<socket_type> s); | void ssl_handshake(error_code const& ec, boost::shar ed_ptr<socket_type> s); | |||
#endif | #endif | |||
// when as a socks proxy is used for peers, also | // when as a socks proxy is used for peers, also | |||
// listen for incoming connections on a socks connec tion | // listen for incoming connections on a socks connec tion | |||
boost::shared_ptr<socket_type> m_socks_listen_socket ; | boost::shared_ptr<socket_type> m_socks_listen_socket ; | |||
boost::uint16_t m_socks_listen_port; | boost::uint16_t m_socks_listen_port; | |||
void open_new_incoming_socks_connection(); | void open_new_incoming_socks_connection(); | |||
#if TORRENT_USE_I2P | ||||
i2p_connection m_i2p_conn; | ||||
boost::shared_ptr<socket_type> m_i2p_listen_socket; | ||||
#endif | ||||
void setup_listener(listen_socket_t* s, tcp::endpoin t ep, int& retries | void setup_listener(listen_socket_t* s, tcp::endpoin t ep, int& retries | |||
, bool v6_only, int flags, error_code& ec); | , bool v6_only, int flags, error_code& ec); | |||
// the proxy used for bittorrent | // the proxy used for bittorrent | |||
proxy_settings m_proxy; | proxy_settings m_proxy; | |||
#ifndef TORRENT_DISABLE_DHT | #ifndef TORRENT_DISABLE_DHT | |||
entry m_dht_state; | entry m_dht_state; | |||
#endif | #endif | |||
// set to true when the session object | ||||
// is being destructed and the thread | ||||
// should exit | ||||
bool m_abort; | ||||
// is true if the session is paused | ||||
bool m_paused; | ||||
// the number of unchoked peers as set by the auto-u nchoker | // the number of unchoked peers as set by the auto-u nchoker | |||
// this should always be >= m_max_uploads | // this should always be >= m_max_uploads | |||
int m_allowed_upload_slots; | int m_allowed_upload_slots; | |||
// the number of unchoked peers | // the number of unchoked peers | |||
int m_num_unchoked; | int m_num_unchoked; | |||
// this is initialized to the unchoke_interval | // this is initialized to the unchoke_interval | |||
// session_setting and decreased every second. | // session_setting and decreased every second. | |||
skipping to change at line 804 | skipping to change at line 891 | |||
// the next time the read cache is rotated, if we're | // the next time the read cache is rotated, if we're | |||
// using an explicit read read cache. | // using an explicit read read cache. | |||
int m_cache_rotation_timer; | int m_cache_rotation_timer; | |||
// statistics gathered from all torrents. | // statistics gathered from all torrents. | |||
stat m_stat; | stat m_stat; | |||
int m_peak_up_rate; | int m_peak_up_rate; | |||
int m_peak_down_rate; | int m_peak_down_rate; | |||
// is false by default and set to true when | ||||
// the first incoming connection is established | ||||
// this is used to know if the client is behind | ||||
// NAT or not. | ||||
bool m_incoming_connection; | ||||
void on_disk_queue(); | void on_disk_queue(); | |||
void on_tick(error_code const& e); | void on_tick(error_code const& e); | |||
void try_connect_more_peers(int num_downloads, int n um_downloads_peers); | ||||
void auto_manage_torrents(std::vector<torrent*>& lis t | void auto_manage_torrents(std::vector<torrent*>& lis t | |||
, int& dht_limit, int& tracker_limit, int& l sd_limit | , int& dht_limit, int& tracker_limit, int& l sd_limit | |||
, int& hard_limit, int type_limit); | , int& hard_limit, int type_limit); | |||
void recalculate_auto_managed_torrents(); | void recalculate_auto_managed_torrents(); | |||
void recalculate_unchoke_slots(int congested_torrent s | void recalculate_unchoke_slots(int congested_torrent s | |||
, int uncongested_torrents); | , int uncongested_torrents); | |||
void recalculate_optimistic_unchoke_slots(); | void recalculate_optimistic_unchoke_slots(); | |||
ptime m_created; | ptime m_created; | |||
int session_time() const { return total_seconds(time _now() - m_created); } | boost::int64_t session_time() const { return total_s econds(time_now() - m_created); } | |||
ptime m_last_tick; | ptime m_last_tick; | |||
ptime m_last_second_tick; | ptime m_last_second_tick; | |||
// used to limit how often disk warnings are generat ed | // used to limit how often disk warnings are generat ed | |||
ptime m_last_disk_performance_warning; | ptime m_last_disk_performance_warning; | |||
ptime m_last_disk_queue_performance_warning; | ptime m_last_disk_queue_performance_warning; | |||
// the last time we went through the peers | // the last time we went through the peers | |||
// to decide which ones to choke/unchoke | // to decide which ones to choke/unchoke | |||
ptime m_last_choke; | ptime m_last_choke; | |||
skipping to change at line 856 | skipping to change at line 938 | |||
boost::intrusive_ptr<dht::dht_tracker> m_dht; | boost::intrusive_ptr<dht::dht_tracker> m_dht; | |||
dht_settings m_dht_settings; | dht_settings m_dht_settings; | |||
// these are used when starting the DHT | // these are used when starting the DHT | |||
// (and bootstrapping it), and then erased | // (and bootstrapping it), and then erased | |||
std::list<udp::endpoint> m_dht_router_nodes; | std::list<udp::endpoint> m_dht_router_nodes; | |||
// this announce timer is used | // this announce timer is used | |||
// by the DHT. | // by the DHT. | |||
deadline_timer m_dht_announce_timer; | deadline_timer m_dht_announce_timer; | |||
#endif | ||||
void on_receive_udp(error_code const& e | // the number of torrents there were when the | |||
, udp::endpoint const& ep, char const* buf, | // update_dht_announce_interval() was last called. | |||
int len); | // if the number of torrents changes significantly | |||
// compared to this number, the DHT announce interva | ||||
l | ||||
// is updated again. This especially matters for | ||||
// small numbers. | ||||
int m_dht_interval_update_torrents; | ||||
#endif | ||||
void on_receive_udp_hostname(error_code const& e | bool incoming_packet(error_code const& ec | |||
, char const* hostname, char const* buf, int | , udp::endpoint const&, char const* buf, int | |||
len); | size); | |||
// see m_external_listen_port. This is the same | // see m_external_listen_port. This is the same | |||
// but for the udp port used by the DHT. | // but for the udp port used by the DHT. | |||
int m_external_udp_port; | int m_external_udp_port; | |||
rate_limited_udp_socket m_udp_socket; | rate_limited_udp_socket m_udp_socket; | |||
utp_socket_manager m_utp_socket_manager; | utp_socket_manager m_utp_socket_manager; | |||
// the number of torrent connection boosts | // the number of torrent connection boosts | |||
skipping to change at line 912 | skipping to change at line 999 | |||
// within the LSD announce interval (which defaults to | // within the LSD announce interval (which defaults to | |||
// 5 minutes) | // 5 minutes) | |||
torrent_map::iterator m_next_lsd_torrent; | torrent_map::iterator m_next_lsd_torrent; | |||
#ifndef TORRENT_DISABLE_DHT | #ifndef TORRENT_DISABLE_DHT | |||
// torrents are announced on the DHT in a | // torrents are announced on the DHT in a | |||
// round-robin fashion. All torrents are cycled thro ugh | // round-robin fashion. All torrents are cycled thro ugh | |||
// within the DHT announce interval (which defaults to | // within the DHT announce interval (which defaults to | |||
// 15 minutes) | // 15 minutes) | |||
torrent_map::iterator m_next_dht_torrent; | torrent_map::iterator m_next_dht_torrent; | |||
// torrents that don't have any peers | ||||
// when added should be announced to the DHT | ||||
// as soon as possible. Such torrents are put | ||||
// in this queue and get announced the next time | ||||
// the timer fires, instead of the next one in | ||||
// the round-robin sequence. | ||||
std::deque<boost::weak_ptr<torrent> > m_dht_torrents | ||||
; | ||||
#endif | #endif | |||
// torrents prioritized to get connection attempts | ||||
std::deque<std::pair<boost::weak_ptr<torrent>, int> | ||||
> m_prio_torrents; | ||||
// this announce timer is used | // this announce timer is used | |||
// by Local service discovery | // by Local service discovery | |||
deadline_timer m_lsd_announce_timer; | deadline_timer m_lsd_announce_timer; | |||
tcp::resolver m_host_resolver; | tcp::resolver m_host_resolver; | |||
// the index of the torrent that will be offered to | // the index of the torrent that will be offered to | |||
// connect to a peer next time on_tick is called. | // connect to a peer next time on_tick is called. | |||
// This implements a round robin. | // This implements a round robin. | |||
torrent_map::iterator m_next_connect_torrent; | torrent_map::iterator m_next_connect_torrent; | |||
// this is the number of attempts of connecting to | ||||
// peers we have given to the torrent pointed to | ||||
// by m_next_connect_torrent. Once this reaches | ||||
// the number of connection attempts this particular | ||||
// torrent should have, the counter is reset and | ||||
// m_next_connect_torrent takes a step forward | ||||
// to give the next torrent its connection attempts. | ||||
int m_current_connect_attempts; | ||||
// this is the round-robin cursor for peers that | // this is the round-robin cursor for peers that | |||
// get to download again after the disk has been | // get to download again after the disk has been | |||
// blocked | // blocked | |||
connection_map::iterator m_next_disk_peer; | connection_map::iterator m_next_disk_peer; | |||
#ifdef TORRENT_DEBUG | #if TORRENT_USE_INVARIANT_CHECKS | |||
void check_invariant() const; | void check_invariant() const; | |||
#endif | #endif | |||
#ifdef TORRENT_DISK_STATS | #ifdef TORRENT_DISK_STATS | |||
void log_buffer_usage(); | void log_buffer_usage(); | |||
// used to log send buffer usage statistics | // used to log send buffer usage statistics | |||
std::ofstream m_buffer_usage_logger; | std::ofstream m_buffer_usage_logger; | |||
// the number of send buffers that are allocated | // the number of send buffers that are allocated | |||
int m_buffer_allocations; | int m_buffer_allocations; | |||
#endif | #endif | |||
skipping to change at line 1061 | skipping to change at line 1168 | |||
boost::uint16_t m_tick_residual; | boost::uint16_t m_tick_residual; | |||
// the number of torrents that have apply_ip_filter | // the number of torrents that have apply_ip_filter | |||
// set to false. This is typically 0 | // set to false. This is typically 0 | |||
int m_non_filtered_torrents; | int m_non_filtered_torrents; | |||
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T ORRENT_ERROR_LOGGING | #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T ORRENT_ERROR_LOGGING | |||
boost::shared_ptr<logger> create_log(std::string con st& name | boost::shared_ptr<logger> create_log(std::string con st& name | |||
, int instance, bool append = true); | , int instance, bool append = true); | |||
void session_log(char const* fmt, ...) const; | ||||
// this list of tracker loggers serves as tracker_ca llbacks when | // this list of tracker loggers serves as tracker_ca llbacks when | |||
// shutting down. This list is just here to keep the m alive during | // shutting down. This list is just here to keep the m alive during | |||
// whe shutting down process | // whe shutting down process | |||
std::list<boost::shared_ptr<tracker_logger> > m_trac ker_loggers; | std::list<boost::shared_ptr<tracker_logger> > m_trac ker_loggers; | |||
std::string get_log_path() const | ||||
{ return m_logpath; } | ||||
std::string m_logpath; | std::string m_logpath; | |||
private: | private: | |||
#endif | #endif | |||
#ifdef TORRENT_UPNP_LOGGING | #ifdef TORRENT_UPNP_LOGGING | |||
std::ofstream m_upnp_log; | std::ofstream m_upnp_log; | |||
#endif | #endif | |||
struct external_ip_t | ||||
{ | ||||
external_ip_t(): sources(0), num_votes(0) {} | ||||
bool add_vote(sha1_hash const& k, int type); | ||||
bool operator<(external_ip_t const& rhs) con | ||||
st | ||||
{ | ||||
if (num_votes < rhs.num_votes) retur | ||||
n true; | ||||
if (num_votes > rhs.num_votes) retur | ||||
n false; | ||||
return sources < rhs.sources; | ||||
} | ||||
// this is a bloom filter of the IPs that ha | ||||
ve | ||||
// reported this address | ||||
bloom_filter<16> voters; | ||||
// this is the actual external address | ||||
address addr; | ||||
// a bitmask of sources the reporters have c | ||||
ome from | ||||
boost::uint16_t sources; | ||||
// the total number of votes for this IP | ||||
boost::uint16_t num_votes; | ||||
}; | ||||
// this is a bloom filter of all the IPs that have | // state for keeping track of external IPs | |||
// been the first to report an external address. Eac | external_ip m_external_ip; | |||
h | ||||
// IP only gets to add a new item once. | ||||
bloom_filter<32> m_external_address_voters; | ||||
std::vector<external_ip_t> m_external_addresses; | ||||
address m_external_address; | ||||
#ifndef TORRENT_DISABLE_EXTENSIONS | #ifndef TORRENT_DISABLE_EXTENSIONS | |||
typedef std::list<boost::function<boost::shared_ptr< | ||||
torrent_plugin>(torrent*, void*)> > extensio | ||||
n_list_t; | ||||
extension_list_t m_extensions; | ||||
typedef std::list<boost::shared_ptr<plugin> > ses_ex tension_list_t; | typedef std::list<boost::shared_ptr<plugin> > ses_ex tension_list_t; | |||
ses_extension_list_t m_ses_extensions; | ses_extension_list_t m_ses_extensions; | |||
#endif | #endif | |||
#ifndef TORRENT_DISABLE_GEO_IP | #ifndef TORRENT_DISABLE_GEO_IP | |||
GeoIP* m_asnum_db; | GeoIP* m_asnum_db; | |||
GeoIP* m_country_db; | GeoIP* m_country_db; | |||
// maps AS number to the peak download rate | // maps AS number to the peak download rate | |||
// we've seen from it. Entries are never removed | // we've seen from it. Entries are never removed | |||
// from this map. Pointers to its elements | // from this map. Pointers to its elements | |||
// are kept in the policy::peer structures. | // are kept in the policy::peer structures. | |||
std::map<int, int> m_as_peak; | std::map<int, int> m_as_peak; | |||
#endif | #endif | |||
// total redundant and failed bytes | // total redundant and failed bytes | |||
size_type m_total_failed_bytes; | size_type m_total_failed_bytes; | |||
size_type m_total_redundant_bytes; | size_type m_total_redundant_bytes; | |||
// this is set to true when a torrent auto-manage | ||||
// event is triggered, and reset whenever the messag | ||||
e | ||||
// is delivered and the auto-manage is executed. | ||||
// there should never be more than a single pending | ||||
auto-manage | ||||
// message in-flight at any given time. | ||||
bool m_pending_auto_manage; | ||||
// this is also set to true when triggering an auto- | ||||
manage | ||||
// of the torrents. However, if the normal auto-mana | ||||
ge | ||||
// timer comes along and executes the auto-managemen | ||||
t, | ||||
// this is set to false, which means the triggered e | ||||
vent | ||||
// no longer needs to execute the auto-management. | ||||
bool m_need_auto_manage; | ||||
// set to true when the session object | ||||
// is being destructed and the thread | ||||
// should exit | ||||
bool m_abort; | ||||
// is true if the session is paused | ||||
bool m_paused; | ||||
// is false by default and set to true when | ||||
// the first incoming connection is established | ||||
// this is used to know if the client is behind | ||||
// NAT or not. | ||||
bool m_incoming_connection; | ||||
// redundant bytes per category | // redundant bytes per category | |||
size_type m_redundant_bytes[7]; | size_type m_redundant_bytes[7]; | |||
std::vector<boost::shared_ptr<feed> > m_feeds; | std::vector<boost::shared_ptr<feed> > m_feeds; | |||
// this is the set of (subscribed) torrents that hav e changed | // this is the set of (subscribed) torrents that hav e changed | |||
// their states since the last time the user request ed updates. | // their states since the last time the user request ed updates. | |||
std::vector<boost::weak_ptr<torrent> > m_state_updat es; | std::vector<boost::weak_ptr<torrent> > m_state_updat es; | |||
// the main working thread | // the main working thread | |||
boost::scoped_ptr<thread> m_thread; | boost::scoped_ptr<thread> m_thread; | |||
#if (defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS) && defined BOOST_HAS _PTHREADS | #if TORRENT_USE_ASSERTS && defined BOOST_HAS_PTHREADS | |||
pthread_t m_network_thread; | pthread_t m_network_thread; | |||
#endif | #endif | |||
}; | }; | |||
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T ORRENT_ERROR_LOGGING | #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T ORRENT_ERROR_LOGGING | |||
struct tracker_logger : request_callback | struct tracker_logger : request_callback | |||
{ | { | |||
tracker_logger(session_impl& ses): m_ses(ses) {} | tracker_logger(session_impl& ses); | |||
void tracker_warning(tracker_request const& req | void tracker_warning(tracker_request const& req | |||
, std::string const& str) | , std::string const& str); | |||
{ | ||||
debug_log("*** tracker warning: %s", str.c_s | ||||
tr()); | ||||
} | ||||
void tracker_response(tracker_request const& | void tracker_response(tracker_request const& | |||
, libtorrent::address const& tracker_ip | , libtorrent::address const& tracker_ip | |||
, std::list<address> const& ip_list | , std::list<address> const& ip_list | |||
, std::vector<peer_entry>& peers | , std::vector<peer_entry>& peers | |||
, int interval | , int interval | |||
, int min_interval | , int min_interval | |||
, int complete | , int complete | |||
, int incomplete | , int incomplete | |||
, int downloaded | ||||
, address const& external_ip | , address const& external_ip | |||
, std::string const& tracker_id) | , std::string const& tracker_id); | |||
{ | ||||
std::string s; | ||||
s = "TRACKER RESPONSE:\n"; | ||||
char tmp[200]; | ||||
snprintf(tmp, 200, "interval: %d\nmin_interv | ||||
al: %d\npeers:\n", interval, min_interval); | ||||
s += tmp; | ||||
for (std::vector<peer_entry>::const_iterator | ||||
i = peers.begin(); | ||||
i != peers.end(); ++i) | ||||
{ | ||||
char pid[41]; | ||||
to_hex((const char*)&i->pid[0], 20, | ||||
pid); | ||||
if (i->pid.is_all_zeros()) pid[0] = | ||||
0; | ||||
snprintf(tmp, 200, " %-16s %-5d %s\n | ||||
", i->ip.c_str(), i->port, pid); | ||||
s += tmp; | ||||
} | ||||
snprintf(tmp, 200, "external ip: %s\n", prin | ||||
t_address(external_ip).c_str()); | ||||
s += tmp; | ||||
debug_log("%s", s.c_str()); | ||||
} | ||||
void tracker_request_timed_out( | void tracker_request_timed_out( | |||
tracker_request const&) | tracker_request const&); | |||
{ | ||||
debug_log("*** tracker timed out"); | ||||
} | ||||
void tracker_request_error(tracker_request const& r | void tracker_request_error(tracker_request const& r | |||
, int response_code, error_code const& ec, c onst std::string& str | , int response_code, error_code const& ec, c onst std::string& str | |||
, int retry_interval) | , int retry_interval); | |||
{ | void debug_log(const char* fmt, ...) const; | |||
debug_log("*** tracker error: %d: %s %s" | ||||
, response_code, ec.message().c_str( | ||||
), str.c_str()); | ||||
} | ||||
void debug_log(const char* fmt, ...) const | ||||
{ | ||||
if (!m_ses.m_logger) return; | ||||
va_list v; | ||||
va_start(v, fmt); | ||||
char usr[1024]; | ||||
vsnprintf(usr, sizeof(usr), fmt, v); | ||||
va_end(v); | ||||
char buf[1280]; | ||||
snprintf(buf, sizeof(buf), "%s: %s\n", time_ | ||||
now_string(), usr); | ||||
(*m_ses.m_logger) << buf; | ||||
} | ||||
session_impl& m_ses; | session_impl& m_ses; | |||
}; | }; | |||
#endif | #endif | |||
} | } | |||
} | } | |||
#endif | #endif | |||
End of changes. 51 change blocks. | ||||
153 lines changed or deleted | 228 lines changed or added | |||
session_settings.hpp | session_settings.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2003, Arvid Norberg | Copyright (c) 2003-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 40 | skipping to change at line 40 | |||
*/ | */ | |||
#ifndef TORRENT_SESSION_SETTINGS_HPP_INCLUDED | #ifndef TORRENT_SESSION_SETTINGS_HPP_INCLUDED | |||
#define TORRENT_SESSION_SETTINGS_HPP_INCLUDED | #define TORRENT_SESSION_SETTINGS_HPP_INCLUDED | |||
#include "libtorrent/version.hpp" | #include "libtorrent/version.hpp" | |||
#include "libtorrent/config.hpp" | #include "libtorrent/config.hpp" | |||
#include "libtorrent/version.hpp" | #include "libtorrent/version.hpp" | |||
#include <boost/cstdint.hpp> | ||||
#include <string> | #include <string> | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
// The ``proxy_settings`` structs contains the information needed to | ||||
// direct certain traffic to a proxy. | ||||
struct TORRENT_EXPORT proxy_settings | struct TORRENT_EXPORT proxy_settings | |||
{ | { | |||
proxy_settings() : port(0), type(none) | // defaults constructs proxy settings, initializing it to th | |||
, proxy_hostnames(true) | e default | |||
// settings. | ||||
proxy_settings() : type(none) | ||||
, port(0), proxy_hostnames(true) | ||||
, proxy_peer_connections(true) | , proxy_peer_connections(true) | |||
{} | {} | |||
// the name or IP of the proxy server. ``port`` is the port | ||||
number the | ||||
// proxy listens to. If required, ``username`` and ``passwor | ||||
d`` can be | ||||
// set to authenticate with the proxy. | ||||
std::string hostname; | std::string hostname; | |||
int port; | ||||
// when using a proy type that requires authentication, the | ||||
username | ||||
// and password fields must be set to the credentials for th | ||||
e proxy. | ||||
std::string username; | std::string username; | |||
std::string password; | std::string password; | |||
// the type of proxy to use. Assign one of these to the | ||||
// proxy_settings::type field. | ||||
enum proxy_type | enum proxy_type | |||
{ | { | |||
// a plain tcp socket is used, and | // This is the default, no proxy server is used, all | |||
// the other settings are ignored. | other fields are | |||
// ignored. | ||||
none, | none, | |||
// socks4 server, requires username. | ||||
// The server is assumed to be a `SOCKS4 server`_ th | ||||
at requires a | ||||
// username. | ||||
// | ||||
// .. _`SOCKS4 server`: http://www.ufasoft.com/doc/s | ||||
ocks4_protocol.htm | ||||
socks4, | socks4, | |||
// the hostname and port settings are | ||||
// used to connect to the proxy. No | // The server is assumed to be a SOCKS5 server (`RFC | |||
// username or password is sent. | 1928`_) that does | |||
// not require any authentication. The username and | ||||
password are | ||||
// ignored. | ||||
// | ||||
// .. _`RFC 1928`: http://www.faqs.org/rfcs/rfc1928. | ||||
html | ||||
socks5, | socks5, | |||
// the hostname and port are used to | ||||
// connect to the proxy. the username | // The server is assumed to be a SOCKS5 server that | |||
// and password are used to authenticate | supports plain | |||
// with the proxy server. | // text username and password authentication (`RFC 1 | |||
929`_). The | ||||
// username and password specified may be sent to th | ||||
e proxy if it | ||||
// requires. | ||||
// | ||||
// .. _`RFC 1929`: http://www.faqs.org/rfcs/rfc1929. | ||||
html | ||||
socks5_pw, | socks5_pw, | |||
// the http proxy is only available for | ||||
// tracker and web seed traffic | // The server is assumed to be an HTTP proxy. If the | |||
// assumes anonymous access to proxy | transport used | |||
// for the connection is non-HTTP, the server is ass | ||||
umed to support | ||||
// the CONNECT_ method. i.e. for web seeds and HTTP | ||||
trackers, a plain | ||||
// proxy will suffice. The proxy is assumed to not r | ||||
equire | ||||
// authorization. The username and password will not | ||||
be used. | ||||
// | ||||
// .. _CONNECT: http://tools.ietf.org/html/draft-luo | ||||
tonen-web-proxy-tunneling-01 | ||||
http, | http, | |||
// http proxy with basic authentication | ||||
// uses username and password | // The server is assumed to be an HTTP proxy that re | |||
quires user | ||||
// authorization. The username and password will be | ||||
sent to the proxy. | ||||
http_pw, | http_pw, | |||
// route through a i2p SAM proxy | // route through a i2p SAM proxy | |||
i2p_proxy | i2p_proxy | |||
}; | }; | |||
proxy_type type; | // tells libtorrent what kind of proxy server it is. See pro | |||
xy_type | ||||
// when set to true, hostname are resolved | // enum for options | |||
// through the proxy (if supported) | boost::uint8_t type; | |||
// the port the proxy server is running on | ||||
boost::uint16_t port; | ||||
// defaults to true. It means that hostnames should be attem | ||||
pted to be | ||||
// resolved through the proxy instead of using the local DNS | ||||
service. | ||||
// This is only supported by SOCKS5 and HTTP. | ||||
bool proxy_hostnames; | bool proxy_hostnames; | |||
// if true, use this proxy for peers too | // determines whether or not to excempt peer and web seed co | |||
nnections | ||||
// from using the proxy. This defaults to true, i.e. peer co | ||||
nnections are | ||||
// proxied by default. | ||||
bool proxy_peer_connections; | bool proxy_peer_connections; | |||
}; | }; | |||
// This holds most of the session-wide settings in libtorrent. Pass | ||||
this | ||||
// to session::set_settings() to change the settings, initialize it | ||||
from | ||||
// session::get_settings() to get the current settings. | ||||
struct TORRENT_EXPORT session_settings | struct TORRENT_EXPORT session_settings | |||
{ | { | |||
session_settings(std::string const& user_agent_ = "libtorren | // initializes the session_settings to the default settings. | |||
t/" | session_settings(std::string const& user_agent = "libtorrent | |||
/" | ||||
LIBTORRENT_VERSION); | LIBTORRENT_VERSION); | |||
~session_settings(); | ~session_settings(); | |||
// libtorrent version. Used for forward binary compatibility | // automatically set to the libtorrent version you're using | |||
in order to | ||||
// be forward binary compatible. This field should not be ch | ||||
anged. | ||||
int version; | int version; | |||
// this is the user agent that will be sent to the tracker | // the client identification to the tracker. The recommended | |||
// when doing requests. It is used to identify the client. | format of | |||
// It cannot contain \r or \n | // this string is: "ClientName/ClientVersion | |||
// libtorrent/libtorrentVersion". This name will not only be | ||||
used when | ||||
// making HTTP requests, but also when sending extended head | ||||
ers to peers | ||||
// that support that extension. | ||||
std::string user_agent; | std::string user_agent; | |||
// the number of seconds to wait until giving up on a | // the number of seconds the tracker connection will wait fr | |||
// tracker request if it hasn't finished | om when it | |||
// sent the request until it considers the tracker to have t | ||||
imed-out. | ||||
// Default value is 60 seconds. | ||||
int tracker_completion_timeout; | int tracker_completion_timeout; | |||
// the number of seconds where no data is received | // the number of seconds to wait to receive any data from th | |||
// from the tracker until it should be considered | e tracker. If | |||
// as timed out | // no data is received for this number of seconds, the track | |||
er will be | ||||
// considered as having timed out. If a tracker is down, thi | ||||
s is the kind | ||||
// of timeout that will occur. The default value is 20 secon | ||||
ds. | ||||
int tracker_receive_timeout; | int tracker_receive_timeout; | |||
// the time to wait when sending a stopped message | // the time to wait when sending a stopped message before co | |||
// before considering a tracker to have timed out. | nsidering a | |||
// this is usually shorter, to make the client quit | // tracker to have timed out. this is usually shorter, to ma | |||
// faster | ke the client | |||
// quit faster | ||||
// | ||||
// This is given in seconds. Default is 10 seconds. | ||||
int stop_tracker_timeout; | int stop_tracker_timeout; | |||
// if the content-length is greater than this value | // the maximum number of bytes in a tracker response. If a r | |||
// the tracker connection will be aborted | esponse size | |||
// passes this number it will be rejected and the connection | ||||
will be | ||||
// closed. On gzipped responses this size is measured on the | ||||
uncompressed | ||||
// data. So, if you get 20 bytes of gzip response that'll ex | ||||
pand to 2 | ||||
// megs, it will be interrupted before the entire response h | ||||
as been | ||||
// uncompressed (given your limit is lower than 2 megs). Def | ||||
ault limit is | ||||
// 1 megabyte. | ||||
int tracker_maximum_response_length; | int tracker_maximum_response_length; | |||
// the number of seconds from a request is sent until | // controls the number of seconds from a request is sent unt | |||
// it times out if no piece response is returned. | il it times | |||
// out if no piece response is returned. | ||||
int piece_timeout; | int piece_timeout; | |||
// the number of seconds one block (16kB) is expected | // the number of seconds one block (16kB) is expected to be | |||
// to be received within. If it's not, the block is | received | |||
// requested from a different peer | // within. If it's not, the block is requested from a differ | |||
ent peer | ||||
int request_timeout; | int request_timeout; | |||
// the length of the request queue given in the number | // the length of the request queue given in the number of se | |||
// of seconds it should take for the other end to send | conds it | |||
// all the pieces. i.e. the actual number of requests | // should take for the other end to send all the pieces. i.e | |||
// depends on the download rate and this number. | . the actual | |||
// number of requests depends on the download rate and this | ||||
number. | ||||
int request_queue_time; | int request_queue_time; | |||
// the number of outstanding block requests a peer is | // the number of outstanding block requests a peer is allowe | |||
// allowed to queue up in the client. If a peer sends | d to queue up | |||
// more requests than this (before the first one has | // in the client. If a peer sends more requests than this (b | |||
// been sent) the last request will be dropped. | efore the | |||
// the higher this is, the faster upload speeds the | // first one has been sent) the last request will be dropped | |||
// client can get to a single peer. | . the higher | |||
// this is, the faster upload speeds the client can get to a | ||||
single peer. | ||||
int max_allowed_in_request_queue; | int max_allowed_in_request_queue; | |||
// the maximum number of outstanding requests to | // the maximum number of outstanding requests to send to a p | |||
// send to a peer. This limit takes precedence over | eer. This | |||
// request_queue_time. | // limit takes precedence over request_queue_time. i.e. no m | |||
atter the | ||||
// download speed, the number of outstanding requests will n | ||||
ever exceed | ||||
// this limit. | ||||
int max_out_request_queue; | int max_out_request_queue; | |||
// if a whole piece can be downloaded in this number | // if a whole piece can be downloaded in this number of seco | |||
// of seconds, or less, the peer_connection will prefer | nds, or less, | |||
// to request whole pieces at a time from this peer. | // the peer_connection will prefer to request whole pieces a | |||
// The benefit of this is to better utilize disk caches by | t a time from | |||
// doing localized accesses and also to make it easier | // this peer. The benefit of this is to better utilize disk | |||
// to identify bad peers if a piece fails the hash check. | caches by | |||
// doing localized accesses and also to make it easier to id | ||||
entify bad | ||||
// peers if a piece fails the hash check. | ||||
int whole_pieces_threshold; | int whole_pieces_threshold; | |||
// the number of seconds to wait for any activity on | // the number of seconds to wait for any activity on the pee | |||
// the peer wire before closing the connectiong due | r wire before | |||
// to time out. | // closing the connectiong due to time out. This defaults to | |||
120 seconds, | ||||
// since that's what's specified in the protocol specificati | ||||
on. After | ||||
// half the time out, a keep alive message is sent. | ||||
int peer_timeout; | int peer_timeout; | |||
// same as peer_timeout, but only applies to url-seeds. | // same as peer_timeout, but only applies to url-seeds. this | |||
// this is usually set lower, because web servers are | is usually | |||
// expected to be more reliable. | // set lower, because web servers are expected to be more re | |||
liable. This | ||||
// value defaults to 20 seconds. | ||||
int urlseed_timeout; | int urlseed_timeout; | |||
// controls the pipelining size of url-seeds | // controls the pipelining with the web server. When using p | |||
ersistent | ||||
// connections to HTTP 1.1 servers, the client is allowed to | ||||
send more | ||||
// requests before the first response is received. This numb | ||||
er controls | ||||
// the number of outstanding requests to use with url-seeds. | ||||
Default is | ||||
// 5. | ||||
int urlseed_pipeline_size; | int urlseed_pipeline_size; | |||
// time to wait until a new retry takes place | // time to wait until a new retry takes place | |||
int urlseed_wait_retry; | int urlseed_wait_retry; | |||
// sets the upper limit on the total number of files this | // sets the upper limit on the total number of files this se | |||
// session will keep open. The reason why files are | ssion will | |||
// left open at all is that some anti virus software | // keep open. The reason why files are left open at all is t | |||
// hooks on every file close, and scans the file for | hat some anti | |||
// viruses. deferring the closing of the files will | // virus software hooks on every file close, and scans the f | |||
// be the difference between a usable system and | ile for | |||
// a completely hogged down system. Most operating | // viruses. deferring the closing of the files will be the d | |||
// systems also has a limit on the total number of | ifference | |||
// file descriptors a process may have open. It is | // between a usable system and a completely hogged down syst | |||
// usually a good idea to find this limit and set the | em. Most | |||
// number of connections and the number of files | // operating systems also has a limit on the total number of | |||
file | ||||
// descriptors a process may have open. It is usually a good | ||||
idea to find | ||||
// this limit and set the number of connections and the numb | ||||
er of files | ||||
// limits so their sum is slightly below it. | // limits so their sum is slightly below it. | |||
int file_pool_size; | int file_pool_size; | |||
// false to not allow multiple connections from the same | // determines if connections from the same IP address as exi | |||
// IP address. true will allow it. | sting | |||
// connections should be rejected or not. Multiple connectio | ||||
ns from the | ||||
// same IP address is not allowed by default, to prevent abu | ||||
sive behavior | ||||
// by peers. It may be useful to allow such connections in c | ||||
ases where | ||||
// simulations are run on the same machie, and all peers in | ||||
a swarm has | ||||
// the same IP address. | ||||
bool allow_multiple_connections_per_ip; | bool allow_multiple_connections_per_ip; | |||
// the number of times we can fail to connect to a peer | // the maximum times we try to connect to a peer before stop | |||
// before we stop retrying it. | connecting | |||
// again. If a peer succeeds, its failcounter is reset. If a | ||||
peer is | ||||
// retrieved from a peer source (other than DHT) the failcou | ||||
nt is | ||||
// decremented by one, allowing another try. | ||||
int max_failcount; | int max_failcount; | |||
// the number of seconds to wait to reconnect to a peer. | // the number of seconds to wait to reconnect to a peer. thi | |||
// this time is multiplied with the failcount. | s time is | |||
// multiplied with the failcount. | ||||
int min_reconnect_time; | int min_reconnect_time; | |||
// this is the timeout for a connection attempt. If | // the number of seconds to wait after a connection attempt | |||
// the connect does not succeed within this time, the | is initiated | |||
// connection is dropped. The time is specified in seconds. | // to a peer until it is considered as having timed out. The | |||
default is | ||||
// 10 seconds. This setting is especially important in case | ||||
the number of | ||||
// half-open connections are limited, since stale half-open | ||||
connection | ||||
// may delay the connection of other peers considerably. | ||||
int peer_connect_timeout; | int peer_connect_timeout; | |||
// if set to true, upload, download and unchoke limits | // if set to true, upload, download and unchoke limits are i | |||
// are ignored for peers on the local network. | gnored for | |||
// peers on the local network. | ||||
bool ignore_limits_on_local_network; | bool ignore_limits_on_local_network; | |||
// the number of connection attempts that | // the number of connection attempts that are made per secon | |||
// are made per second. | d. If a | |||
// number < 0 is specified, it will default to 200 connectio | ||||
ns per | ||||
// second. If 0 is specified, it means don't make outgoing c | ||||
onnections at | ||||
// all. | ||||
int connection_speed; | int connection_speed; | |||
// if this is set to true, have messages will be sent | // if this is set to true, have messages will be sent to pee | |||
// to peers that already have the piece. This is | rs that | |||
// typically not necessary, but it might be necessary | // already have the piece. This is typically not necessary, | |||
// for collecting statistics in some cases. Default is false | but it might | |||
. | // be necessary for collecting statistics in some cases. Def | |||
ault is | ||||
// false. | ||||
bool send_redundant_have; | bool send_redundant_have; | |||
// if this is true, outgoing bitfields will never be fuil. I | // prevents outgoing bitfields from being full. If the clien | |||
f the | t is seed, a | |||
// client is seed, a few bits will be set to 0, and later fi | // few bits will be set to 0, and later filled in with have- | |||
lled | messages. | |||
// in with have messages. This is to prevent certain ISPs | // This is an old attempt to prevent certain ISPs from stopp | |||
// from stopping people from seeding. | ing people | |||
// from seeding. | ||||
bool lazy_bitfields; | bool lazy_bitfields; | |||
// if a peer is uninteresting and uninterested for longer | // if a peer is uninteresting and uninterested for longer th | |||
// than this number of seconds, it will be disconnected. | an this | |||
// default is 10 minutes | // number of seconds, it will be disconnected. default is 10 | |||
minutes | ||||
int inactivity_timeout; | int inactivity_timeout; | |||
// the number of seconds between chokes/unchokes | // the number of seconds between chokes/unchokes. On this in | |||
terval, peers | ||||
// are re-evaluated for being choked/unchoked. This is defin | ||||
ed as 30 | ||||
// seconds in the protocol, and it should be significantly l | ||||
onger than | ||||
// what it takes for TCP to ramp up to it's max rate. | ||||
int unchoke_interval; | int unchoke_interval; | |||
// the number of seconds between | // the number of seconds between each *optimistic* unchoke. | |||
// optimistic unchokes | On this | |||
// timer, the currently optimistically unchoked peer will ch | ||||
ange. | ||||
int optimistic_unchoke_interval; | int optimistic_unchoke_interval; | |||
// if this is set, this IP will be reported do the | // the ip address passed along to trackers as the ``&ip=`` p | |||
// tracker in the ip= parameter. | arameter. If | |||
// left as the default (an empty string), that parameter is | ||||
omitted. Most | ||||
// trackers ignore this argument. This is here for completen | ||||
ess for | ||||
// edge-cases where it may be useful. | ||||
std::string announce_ip; | std::string announce_ip; | |||
// the num want sent to trackers | // the number of peers we want from each tracker request. It | |||
defines what | ||||
// is sent as the ``&num_want=`` parameter to the tracker. S | ||||
topped | ||||
// messages always send num_want=0. This setting control wha | ||||
t to say in | ||||
// the case where we actually want peers. | ||||
int num_want; | int num_want; | |||
// while we have fewer pieces than this, pick | // specifies the number of pieces we need before we switch t | |||
// random pieces instead of rarest first. | o rarest | |||
// first picking. This defaults to 4, which means the 4 firs | ||||
t pieces in | ||||
// any torrent are picked at random, the following pieces ar | ||||
e picked in | ||||
// rarest first order. | ||||
int initial_picker_threshold; | int initial_picker_threshold; | |||
// the number of allowed pieces to send to peers | // the number of allowed pieces to send to choked peers that | |||
// that supports the fast extensions | supports the | |||
// fast extensions | ||||
int allowed_fast_set_size; | int allowed_fast_set_size; | |||
// this determines which pieces will be suggested to peers | // options for session_settings::suggest_mode. | |||
// suggest read cache will make libtorrent suggest pieces | enum suggest_mode_t | |||
// that are fresh in the disk read cache, to potentially | { | |||
// lower disk access and increase the cache hit ratio | // the default. will not send out suggest messages. | |||
enum suggest_mode_t { no_piece_suggestions = 0, suggest_read | no_piece_suggestions = 0, | |||
_cache = 1 }; | ||||
// send out suggest messages for the most recent pie | ||||
ces that are in | ||||
// the read cache. | ||||
suggest_read_cache = 1 | ||||
}; | ||||
// this determines which pieces will be suggested to peers s | ||||
uggest read | ||||
// cache will make libtorrent suggest pieces that are fresh | ||||
in the disk | ||||
// read cache, to potentially lower disk access and increase | ||||
the cache | ||||
// hit ratio | ||||
// | ||||
// for options, see suggest_mode_t. | ||||
int suggest_mode; | int suggest_mode; | |||
// the maximum number of bytes a connection may have | // the maximum number of bytes a connection may have pending | |||
// pending in the disk write queue before its download | in the disk | |||
// rate is being throttled. This prevents fast downloads | // write queue before its download rate is being throttled. | |||
// to slow medias to allocate more and more memory | This prevents | |||
// indefinitely. This should be set to at least 16 kB | // fast downloads to slow medias to allocate more memory ind | |||
// to not completely disrupt normal downloads. If it's | efinitely. | |||
// set to 0, you will be starving the disk thread and | // This should be set to at least 16 kB to not completely di | |||
// nothing will be written to disk. | srupt normal | |||
// this is a per session setting. | // downloads. If it's set to 0, you will be starving the dis | |||
k thread and | ||||
// nothing will be written to disk. this is a per session se | ||||
tting. | ||||
// | ||||
// When this limit is reached, the peer connections will sto | ||||
p reading | ||||
// data from their sockets, until the disk thread catches up | ||||
. Setting | ||||
// this too low will severly limit your download rate. | ||||
int max_queued_disk_bytes; | int max_queued_disk_bytes; | |||
// this is the low watermark for the disk buffer queue. | // this is the low watermark for the disk buffer queue. when | |||
// whenever the number of queued bytes exceed the | ever the | |||
// max_queued_disk_bytes, libtorrent will wait for | // number of queued bytes exceed the max_queued_disk_bytes, | |||
// it to drop below this value before issuing more | libtorrent | |||
// reads from the sockets. If set to 0, the | // will wait for it to drop below this value before issuing | |||
// low watermark will be half of the max queued disk bytes | more reads | |||
// from the sockets. If set to 0, the low watermark will be | ||||
half of the | ||||
// max queued disk bytes | ||||
int max_queued_disk_bytes_low_watermark; | int max_queued_disk_bytes_low_watermark; | |||
// the number of seconds to wait for a handshake | // the number of seconds to wait for a handshake response fr | |||
// response from a peer. If no response is received | om a peer. If | |||
// within this time, the peer is disconnected. | // no response is received within this time, the peer is dis | |||
connected. | ||||
int handshake_timeout; | int handshake_timeout; | |||
#ifndef TORRENT_DISABLE_DHT | // determines how the DHT is used. If this is true, the DHT | |||
// while this is true, the dht will not be used unless the | will only be | |||
// tracker is online | // used for torrents where all trackers in its tracker list | |||
has failed. | ||||
// Either by an explicit error message or a time out. This i | ||||
s false by | ||||
// default, which means the DHT is used by default regardles | ||||
s of if the | ||||
// trackers fail or not. | ||||
bool use_dht_as_fallback; | bool use_dht_as_fallback; | |||
#endif | ||||
// if this is true, the piece hashes will be freed, in order | // determines whether or not the torrent's piece hashes are | |||
// to save memory, once the torrent is seeding. This will | kept in | |||
// make the get_torrent_info() function to return an incompl | // memory after the torrent becomes a seed or not. If it is | |||
ete | set to | |||
// torrent object that cannot be passed back to add_torrent( | // ``true`` the hashes are freed once the torrent is a seed | |||
) | (they're not | |||
// needed anymore since the torrent won't download anything | ||||
more). If | ||||
// it's set to false they are not freed. If they are freed, | ||||
the | ||||
// torrent_info returned by get_torrent_info() will return a | ||||
n object that | ||||
// may be incomplete, that cannot be passed back to async_ad | ||||
d_torrent() | ||||
// and add_torrent() for instance. | ||||
bool free_torrent_hashes; | bool free_torrent_hashes; | |||
// when this is true, the upnp port mapper will ignore | // indicates whether or not the UPnP implementation should i | |||
// any upnp devices that don't have an address that matches | gnore any | |||
// our currently configured router. | // broadcast response from a device whose address is not the | |||
configured | ||||
// router for this machine. i.e. it's a way to not talk to o | ||||
ther people's | ||||
// routers by mistake. | ||||
bool upnp_ignore_nonrouters; | bool upnp_ignore_nonrouters; | |||
// This is the minimum send buffer target size (send buffer | // This is the minimum send buffer target size (send buffer | |||
// includes bytes pending being read from disk). For good | includes | |||
// and snappy seeding performance, set this fairly high, to | // bytes pending being read from disk). For good and snappy | |||
// at least fit a few blocks. This is essentially the initia | seeding | |||
l | // performance, set this fairly high, to at least fit a few | |||
// window size which will determine how fast we can ramp up | blocks. This | |||
// the send rate | // is essentially the initial window size which will determi | |||
int send_buffer_low_watermark; | ne how fast | |||
// we can ramp up the send rate | ||||
// if the send buffer has fewer bytes than this, we'll | int send_buffer_low_watermark; | |||
// read another 16kB block onto it. If set too small, | ||||
// upload rate capacity will suffer. If set too high, | // the upper limit of the send buffer low-watermark. | |||
// memory will be wasted. | // | |||
// The actual watermark may be lower than this in case | // if the send buffer has fewer bytes than this, we'll read | |||
// the upload rate is low, this is the upper limit. | another 16kB | |||
int send_buffer_watermark; | // block onto it. If set too small, upload rate capacity wil | |||
l suffer. If | ||||
// the current upload rate to a peer is multiplied by | // set too high, memory will be wasted. The actual watermark | |||
// this factor to get the send buffer watermark. The | may be lower | |||
// factor is specified as a percentage. i.e. 50 -> 0.5 | // than this in case the upload rate is low, this is the upp | |||
// This product is clamped to the send_buffer_watermark | er limit. | |||
// setting to not exceed the max. For high speed | int send_buffer_watermark; | |||
// upload, this should be set to a greater value than | ||||
// 100. The default is 50. | // the current upload rate to a peer is multiplied by this f | |||
actor to get | ||||
// the send buffer watermark. The factor is specified as a p | ||||
ercentage. | ||||
// i.e. 50 indicates a factor of 0.5. | ||||
// | ||||
// This product is clamped to the send_buffer_watermark sett | ||||
ing to not | ||||
// exceed the max. For high speed upload, this should be set | ||||
to a greater | ||||
// value than 100. The default is 50. | ||||
// | ||||
// For high capacity connections, setting this higher can im | ||||
prove upload | ||||
// performance and disk throughput. Setting it too high may | ||||
waste RAM and | ||||
// create a bias towards read jobs over write jobs. | ||||
int send_buffer_watermark_factor; | int send_buffer_watermark_factor; | |||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
// deprecated in 0.16 | // deprecated in 0.16 defaults to true. When true, if there | |||
is a global | ||||
// upload limit set and the current upload rate is less than | ||||
90% of that, | ||||
// another upload slot is opened. If the upload rate has bee | ||||
n saturated | ||||
// for an extended period of time, on upload slot is closed. | ||||
The number | ||||
// of upload slots will never be less than what has been set | ||||
by | ||||
// ``session::set_max_uploads()``. To query the current numb | ||||
er of upload | ||||
// slots, see ``session_status::allowed_upload_slots``. | ||||
bool auto_upload_slots; | bool auto_upload_slots; | |||
// When set, and ``auto_upload_slots`` is set, the max uploa | ||||
d slots | ||||
// setting is used as a minimum number of unchoked slots. Th | ||||
is algorithm | ||||
// is designed to prevent the peer from spreading its upload | ||||
capacity too | ||||
// thin, but still open more slots in order to utilize the f | ||||
ull capacity. | ||||
bool auto_upload_slots_rate_based; | bool auto_upload_slots_rate_based; | |||
#endif | #endif | |||
// the different choking algorithms available. Set | ||||
// session_settings::choking_algorithm to one of these | ||||
enum choking_algorithm_t | enum choking_algorithm_t | |||
{ | { | |||
// the traditional choker with a fixed number of unc | ||||
hoke slots, as | ||||
// specified by session::set_max_uploads().. | ||||
fixed_slots_choker, | fixed_slots_choker, | |||
// opens at least the number of slots as specified b | ||||
y | ||||
// session::set_max_uploads() but opens up more slot | ||||
s if the upload | ||||
// capacity is not saturated. This unchoker will wor | ||||
k just like the | ||||
// ``fixed_slot_choker`` if there's no global upload | ||||
rate limit set. | ||||
auto_expand_choker, | auto_expand_choker, | |||
// opens up unchoke slots based on the upload rate a | ||||
chieved to peers. | ||||
// The more slots that are opened, the marginal uplo | ||||
ad rate required | ||||
// to open up another slot increases. | ||||
rate_based_choker, | rate_based_choker, | |||
// attempts to optimize download rate by finding the | ||||
reciprocation | ||||
// rate of each peer individually and prefers peers | ||||
that gives the | ||||
// highest *return on investment*. It still allocate | ||||
s all upload | ||||
// capacity, but shuffles it around to the best peer | ||||
s first. For this | ||||
// choker to be efficient, you need to set a global | ||||
upload rate limit | ||||
// session_settings::upload_rate_limit. For more inf | ||||
ormation about | ||||
// this choker, see the paper_. | ||||
// | ||||
// .. _paper: http://bittyrant.cs.washington.edu/#pa | ||||
pers | ||||
bittyrant_choker | bittyrant_choker | |||
}; | }; | |||
// specifies which algorithm to use to determine which peers | ||||
to unchoke. | ||||
// This setting replaces the deprecated settings ``auto_uplo | ||||
ad_slots`` | ||||
// and ``auto_upload_slots_rate_based``. For options, see | ||||
// choking_algorithm_t. | ||||
int choking_algorithm; | int choking_algorithm; | |||
// the different choking algorithms available when seeding. | ||||
Set | ||||
// session_settings::seed_choking_algorithm to one of these | ||||
enum seed_choking_algorithm_t | enum seed_choking_algorithm_t | |||
{ | { | |||
// round-robins the peers that are unchoked when see | ||||
ding. This | ||||
// distributes the upload bandwidht uniformly and fa | ||||
irly. It minimizes | ||||
// the ability for a peer to download everything wit | ||||
hout | ||||
// redistributing it. | ||||
round_robin, | round_robin, | |||
// unchokes the peers we can send to the fastest. Th | ||||
is might be a bit | ||||
// more reliable in utilizing all available capacity | ||||
. | ||||
fastest_upload, | fastest_upload, | |||
// prioritizes peers who have just started or are ju | ||||
st about to finish | ||||
// the download. The intention is to force peers in | ||||
the middle of the | ||||
// download to trade with each other. | ||||
anti_leech | anti_leech | |||
}; | }; | |||
// the choking algorithm to use for seeding torrents | // controls the seeding unchoke behavior. For options, see | |||
// seed_choking_algorithm_t. | ||||
int seed_choking_algorithm; | int seed_choking_algorithm; | |||
// if set to true, peers that participate in a failing | // specifies if parole mode should be used. Parole mode mean | |||
// piece is put in parole mode. i.e. They will only | s that peers | |||
// download whole pieces until they either fail or pass. | // that participate in pieces that fail the hash check are p | |||
// they are taken out of parole mode as soon as they | ut in a mode | |||
// participate in a piece that passes. | // where they are only allowed to download whole pieces. If | |||
the whole | ||||
// piece a peer in parole mode fails the hash check, it is b | ||||
anned. If a | ||||
// peer participates in a piece that passes the hash check, | ||||
it is taken | ||||
// out of parole mode. | ||||
bool use_parole_mode; | bool use_parole_mode; | |||
// the disk write cache, specified in 16 KiB blocks. | // the disk write and read cache. It is specified in units | |||
// default is 1024 (= 16 MiB). -1 means automatic, which | of 16 KiB | |||
// adjusts the cache size depending on the amount | // blocks. Buffers that are part of a peer's send or receive | |||
// of physical RAM in the machine. | buffer also | |||
// count against this limit. Send and receive buffers will n | ||||
ever be | ||||
// denied to be allocated, but they will cause the actual ca | ||||
ched blocks | ||||
// to be flushed or evicted. If this is set to -1, the cache | ||||
size is | ||||
// automatically set to the amount of physical RAM available | ||||
in the | ||||
// machine divided by 8. If the amount of physical RAM canno | ||||
t be | ||||
// determined, it's set to 1024 (= 16 MiB). | ||||
// | ||||
// Disk buffers are allocated using a pool allocator, the nu | ||||
mber of | ||||
// blocks that are allocated at a time when the pool needs t | ||||
o grow can be | ||||
// specified in ``cache_buffer_chunk_size``. This defaults t | ||||
o 16 blocks. | ||||
// Lower numbers saves memory at the expense of more heap al | ||||
locations. It | ||||
// must be at least 1. | ||||
int cache_size; | int cache_size; | |||
// this is the number of disk buffer blocks (16 kiB) | // this is the number of disk buffer blocks (16 kiB) that sh | |||
// that should be allocated at a time. It must be | ould be | |||
// at least 1. Lower number saves memory at the expense | // allocated at a time. It must be at least 1. Lower number | |||
// of more heap allocations | saves memory | |||
// at the expense of more heap allocations | ||||
int cache_buffer_chunk_size; | int cache_buffer_chunk_size; | |||
// the number of seconds a write cache entry sits | // the number of seconds a write cache entry sits idle in th | |||
// idle in the cache before it's forcefully flushed | e cache | |||
// to disk. Default is 5 minutes. | // before it's forcefully flushed to disk. | |||
int cache_expiry; | int cache_expiry; | |||
// when true, the disk I/O thread uses the disk | // when set to true (default), the disk cache is also used t | |||
// cache for caching blocks read from disk too | o cache | |||
// pieces read from disk. Blocks for writing pieces takes pr | ||||
esedence. | ||||
bool use_read_cache; | bool use_read_cache; | |||
// don't implicitly cache pieces in the read cache, | // defaults to 0. If set to something greater than 0, the di | |||
// only cache pieces that are explicitly asked to be | sk read cache | |||
// cached. | // will not be evicted by cache misses and will explicitly b | |||
e controlled | ||||
// based on the rarity of pieces. Rare pieces are more likel | ||||
y to be | ||||
// cached. This would typically be used together with ``sugg | ||||
est_mode`` | ||||
// set to ``suggest_read_cache``. The value is the number of | ||||
pieces to | ||||
// keep in the read cache. If the actual read cache can't fi | ||||
t as many, it | ||||
// will essentially be clamped. | ||||
bool explicit_read_cache; | bool explicit_read_cache; | |||
// the number of seconds between refreshes of | // the number of seconds in between each refresh of a part o | |||
// explicit caches | f the | |||
// explicit read cache. Torrents take turns in refreshing an | ||||
d this is the | ||||
// time in between each torrent refresh. Refreshing a torren | ||||
t's explicit | ||||
// read cache means scanning all pieces and picking a random | ||||
set of the | ||||
// rarest ones. There is an affinity to pick pieces that are | ||||
already in | ||||
// the cache, so that subsequent refreshes only swaps in pie | ||||
ces that are | ||||
// rarer than whatever is in the cache at the time. | ||||
int explicit_cache_interval; | int explicit_cache_interval; | |||
// the buffer modes to use for reading and writing. Set | ||||
// session_settings::disk_io_read_mode and disk_io_write_mod | ||||
e to one of | ||||
// these. | ||||
enum io_buffer_mode_t | enum io_buffer_mode_t | |||
{ | { | |||
// This is the default and files are opened normally | ||||
, with the OS | ||||
// caching reads and writes. | ||||
enable_os_cache = 0, | enable_os_cache = 0, | |||
// This will open files in unbuffered mode for files | ||||
where every read | ||||
// and write would be sector aligned. Using aligned | ||||
disk offsets is a | ||||
// requirement on some operating systems. | ||||
disable_os_cache_for_aligned_files = 1, | disable_os_cache_for_aligned_files = 1, | |||
// This opens all files in unbuffered mode (if allow | ||||
ed by the | ||||
// operating system). Linux and Windows, for instanc | ||||
e, require disk | ||||
// offsets to be sector aligned, and in those cases, | ||||
this option is | ||||
// the same as ``disable_os_caches_for_aligned_files | ||||
``. | ||||
disable_os_cache = 2 | disable_os_cache = 2 | |||
}; | }; | |||
// determines how files are opened when they're in read only | ||||
mode versus | ||||
// read and write mode. For options, see io_buffer_mode_t. | ||||
// | ||||
// One reason to disable caching is that it may help the ope | ||||
rating system | ||||
// from growing its file cache indefinitely. Since some OSes | ||||
only allow | ||||
// aligned files to be opened in unbuffered mode, It is reco | ||||
mmended to | ||||
// make the largest file in a torrent the first file (with o | ||||
ffset 0) or | ||||
// use pad files to align all files to piece boundries. | ||||
int disk_io_write_mode; | int disk_io_write_mode; | |||
int disk_io_read_mode; | int disk_io_read_mode; | |||
// when set to true, instead of issuing multiple adjacent re | ||||
ads or writes | ||||
// to the disk, allocate a larger buffer, copy all writes in | ||||
to it and | ||||
// issue a single write. For reads, read into a larger buffe | ||||
r and copy | ||||
// the buffer into the smaller individual read buffers after | ||||
wards. This | ||||
// may save system calls, but will cost in additional memory | ||||
allocation | ||||
// and copying. | ||||
bool coalesce_reads; | bool coalesce_reads; | |||
bool coalesce_writes; | bool coalesce_writes; | |||
// if != (0, 0), this is the range of ports that | // if set to something other than (0, 0) is a range of ports | |||
// outgoing connections will be bound to. This | used to bind | |||
// is useful for users that have routers that | // outgoing sockets to. This may be useful for users whose r | |||
// allow QoS settings based on local port. | outer allows | |||
// them to assign QoS classes to traffic based on its local | ||||
port. It is a | ||||
// range instead of a single port because of the problems wi | ||||
th failing to | ||||
// reconnect to peers if a previous socket to that peer and | ||||
port is in | ||||
// ``TIME_WAIT`` state. | ||||
// | ||||
//.. warning:: | ||||
// setting outgoing ports will limit the ability to kee | ||||
p multiple | ||||
// connections to the same client, even for different t | ||||
orrents. It is not | ||||
// recommended to change this setting. Its main purpose | ||||
is to use as an | ||||
// escape hatch for cheap routers with QoS capability b | ||||
ut can only | ||||
// classify flows based on port numbers. | ||||
std::pair<int, int> outgoing_ports; | std::pair<int, int> outgoing_ports; | |||
// the TOS byte of all peer traffic (including | // determines the TOS byte set in the IP header of every pac | |||
// web seeds) is set to this value. The default | ket sent to | |||
// is the QBSS scavenger service | // peers (including web seeds). The default value for this i | |||
// http://qbone.internet2.edu/qbss/ | s ``0x0`` (no | |||
// For unmarked packets, set to 0 | // marking). One potentially useful TOS mark is ``0x20``, th | |||
is represents | ||||
// the *QBone scavenger service*. For more details, see QBSS | ||||
_. | ||||
// | ||||
// .. _`QBSS`: http://qbone.internet2.edu/qbss/ | ||||
char peer_tos; | char peer_tos; | |||
// for auto managed torrents, these are the limits | // for auto managed torrents, these are the limits they are | |||
// they are subject to. If there are too many torrents | subject to. | |||
// some of the auto managed ones will be paused until | // If there are too many torrents some of the auto managed o | |||
// some slots free up. | nes will be | |||
// active_dht_limit and active_tracker_limit limits the | // paused until some slots free up. | |||
// number of torrents that will be active on the DHT | // | |||
// versus the tracker. If the active limit is set higher | // ``active_dht_limit`` and ``active_tracker_limit`` limits | |||
// than these numbers, some torrents will be "active" in | the number of | |||
// the sense that they will accept incoming connections, | // torrents that will be active on the DHT and their tracker | |||
// but not announce on the DHT or the tracker | . If the | |||
// active limit is set higher than these numbers, some torre | ||||
nts will be | ||||
// "active" in the sense that they will accept incoming conn | ||||
ections, but | ||||
// not announce on the DHT or their trackers. | ||||
// | ||||
// ``active_lsd_limit`` is the max number of torrents to ann | ||||
ounce to the | ||||
// local network over the local service discovery protocol. | ||||
By default | ||||
// this is 80, which is no more than one announce every 5 se | ||||
conds | ||||
// (assuming the default announce interval of 5 minutes). | ||||
// | ||||
// ``active_limit`` is a hard limit on the number of active | ||||
torrents. | ||||
// This applies even to slow torrents. | ||||
// | ||||
// You can have more torrents *active*, even though they are | ||||
not | ||||
// announced to the DHT, lsd or their tracker. If some peer | ||||
knows about | ||||
// you for any reason and tries to connect, it will still be | ||||
accepted, | ||||
// unless the torrent is paused, which means it won't accept | ||||
any | ||||
// connections. | ||||
// | ||||
// ``active_downloads`` and ``active_seeds`` controls how ma | ||||
ny active | ||||
// seeding and downloading torrents the queuing mechanism al | ||||
lows. The | ||||
// target number of active torrents is ``min(active_download | ||||
s + | ||||
// active_seeds, active_limit)``. ``active_downloads`` and | ||||
// ``active_seeds`` are upper limits on the number of downlo | ||||
ading | ||||
// torrents and seeding torrents respectively. Setting the v | ||||
alue to -1 | ||||
// means unlimited. | ||||
// | ||||
// For example if there are 10 seeding torrents and 10 downl | ||||
oading | ||||
// torrents, and ``active_downloads`` is 4 and ``active_seed | ||||
s`` is 4, | ||||
// there will be 4 seeds active and 4 downloading torrents. | ||||
If the | ||||
// settings are ``active_downloads`` = 2 and ``active_seeds` | ||||
` = 4, then | ||||
// there will be 2 downloading torrents and 4 seeding torren | ||||
ts active. | ||||
// Torrents that are not auto managed are also counted again | ||||
st these | ||||
// limits. If there are non-auto managed torrents that use u | ||||
p all the | ||||
// slots, no auto managed torrent will be activated. | ||||
int active_downloads; | int active_downloads; | |||
int active_seeds; | int active_seeds; | |||
int active_dht_limit; | int active_dht_limit; | |||
int active_tracker_limit; | int active_tracker_limit; | |||
int active_lsd_limit; | int active_lsd_limit; | |||
int active_limit; | int active_limit; | |||
// prefer seeding torrents when determining which torrents t | // prefer seeding torrents when determining which torrents t | |||
o give | o give active | |||
// active slots to, the default is false which gives prefere | // slots to, the default is false which gives preference to | |||
nce to | downloading | |||
// downloading torrents | // torrents | |||
bool auto_manage_prefer_seeds; | bool auto_manage_prefer_seeds; | |||
// if this is true, torrents that don't have any significant | // if true, torrents without any payload transfers are not s | |||
// transfers are not counted as active when determining whic | ubject to the | |||
h | // ``active_seeds`` and ``active_downloads`` limits. This is | |||
// auto managed torrents to pause and resume | intended to | |||
// make it more likely to utilize all available bandwidth, a | ||||
nd avoid | ||||
// having torrents that don't transfer anything block the ac | ||||
tive slots. | ||||
bool dont_count_slow_torrents; | bool dont_count_slow_torrents; | |||
// the number of seconds in between recalculating which | // the number of seconds in between recalculating which torr | |||
// torrents to activate and which ones to queue | ents to | |||
// activate and which ones to queue | ||||
int auto_manage_interval; | int auto_manage_interval; | |||
// when a seeding torrent reaches eaither the share ratio | // when a seeding torrent reaches either the share ratio (by | |||
// (bytes up / bytes down) or the seed time ratio | tes up / | |||
// (seconds as seed / seconds as downloader) or the seed | // bytes down) or the seed time ratio (seconds as seed / sec | |||
// time limit (seconds as seed) it is considered | onds as | |||
// done, and it will leave room for other torrents | // downloader) or the seed time limit (seconds as seed) it i | |||
// the default value for share ratio is 2 | s considered | |||
// the default seed time ratio is 7, because that's a common | // done, and it will leave room for other torrents the defau | |||
// asymmetry ratio on connections | lt value for | |||
// share ratio is 2 the default seed time ratio is 7, becaus | ||||
e that's a | ||||
// common asymmetry ratio on connections | ||||
// | ||||
//.. note:: | ||||
// This is an out-dated option that doesn't make much s | ||||
ense. It will be | ||||
// removed in future versions of libtorrent | ||||
float share_ratio_limit; | float share_ratio_limit; | |||
// the seeding time / downloading time ratio limit for consi | ||||
dering a | ||||
// seeding torrent to have met the seed limit criteria. See | ||||
queuing_. | ||||
float seed_time_ratio_limit; | float seed_time_ratio_limit; | |||
// the limit on the time a torrent has been an active seed ( | ||||
specified in | ||||
// seconds) before it is considered having met the seed limi | ||||
t criteria. | ||||
// See queuing_. | ||||
int seed_time_limit; | int seed_time_limit; | |||
// the interval (in seconds) between optimistic disconnects | // controls a feature where libtorrent periodically can disc | |||
// if the disconnects happen and how many peers are disconne | onnect the | |||
cted | // least useful peers in the hope of connecting to better on | |||
// is controlled by peer_turnover and peer_turnover_cutoff | es. | |||
// ``peer_turnover_interval`` controls the interval of this | ||||
optimistic | ||||
// disconnect. It defaults to every 5 minutes, and is specif | ||||
ied in | ||||
// seconds. | ||||
// | ||||
// ``peer_turnover`` Is the fraction of the peers that are d | ||||
isconnected. | ||||
// This is a float where 1.f represents all peers an 0 repre | ||||
sents no | ||||
// peers. It defaults to 4% (i.e. 0.04f) | ||||
// | ||||
// ``peer_turnover_cutoff`` is the cut off trigger for optim | ||||
istic | ||||
// unchokes. If a torrent has more than this fraction of its | ||||
connection | ||||
// limit, the optimistic unchoke is triggered. This defaults | ||||
to 90% (i.e. | ||||
// 0.9f). | ||||
int peer_turnover_interval; | int peer_turnover_interval; | |||
// the percentage of peers to disconnect every | ||||
// turnoever interval (if we're at the peer limit) | ||||
// defaults to 2/50:th | ||||
float peer_turnover; | float peer_turnover; | |||
// when we are connected to more than | ||||
// limit * peer_turnover_cutoff peers | ||||
// disconnect peer_turnover fraction | ||||
// of the peers | ||||
float peer_turnover_cutoff; | float peer_turnover_cutoff; | |||
// if this is true (default) connections where both | // specifies whether libtorrent should close connections whe | |||
// ends have no utility in keeping the connection open | re both ends | |||
// are closed. for instance if both ends have completed | // have no utility in keeping the connection open. For insta | |||
// their downloads | nce if both | |||
// ends have completed their downloads, there's no point in | ||||
keeping it | ||||
// open. This defaults to ``true``. | ||||
bool close_redundant_connections; | bool close_redundant_connections; | |||
// the number of seconds between scrapes of | // the number of seconds between scrapes of queued torrents | |||
// queued torrents (auto managed and paused) | (auto managed | |||
// and paused torrents). Auto managed torrents that are paus | ||||
ed, are | ||||
// scraped regularly in order to keep track of their downloa | ||||
der/seed | ||||
// ratio. This ratio is used to determine which torrents to | ||||
seed and | ||||
// which to pause. | ||||
int auto_scrape_interval; | int auto_scrape_interval; | |||
// the minimum number of seconds between any | // the minimum number of seconds between any automatic scrap | |||
// automatic scrape (regardless of torrent) | e (regardless | |||
// of torrent). In case there are a large number of paused a | ||||
uto managed | ||||
// torrents, this puts a limit on how often a scrape request | ||||
is sent. | ||||
int auto_scrape_min_interval; | int auto_scrape_min_interval; | |||
// the max number of peers in the peer list | // the maximum number of peers in the list of known peers. T | |||
// per torrent. This is the peers we know | hese peers | |||
// about, not necessarily connected to. | // are not necessarily connected, so this number should be m | |||
uch greater | ||||
// than the maximum number of connected peers. Peers are evi | ||||
cted from the | ||||
// cache when the list grows passed 90% of this limit, and o | ||||
nce the size | ||||
// hits the limit, peers are no longer added to the list. If | ||||
this limit | ||||
// is set to 0, there is no limit on how many peers we'll ke | ||||
ep in the | ||||
// peer list. | ||||
int max_peerlist_size; | int max_peerlist_size; | |||
// when a torrent is paused, this is the max peer | // the max peer list size used for torrents that are paused. | |||
// list size that's used | This default | |||
// to the same as ``max_peerlist_size``, but can be used to | ||||
save memory | ||||
// for paused torrents, since it's not as important for them | ||||
to keep a | ||||
// large peer list. | ||||
int max_paused_peerlist_size; | int max_paused_peerlist_size; | |||
// any announce intervals reported from a tracker | // the minimum allowed announce interval for a tracker. This | |||
// that is lower than this, will be clamped to this | is specified | |||
// value. It's specified in seconds | // in seconds, defaults to 5 minutes and is used as a sanity | |||
check on | ||||
// what is returned from a tracker. It mitigates hammering m | ||||
isconfigured | ||||
// trackers. | ||||
int min_announce_interval; | int min_announce_interval; | |||
// if true, partial pieces are picked before pieces | // If true, partial pieces are picked before pieces that are | |||
// that are more rare | more rare. | |||
// If false, rare pieces are always prioritized, unless the | ||||
number of | ||||
// partial pieces is growing out of proportion. | ||||
bool prioritize_partial_pieces; | bool prioritize_partial_pieces; | |||
// the number of seconds a torrent is considered | // the number of seconds a torrent is considered active afte | |||
// active after it was started, regardless of | r it was | |||
// upload and download speed. This is so that | // started, regardless of upload and download speed. This is | |||
// newly started torrents are not considered | so that | |||
// inactive until they have a fair chance to | // newly started torrents are not considered inactive until | |||
// start downloading. | they have a | |||
// fair chance to start downloading. | ||||
int auto_manage_startup; | int auto_manage_startup; | |||
// if set to true, the estimated TCP/IP overhead is | // if set to true, the estimated TCP/IP overhead is drained | |||
// drained from the rate limiters, to avoid exceeding | from the rate | |||
// the limits with the total traffic | // limiters, to avoid exceeding the limits with the total tr | |||
affic | ||||
bool rate_limit_ip_overhead; | bool rate_limit_ip_overhead; | |||
// this announces to all trackers within the current | // controls how multi tracker torrents are treated. If this | |||
// tier. Trackers within a tier are supposed to share | is set to | |||
// peers, this could be used for trackers that don't, | // true, all trackers in the same tier are announced to in p | |||
// and require the clients to announce to all of them. | arallel. If | |||
// all trackers in tier 0 fails, all trackers in tier 1 are | ||||
announced as | ||||
// well. If it's set to false, the behavior is as defined by | ||||
the multi | ||||
// tracker specification. It defaults to false, which is the | ||||
same | ||||
// behavior previous versions of libtorrent has had as well. | ||||
bool announce_to_all_trackers; | bool announce_to_all_trackers; | |||
// if set to true, multi tracker torrents are treated | // controls how multi tracker torrents are treated. When thi | |||
// the same way uTorrent treats them. It defaults to | s is set to | |||
// false in order to comply with the extension definition. | // true, one tracker from each tier is announced to. This is | |||
// When this is enabled, one tracker from each tier is | the uTorrent | |||
// announced | // behavior. This is false by default in order to comply wit | |||
h the | ||||
// multi-tracker specification. | ||||
bool announce_to_all_tiers; | bool announce_to_all_tiers; | |||
// when this is set to true, if there is a tracker entry | // true by default. It means that trackers may be rearranged | |||
// with udp:// protocol, it is preferred over the same | in a way | |||
// tracker over http://. | // that udp trackers are always tried before http trackers f | |||
or the same | ||||
// hostname. Setting this to fails means that the trackers' | ||||
tier is | ||||
// respected and there's no preference of one protocol over | ||||
another. | ||||
bool prefer_udp_trackers; | bool prefer_udp_trackers; | |||
// when set to true, a piece has to have been forwarded | // when this is set to true, a piece has to have been forwar | |||
// to a third peer before another one is handed out | ded to a | |||
// third peer before another one is handed out. This is the | ||||
traditional | ||||
// definition of super seeding. | ||||
bool strict_super_seeding; | bool strict_super_seeding; | |||
// the number of pieces to send to each peer when seeding | // the number of pieces to send to a peer, when seeding, bef | |||
// before rotating to a new peer | ore rotating | |||
// in another peer to the unchoke set. It defaults to 3 piec | ||||
es, which | ||||
// means that when seeding, any peer we've sent more than th | ||||
is number of | ||||
// pieces to will be unchoked in favour of a choked peer. | ||||
int seeding_piece_quota; | int seeding_piece_quota; | |||
// the maximum number of sparse regions before starting | // is a limit of the number of *sparse regions* in a torrent | |||
// to prioritize pieces close to other pieces (to maintain | . A sparse | |||
// the number of sparse regions). This is set to 30000 on | // region is defined as a hole of pieces we have not yet dow | |||
// windows because windows vista has a new limit on the | nloaded, in | |||
// numbers of sparse regions one file may have | // between pieces that have been downloaded. This is used as | |||
// if it is set to 0 this behavior is disabled | a hack for | |||
// this is a hack to avoid a terrible bug on windows | // windows vista which has a bug where you cannot write file | |||
// don't use unless you have to, it screws with rarest-first | s with more | |||
// piece selection, and reduces swarm performance | // than a certain number of sparse regions. This limit is no | |||
t hard, it | ||||
// will be exceeded. Once it's exceeded, pieces that will ma | ||||
intain or | ||||
// decrease the number of sparse regions are prioritized. To | ||||
disable this | ||||
// functionality, set this to 0. It defaults to 0 on all pla | ||||
tforms except | ||||
// windows. | ||||
int max_sparse_regions; | int max_sparse_regions; | |||
#ifndef TORRENT_DISABLE_MLOCK | // if lock disk cache is set to true the disk cache that's i | |||
// if this is set to true, the memory allocated for the | n use, will | |||
// disk cache will be locked in physical RAM, never to | // be locked in physical memory, preventing it from being sw | |||
// be swapped out | apped out. | |||
bool lock_disk_cache; | bool lock_disk_cache; | |||
#endif | ||||
// the number of times to reject requests while being | // the number of piece requests we will reject in a row whil | |||
// choked before disconnecting a peer for being malicious | e a peer is | |||
// choked before the peer is considered abusive and is disco | ||||
nnected. | ||||
int max_rejects; | int max_rejects; | |||
// sets the socket send and receive buffer sizes | // specifies the buffer sizes set on peer sockets. 0 (which | |||
// 0 means OS default | is the | |||
// default) means the OS default (i.e. don't change the buff | ||||
er sizes). | ||||
// The socket buffer sizes are changed using setsockopt() wi | ||||
th | ||||
// SOL_SOCKET/SO_RCVBUF and SO_SNDBUFFER. | ||||
int recv_socket_buffer_size; | int recv_socket_buffer_size; | |||
int send_socket_buffer_size; | int send_socket_buffer_size; | |||
// if this is set to false, the hashing will be | // chooses between two ways of reading back piece data from | |||
// optimized for memory usage instead of the | disk when its | |||
// number of read operations | // complete and needs to be verified against the piece hash. | |||
This happens | ||||
// if some blocks were flushed to the disk out of order. Eve | ||||
rything that | ||||
// is flushed in order is hashed as it goes along. Optimizin | ||||
g for speed | ||||
// will allocate space to fit all the the remaingin, unhashe | ||||
d, part of | ||||
// the piece, reads the data into it in a single call and ha | ||||
shes it. This | ||||
// is the default. If ``optimizing_hashing_for_speed`` is fa | ||||
lse, a single | ||||
// block will be allocated (16 kB), and the unhashed parts o | ||||
f the piece | ||||
// are read, one at a time, and hashed in this single block. | ||||
This is | ||||
// appropriate on systems that are memory constrained. | ||||
bool optimize_hashing_for_speed; | bool optimize_hashing_for_speed; | |||
// if > 0, file checks will have a short | // the number of milliseconds to sleep | |||
// delay between disk operations, to make it | // in between disk read operations when checking torrents. T | |||
// less intrusive on the system as a whole | his defaults | |||
// blocking the disk. This delay is specified | // to 0, but can be set to higher numbers to slow down the r | |||
// in milliseconds and the delay will be this | ate at which | |||
// long per 16kiB block | // data is read from the disk while checking. This may be us | |||
// the default of 10 ms/16kiB will limit | eful for | |||
// the checking rate to 1.6 MiB per second | // background tasks that doesn't matter if they take a bit l | |||
onger, as long | ||||
// as they leave disk I/O time for other processes. | ||||
int file_checks_delay_per_block; | int file_checks_delay_per_block; | |||
// the disk cache algorithms available. Set | ||||
// session_settings::disk_cache_algorithm to one of these. | ||||
enum disk_cache_algo_t | enum disk_cache_algo_t | |||
{ lru, largest_contiguous, avoid_readback }; | { | |||
// This flushes the entire piece, in the write cache | ||||
, that was least | ||||
// recently written to. | ||||
lru, | ||||
// will flush the largest sequences of contiguous bl | ||||
ocks from the | ||||
// write cache, regarless of the piece's last use ti | ||||
me. | ||||
largest_contiguous, | ||||
// will prioritize flushing blocks that will avoid h | ||||
aving to read them | ||||
// back in to verify the hash of the piece once it's | ||||
done. This is | ||||
// especially useful for high throughput setups, whe | ||||
re reading from | ||||
// the disk is especially expensive. | ||||
avoid_readback | ||||
}; | ||||
// tells the disk I/O thread which cache flush algorithm to | ||||
use. | ||||
// This is specified by the disk_cache_algo_t enum. | ||||
disk_cache_algo_t disk_cache_algorithm; | disk_cache_algo_t disk_cache_algorithm; | |||
// the number of blocks that will be read ahead | // the number of blocks to read into the read cache when a r | |||
// when reading a block into the read cache | ead cache | |||
// miss occurs. Setting this to 0 is essentially the same th | ||||
ing as | ||||
// disabling read cache. The number of blocks read into the | ||||
read cache is | ||||
// always capped by the piece boundry. | ||||
// | ||||
// When a piece in the write cache has ``write_cache_line_si | ||||
ze`` | ||||
// contiguous blocks in it, they will be flushed. Setting th | ||||
is to 1 | ||||
// effectively disables the write cache. | ||||
int read_cache_line_size; | int read_cache_line_size; | |||
// whenever a contiguous range of this many | // whenever a contiguous range of this many blocks is found | |||
// blocks is found in the write cache, it | in the write | |||
// is flushed immediately | // cache, it is flushed immediately | |||
int write_cache_line_size; | int write_cache_line_size; | |||
// this is the number of seconds a disk failure | // the number of seconds from a disk write errors occur on a | |||
// occurs until libtorrent will re-try. | torrent | |||
// until libtorrent will take it out of the upload mode, to | ||||
test if the | ||||
// error condition has been fixed. | ||||
// | ||||
// libtorrent will only do this automatically for auto manag | ||||
ed torrents. | ||||
// | ||||
// You can explicitly take a torrent out of upload only mode | ||||
using | ||||
// set_upload_mode(). | ||||
int optimistic_disk_retry; | int optimistic_disk_retry; | |||
// when set to true, all data downloaded from | // controls if downloaded pieces are verified against the pi | |||
// peers will be assumed to be correct, and not | ece hashes in | |||
// tested to match the hashes in the torrent | // the torrent file or not. The default is false, i.e. to ve | |||
// this is only useful for simulation and | rify all | |||
// testing purposes (typically combined with | // downloaded data. It may be useful to turn this off for pe | |||
// disabled_storage) | rformance | |||
// profiling and simulation scenarios. Do not disable the ha | ||||
sh check for | ||||
// regular bittorrent clients. | ||||
bool disable_hash_checks; | bool disable_hash_checks; | |||
// if this is true, disk read operations may | // if this is true, disk read operations may be re-ordered b | |||
// be re-ordered based on their physical disk | ased on their | |||
// read offset. This greatly improves throughput | // physical disk read offset. This greatly improves throughp | |||
// when uploading to many peers. This assumes | ut when | |||
// a traditional hard drive with a read head | // uploading to many peers. This assumes a traditional hard | |||
// and spinning platters. If your storage medium | drive with a | |||
// is a solid state drive, this optimization | // read head and spinning platters. If your storage medium i | |||
// doesn't give you an benefits | s a solid | |||
// state drive, this optimization doesn't give you an benefi | ||||
ts | ||||
bool allow_reordered_disk_operations; | bool allow_reordered_disk_operations; | |||
// if this is true, i2p torrents are allowed | // if this is true, i2p torrents are allowed to also get pee | |||
// to also get peers from other sources than | rs from other | |||
// the tracker, and connect to regular IPs, | // sources than the tracker, and connect to regular IPs, not | |||
// not providing any anonymization. This may | providing | |||
// be useful if the user is not interested in | // any anonymization. This may be useful if the user is not | |||
// the anonymization of i2p, but still wants to | interested in | |||
// be able to connect to i2p peers. | // the anonymization of i2p, but still wants to be able to c | |||
onnect to i2p | ||||
// peers. | ||||
bool allow_i2p_mixed; | bool allow_i2p_mixed; | |||
// the max number of pieces that a peer can | // the max number of suggested piece indices received from a | |||
// suggest to use before we start dropping | peer that's | |||
// previous suggested piece | // remembered. If a peer floods suggest messages, this limit | |||
prevents | ||||
// libtorrent from using too much RAM. It defaults to 10. | ||||
int max_suggest_pieces; | int max_suggest_pieces; | |||
// if set to true, requests that have have not been | // If set to true (it defaults to false), piece requests tha | |||
// satisfied after the equivalence of the entire | t have been | |||
// request queue has been received, will be considered lost | // skipped enough times when piece messages are received, wi | |||
ll be | ||||
// considered lost. Requests are considered skipped when the | ||||
returned | ||||
// piece messages are re-ordered compared to the order of th | ||||
e requests. | ||||
// This was an attempt to get out of dead-locks caused by Bi | ||||
tComet peers | ||||
// silently ignoring some requests. It may cause problems at | ||||
high rates, | ||||
// and high level of reordering in the uploading peer, that' | ||||
s why it's | ||||
// disabled by default. | ||||
bool drop_skipped_requests; | bool drop_skipped_requests; | |||
// if this is set to true, the disk I/O will be | // determines if the disk I/O should use a normal | |||
// run at lower-than-normal priority. This is | // or low priority policy. This defaults to true, which mean | |||
// intended to make the machine more responsive | s that | |||
// to foreground tasks, while bittorrent runs | // it's low priority by default. Other processes doing disk | |||
// in the background | I/O will | |||
// normally take priority in this mode. This is meant to imp | ||||
rove the | ||||
// overall responsiveness of the system while downloading in | ||||
the | ||||
// background. For high-performance server setups, this migh | ||||
t not | ||||
// be desirable. | ||||
bool low_prio_disk; | bool low_prio_disk; | |||
// number of seconds between local service announces for | // the time between local | |||
// torrents. Defaults to 5 minutes | // network announces for a torrent. By default, when local s | |||
ervice | ||||
// discovery is enabled a torrent announces itself every 5 m | ||||
inutes. | ||||
// This interval is specified in seconds. | ||||
int local_service_announce_interval; | int local_service_announce_interval; | |||
// number of seconds between DHT announces for | // the number of seconds between announcing | |||
// torrents. Defaults to 15 minutes | // torrents to the distributed hash table (DHT). This is spe | |||
cified to | ||||
// be 15 minutes which is its default. | ||||
int dht_announce_interval; | int dht_announce_interval; | |||
// the number of seconds a connection ID received | // the number of seconds libtorrent | |||
// from a UDP tracker is valid for. This is specified | // will keep UDP tracker connection tokens around for. This | |||
// as 60 seconds | is specified | |||
// to be 60 seconds, and defaults to that. The higher this v | ||||
alue is, the | ||||
// fewer packets have to be sent to the UDP tracker. In orde | ||||
r for higher | ||||
// values to work, the tracker needs to be configured to mat | ||||
ch the | ||||
// expiration time for tokens. | ||||
int udp_tracker_token_expiry; | int udp_tracker_token_expiry; | |||
// if this is set to true, any block read from the | // if this is set to true, read cache blocks | |||
// disk cache will be dropped from the cache immediately | // that are hit by peer read requests are removed from the d | |||
// following. This may be useful if the block is not | isk cache | |||
// expected to be hit again. It would save some memory | // to free up more space. This is useful if you don't expect | |||
the disk | ||||
// cache to create any cache hits from other peers than the | ||||
one who | ||||
// triggered the cache line to be read into the cache in the | ||||
first place. | ||||
bool volatile_read_cache; | bool volatile_read_cache; | |||
// if this is set to true, the size of the cache line | // enables the disk cache to adjust the size | |||
// generated by a particular read request depends on the | // of a cache line generated by peers to depend on the uploa | |||
// rate you're sending to that peer. This optimizes the | d rate | |||
// memory usage of the disk read cache by reading | // you are sending to that peer. The intention is to optimiz | |||
// further ahead for peers that you're uploading at high | e the RAM | |||
// rates to | // usage of the cache, to read ahead further for peers that | |||
you're | ||||
// sending faster to. | ||||
bool guided_read_cache; | bool guided_read_cache; | |||
// this is the default minimum time any read cache line | // the minimum number of seconds any read cache line is kept | |||
// is kept in the cache. | in the | |||
// cache. This defaults to one second but may be greater if | ||||
// ``guided_read_cache`` is enabled. Having a lower bound on | ||||
the time a | ||||
// cache line stays in the cache is an attempt to avoid swap | ||||
ping the same | ||||
// pieces in and out of the cache in case there is a shortag | ||||
e of spare | ||||
// cache space. | ||||
int default_cache_min_age; | int default_cache_min_age; | |||
// the global number of optimistic unchokes | // the number of optimistic unchoke slots to use. It default | |||
// 0 means automatic | s to 0, which | |||
// means automatic. Having a higher number of optimistic unc | ||||
hoke slots | ||||
// mean you will find the good peers faster but with the tra | ||||
de-off to use | ||||
// up more bandwidth. When this is set to 0, libtorrent open | ||||
s up 20% of | ||||
// your allowed upload slots as optimistic unchoke slots. | ||||
int num_optimistic_unchoke_slots; | int num_optimistic_unchoke_slots; | |||
// if set to true, files won't have their atime updated | // this is a linux-only option and passes in the ``O_NOATIME | |||
// on disk reads. This works on linux | `` to | |||
// ``open()`` when opening files. This may lead to some disk | ||||
performance | ||||
// improvements. | ||||
bool no_atime_storage; | bool no_atime_storage; | |||
// === BitTyrant unchoker settings == | // the assumed reciprocation rate from peers when using the | |||
BitTyrant | ||||
// when using BitTyrant choker, this is the default | // choker. This defaults to 14 kiB/s. If set too high, you w | |||
// assumed reciprocation rate. This is where each peer start | ill | |||
s | // over-estimate your peers and be more altruistic while fin | |||
ding the true | ||||
// reciprocation rate, if it's set too low, you'll be too st | ||||
ingy and | ||||
// waste finding the true reciprocation rate. | ||||
int default_est_reciprocation_rate; | int default_est_reciprocation_rate; | |||
// this is the increase of the estimated reciprocation rate | // specifies how many percent the extimated reciprocation ra | |||
// in percent. We increase by this amount once every unchoke | te should be | |||
// interval that we are choked by the other peer and we have | // increased by each unchoke interval a peer is still chokin | |||
// unchoked them | g us back. | |||
// This defaults to 20%. This only applies to the BitTyrant | ||||
choker. | ||||
int increase_est_reciprocation_rate; | int increase_est_reciprocation_rate; | |||
// each unchoke interval that we stay unchoked by the other | // specifies how many percent the estimated reciprocation ra | |||
// peer, and we have unchoked this peer as well, we decrease | te should be | |||
// our estimate of the reciprocation rate, since we might ha | // decreased by each unchoke interval a peer unchokes us. Th | |||
ve | is default to | |||
// over-estimated it | // 3%. This only applies to the BitTyrant choker. | |||
int decrease_est_reciprocation_rate; | int decrease_est_reciprocation_rate; | |||
// if set to true, an incoming connection to a torrent that' | // defaults to false. If a torrent has been paused by the au | |||
s | to managed | |||
// paused and auto-managed will make the torrent start. | // feature in libtorrent, i.e. the torrent is paused and aut | |||
o managed, | ||||
// this feature affects whether or not it is automatically s | ||||
tarted on an | ||||
// incoming connection. The main reason to queue torrents, i | ||||
s not to make | ||||
// them unavailable, but to save on the overhead of announci | ||||
ng to the | ||||
// trackers, the DHT and to avoid spreading one's unchoke sl | ||||
ots too thin. | ||||
// If a peer managed to find us, even though we're no in the | ||||
torrent | ||||
// anymore, this setting can make us start the torrent and s | ||||
erve it. | ||||
bool incoming_starts_queued_torrents; | bool incoming_starts_queued_torrents; | |||
// when set to true, the downloaded counter sent to trackers | // when set to true, the downloaded counter sent to trackers | |||
// will include the actual number of payload bytes donwnload | will include | |||
ed | // the actual number of payload bytes donwnloaded including | |||
// including redundant bytes. If set to false, it will not i | redundant | |||
nclude | // bytes. If set to false, it will not include any redundany | |||
// any redundany bytes | bytes | |||
bool report_true_downloaded; | bool report_true_downloaded; | |||
// if set to true, libtorrent won't request a piece multiple | // defaults to true, and controls when a block may be reques | |||
times | ted twice. If | |||
// until every piece is requested | // this is ``true``, a block may only be requested twice whe | |||
n there's ay | ||||
// least one request to every piece that's left to download | ||||
in the | ||||
// torrent. This may slow down progress on some pieces somet | ||||
imes, but it | ||||
// may also avoid downloading a lot of redundant bytes. If t | ||||
his is | ||||
// ``false``, libtorrent attempts to use each peer connectio | ||||
n to its max, | ||||
// by always requesting something, even if it means requesti | ||||
ng something | ||||
// that has been requested from another peer already. | ||||
bool strict_end_game_mode; | bool strict_end_game_mode; | |||
// if this is true, the broadcast socket will not only use I | // if set to true, the local peer discovery (or Local Servic | |||
P multicast | e Discovery) | |||
// but also send the messages on the broadcast address. This | // will not only use IP multicast, but also broadcast its me | |||
is false by | ssages. This | |||
// default in order to avoid flooding networks for no good r | // can be useful when running on networks that don't support | |||
eason. If | multicast. | |||
// a network is known not to support multicast, this can be | // Since broadcast messages might be expensive and disruptiv | |||
enabled | e on | |||
// networks, only every 8th announce uses broadcast. | ||||
bool broadcast_lsd; | bool broadcast_lsd; | |||
// when set to true, libtorrent will try to make outgoing ut | // these all determines if libtorrent should attempt to make | |||
p connections | outgoing | |||
// connections of the specific type, or allow incoming conne | ||||
ction. By | ||||
// default all of them are enabled. | ||||
bool enable_outgoing_utp; | bool enable_outgoing_utp; | |||
// if set to false, libtorrent will reject incoming utp conn | ||||
ections | ||||
bool enable_incoming_utp; | bool enable_incoming_utp; | |||
// when set to false, no outgoing TCP connections will be ma | ||||
de | ||||
bool enable_outgoing_tcp; | bool enable_outgoing_tcp; | |||
// if set to false, libtorrent will reject incoming tcp conn | ||||
ections | ||||
bool enable_incoming_tcp; | bool enable_incoming_tcp; | |||
// the max number of peers we accept from pex messages from a single peer. | // the max number of peers we accept from pex messages from a single peer. | |||
// this limits the number of concurrent peers any of our pee rs claims to | // this limits the number of concurrent peers any of our pee rs claims to | |||
// be connected to. If they clain to be connected to more th an this, we'll | // be connected to. If they clain to be connected to more th an this, we'll | |||
// ignore any peer that exceeds this limit | // ignore any peer that exceeds this limit | |||
int max_pex_peers; | int max_pex_peers; | |||
// when set to true, the file modification time is ignored w | // determines if the storage, when loading resume data files | |||
hen loading | , should | |||
// resume data. The resume data includes the expected timest | // verify that the file modification time with the timestamp | |||
amp of each | s in the | |||
// file and is typically compared to make sure the files hav | // resume data. This defaults to false, which means timestam | |||
en't changed | ps are taken | |||
// since the last session | // into account, and resume data is less likely to accepted | |||
(torrents are | ||||
// more likely to be fully checked when loaded). It might be | ||||
useful to | ||||
// set this to true if your network is faster than your disk | ||||
, and it | ||||
// would be faster to redownload potentially missed pieces t | ||||
han to go | ||||
// through the whole storage to look for them. | ||||
bool ignore_resume_timestamps; | bool ignore_resume_timestamps; | |||
// normally, if a resume file is incomplete (typically there | // determines if the storage should check the whole files wh | |||
's no | en resume | |||
// "file sizes" field) the torrent is queued for a full chec | // data is incomplete or missing or whether it should simply | |||
k. If | assume we | |||
// this settings is set to true, instead libtorrent will ass | // don't have any of the data. By default, this is determine | |||
ume | d by the | |||
// we have none of the files and go straight to download | // existance of any of the files. By setting this setting to | |||
true, the | ||||
// files won't be checked, but will go straight to download | ||||
mode. | ||||
bool no_recheck_incomplete_resume; | bool no_recheck_incomplete_resume; | |||
// when this is true, libtorrent will take actions to make s | // defaults to false. When set to true, the client tries to | |||
ure no | hide its | |||
// privacy sensitive information is leaked out from the clie | // identity to a certain degree. The peer-ID will no longer | |||
nt. This | include the | |||
// mode is assumed to be combined with using a proxy for all | // client's fingerprint. The user-agent will be reset to an | |||
your | empty string. | |||
// traffic. With this option, your true IP address will not | // It will also try to not leak other identifying informatio | |||
be exposed | n, such as | |||
// nor anything that can tie your connection to your true IP | // your local listen port, your IP etc. | |||
// | ||||
// If you're using I2P, a VPN or a proxy, it might make sens | ||||
e to enable | ||||
// anonymous mode. | ||||
bool anonymous_mode; | bool anonymous_mode; | |||
// the number of milliseconds between internal ticks. Should | // disables any communication that's not going over a proxy. | |||
be no | Enabling | |||
// more than one second (i.e. 1000). | // this requires a proxy to be configured as well, see | |||
// ``set_proxy_settings``. The listen sockets are closed, an | ||||
d incoming | ||||
// connections will only be accepted through a SOCKS5 or I2P | ||||
proxy (if a | ||||
// peer proxy is set up and is run on the same machine as th | ||||
e tracker | ||||
// proxy). This setting also disabled peer country lookups, | ||||
since those | ||||
// are done via DNS lookups that aren't supported by proxies | ||||
. | ||||
bool force_proxy; | ||||
// specifies the number of milliseconds between internal tic | ||||
ks. This is | ||||
// the frequency with which bandwidth quota is distributed t | ||||
o peers. It | ||||
// should not be more than one second (i.e. 1000 ms). Settin | ||||
g this to a | ||||
// low value (around 100) means higher resolution bandwidth | ||||
quota | ||||
// distribution, setting it to a higher value saves CPU cycl | ||||
es. | ||||
int tick_interval; | int tick_interval; | |||
// specifies whether downloads from web seeds is reported to the | // specifies whether downloads from web seeds is reported to the | |||
// tracker or not. Defaults to on | // tracker or not. Defaults to on | |||
bool report_web_seed_downloads; | bool report_web_seed_downloads; | |||
// this is the target share ratio for share-mode torrents | // specifies the target share ratio for share mode torrents. | |||
This | ||||
// defaults to 3, meaning we'll try to upload 3 times as muc | ||||
h as we | ||||
// download. Setting this very high, will make it very conse | ||||
rvative and | ||||
// you might end up not downloading anything ever (and not a | ||||
ffecting your | ||||
// share ratio). It does not make any sense to set this any | ||||
lower than 2. | ||||
// For instance, if only 3 peers need to download the rarest | ||||
piece, it's | ||||
// impossible to download a single piece and upload it more | ||||
than 3 times. | ||||
// If the share_mode_target is set to more than 3, nothing i | ||||
s downloaded. | ||||
int share_mode_target; | int share_mode_target; | |||
// max upload rate in bytes per second for the session | // sets the session-global limits of upload and download rat | |||
e limits, in | ||||
// bytes per second. The local rates refer to peers on the l | ||||
ocal network. | ||||
// By default peers on the local network are not rate limite | ||||
d. | ||||
// | ||||
// These rate limits are only used for local peers (peers wi | ||||
thin the same | ||||
// subnet as the client itself) and it is only used when | ||||
// ``session_settings::ignore_limits_on_local_network`` is s | ||||
et to true | ||||
// (which it is by default). These rate limits default to un | ||||
throttled, | ||||
// but can be useful in case you want to treat local peers | ||||
// preferentially, but not quite unthrottled. | ||||
// | ||||
// A value of 0 means unlimited. | ||||
int upload_rate_limit; | int upload_rate_limit; | |||
// max download rate in bytes per second for the session | ||||
int download_rate_limit; | int download_rate_limit; | |||
// max upload rate in bytes per second for peers on the loca | ||||
l | ||||
// network, in the session | ||||
int local_upload_rate_limit; | int local_upload_rate_limit; | |||
// max download rate in bytes per second for peers on the lo | ||||
cal | ||||
// network, in the session | ||||
int local_download_rate_limit; | int local_download_rate_limit; | |||
// max upload rate used by the DHT in bytes per second | // sets the rate limit on the DHT. This is specified in byte | |||
s per second | ||||
// and defaults to 4000. For busy boxes with lots of torrent | ||||
s that | ||||
// requires more DHT traffic, this should be raised. | ||||
int dht_upload_rate_limit; | int dht_upload_rate_limit; | |||
// the max number of unchoke slots in the session (might be | // the max number of unchoked peers in the session. The numb | |||
// overridden by unchoke algorithm) | er of unchoke | |||
// slots may be ignored depending on what ``choking_algorith | ||||
m`` is set | ||||
// to. A value of -1 means infinite. | ||||
int unchoke_slots_limit; | int unchoke_slots_limit; | |||
// the max number of half-open TCP connections | // sets the maximum number of half-open connections libtorre | |||
nt will have | ||||
// when connecting to peers. A half-open connection is one w | ||||
here | ||||
// connect() has been called, but the connection still hasn' | ||||
t been | ||||
// established (nor failed). Windows XP Service Pack 2 sets | ||||
a default, | ||||
// system wide, limit of the number of half-open connections | ||||
to 10. So, | ||||
// this limit can be used to work nicer together with other | ||||
network | ||||
// applications on that system. The default is to have no li | ||||
mit, and | ||||
// passing -1 as the limit, means to have no limit. When lim | ||||
iting the | ||||
// number of simultaneous connection attempts, peers will be | ||||
put in a | ||||
// queue waiting for their turn to get connected. | ||||
int half_open_limit; | int half_open_limit; | |||
// the max number of connections in the session | // sets a global limit on the number of connections opened. | |||
The number of | ||||
// connections is set to a hard minimum of at least two per | ||||
torrent, so | ||||
// if you set a too low connections limit, and open too many | ||||
torrents, | ||||
// the limit will not be met. | ||||
int connections_limit; | int connections_limit; | |||
// target delay, milliseconds | // the number of extra incoming connections allowed temporar | |||
ily, in order | ||||
// to support replacing peers | ||||
int connections_slack; | ||||
// the target delay for uTP sockets in milliseconds. A high | ||||
value will | ||||
// make uTP connections more aggressive and cause longer que | ||||
ues in the | ||||
// upload bottleneck. It cannot be too low, since the noise | ||||
in the | ||||
// measurements would cause it to send too slow. The default | ||||
is 50 | ||||
// milliseconds. | ||||
int utp_target_delay; | int utp_target_delay; | |||
// max number of bytes to increase cwnd per rtt in uTP | // the number of bytes the uTP congestion window can increas | |||
// congestion controller | e at the most | |||
// in one RTT. This defaults to 300 bytes. If this is set to | ||||
o high, the | ||||
// congestion controller reacts too hard to noise and will n | ||||
ot be stable, | ||||
// if it's set too low, it will react slow to congestion and | ||||
not back off | ||||
// as fast. | ||||
int utp_gain_factor; | int utp_gain_factor; | |||
// the shortest allowed uTP connection timeout in millisecon | // the shortest allowed uTP socket timeout, specified in mil | |||
ds | liseconds. | |||
// defaults to 500 milliseconds. The shorter timeout, the | // This defaults to 500 milliseconds. The timeout depends on | |||
// faster the connection recovers from a loss of an entire w | the RTT of | |||
indow | // the connection, but is never smaller than this value. A c | |||
onnection | ||||
// times out when every packet in a window is lost, or when | ||||
a packet is | ||||
// lost twice in a row (i.e. the resent packet is lost as we | ||||
ll). | ||||
// | ||||
// The shorter the timeout is, the faster the connection wil | ||||
l recover | ||||
// from this situation, assuming the RTT is low enough. | ||||
int utp_min_timeout; | int utp_min_timeout; | |||
// the number of SYN packets that are sent before giving up | // the number of SYN packets that are sent (and timed out) b | |||
efore | ||||
// giving up and closing the socket. | ||||
int utp_syn_resends; | int utp_syn_resends; | |||
// the number of resent packets sent on a closed socket befo re giving up | // the number of resent packets sent on a closed socket befo re giving up | |||
int utp_fin_resends; | int utp_fin_resends; | |||
// the number of times to send a packet before giving up | // the number of times a packet is sent (and lossed or timed | |||
out) | ||||
// before giving up and closing the connection. | ||||
int utp_num_resends; | int utp_num_resends; | |||
// initial timeout for uTP SYN packets | // the number of milliseconds of timeout for the initial SYN | |||
packet for | ||||
// uTP connections. For each timed out packet (in a row), th | ||||
e timeout is | ||||
// doubled. | ||||
int utp_connect_timeout; | int utp_connect_timeout; | |||
#ifndef TORRENT_NO_DEPRECATE | ||||
// number of milliseconds of delaying ACKing packets the mos t | // number of milliseconds of delaying ACKing packets the mos t | |||
int utp_delayed_ack; | int utp_delayed_ack; | |||
#endif | ||||
// set to true if the uTP socket buffer size is allowed to i | // controls if the uTP socket manager is allowed to increase | |||
ncrease | the socket | |||
// dynamically based on the NIC MTU setting. This is true by | // buffer if a network interface with a large MTU is used (s | |||
default | uch as | |||
// and improves uTP performance for networks with larger fra | // loopback or ethernet jumbo frames). This defaults to true | |||
me sizes | and might | |||
// including loopback | // improve uTP throughput. For RAM constrained systems, disa | |||
bling this | ||||
// typically saves around 30kB in user space and probably ar | ||||
ound 400kB in | ||||
// kernel socket buffers (it adjusts the send and receive bu | ||||
ffer size on | ||||
// the kernel socket, both for IPv4 and IPv6). | ||||
bool utp_dynamic_sock_buf; | bool utp_dynamic_sock_buf; | |||
// what to multiply the congestion window by on packet loss. | // controls how the congestion window is changed when a pack | |||
// it's specified as a percent. The default is 50, i.e. cut | et loss is | |||
// in half | // experienced. It's specified as a percentage multiplier fo | |||
r ``cwnd``. | ||||
// By default it's set to 50 (i.e. cut in half). Do not chan | ||||
ge this value | ||||
// unless you know what you're doing. Never set it higher th | ||||
an 100. | ||||
int utp_loss_multiplier; | int utp_loss_multiplier; | |||
// the options for session_settings::mixed_mode_algorithm. | ||||
enum bandwidth_mixed_algo_t | enum bandwidth_mixed_algo_t | |||
{ | { | |||
// disables the mixed mode bandwidth balancing | // disables the mixed mode bandwidth balancing | |||
prefer_tcp = 0, | prefer_tcp = 0, | |||
// does not throttle uTP, throttles TCP to the same proportion | // does not throttle uTP, throttles TCP to the same proportion | |||
// of throughput as there are TCP connections | // of throughput as there are TCP connections | |||
peer_proportional = 1 | peer_proportional = 1 | |||
}; | }; | |||
// the algorithm to use to balance bandwidth between tcp | ||||
// connections and uTP connections | // determines how to treat TCP connections when there are uT | |||
P | ||||
// connections. Since uTP is designed to yield to TCP, there | ||||
's an | ||||
// inherent problem when using swarms that have both TCP and | ||||
uTP | ||||
// connections. If nothing is done, uTP connections would of | ||||
ten be | ||||
// starved out for bandwidth by the TCP connections. This mo | ||||
de is | ||||
// ``prefer_tcp``. The ``peer_proportional`` mode simply loo | ||||
ks at the | ||||
// current throughput and rate limits all TCP connections to | ||||
their | ||||
// proportional share based on how many of the connections a | ||||
re TCP. This | ||||
// works best if uTP connections are not rate limited by the | ||||
global rate | ||||
// limiter, see rate_limit_utp. | ||||
// | ||||
// see bandwidth_mixed_algo_t for options. | ||||
int mixed_mode_algorithm; | int mixed_mode_algorithm; | |||
// set to true if uTP connections should be rate limited | // determines if uTP connections should be throttled by the | |||
// defaults to true. | global rate | |||
// limiter or not. By default they are. | ||||
bool rate_limit_utp; | bool rate_limit_utp; | |||
// this is the number passed in to listen(). i.e. | // the value passed in to listen() for the listen socket. It | |||
// the number of connections to accept while we're | is the | |||
// not waiting in an accept() call. | // number of outstanding incoming connections to queue up wh | |||
ile we're not | ||||
// actively waiting for a connection to be accepted. The def | ||||
ault is 5 | ||||
// which should be sufficient for any normal client. If this | ||||
is a high | ||||
// performance server which expects to receive a lot of conn | ||||
ections, or | ||||
// used in a simulator or test, it might make sense to raise | ||||
this number. | ||||
// It will not take affect until listen_on() is called again | ||||
(or for the | ||||
// first time). | ||||
int listen_queue_size; | int listen_queue_size; | |||
// if this is true, the &ip= argument in tracker requests | // if true, the ``&ip=`` argument in tracker requests (unles | |||
// (unless otherwise specified) will be set to the intermedi | s otherwise | |||
ate | // specified) will be set to the intermediate IP address, if | |||
// IP address if the user is double NATed. If ther user is n | the user is | |||
ot | // double NATed. If ther user is not double NATed, this opti | |||
// double NATed, this option does not have an affect | on has no | |||
// affect. | ||||
bool announce_double_nat; | bool announce_double_nat; | |||
// the first tracker response after a torrent is started | // the number of peers to try to connect to immediately when | |||
// will cause this many connections to be made immediately. | the first | |||
// instead of waiting for the connection scheduler which | // tracker response is received for a torrent. This is a boo | |||
// triggeres every second | st to given | |||
// to new torrents to accelerate them starting up. The norma | ||||
l connect | ||||
// scheduler is run once every second, this allows peers to | ||||
be connected | ||||
// immediately instead of waiting for the session tick to tr | ||||
igger | ||||
// connections. | ||||
int torrent_connect_boost; | int torrent_connect_boost; | |||
// this controls whether or not seeding (and complete) torre | // determines if seeding (and finished) torrents should atte | |||
nts | mpt to make | |||
// attempt to make outgoing connections or not. It defaults | // outgoing connections or not. By default this is true. It | |||
to | may be set to | |||
// true, but can be set to zero for specific applications wh | // false in very specific applications where the cost of mak | |||
ere | ing outgoing | |||
// making outgoing connections is costly and known to not | // connections is high, and there are no or small benefits o | |||
// add any benefits | f doing so. | |||
// For instance, if no nodes are behind a firewall or a NAT, | ||||
seeds don't | ||||
// need to make outgoing connections. | ||||
bool seeding_outgoing_connections; | bool seeding_outgoing_connections; | |||
// when this is true, libtorrent will not attempt to make ou | // if true (which is the default), libtorrent will not conne | |||
tgoing | ct to any | |||
// connections to peers whose port is < 1024. This is a safe | // peers on priviliged ports (<= 1023). This can mitigate us | |||
ty | ing | |||
// precaution to avoid being part of a DDoS attack | // bittorrent swarms for certain DDoS attacks. | |||
bool no_connect_privileged_ports; | bool no_connect_privileged_ports; | |||
// the max alert queue size | // the maximum number of alerts queued up internally. If ale | |||
rts are not | ||||
// popped, the queue will eventually fill up to this level. | ||||
This defaults | ||||
// to 1000. | ||||
int alert_queue_size; | int alert_queue_size; | |||
// the max allowed size for metadata received by the | // the maximum allowed size (in bytes) to be received | |||
// ut_metadata extension (i.e. magnet links) | // by the metadata extension, i.e. magnet links. It defaults | |||
to 1 MiB. | ||||
int max_metadata_size; | int max_metadata_size; | |||
// attempt to smooth out connects to avoid getting spikes in | // true by default, which means the number of connection att | |||
// opening connections and timing out connections | empts per | |||
// second may be limited to below the ``connection_speed``, | ||||
in case we're | ||||
// close to bump up against the limit of number of connectio | ||||
ns. The | ||||
// intention of this setting is to more evenly distribute ou | ||||
r connection | ||||
// attempts over time, instead of attempting to connectin in | ||||
batches, and | ||||
// timing them out in batches. | ||||
bool smooth_connects; | bool smooth_connects; | |||
// always send user-agent | // defaults to false. When set to true, web connections will | |||
include a | ||||
// user-agent with every request, as opposed to just the fir | ||||
st request in | ||||
// a connection. | ||||
bool always_send_user_agent; | bool always_send_user_agent; | |||
// if true, trackers will also be filtered by the IP | // defaults to true. It determines whether the IP filter app | |||
// filter, otherwise they are exempt | lies to | |||
// trackers as well as peers. If this is set to false, track | ||||
ers are | ||||
// exempt from the IP filter (if there is one). If no IP fil | ||||
ter is set, | ||||
// this setting is irrelevant. | ||||
bool apply_ip_filter_to_trackers; | bool apply_ip_filter_to_trackers; | |||
// to avoid write jobs starving read jobs, if this many | // used to avoid starvation of read jobs in the disk I/O thr | |||
// write jobs have been taking priority in a row, service | ead. By | |||
// one read job | // default, read jobs are deferred, sorted by physical disk | |||
location and | ||||
// serviced once all write jobs have been issued. In scenari | ||||
os where the | ||||
// download rate is enough to saturate the disk, there's a r | ||||
isk the read | ||||
// jobs will never be serviced. With this setting, every *x* | ||||
write job, | ||||
// issued in a row, will instead pick one read job off of th | ||||
e sorted | ||||
// queue, where *x* is ``read_job_every``. | ||||
int read_job_every; | int read_job_every; | |||
// issue posix_fadvise() or fcntl(F_RDADVISE) for disk reads | // defaults to true and will attempt to optimize disk reads | |||
// ahead of time | by giving the | |||
// operating system heads up of disk read requests as they a | ||||
re queued in | ||||
// the disk job queue. This gives a significant performance | ||||
boost for | ||||
// seeding. | ||||
bool use_disk_read_ahead; | bool use_disk_read_ahead; | |||
// if set to true, files will be locked when opened. | // determines whether or not to lock files which libtorrent | |||
// preventing any other process from modifying them | is | |||
// downloading to or seeding from. This is implemented using | ||||
// ``fcntl(F_SETLK)`` on unix systems and by not passing in | ||||
// ``SHARE_READ`` and ``SHARE_WRITE`` on windows. This might | ||||
prevent 3rd | ||||
// party processes from corrupting the files under libtorren | ||||
t's feet. | ||||
bool lock_files; | bool lock_files; | |||
// open an ssl listen socket for ssl torrents on this port | // sets the listen port for SSL connections. If this is set | |||
to 0, no SSL | ||||
// listen port is opened. Otherwise a socket is opened on th | ||||
is port. This | ||||
// setting is only taken into account when opening the regul | ||||
ar listen | ||||
// port, and won't re-open the listen socket simply by chang | ||||
ing this | ||||
// setting. | ||||
// | ||||
// if this is 0, outgoing SSL connections are disabled | // if this is 0, outgoing SSL connections are disabled | |||
// | ||||
// It defaults to port 4433. | ||||
int ssl_listen; | int ssl_listen; | |||
// this is the factor X in the formula to calculate the | // ``tracker_backoff`` determines how aggressively to back o | |||
// next tracker timeout: | ff from | |||
// delay = 5 + X/100 * fails^2 | // retrying failing trackers. This value determines *x* in t | |||
// so, it's an exponential back-off, and this factor | he following | |||
// determines how fast the back-off happens. Default | // formula, determining the number of seconds to wait until | |||
// is 250 | the next | |||
// retry: | ||||
// | ||||
// delay = 5 + 5 * x / 100 * fails^2 | ||||
// | ||||
// It defaults to 250. | ||||
// | ||||
// This setting may be useful to make libtorrent more or les | ||||
s aggressive | ||||
// in hitting trackers. | ||||
// | ||||
int tracker_backoff; | int tracker_backoff; | |||
// when true, web seeds sending bad data will be banned | // enables banning web seeds. By default, web seeds that sen | |||
d corrupt | ||||
// data are banned. | ||||
bool ban_web_seeds; | bool ban_web_seeds; | |||
// specifies the max number of bytes to receive into RAM buf | ||||
fers when | ||||
// downloading stuff over HTTP. Specifically when specifying | ||||
a URL to a | ||||
// .torrent file when adding a torrent or when announcing to | ||||
an HTTP | ||||
// tracker. The default is 2 MiB. | ||||
int max_http_recv_buffer_size; | ||||
// enables or disables the share mode extension. This is ena | ||||
bled by | ||||
// default. | ||||
bool support_share_mode; | ||||
// enables or disables the merkle tree torrent support. This | ||||
is enabled | ||||
// by default. | ||||
bool support_merkle_torrents; | ||||
// enables or disables reporting redundant bytes to the trac | ||||
ker. This is | ||||
// enabled by default. | ||||
bool report_redundant_bytes; | ||||
// the version string to advertise for this client in the pe | ||||
er protocol | ||||
// handshake. If this is empty the user_agent is used | ||||
std::string handshake_client_version; | ||||
// if this is true, the disk cache uses a pool allocator for | ||||
disk cache | ||||
// blocks. Enabling this improves performance of the disk ca | ||||
che with the | ||||
// side effect that the disk cache is less likely and slower | ||||
at returning | ||||
// memory to the kernel when cache pressure is low. | ||||
bool use_disk_cache_pool; | ||||
// the download and upload rate limits for a torrent to be c | ||||
onsidered | ||||
// active by the queuing mechanism. A torrent whose download | ||||
rate is less | ||||
// than ``inactive_down_rate`` and whose upload rate is less | ||||
than | ||||
// ``inactive_up_rate`` for ``auto_manage_startup`` seconds, | ||||
is | ||||
// considered inactive, and another queued torrent may be st | ||||
artert. | ||||
// This logic is disabled if ``dont_count_slow_torrents`` is | ||||
false. | ||||
int inactive_down_rate; | ||||
int inactive_up_rate; | ||||
}; | }; | |||
#ifndef TORRENT_DISABLE_DHT | // structure used to hold configuration options for the DHT | |||
struct dht_settings | // | |||
// The ``dht_settings`` struct used to contain a ``service_port`` me | ||||
mber to | ||||
// control which port the DHT would listen on and send messages from | ||||
. This | ||||
// field is deprecated and ignored. libtorrent always tries to open | ||||
the UDP | ||||
// socket on the same port as the TCP socket. | ||||
struct TORRENT_EXPORT dht_settings | ||||
{ | { | |||
// initialized dht_settings to the default values | ||||
dht_settings() | dht_settings() | |||
: max_peers_reply(100) | : max_peers_reply(100) | |||
, search_branching(5) | , search_branching(5) | |||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
, service_port(0) | , service_port(0) | |||
#endif | #endif | |||
, max_fail_count(20) | , max_fail_count(20) | |||
, max_torrents(2000) | , max_torrents(2000) | |||
, max_dht_items(700) | , max_dht_items(700) | |||
, max_torrent_search_reply(20) | , max_torrent_search_reply(20) | |||
, restrict_routing_ips(true) | , restrict_routing_ips(true) | |||
, restrict_search_ips(true) | , restrict_search_ips(true) | |||
, extended_routing_table(true) | ||||
, aggressive_lookups(true) | ||||
, privacy_lookups(false) | ||||
, enforce_node_id(false) | ||||
, ignore_dark_internet(true) | ||||
{} | {} | |||
// the maximum number of peers to send in a | // the maximum number of peers to send in a reply to ``get_p | |||
// reply to get_peers | eers`` | |||
int max_peers_reply; | int max_peers_reply; | |||
// the number of simultanous "connections" when | // the number of concurrent search request the node will sen | |||
// searching the DHT. | d when | |||
// announcing and refreshing the routing table. This paramet | ||||
er is called | ||||
// alpha in the kademlia paper | ||||
int search_branching; | int search_branching; | |||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
// the listen port for the dht. This is a UDP port. | // the listen port for the dht. This is a UDP port. zero mea | |||
// zero means use the same as the tcp interface | ns use the | |||
// same as the tcp interface | ||||
int service_port; | int service_port; | |||
#endif | #endif | |||
// the maximum number of times a node can fail | // the maximum number of failed tries to contact a node befo | |||
// in a row before it is removed from the table. | re it is | |||
// removed from the routing table. If there are known workin | ||||
g nodes that | ||||
// are ready to replace a failing node, it will be replaced | ||||
immediately, | ||||
// this limit is only used to clear out nodes that don't hav | ||||
e any node | ||||
// that can replace them. | ||||
int max_fail_count; | int max_fail_count; | |||
// this is the max number of torrents the DHT will track | // the total number of torrents to track from the DHT. This | |||
is simply an | ||||
// upper limit to make sure malicious DHT nodes cannot make | ||||
us allocate | ||||
// an unbounded amount of memory. | ||||
int max_torrents; | int max_torrents; | |||
// max number of items the DHT will store | // max number of items the DHT will store | |||
int max_dht_items; | int max_dht_items; | |||
// the max number of torrents to return in a | // the max number of torrents to return in a torrent search | |||
// torrent search query to the DHT | query to the | |||
// DHT | ||||
int max_torrent_search_reply; | int max_torrent_search_reply; | |||
// when set, nodes whose IP address that's in | // determines if the routing table entries should restrict e | |||
// the same /24 (or /64 for IPv6) range in the | ntries to one | |||
// same routing table bucket. This is an attempt | // per IP. This defaults to true, which helps mitigate some | |||
// to mitigate node ID spoofing attacks | attacks on | |||
// also restrict any IP to only have a single | // the DHT. It prevents adding multiple nodes with IPs with | |||
// entry in the whole routing table | a very close | |||
// CIDR distance. | ||||
// | ||||
// when set, nodes whose IP address that's in the same /24 ( | ||||
or /64 for | ||||
// IPv6) range in the same routing table bucket. This is an | ||||
attempt to | ||||
// mitigate node ID spoofing attacks also restrict any IP to | ||||
only have a | ||||
// single entry in the whole routing table | ||||
bool restrict_routing_ips; | bool restrict_routing_ips; | |||
// applies the same IP restrictions on nodes | // determines if DHT searches should prevent adding nodes wi | |||
// received during a DHT search (traversal algorithm) | th IPs with | |||
// very close CIDR distance. This also defaults to true and | ||||
helps | ||||
// mitigate certain attacks on the DHT. | ||||
bool restrict_search_ips; | bool restrict_search_ips; | |||
}; | ||||
#endif | ||||
#ifndef TORRENT_DISABLE_ENCRYPTION | // makes the first buckets in the DHT routing table fit 128, | |||
64, 32 and | ||||
// 16 nodes respectively, as opposed to the standard size of | ||||
8. All other | ||||
// buckets have size 8 still. | ||||
bool extended_routing_table; | ||||
// slightly changes the lookup behavior in terms of how many | ||||
outstanding | ||||
// requests we keep. Instead of having branch factor be a ha | ||||
rd limit, we | ||||
// always keep *branch factor* outstanding requests to the c | ||||
losest nodes. | ||||
// i.e. every time we get results back with closer nodes, we | ||||
query them | ||||
// right away. It lowers the lookup times at the cost of mor | ||||
e outstanding | ||||
// queries. | ||||
bool aggressive_lookups; | ||||
// when set, perform lookups in a way that is slightly more | ||||
expensive, | ||||
// but which minimizes the amount of information leaked abou | ||||
t you. | ||||
bool privacy_lookups; | ||||
// when set, node's whose IDs that are not correctly generat | ||||
ed based on | ||||
// its external IP are ignored. When a query arrives from su | ||||
ch node, an | ||||
// error message is returned with a message saying "invalid | ||||
node ID". | ||||
bool enforce_node_id; | ||||
// ignore DHT messages from parts of the internet we wouldn' | ||||
t expect to | ||||
// see any traffic from | ||||
bool ignore_dark_internet; | ||||
}; | ||||
struct pe_settings | // The ``pe_settings`` structure is used to control the settings rel | |||
ated | ||||
// to peer protocol encryption. | ||||
struct TORRENT_EXPORT pe_settings | ||||
{ | { | |||
// initializes the encryption settings with the default vaue s | ||||
pe_settings() | pe_settings() | |||
: out_enc_policy(enabled) | : out_enc_policy(enabled) | |||
, in_enc_policy(enabled) | , in_enc_policy(enabled) | |||
, allowed_enc_level(both) | , allowed_enc_level(both) | |||
, prefer_rc4(false) | , prefer_rc4(false) | |||
{} | {} | |||
// the encoding policy options for use with pe_settings::out | ||||
_enc_policy | ||||
// and pe_settings::in_enc_policy. | ||||
enum enc_policy | enum enc_policy | |||
{ | { | |||
forced, // disallow non encrypted connections | // Only encrypted connections are allowed. Incoming | |||
enabled, // allow encrypted and non encrypted connec | connections that | |||
tions | // are not encrypted are closed and if the encrypted | |||
disabled // disallow encrypted connections | outgoing | |||
// connection fails, a non-encrypted retry will not | ||||
be made. | ||||
forced, | ||||
// encrypted connections are enabled, but non-encryp | ||||
ted connections | ||||
// are allowed. An incoming non-encrypted connection | ||||
will be accepted, | ||||
// and if an outgoing encrypted connection fails, a | ||||
non- encrypted | ||||
// connection will be tried. | ||||
enabled, | ||||
// only non-encrypted connections are allowed. | ||||
disabled | ||||
}; | }; | |||
// the encryption levels, to be used with pe_settings::allow ed_enc_level. | ||||
enum enc_level | enum enc_level | |||
{ | { | |||
plaintext = 1, // use only plaintext encryption | // use only plaintext encryption | |||
rc4 = 2, // use only rc4 encryption | plaintext = 1, | |||
both = 3 // allow both | // use only rc4 encryption | |||
rc4 = 2, | ||||
// allow both | ||||
both = 3 | ||||
}; | }; | |||
enc_policy out_enc_policy; | // control the settings for incoming | |||
enc_policy in_enc_policy; | // and outgoing connections respectively. | |||
// see enc_policy enum for the available options. | ||||
boost::uint8_t out_enc_policy; | ||||
boost::uint8_t in_enc_policy; | ||||
// determines the encryption level of the | ||||
// connections. This setting will adjust which encryption s | ||||
cheme is | ||||
// offered to the other peer, as well as which encryption sc | ||||
heme is | ||||
// selected by the client. See enc_level enum for options. | ||||
boost::uint8_t allowed_enc_level; | ||||
enc_level allowed_enc_level; | ||||
// if the allowed encryption level is both, setting this to | // if the allowed encryption level is both, setting this to | |||
// true will prefer rc4 if both methods are offered, plainte xt | // true will prefer rc4 if both methods are offered, plainte xt | |||
// otherwise | // otherwise | |||
bool prefer_rc4; | bool prefer_rc4; | |||
}; | }; | |||
#endif | ||||
} | } | |||
#endif | #endif | |||
End of changes. 216 change blocks. | ||||
591 lines changed or deleted | 1782 lines changed or added | |||
session_status.hpp | session_status.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2006, Arvid Norberg | Copyright (c) 2006-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 43 | skipping to change at line 43 | |||
#ifndef TORRENT_SESSION_STATUS_HPP_INCLUDED | #ifndef TORRENT_SESSION_STATUS_HPP_INCLUDED | |||
#define TORRENT_SESSION_STATUS_HPP_INCLUDED | #define TORRENT_SESSION_STATUS_HPP_INCLUDED | |||
#include "libtorrent/config.hpp" | #include "libtorrent/config.hpp" | |||
#include "libtorrent/size_type.hpp" | #include "libtorrent/size_type.hpp" | |||
#include <vector> | #include <vector> | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
#ifndef TORRENT_DISABLE_DHT | // holds statistics about a current dht_lookup operation. | |||
// a DHT lookup is the travesal of nodes, looking up a | ||||
struct dht_lookup | // set of target nodes in the DHT for retrieving and possibly | |||
// storing information in the DHT | ||||
struct TORRENT_EXPORT dht_lookup | ||||
{ | { | |||
// string literal indicating which kind of lookup this is | ||||
char const* type; | char const* type; | |||
// the number of outstanding request to individual nodes | ||||
// this lookup has right now | ||||
int outstanding_requests; | int outstanding_requests; | |||
// the total number of requests that have timed out so far | ||||
// for this lookup | ||||
int timeouts; | int timeouts; | |||
// the total number of responses we have received for this | ||||
// lookup so far for this lookup | ||||
int responses; | int responses; | |||
// the branch factor for this lookup. This is the number of | ||||
// nodes we keep outstanding requests to in parallel by defa | ||||
ult. | ||||
// when nodes time out we may increase this. | ||||
int branch_factor; | int branch_factor; | |||
// the number of nodes left that could be queries for this | ||||
// lookup. Many of these are likely to be part of the trail | ||||
// while performing the lookup and would never end up actual | ||||
ly | ||||
// being queried. | ||||
int nodes_left; | int nodes_left; | |||
// the number of seconds ago the | // the number of seconds ago the | |||
// last message was sent that's still | // last message was sent that's still | |||
// outstanding | // outstanding | |||
int last_sent; | int last_sent; | |||
// the number of outstanding requests | // the number of outstanding requests | |||
// that have exceeded the short timeout | // that have exceeded the short timeout | |||
// and are considered timed out in the | // and are considered timed out in the | |||
// sense that they increased the branch | // sense that they increased the branch | |||
// factor | // factor | |||
int first_timeout; | int first_timeout; | |||
}; | }; | |||
struct dht_routing_bucket | // holds dht routing table stats | |||
struct TORRENT_EXPORT dht_routing_bucket | ||||
{ | { | |||
// the total number of nodes and replacement nodes | ||||
// in the routing table | ||||
int num_nodes; | int num_nodes; | |||
int num_replacements; | int num_replacements; | |||
// number of seconds since last activity | // number of seconds since last activity | |||
int last_active; | int last_active; | |||
}; | }; | |||
#endif | // holds counters and gauges for the uTP sockets | |||
struct TORRENT_EXPORT utp_status | ||||
struct utp_status | ||||
{ | { | |||
// gauges. These are snapshots of the number of | ||||
// uTP sockets in each respective state | ||||
int num_idle; | int num_idle; | |||
int num_syn_sent; | int num_syn_sent; | |||
int num_connected; | int num_connected; | |||
int num_fin_sent; | int num_fin_sent; | |||
int num_close_wait; | int num_close_wait; | |||
// counters. These are monotonically increasing | ||||
// and cumulative counters for their respective event. | ||||
boost::uint64_t packet_loss; | ||||
boost::uint64_t timeout; | ||||
boost::uint64_t packets_in; | ||||
boost::uint64_t packets_out; | ||||
boost::uint64_t fast_retransmit; | ||||
boost::uint64_t packet_resend; | ||||
boost::uint64_t samples_above_target; | ||||
boost::uint64_t samples_below_target; | ||||
boost::uint64_t payload_pkts_in; | ||||
boost::uint64_t payload_pkts_out; | ||||
boost::uint64_t invalid_pkts_in; | ||||
boost::uint64_t redundant_pkts_in; | ||||
}; | }; | |||
// contains session wide state and counters | ||||
struct TORRENT_EXPORT session_status | struct TORRENT_EXPORT session_status | |||
{ | { | |||
// false as long as no incoming connections have been | ||||
// established on the listening socket. Every time you chang | ||||
e the listen port, this will | ||||
// be reset to false. | ||||
bool has_incoming_connections; | bool has_incoming_connections; | |||
// the total download and upload rates accumulated | ||||
// from all torrents. This includes bittorrent protocol, DHT | ||||
and an estimated TCP/IP | ||||
// protocol overhead. | ||||
int upload_rate; | int upload_rate; | |||
int download_rate; | int download_rate; | |||
// the total number of bytes downloaded and | ||||
// uploaded to and from all torrents. This also includes all | ||||
the protocol overhead. | ||||
size_type total_download; | size_type total_download; | |||
size_type total_upload; | size_type total_upload; | |||
// the rate of the payload | ||||
// down- and upload only. | ||||
int payload_upload_rate; | int payload_upload_rate; | |||
int payload_download_rate; | int payload_download_rate; | |||
// the total transfers of payload | ||||
// only. The payload does not include the bittorrent protoco | ||||
l overhead, but only parts of the | ||||
// actual files to be downloaded. | ||||
size_type total_payload_download; | size_type total_payload_download; | |||
size_type total_payload_upload; | size_type total_payload_upload; | |||
// the estimated TCP/IP overhead in each direction. | ||||
int ip_overhead_upload_rate; | int ip_overhead_upload_rate; | |||
int ip_overhead_download_rate; | int ip_overhead_download_rate; | |||
size_type total_ip_overhead_download; | size_type total_ip_overhead_download; | |||
size_type total_ip_overhead_upload; | size_type total_ip_overhead_upload; | |||
// the upload and download rate used by DHT traffic. Also th | ||||
e total number | ||||
// of bytes sent and received to and from the DHT. | ||||
int dht_upload_rate; | int dht_upload_rate; | |||
int dht_download_rate; | int dht_download_rate; | |||
size_type total_dht_download; | size_type total_dht_download; | |||
size_type total_dht_upload; | size_type total_dht_upload; | |||
// the upload and download rate used by tracker traffic. Als | ||||
o the total number | ||||
// of bytes sent and received to and from trackers. | ||||
int tracker_upload_rate; | int tracker_upload_rate; | |||
int tracker_download_rate; | int tracker_download_rate; | |||
size_type total_tracker_download; | size_type total_tracker_download; | |||
size_type total_tracker_upload; | size_type total_tracker_upload; | |||
// the number of bytes that has been received more than once | ||||
. | ||||
// This can happen if a request from a peer times out and is | ||||
requested from a different | ||||
// peer, and then received again from the first one. To make | ||||
this lower, increase the | ||||
// ``request_timeout`` and the ``piece_timeout`` in the sess | ||||
ion settings. | ||||
size_type total_redundant_bytes; | size_type total_redundant_bytes; | |||
// the number of bytes that was downloaded which later faile | ||||
d | ||||
// the hash-check. | ||||
size_type total_failed_bytes; | size_type total_failed_bytes; | |||
// the total number of peer connections this session has. Th | ||||
is includes | ||||
// incoming connections that still hasn't sent their handsha | ||||
ke or outgoing connections | ||||
// that still hasn't completed the TCP connection. This numb | ||||
er may be slightly higher | ||||
// than the sum of all peers of all torrents because the inc | ||||
oming connections may not | ||||
// be assigned a torrent yet. | ||||
int num_peers; | int num_peers; | |||
// the current number of unchoked peers. | ||||
int num_unchoked; | int num_unchoked; | |||
// the current allowed number of unchoked peers. | ||||
int allowed_upload_slots; | int allowed_upload_slots; | |||
// the number of peers that are | ||||
// waiting for more bandwidth quota from the torrent rate li | ||||
miter. | ||||
int up_bandwidth_queue; | int up_bandwidth_queue; | |||
int down_bandwidth_queue; | int down_bandwidth_queue; | |||
// count the number of | ||||
// bytes the connections are waiting for to be able to send | ||||
and receive. | ||||
int up_bandwidth_bytes_queue; | int up_bandwidth_bytes_queue; | |||
int down_bandwidth_bytes_queue; | int down_bandwidth_bytes_queue; | |||
// tells the number of | ||||
// seconds until the next optimistic unchoke change and the | ||||
start of the next | ||||
// unchoke interval. These numbers may be reset prematurely | ||||
if a peer that is | ||||
// unchoked disconnects or becomes notinterested. | ||||
int optimistic_unchoke_counter; | int optimistic_unchoke_counter; | |||
int unchoke_counter; | int unchoke_counter; | |||
// the number of peers currently | ||||
// waiting on a disk write or disk read to complete before i | ||||
t receives or sends | ||||
// any more data on the socket. It'a a metric of how disk bo | ||||
und you are. | ||||
int disk_write_queue; | int disk_write_queue; | |||
int disk_read_queue; | int disk_read_queue; | |||
#ifndef TORRENT_DISABLE_DHT | // only available when | |||
// built with DHT support. They are all set to 0 if the DHT | ||||
isn't running. When | ||||
// the DHT is running, ``dht_nodes`` is set to the number of | ||||
nodes in the routing | ||||
// table. This number only includes *active* nodes, not cach | ||||
e nodes. The | ||||
// ``dht_node_cache`` is set to the number of nodes in the n | ||||
ode cache. These nodes | ||||
// are used to replace the regular nodes in the routing tabl | ||||
e in case any of them | ||||
// becomes unresponsive. | ||||
int dht_nodes; | int dht_nodes; | |||
int dht_node_cache; | int dht_node_cache; | |||
// the number of torrents tracked by the DHT at the moment. | ||||
int dht_torrents; | int dht_torrents; | |||
// an estimation of the total number of nodes in the DHT | ||||
// network. | ||||
size_type dht_global_nodes; | size_type dht_global_nodes; | |||
// a vector of the currently running DHT lookups. | ||||
std::vector<dht_lookup> active_requests; | std::vector<dht_lookup> active_requests; | |||
// contains information about every bucket in the DHT routin | ||||
g | ||||
// table. | ||||
std::vector<dht_routing_bucket> dht_routing_table; | std::vector<dht_routing_bucket> dht_routing_table; | |||
// the number of nodes allocated dynamically for a | ||||
// particular DHT lookup. This represents roughly the amount | ||||
of memory used | ||||
// by the DHT. | ||||
int dht_total_allocations; | int dht_total_allocations; | |||
#endif | ||||
// statistics on the uTP sockets. | ||||
utp_status utp_stats; | utp_status utp_stats; | |||
// the number of known peers across all torrents. These are | ||||
not necessarily | ||||
// connected peers, just peers we know of. | ||||
int peerlist_size; | int peerlist_size; | |||
}; | }; | |||
} | } | |||
#endif // TORRENT_SESSION_STATUS_HPP_INCLUDED | #endif // TORRENT_SESSION_STATUS_HPP_INCLUDED | |||
End of changes. 43 change blocks. | ||||
10 lines changed or deleted | 154 lines changed or added | |||
settings.hpp | settings.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2010, Arvid Norberg | Copyright (c) 2010-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 44 | skipping to change at line 44 | |||
#define SETTINGS_HPP_INCLUDED | #define SETTINGS_HPP_INCLUDED | |||
#include "libtorrent/config.hpp" | #include "libtorrent/config.hpp" | |||
#include "libtorrent/session_settings.hpp" | #include "libtorrent/session_settings.hpp" | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
struct lazy_entry; | struct lazy_entry; | |||
class entry; | class entry; | |||
enum { std_string, character, integer | // internal | |||
, floating_point, boolean, size_integer | enum struct_field_type_t | |||
, time_integer }; | { | |||
std_string, character, integer, floating_point, | ||||
boolean, size_integer, time_integer, integer16 | ||||
}; | ||||
// this is used to map struct entries | // this is used to map struct entries | |||
// to names in a bencoded dictionary to | // to names in a bencoded dictionary to | |||
// save and load the struct | // save and load the struct | |||
struct bencode_map_entry | struct bencode_map_entry | |||
{ | { | |||
char const* name; | char const* name; | |||
int offset; // struct offset | int offset; // struct offset | |||
int type; | int type; | |||
}; | }; | |||
End of changes. 2 change blocks. | ||||
4 lines changed or deleted | 7 lines changed or added | |||
size_type.hpp | size_type.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2003, Arvid Norberg | Copyright (c) 2003-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
sliding_average.hpp | sliding_average.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2010, Arvid Norberg | Copyright (c) 2010-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
smart_ban.hpp | smart_ban.hpp | |||
---|---|---|---|---|
skipping to change at line 36 | skipping to change at line 36 | |||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 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 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||
POSSIBILITY OF SUCH DAMAGE. | POSSIBILITY OF SUCH DAMAGE. | |||
*/ | */ | |||
#ifndef TORRENT_SMART_BAN_HPP_INCLUDED | #ifndef TORRENT_SMART_BAN_HPP_INCLUDED | |||
#define TORRENT_SMART_BAN_HPP_INCLUDED | #define TORRENT_SMART_BAN_HPP_INCLUDED | |||
#ifndef TORRENT_DISABLE_EXTENSIONS | ||||
#ifdef _MSC_VER | #ifdef _MSC_VER | |||
#pragma warning(push, 1) | #pragma warning(push, 1) | |||
#endif | #endif | |||
#include <boost/shared_ptr.hpp> | #include <boost/shared_ptr.hpp> | |||
#include "libtorrent/config.hpp" | #include "libtorrent/config.hpp" | |||
#ifdef _MSC_VER | #ifdef _MSC_VER | |||
#pragma warning(pop) | #pragma warning(pop) | |||
#endif | #endif | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
struct torrent_plugin; | struct torrent_plugin; | |||
class torrent; | class torrent; | |||
// constructor function for the smart ban extension. The extension k | ||||
eeps | ||||
// track of the data peers have sent us for failing pieces and once | ||||
the | ||||
// piece completes and passes the hash check bans the peers that tur | ||||
ned | ||||
// out to have sent corrupt data. | ||||
// This function can either be passed in the add_torrent_params::ext | ||||
ensions | ||||
// field, or via torrent_handle::add_extension(). | ||||
TORRENT_EXPORT boost::shared_ptr<torrent_plugin> create_smart_ban_pl ugin(torrent*, void*); | TORRENT_EXPORT boost::shared_ptr<torrent_plugin> create_smart_ban_pl ugin(torrent*, void*); | |||
} | } | |||
#endif // TORRENT_DISABLE_EXTENSIONS | ||||
#endif // TORRENT_SMART_BAN_HPP_INCLUDED | #endif // TORRENT_SMART_BAN_HPP_INCLUDED | |||
End of changes. 3 change blocks. | ||||
0 lines changed or deleted | 15 lines changed or added | |||
socket.hpp | socket.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2003, Arvid Norberg | Copyright (c) 2003-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
socket_io.hpp | socket_io.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2009, Arvid Norberg | Copyright (c) 2009-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 41 | skipping to change at line 41 | |||
*/ | */ | |||
#ifndef TORRENT_SOCKET_IO_HPP_INCLUDED | #ifndef TORRENT_SOCKET_IO_HPP_INCLUDED | |||
#define TORRENT_SOCKET_IO_HPP_INCLUDED | #define TORRENT_SOCKET_IO_HPP_INCLUDED | |||
#include "libtorrent/socket.hpp" | #include "libtorrent/socket.hpp" | |||
#include "libtorrent/address.hpp" | #include "libtorrent/address.hpp" | |||
#include "libtorrent/io.hpp" | #include "libtorrent/io.hpp" | |||
#include "libtorrent/error_code.hpp" | #include "libtorrent/error_code.hpp" | |||
#include "libtorrent/lazy_entry.hpp" | #include "libtorrent/lazy_entry.hpp" | |||
#include "libtorrent/bencode.hpp" | ||||
#include "libtorrent/peer_id.hpp" // for sha1_hash | #include "libtorrent/peer_id.hpp" // for sha1_hash | |||
#include <string> | #include <string> | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
TORRENT_EXPORT std::string print_address(address const& addr); | TORRENT_EXTRA_EXPORT std::string print_address(address const& addr); | |||
TORRENT_EXPORT std::string print_endpoint(tcp::endpoint const& ep); | TORRENT_EXTRA_EXPORT std::string print_endpoint(tcp::endpoint const& | |||
TORRENT_EXPORT std::string print_endpoint(udp::endpoint const& ep); | ep); | |||
TORRENT_EXPORT std::string address_to_bytes(address const& a); | TORRENT_EXTRA_EXPORT std::string print_endpoint(udp::endpoint const& | |||
ep); | ||||
TORRENT_EXTRA_EXPORT std::string address_to_bytes(address const& a); | ||||
// internal | ||||
TORRENT_EXPORT std::string endpoint_to_bytes(udp::endpoint const& ep ); | TORRENT_EXPORT std::string endpoint_to_bytes(udp::endpoint const& ep ); | |||
TORRENT_EXTRA_EXPORT void hash_address(address const& ip, sha1_hash& h); | TORRENT_EXTRA_EXPORT void hash_address(address const& ip, sha1_hash& h); | |||
namespace detail | namespace detail | |||
{ | { | |||
template<class OutIt> | template<class OutIt> | |||
void write_address(address const& a, OutIt& out) | void write_address(address const& a, OutIt& out) | |||
{ | { | |||
#if TORRENT_USE_IPV6 | #if TORRENT_USE_IPV6 | |||
if (a.is_v4()) | if (a.is_v4()) | |||
skipping to change at line 140 | skipping to change at line 142 | |||
if (e->string_length() < 6) continue; | if (e->string_length() < 6) continue; | |||
char const* in = e->string_ptr(); | char const* in = e->string_ptr(); | |||
if (e->string_length() == 6) | if (e->string_length() == 6) | |||
epl.push_back(read_v4_endpoint<Endpo intType>(in)); | epl.push_back(read_v4_endpoint<Endpo intType>(in)); | |||
#if TORRENT_USE_IPV6 | #if TORRENT_USE_IPV6 | |||
else if (e->string_length() == 18) | else if (e->string_length() == 18) | |||
epl.push_back(read_v6_endpoint<Endpo intType>(in)); | epl.push_back(read_v6_endpoint<Endpo intType>(in)); | |||
#endif | #endif | |||
} | } | |||
} | } | |||
} | ||||
template <class EndpointType> | ||||
void read_endpoint_list(libtorrent::entry const* n, std::vector<Endp | ||||
ointType>& epl) | ||||
{ | ||||
using namespace libtorrent; | ||||
if (n->type() != entry::list_t) return; | ||||
entry::list_type const& contacts = n->list(); | ||||
for (entry::list_type::const_iterator i = contacts.begin() | ||||
, end(contacts.end()); i != end; ++i) | ||||
{ | ||||
if (i->type() != entry::string_t) return; | ||||
std::string const& p = i->string(); | ||||
if (p.size() < 6) continue; | ||||
std::string::const_iterator in = p.begin(); | ||||
if (p.size() == 6) | ||||
epl.push_back(detail::read_v4_endpoint<Endpo | ||||
intType>(in)); | ||||
#if TORRENT_USE_IPV6 | ||||
else if (p.size() == 18) | ||||
epl.push_back(detail::read_v6_endpoint<Endpo | ||||
intType>(in)); | ||||
#endif | ||||
} | ||||
} | } | |||
} | } | |||
#endif | #endif | |||
End of changes. 5 change blocks. | ||||
5 lines changed or deleted | 33 lines changed or added | |||
socket_type.hpp | socket_type.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2009, Arvid Norberg | Copyright (c) 2009-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 54 | skipping to change at line 54 | |||
#include "libtorrent/assert.hpp" | #include "libtorrent/assert.hpp" | |||
#ifdef TORRENT_USE_OPENSSL | #ifdef TORRENT_USE_OPENSSL | |||
#include "libtorrent/ssl_stream.hpp" | #include "libtorrent/ssl_stream.hpp" | |||
#endif | #endif | |||
#if defined TORRENT_ASIO_DEBUGGING | #if defined TORRENT_ASIO_DEBUGGING | |||
#include "libtorrent/debug.hpp" | #include "libtorrent/debug.hpp" | |||
#endif | #endif | |||
#if defined TORRENT_OS2 && defined ioc | ||||
#undef ioc | ||||
#endif | ||||
#if TORRENT_USE_I2P | #if TORRENT_USE_I2P | |||
#define TORRENT_SOCKTYPE_I2P_FORWARD(x) \ | #define TORRENT_SOCKTYPE_I2P_FORWARD(x) \ | |||
case socket_type_int_impl<i2p_stream>::value: \ | case socket_type_int_impl<i2p_stream>::value: \ | |||
get<i2p_stream>()->x; break; | get<i2p_stream>()->x; break; | |||
#define TORRENT_SOCKTYPE_I2P_FORWARD_RET(x, def) \ | #define TORRENT_SOCKTYPE_I2P_FORWARD_RET(x, def) \ | |||
case socket_type_int_impl<i2p_stream>::value: \ | case socket_type_int_impl<i2p_stream>::value: \ | |||
return get<i2p_stream>()->x; | return get<i2p_stream>()->x; | |||
skipping to change at line 251 | skipping to change at line 255 | |||
#ifndef BOOST_NO_EXCEPTIONS | #ifndef BOOST_NO_EXCEPTIONS | |||
template <class SettableSocketOption> | template <class SettableSocketOption> | |||
void set_option(SettableSocketOption const& opt) | void set_option(SettableSocketOption const& opt) | |||
{ TORRENT_SOCKTYPE_FORWARD(set_option(opt)) } | { TORRENT_SOCKTYPE_FORWARD(set_option(opt)) } | |||
#endif | #endif | |||
template <class SettableSocketOption> | template <class SettableSocketOption> | |||
error_code set_option(SettableSocketOption const& opt, error _code& ec) | error_code set_option(SettableSocketOption const& opt, error _code& ec) | |||
{ TORRENT_SOCKTYPE_FORWARD_RET(set_option(opt, ec), ec) } | { TORRENT_SOCKTYPE_FORWARD_RET(set_option(opt, ec), ec) } | |||
#ifndef BOOST_NO_EXCEPTIONS | ||||
template <class GettableSocketOption> | ||||
void get_option(GettableSocketOption& opt) | ||||
{ TORRENT_SOCKTYPE_FORWARD(get_option(opt)) } | ||||
#endif | ||||
template <class GettableSocketOption> | ||||
error_code get_option(GettableSocketOption& opt, error_code& | ||||
ec) | ||||
{ TORRENT_SOCKTYPE_FORWARD_RET(get_option(opt, ec), ec) } | ||||
template <class S> | template <class S> | |||
void instantiate(io_service& ios, void* userdata = 0) | void instantiate(io_service& ios, void* userdata = 0) | |||
{ | { | |||
TORRENT_ASSERT(&ios == &m_io_service); | TORRENT_ASSERT(&ios == &m_io_service); | |||
construct(socket_type_int_impl<S>::value, userdata); | construct(socket_type_int_impl<S>::value, userdata); | |||
} | } | |||
template <class S> S* get() | template <class S> S* get() | |||
{ | { | |||
if (m_type != socket_type_int_impl<S>::value) return 0; | if (m_type != socket_type_int_impl<S>::value) return 0; | |||
End of changes. 3 change blocks. | ||||
1 lines changed or deleted | 16 lines changed or added | |||
socket_type_fwd.hpp | socket_type_fwd.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2009, Arvid Norberg | Copyright (c) 2009-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
socks5_stream.hpp | socks5_stream.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2007, Arvid Norberg | Copyright (c) 2007-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 40 | skipping to change at line 40 | |||
*/ | */ | |||
#ifndef TORRENT_SOCKS5_STREAM_HPP_INCLUDED | #ifndef TORRENT_SOCKS5_STREAM_HPP_INCLUDED | |||
#define TORRENT_SOCKS5_STREAM_HPP_INCLUDED | #define TORRENT_SOCKS5_STREAM_HPP_INCLUDED | |||
#include <boost/function/function1.hpp> | #include <boost/function/function1.hpp> | |||
#include <boost/bind.hpp> | #include <boost/bind.hpp> | |||
#include <boost/shared_ptr.hpp> | #include <boost/shared_ptr.hpp> | |||
#include "libtorrent/proxy_base.hpp" | #include "libtorrent/proxy_base.hpp" | |||
#if defined TORRENT_ASIO_DEBUGGING | ||||
#include "libtorrent/debug.hpp" | ||||
#endif | ||||
namespace libtorrent { | namespace libtorrent { | |||
namespace socks_error { | ||||
namespace socks_error { | // SOCKS5 error values. If an error_code has the | |||
// socks error category (get_socks_category()), these | ||||
enum socks_error_code | // are the error values. | |||
{ | enum socks_error_code | |||
no_error = 0, | { | |||
unsupported_version, | no_error = 0, | |||
unsupported_authentication_method, | unsupported_version, | |||
unsupported_authentication_version, | unsupported_authentication_method, | |||
authentication_error, | unsupported_authentication_version, | |||
username_required, | authentication_error, | |||
general_failure, | username_required, | |||
command_not_supported, | general_failure, | |||
no_identd, | command_not_supported, | |||
identd_error, | no_identd, | |||
identd_error, | ||||
num_errors | ||||
}; | ||||
} | ||||
#if BOOST_VERSION < 103500 | num_errors | |||
typedef asio::error::error_category socks_error_category; | }; | |||
#else | ||||
struct TORRENT_EXTRA_EXPORT socks_error_category : boost::system::error_cat | TORRENT_EXPORT boost::system::error_code make_error_code(socks_error | |||
egory | _code e); | |||
{ | } // namespace socks_error | |||
virtual const char* name() const BOOST_SYSTEM_NOEXCEPT; | ||||
virtual std::string message(int ev) const BOOST_SYSTEM_NOEXCEPT; | ||||
virtual boost::system::error_condition default_error_condition(int e | ||||
v) const BOOST_SYSTEM_NOEXCEPT | ||||
{ return boost::system::error_condition(ev, *this); } | ||||
}; | ||||
#endif | // returns the error_category for SOCKS5 errors | |||
TORRENT_EXPORT boost::system::error_category& get_socks_category(); | ||||
extern socks_error_category socks_category; | ||||
class socks5_stream : public proxy_base | class socks5_stream : public proxy_base | |||
{ | { | |||
public: | public: | |||
explicit socks5_stream(io_service& io_service) | explicit socks5_stream(io_service& io_service) | |||
: proxy_base(io_service) | : proxy_base(io_service) | |||
, m_version(5) | , m_version(5) | |||
, m_command(1) | , m_command(1) | |||
, m_listen(0) | , m_listen(0) | |||
skipping to change at line 145 | skipping to change at line 139 | |||
// 3. if version == 5: | // 3. if version == 5: | |||
// 3.1 send SOCKS5 authentication method message | // 3.1 send SOCKS5 authentication method message | |||
// 3.2 read SOCKS5 authentication response | // 3.2 read SOCKS5 authentication response | |||
// 3.3 send username+password | // 3.3 send username+password | |||
// 4. send SOCKS command message | // 4. send SOCKS command message | |||
// to avoid unnecessary copying of the handler, | // to avoid unnecessary copying of the handler, | |||
// store it in a shaed_ptr | // store it in a shaed_ptr | |||
boost::shared_ptr<handler_type> h(new handler_type(handler)) ; | boost::shared_ptr<handler_type> h(new handler_type(handler)) ; | |||
#if defined TORRENT_ASIO_DEBUGGING | ||||
add_outstanding_async("socks5_stream::name_lookup"); | ||||
#endif | ||||
tcp::resolver::query q(m_hostname, to_string(m_port).elems); | tcp::resolver::query q(m_hostname, to_string(m_port).elems); | |||
m_resolver.async_resolve(q, boost::bind( | m_resolver.async_resolve(q, boost::bind( | |||
&socks5_stream::name_lookup, this, _1, _2, h)); | &socks5_stream::name_lookup, this, _1, _2, h)); | |||
} | } | |||
private: | private: | |||
void name_lookup(error_code const& e, tcp::resolver::iterator i | void name_lookup(error_code const& e, tcp::resolver::iterator i | |||
, boost::shared_ptr<handler_type> h); | , boost::shared_ptr<handler_type> h); | |||
void connected(error_code const& e, boost::shared_ptr<handler_type> h); | void connected(error_code const& e, boost::shared_ptr<handler_type> h); | |||
skipping to change at line 179 | skipping to change at line 176 | |||
std::string m_dst_name; | std::string m_dst_name; | |||
int m_version; | int m_version; | |||
int m_command; | int m_command; | |||
// set to one when we're waiting for the | // set to one when we're waiting for the | |||
// second message to accept an incoming connection | // second message to accept an incoming connection | |||
int m_listen; | int m_listen; | |||
}; | }; | |||
} | } | |||
#if BOOST_VERSION >= 103500 | ||||
namespace boost { namespace system { | ||||
template<> struct is_error_code_enum<libtorrent::socks_error::socks_ | ||||
error_code> | ||||
{ static const bool value = true; }; | ||||
template<> struct is_error_condition_enum<libtorrent::socks_error::s | ||||
ocks_error_code> | ||||
{ static const bool value = true; }; | ||||
} } | ||||
#endif // BOOST_VERSION | ||||
#endif | #endif | |||
End of changes. 9 change blocks. | ||||
34 lines changed or deleted | 45 lines changed or added | |||
ssl_stream.hpp | ssl_stream.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2008, Arvid Norberg | Copyright (c) 2008-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 150 | skipping to change at line 150 | |||
} | } | |||
#endif | #endif | |||
template <class SettableSocketOption> | template <class SettableSocketOption> | |||
error_code set_option(SettableSocketOption const& opt, error_code& e c) | error_code set_option(SettableSocketOption const& opt, error_code& e c) | |||
{ | { | |||
return m_sock.next_layer().set_option(opt, ec); | return m_sock.next_layer().set_option(opt, ec); | |||
} | } | |||
#ifndef BOOST_NO_EXCEPTIONS | #ifndef BOOST_NO_EXCEPTIONS | |||
template <class GettableSocketOption> | ||||
void get_option(GettableSocketOption& opt) | ||||
{ | ||||
m_sock.next_layer().get_option(opt); | ||||
} | ||||
#endif | ||||
template <class GettableSocketOption> | ||||
error_code get_option(GettableSocketOption& opt, error_code& ec) | ||||
{ | ||||
return m_sock.next_layer().get_option(opt, ec); | ||||
} | ||||
#ifndef BOOST_NO_EXCEPTIONS | ||||
template <class Mutable_Buffers> | template <class Mutable_Buffers> | |||
std::size_t read_some(Mutable_Buffers const& buffers) | std::size_t read_some(Mutable_Buffers const& buffers) | |||
{ | { | |||
return m_sock.read_some(buffers); | return m_sock.read_some(buffers); | |||
} | } | |||
template <class IO_Control_Command> | template <class IO_Control_Command> | |||
void io_control(IO_Control_Command& ioc) | void io_control(IO_Control_Command& ioc) | |||
{ | { | |||
m_sock.next_layer().io_control(ioc); | m_sock.next_layer().io_control(ioc); | |||
End of changes. 2 change blocks. | ||||
1 lines changed or deleted | 15 lines changed or added | |||
stat.hpp | stat.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2003, Arvid Norberg | Copyright (c) 2003-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 46 | skipping to change at line 46 | |||
#include <algorithm> | #include <algorithm> | |||
#include <vector> | #include <vector> | |||
#include <assert.h> | #include <assert.h> | |||
#include <cstring> | #include <cstring> | |||
#include "libtorrent/size_type.hpp" | #include "libtorrent/size_type.hpp" | |||
#include "libtorrent/invariant_check.hpp" | #include "libtorrent/invariant_check.hpp" | |||
#include "libtorrent/config.hpp" | #include "libtorrent/config.hpp" | |||
#include "libtorrent/assert.hpp" | #include "libtorrent/assert.hpp" | |||
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T | ||||
ORRENT_ERROR_LOGGING | ||||
#include "libtorrent/debug.hpp" // for logger | ||||
#endif | ||||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
class TORRENT_EXTRA_EXPORT stat_channel | class TORRENT_EXTRA_EXPORT stat_channel | |||
{ | { | |||
public: | public: | |||
stat_channel() | stat_channel() | |||
: m_counter(0) | : m_counter(0) | |||
, m_5_sec_average(0) | , m_5_sec_average(0) | |||
, m_30_sec_average(0) | , m_30_sec_average(0) | |||
skipping to change at line 117 | skipping to change at line 113 | |||
private: | private: | |||
// the accumulator for this second. | // the accumulator for this second. | |||
int m_counter; | int m_counter; | |||
// sliding average | // sliding average | |||
int m_5_sec_average; | int m_5_sec_average; | |||
int m_30_sec_average; | int m_30_sec_average; | |||
// TODO: this is 4 bytes of padding! | ||||
// total counters | // total counters | |||
size_type m_total_counter; | size_type m_total_counter; | |||
}; | }; | |||
class TORRENT_EXTRA_EXPORT stat | class TORRENT_EXTRA_EXPORT stat | |||
{ | { | |||
friend class invariant_access; | friend class invariant_access; | |||
public: | public: | |||
void operator+=(const stat& s) | void operator+=(const stat& s) | |||
{ | { | |||
End of changes. 3 change blocks. | ||||
6 lines changed or deleted | 3 lines changed or added | |||
storage.hpp | storage.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2003, Arvid Norberg | Copyright (c) 2003-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 66 | skipping to change at line 66 | |||
#include "libtorrent/peer_request.hpp" | #include "libtorrent/peer_request.hpp" | |||
#include "libtorrent/hasher.hpp" | #include "libtorrent/hasher.hpp" | |||
#include "libtorrent/config.hpp" | #include "libtorrent/config.hpp" | |||
#include "libtorrent/file.hpp" | #include "libtorrent/file.hpp" | |||
#include "libtorrent/disk_buffer_holder.hpp" | #include "libtorrent/disk_buffer_holder.hpp" | |||
#include "libtorrent/thread.hpp" | #include "libtorrent/thread.hpp" | |||
#include "libtorrent/storage_defs.hpp" | #include "libtorrent/storage_defs.hpp" | |||
#include "libtorrent/allocator.hpp" | #include "libtorrent/allocator.hpp" | |||
#include "libtorrent/bitfield.hpp" | #include "libtorrent/bitfield.hpp" | |||
// OVERVIEW | ||||
// | ||||
// libtorrent provides a customization point for storage of data. By defaul | ||||
t, | ||||
// (``default_storage``) downloaded files are saved to disk according with | ||||
the | ||||
// general conventions of bittorrent clients, mimicing the original file la | ||||
yout | ||||
// when the torrent was created. The libtorrent user may define a custom | ||||
// storage to store piece data in a different way. | ||||
// | ||||
// A custom storage implementation must derive from and implement the | ||||
// storage_interface. You must also provide a function that constructs the | ||||
// custom storage object and provide this function to the add_torrent() cal | ||||
l | ||||
// via add_torrent_params. Either passed in to the constructor or by settin | ||||
g | ||||
// the add_torrent_params::storage field. | ||||
// | ||||
// This is an example storage implementation that stores all pieces in a | ||||
// ``std::map``, i.e. in RAM. It's not necessarily very useful in practice, | ||||
but | ||||
// illustrates the basics of implementing a custom storage. | ||||
// | ||||
//:: | ||||
// | ||||
// struct temp_storage : storage_interface | ||||
// { | ||||
// temp_storage(file_storage const& fs) : m_files(fs) {} | ||||
// void set_file_priority(std::vector<boost::uint8_t> const& pr | ||||
io) {} | ||||
// virtual bool initialize(bool allocate_files) { return false; | ||||
} | ||||
// virtual bool has_any_file() { return false; } | ||||
// virtual int read(char* buf, int slot, int offset, int size) | ||||
// { | ||||
// std::map<int, std::vector<char> >::const_iterator i | ||||
= m_file_data.find(slot); | ||||
// if (i == m_file_data.end()) return 0; | ||||
// int available = i->second.size() - offset; | ||||
// if (available <= 0) return 0; | ||||
// if (available > size) available = size; | ||||
// memcpy(buf, &i->second[offset], available); | ||||
// return available; | ||||
// } | ||||
// virtual int write(const char* buf, int slot, int offset, int | ||||
size) | ||||
// { | ||||
// std::vector<char>& data = m_file_data[slot]; | ||||
// if (data.size() < offset + size) data.resize(offset | ||||
+ size); | ||||
// std::memcpy(&data[offset], buf, size); | ||||
// return size; | ||||
// } | ||||
// virtual bool rename_file(int file, std::string const& new_na | ||||
me) | ||||
// { assert(false); return false; } | ||||
// virtual bool move_storage(std::string const& save_path) { re | ||||
turn false; } | ||||
// virtual bool verify_resume_data(lazy_entry const& rd, error_ | ||||
code& error) { return false; } | ||||
// virtual bool write_resume_data(entry& rd) const { return fal | ||||
se; } | ||||
// virtual bool move_slot(int src_slot, int dst_slot) { assert( | ||||
false); return false; } | ||||
// virtual bool swap_slots(int slot1, int slot2) { assert(false | ||||
); return false; } | ||||
// virtual bool swap_slots3(int slot1, int slot2, int slot3) { | ||||
assert(false); return false; } | ||||
// virtual size_type physical_offset(int slot, int offset) | ||||
// { return slot * m_files.piece_length() + offset; }; | ||||
// virtual sha1_hash hash_for_slot(int slot, partial_hash& ph, | ||||
int piece_size) | ||||
// { | ||||
// int left = piece_size - ph.offset; | ||||
// assert(left >= 0); | ||||
// if (left > 0) | ||||
// { | ||||
// std::vector<char>& data = m_file_data[slot]; | ||||
// // if there are padding files, those blocks | ||||
will be considered | ||||
// // completed even though they haven't been w | ||||
ritten to the storage. | ||||
// // in this case, just extend the piece buffe | ||||
r to its full size | ||||
// // and fill it with zeroes. | ||||
// if (data.size() < piece_size) data.resize(pi | ||||
ece_size, 0); | ||||
// ph.h.update(&data[ph.offset], left); | ||||
// } | ||||
// return ph.h.final(); | ||||
// } | ||||
// virtual bool release_files() { return false; } | ||||
// virtual bool delete_files() { return false; } | ||||
// | ||||
// std::map<int, std::vector<char> > m_file_data; | ||||
// file_storage m_files; | ||||
// }; | ||||
// | ||||
// storage_interface* temp_storage_constructor( | ||||
// file_storage const& fs, file_storage const* mapped | ||||
// , std::string const& path, file_pool& fp | ||||
// , std::vector<boost::uint8_t> const& prio) | ||||
// { | ||||
// return new temp_storage(fs); | ||||
// } | ||||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
class session; | class session; | |||
struct file_pool; | struct file_pool; | |||
struct disk_io_job; | struct disk_io_job; | |||
struct disk_buffer_pool; | struct disk_buffer_pool; | |||
struct session_settings; | struct session_settings; | |||
TORRENT_EXTRA_EXPORT std::vector<std::pair<size_type, std::time_t> > get_filesizes( | TORRENT_EXTRA_EXPORT std::vector<std::pair<size_type, std::time_t> > get_filesizes( | |||
file_storage const& t | file_storage const& t | |||
, std::string const& p); | , std::string const& p); | |||
TORRENT_EXTRA_EXPORT bool match_filesizes( | TORRENT_EXTRA_EXPORT bool match_filesizes( | |||
file_storage const& t | file_storage const& t | |||
, std::string const& p | , std::string const& p | |||
, std::vector<std::pair<size_type, std::time_t> > const& siz es | , std::vector<std::pair<size_type, std::time_t> > const& siz es | |||
, bool compact_mode | , bool compact_mode | |||
, std::string* error = 0); | , std::string* error = 0); | |||
/* | ||||
struct TORRENT_EXTRA_EXPORT file_allocation_failed: std::exception | ||||
{ | ||||
file_allocation_failed(const char* error_msg): m_msg(error_m | ||||
sg) {} | ||||
virtual const char* what() const throw() { return m_msg.c_st | ||||
r(); } | ||||
virtual ~file_allocation_failed() throw() {} | ||||
std::string m_msg; | ||||
}; | ||||
*/ | ||||
struct TORRENT_EXTRA_EXPORT partial_hash | struct TORRENT_EXTRA_EXPORT partial_hash | |||
{ | { | |||
partial_hash(): offset(0) {} | partial_hash(): offset(0) {} | |||
// the number of bytes in the piece that has been hashed | // the number of bytes in the piece that has been hashed | |||
int offset; | int offset; | |||
// the sha-1 context | // the sha-1 context | |||
hasher h; | hasher h; | |||
}; | }; | |||
// The storage interface is a pure virtual class that can be impleme | ||||
nted to | ||||
// customize how and where data for a torrent is stored. The default | ||||
storage | ||||
// implementation uses regular files in the filesystem, mapping the | ||||
files in | ||||
// the torrent in the way one would assume a torrent is saved to dis | ||||
k. | ||||
// Implementing your own storage interface makes it possible to stor | ||||
e all | ||||
// data in RAM, or in some optimized order on disk (the order the pi | ||||
eces are | ||||
// received for instance), or saving multifile torrents in a single | ||||
file in | ||||
// order to be able to take advantage of optimized disk-I/O. | ||||
// | ||||
// It is also possible to write a thin class that uses the default s | ||||
torage | ||||
// but modifies some particular behavior, for instance encrypting th | ||||
e data | ||||
// before it's written to disk, and decrypting it when it's read aga | ||||
in. | ||||
// | ||||
// The storage interface is based on slots, each slot is 'piece_size | ||||
' number | ||||
// of bytes. All access is done by writing and reading whole or part | ||||
ial | ||||
// slots. One slot is one piece in the torrent, but the data in the | ||||
slot | ||||
// does not necessarily correspond to the piece with the same index | ||||
(in | ||||
// compact allocation mode it won't). | ||||
// | ||||
// libtorrent comes with two built-in storage implementations; | ||||
// ``default_storage`` and ``disabled_storage``. Their constructor f | ||||
unctions | ||||
// are called default_storage_constructor() and | ||||
// ``disabled_storage_constructor`` respectively. The disabled stora | ||||
ge does | ||||
// just what it sounds like. It throws away data that's written, and | ||||
it | ||||
// reads garbage. It's useful mostly for benchmarking and profiling | ||||
purpose. | ||||
// | ||||
struct TORRENT_EXPORT storage_interface | struct TORRENT_EXPORT storage_interface | |||
{ | { | |||
// hidden | ||||
storage_interface(): m_disk_pool(0), m_settings(0) {} | storage_interface(): m_disk_pool(0), m_settings(0) {} | |||
// create directories and set file sizes | ||||
// if allocate_files is true. | // This function is called when the storage is to be initial | |||
// allocate_files is true if allocation mode | ized. The | |||
// is set to full and sparse files are supported | // default storage will create directories and empty files a | |||
// false return value indicates an error | t this point. | |||
// If ``allocate_files`` is true, it will also ``ftruncate`` | ||||
all files to | ||||
// their target size. | ||||
// | ||||
// Returning ``true`` indicates an error occurred. | ||||
virtual bool initialize(bool allocate_files) = 0; | virtual bool initialize(bool allocate_files) = 0; | |||
// This function is called when first checking (or re-checki | ||||
ng) the | ||||
// storage for a torrent. It should return true if any of th | ||||
e files that | ||||
// is used in this storage exists on disk. If so, the storag | ||||
e will be | ||||
// checked for existing pieces before starting the download. | ||||
virtual bool has_any_file() = 0; | virtual bool has_any_file() = 0; | |||
// change the priorities of files. | ||||
virtual void set_file_priority(std::vector<boost::uint8_t> c | ||||
onst& prio) = 0; | ||||
// These functions should read or write the data in or to th | ||||
e given | ||||
// ``slot`` at the given ``offset``. It should read or write | ||||
``num_bufs`` | ||||
// buffers sequentially, where the size of each buffer is sp | ||||
ecified in | ||||
// the buffer array ``bufs``. The file::iovec_t type has the | ||||
following | ||||
// members:: | ||||
// | ||||
// struct iovec_t { void* iov_base; size_t iov_len; }; | ||||
// | ||||
// The return value is the number of bytes actually read or | ||||
written, or | ||||
// -1 on failure. If it returns -1, the error code is expect | ||||
ed to be set | ||||
// to | ||||
// | ||||
// Every buffer in ``bufs`` can be assumed to be page aligne | ||||
d and be of a | ||||
// page aligned size, except for the last buffer of the torr | ||||
ent. The | ||||
// allocated buffer can be assumed to fit a fully page align | ||||
ed number of | ||||
// bytes though. This is useful when reading and writing the | ||||
last piece | ||||
// of a file in unbuffered mode. | ||||
// | ||||
// The ``offset`` is aligned to 16 kiB boundries *most of t | ||||
he time*, but | ||||
// there are rare exceptions when it's not. Specifically if | ||||
the read | ||||
// cache is disabled/or full and a client requests unaligned | ||||
data, or the | ||||
// file itself is not aligned in the torrent. Most clients r | ||||
equest | ||||
// aligned data. | ||||
virtual int readv(file::iovec_t const* bufs, int slot, int o ffset, int num_bufs, int flags = file::random_access); | virtual int readv(file::iovec_t const* bufs, int slot, int o ffset, int num_bufs, int flags = file::random_access); | |||
virtual int writev(file::iovec_t const* bufs, int slot, int offset, int num_bufs, int flags = file::random_access); | virtual int writev(file::iovec_t const* bufs, int slot, int offset, int num_bufs, int flags = file::random_access); | |||
virtual void hint_read(int slot, int offset, int len) {} | // This function is called when a read job is queued. It giv | |||
es the | ||||
// storage wrapper an opportunity to hint the operating syst | ||||
em about this | ||||
// coming read. For instance, the storage may call | ||||
// ``posix_fadvise(POSIX_FADV_WILLNEED)`` or ``fcntl(F_RDADV | ||||
ISE)``. | ||||
virtual void hint_read(int, int, int) {} | ||||
// negative return value indicates an error | // negative return value indicates an error | |||
virtual int read(char* buf, int slot, int offset, int size) = 0; | virtual int read(char* buf, int slot, int offset, int size) = 0; | |||
// negative return value indicates an error | // negative return value indicates an error | |||
virtual int write(const char* buf, int slot, int offset, int size) = 0; | virtual int write(const char* buf, int slot, int offset, int size) = 0; | |||
// returns the offset on the physical storage medium for the | ||||
// byte at offset ``offset`` in slot ``slot``. | ||||
virtual size_type physical_offset(int slot, int offset) = 0; | virtual size_type physical_offset(int slot, int offset) = 0; | |||
// returns the end of the sparse region the slot 'start' | // This function is optional. It is supposed to return the f | |||
// resides in i.e. the next slot with content. If start | irst piece, | |||
// is not in a sparse region, start itself is returned | // starting at ``start`` that is fully contained within a da | |||
ta-region on | ||||
// disk (i.e. non-sparse region). The purpose of this is to | ||||
skip parts of | ||||
// files that can be known to contain zeros when checking fi | ||||
les. | ||||
virtual int sparse_end(int start) const { return start; } | virtual int sparse_end(int start) const { return start; } | |||
// non-zero return value indicates an error | // This function should move all the files belonging to the | |||
virtual bool move_storage(std::string const& save_path) = 0; | storage to | |||
// the new save_path. The default storage moves the single f | ||||
// verify storage dependent fast resume entries | ile or the | |||
// directory of the torrent. | ||||
// | ||||
// Before moving the files, any open file handles may have t | ||||
o be closed, | ||||
// like ``release_files()``. | ||||
// | ||||
// returns one of: | ||||
// | no_error = 0 | ||||
// | need_full_check = -1 | ||||
// | fatal_disk_error = -2 | ||||
// | file_exist = -4 | ||||
virtual int move_storage(std::string const& save_path, int f | ||||
lags) = 0; | ||||
// This function should verify the resume data ``rd`` with t | ||||
he files | ||||
// on disk. If the resume data seems to be up-to-date, retur | ||||
n true. If | ||||
// not, set ``error`` to a description of what mismatched an | ||||
d return false. | ||||
// | ||||
// The default storage may compare file sizes and time stamp | ||||
s of the files. | ||||
// | ||||
// Returning ``false`` indicates an error occurred. | ||||
virtual bool verify_resume_data(lazy_entry const& rd, error_ code& error) = 0; | virtual bool verify_resume_data(lazy_entry const& rd, error_ code& error) = 0; | |||
// write storage dependent fast resume entries | // This function should fill in resume data, the current sta | |||
te of the | ||||
// storage, in ``rd``. The default storage adds file timesta | ||||
mps and | ||||
// sizes. | ||||
// | ||||
// Returning ``true`` indicates an error occurred. | ||||
virtual bool write_resume_data(entry& rd) const = 0; | virtual bool write_resume_data(entry& rd) const = 0; | |||
// moves (or copies) the content in src_slot to dst_slot | // This function should copy or move the data in slot ``src_ | |||
slot`` to | ||||
// the slot ``dst_slot``. This is only used in compact mode. | ||||
// | ||||
// If the storage caches slots, this could be implemented mo | ||||
re | ||||
// efficient than reading and writing the data. | ||||
// | ||||
// Returning ``true`` indicates an error occurred. | ||||
virtual bool move_slot(int src_slot, int dst_slot) = 0; | virtual bool move_slot(int src_slot, int dst_slot) = 0; | |||
// swaps the data in slot1 and slot2 | // This function should swap the data in ``slot1`` and ``slo | |||
t2``. The | ||||
// default storage uses a scratch buffer to read the data in | ||||
to, then | ||||
// moving the other slot and finally writing back the tempor | ||||
ary slot's | ||||
// data | ||||
// | ||||
// This is only used in compact mode. | ||||
// | ||||
// Returning ``true`` indicates an error occurred. | ||||
virtual bool swap_slots(int slot1, int slot2) = 0; | virtual bool swap_slots(int slot1, int slot2) = 0; | |||
// swaps the puts the data in slot1 in slot2, the data in sl | // This function should do a 3-way swap, or shift of the slo | |||
ot2 | ts. ``slot1`` | |||
// in slot3 and the data in slot3 in slot1 | // should move to ``slot2``, which should be moved to ``slot | |||
3`` which in | ||||
// turn should be moved to ``slot1``. | ||||
// | ||||
// This is only used in compact mode. | ||||
// | ||||
// Returning ``true`` indicates an error occurred. | ||||
virtual bool swap_slots3(int slot1, int slot2, int slot3) = 0; | virtual bool swap_slots3(int slot1, int slot2, int slot3) = 0; | |||
// this will close all open files that are opened for | // This function should release all the file handles that it | |||
// writing. This is called when a torrent has finished | keeps open to files | |||
// downloading. | // belonging to this storage. The default implementation jus | |||
// non-zero return value indicates an error | t calls | |||
// ``file_pool::release_files(this)``. | ||||
// | ||||
// Returning ``true`` indicates an error occurred. | ||||
virtual bool release_files() = 0; | virtual bool release_files() = 0; | |||
// this will rename the file specified by index. | // Rename file with index ``file`` to the thame ``new_name`` | |||
. If there is an error, | ||||
// ``true`` should be returned. | ||||
virtual bool rename_file(int index, std::string const& new_f ilename) = 0; | virtual bool rename_file(int index, std::string const& new_f ilename) = 0; | |||
// this will close all open files and delete them | // This function should delete all files and directories bel | |||
// non-zero return value indicates an error | onging to | |||
// this storage. | ||||
// | ||||
// Returning ``true`` indicates an error occurred. | ||||
// | ||||
// The ``disk_buffer_pool`` is used to allocate and free dis | ||||
k buffers. It | ||||
// has the following members:: | ||||
// | ||||
// struct disk_buffer_pool : boost::noncopyable | ||||
// { | ||||
// char* allocate_buffer(char const* category); | ||||
// void free_buffer(char* buf); | ||||
// | ||||
// char* allocate_buffers(int blocks, char cons | ||||
t* category); | ||||
// void free_buffers(char* buf, int blocks); | ||||
// | ||||
// int block_size() const { return m_block_size | ||||
; } | ||||
// | ||||
// void release_memory(); | ||||
// }; | ||||
virtual bool delete_files() = 0; | virtual bool delete_files() = 0; | |||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
virtual void finalize_file(int file) {} | // This function is called each time a file is completely do | |||
wnloaded. The | ||||
// storage implementation can perform last operations on a f | ||||
ile. The file | ||||
// will not be opened for writing after this. | ||||
// | ||||
// ``index`` is the index of the file that completed. | ||||
// | ||||
// On windows the default storage implementation clears the | ||||
sparse file | ||||
// flag on the specified file. | ||||
virtual void finalize_file(int) {} | ||||
#endif | #endif | |||
// access global disk_buffer_pool, for allocating and freein g disk buffers | ||||
disk_buffer_pool* disk_pool() { return m_disk_pool; } | disk_buffer_pool* disk_pool() { return m_disk_pool; } | |||
// access global session_settings | ||||
session_settings const& settings() const { return *m_setting s; } | session_settings const& settings() const { return *m_setting s; } | |||
// called by the storage implementation to set it into an | ||||
// error state. Typically whenever a critical file operation | ||||
// fails. | ||||
void set_error(std::string const& file, error_code const& ec ) const; | void set_error(std::string const& file, error_code const& ec ) const; | |||
// returns the currently set error code and file path associ | ||||
ated with it, | ||||
// if set. | ||||
error_code const& error() const { return m_error; } | error_code const& error() const { return m_error; } | |||
std::string const& error_file() const { return m_error_file; } | std::string const& error_file() const { return m_error_file; } | |||
// reset the error state to allow continuing reading and wri | ||||
ting | ||||
// to the storage | ||||
virtual void clear_error() { m_error = error_code(); m_error _file.resize(0); } | virtual void clear_error() { m_error = error_code(); m_error _file.resize(0); } | |||
// hidden | ||||
mutable error_code m_error; | mutable error_code m_error; | |||
mutable std::string m_error_file; | mutable std::string m_error_file; | |||
// hidden | ||||
virtual ~storage_interface() {} | virtual ~storage_interface() {} | |||
// hidden | ||||
disk_buffer_pool* m_disk_pool; | disk_buffer_pool* m_disk_pool; | |||
session_settings* m_settings; | session_settings* m_settings; | |||
}; | }; | |||
// The default implementation of storage_interface. Behaves as a nor | ||||
mal | ||||
// bittorrent client. It is possible to derive from this class in or | ||||
der to | ||||
// override some of its behavior, when implementing a custom storage | ||||
. | ||||
class TORRENT_EXPORT default_storage : public storage_interface, boo st::noncopyable | class TORRENT_EXPORT default_storage : public storage_interface, boo st::noncopyable | |||
{ | { | |||
public: | public: | |||
default_storage(file_storage const& fs, file_storage const* | // constructs the default_storage based on the give file_sto | |||
mapped, std::string const& path | rage (fs). | |||
, file_pool& fp, std::vector<boost::uint8_t> const& | // ``mapped`` is an optional argument (it may be NULL). If n | |||
file_prio); | on-NULL it | |||
// represents the file mappsing that have been made to the t | ||||
orrent before | ||||
// adding it. That's where files are supposed to be saved an | ||||
d looked for | ||||
// on disk. ``save_path`` is the root save folder for this t | ||||
orrent. | ||||
// ``file_pool`` is the cache of file handles that the stora | ||||
ge will use. | ||||
// All files it opens will ask the file_pool to open them. ` | ||||
`file_prio`` | ||||
// is a vector indicating the priority of files on startup. | ||||
It may be | ||||
// an empty vector. Any file whose index is not represented | ||||
by the vector | ||||
// (because the vector is too short) are assumed to have pri | ||||
ority 1. | ||||
// this is used to treat files with priority 0 slightly diff | ||||
erently. | ||||
default_storage(file_storage const& fs, file_storage const* | ||||
mapped | ||||
, std::string const& path, file_pool& fp | ||||
, std::vector<boost::uint8_t> const& file_prio); | ||||
// hidden | ||||
~default_storage(); | ~default_storage(); | |||
void set_file_priority(std::vector<boost::uint8_t> const& pr io); | ||||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
void finalize_file(int file); | void finalize_file(int file); | |||
#endif | #endif | |||
bool has_any_file(); | bool has_any_file(); | |||
bool rename_file(int index, std::string const& new_filename) ; | bool rename_file(int index, std::string const& new_filename) ; | |||
bool release_files(); | bool release_files(); | |||
bool delete_files(); | bool delete_files(); | |||
bool initialize(bool allocate_files); | bool initialize(bool allocate_files); | |||
bool move_storage(std::string const& save_path); | int move_storage(std::string const& save_path, int flags); | |||
int read(char* buf, int slot, int offset, int size); | int read(char* buf, int slot, int offset, int size); | |||
int write(char const* buf, int slot, int offset, int size); | int write(char const* buf, int slot, int offset, int size); | |||
int sparse_end(int start) const; | int sparse_end(int start) const; | |||
void hint_read(int slot, int offset, int len); | void hint_read(int slot, int offset, int len); | |||
int readv(file::iovec_t const* bufs, int slot, int offset, i nt num_bufs, int flags = file::random_access); | int readv(file::iovec_t const* bufs, int slot, int offset, i nt num_bufs, int flags = file::random_access); | |||
int writev(file::iovec_t const* buf, int slot, int offset, i nt num_bufs, int flags = file::random_access); | int writev(file::iovec_t const* buf, int slot, int offset, i nt num_bufs, int flags = file::random_access); | |||
size_type physical_offset(int slot, int offset); | size_type physical_offset(int slot, int offset); | |||
bool move_slot(int src_slot, int dst_slot); | bool move_slot(int src_slot, int dst_slot); | |||
bool swap_slots(int slot1, int slot2); | bool swap_slots(int slot1, int slot2); | |||
bool swap_slots3(int slot1, int slot2, int slot3); | bool swap_slots3(int slot1, int slot2, int slot3); | |||
bool verify_resume_data(lazy_entry const& rd, error_code& er ror); | bool verify_resume_data(lazy_entry const& rd, error_code& er ror); | |||
bool write_resume_data(entry& rd) const; | bool write_resume_data(entry& rd) const; | |||
// if the files in this storage are mapped, returns the mapp | ||||
ed | ||||
// file_storage, otherwise returns the original file_storage | ||||
object. | ||||
file_storage const& files() const { return m_mapped_files?*m | ||||
_mapped_files:m_files; } | ||||
private: | ||||
// this identifies a read or write operation | // this identifies a read or write operation | |||
// so that default_storage::readwritev() knows what to | // so that default_storage::readwritev() knows what to | |||
// do when it's actually touching the file | // do when it's actually touching the file | |||
struct fileop | struct fileop | |||
{ | { | |||
size_type (file::*regular_op)(size_type file_offset | size_type (file::*regular_op)(size_type file_offset | |||
, file::iovec_t const* bufs, int num_bufs, e rror_code& ec); | , file::iovec_t const* bufs, int num_bufs, e rror_code& ec); | |||
size_type (default_storage::*unaligned_op)(boost::in trusive_ptr<file> const& f | size_type (default_storage::*unaligned_op)(boost::in trusive_ptr<file> const& f | |||
, size_type file_offset, file::iovec_t const * bufs, int num_bufs | , size_type file_offset, file::iovec_t const * bufs, int num_bufs | |||
, error_code& ec); | , error_code& ec); | |||
skipping to change at line 237 | skipping to change at line 485 | |||
void delete_one_file(std::string const& p); | void delete_one_file(std::string const& p); | |||
int readwritev(file::iovec_t const* bufs, int slot, int offs et | int readwritev(file::iovec_t const* bufs, int slot, int offs et | |||
, int num_bufs, fileop const&); | , int num_bufs, fileop const&); | |||
size_type read_unaligned(boost::intrusive_ptr<file> const& f ile_handle | size_type read_unaligned(boost::intrusive_ptr<file> const& f ile_handle | |||
, size_type file_offset, file::iovec_t const* bufs, int num_bufs, error_code& ec); | , size_type file_offset, file::iovec_t const* bufs, int num_bufs, error_code& ec); | |||
size_type write_unaligned(boost::intrusive_ptr<file> const& file_handle | size_type write_unaligned(boost::intrusive_ptr<file> const& file_handle | |||
, size_type file_offset, file::iovec_t const* bufs, int num_bufs, error_code& ec); | , size_type file_offset, file::iovec_t const* bufs, int num_bufs, error_code& ec); | |||
file_storage const& files() const { return m_mapped_files?*m | ||||
_mapped_files:m_files; } | ||||
boost::scoped_ptr<file_storage> m_mapped_files; | boost::scoped_ptr<file_storage> m_mapped_files; | |||
file_storage const& m_files; | file_storage const& m_files; | |||
// helper function to open a file in the file pool with the right mode | // helper function to open a file in the file pool with the right mode | |||
boost::intrusive_ptr<file> open_file(file_storage::iterator fe, int mode | boost::intrusive_ptr<file> open_file(int file, int mode | |||
, error_code& ec) const; | , error_code& ec) const; | |||
std::vector<boost::uint8_t> m_file_priority; | std::vector<boost::uint8_t> m_file_priority; | |||
std::string m_save_path; | std::string m_save_path; | |||
// the file pool is typically stored in | // the file pool is typically stored in | |||
// the session, to make all storage | // the session, to make all storage | |||
// instances use the same pool | // instances use the same pool | |||
file_pool& m_pool; | file_pool& m_pool; | |||
// this is a bitfield with one bit per file. A bit being set means | // this is a bitfield with one bit per file. A bit being set means | |||
skipping to change at line 276 | skipping to change at line 522 | |||
// this is useful when simulating many clients on the same machine | // this is useful when simulating many clients on the same machine | |||
// or when running stress tests and want to take the cost of the | // or when running stress tests and want to take the cost of the | |||
// disk I/O out of the picture. This cannot be used for any kind | // disk I/O out of the picture. This cannot be used for any kind | |||
// of normal bittorrent operation, since it will just send garbage | // of normal bittorrent operation, since it will just send garbage | |||
// to peers and throw away all the data it downloads. It would end | // to peers and throw away all the data it downloads. It would end | |||
// up being banned immediately | // up being banned immediately | |||
class disabled_storage : public storage_interface, boost::noncopyabl e | class disabled_storage : public storage_interface, boost::noncopyabl e | |||
{ | { | |||
public: | public: | |||
disabled_storage(int piece_size) : m_piece_size(piece_size) {} | disabled_storage(int piece_size) : m_piece_size(piece_size) {} | |||
void set_file_priority(std::vector<boost::uint8_t> const&) { } | ||||
bool has_any_file() { return false; } | bool has_any_file() { return false; } | |||
bool rename_file(int index, std::string const& new_filename) { return false; } | bool rename_file(int, std::string const&) { return false; } | |||
bool release_files() { return false; } | bool release_files() { return false; } | |||
bool delete_files() { return false; } | bool delete_files() { return false; } | |||
bool initialize(bool allocate_files) { return false; } | bool initialize(bool) { return false; } | |||
bool move_storage(std::string const& save_path) { return tru | int move_storage(std::string const&, int) { return 0; } | |||
e; } | int read(char*, int, int, int size) { return size; } | |||
int read(char* buf, int slot, int offset, int size) { return | int write(char const*, int, int, int size) { return size; } | |||
size; } | size_type physical_offset(int, int) { return 0; } | |||
int write(char const* buf, int slot, int offset, int size) { | ||||
return size; } | ||||
size_type physical_offset(int slot, int offset) { return 0; | ||||
} | ||||
int readv(file::iovec_t const* bufs, int slot, int offset, i nt num_bufs, int flags = file::random_access); | int readv(file::iovec_t const* bufs, int slot, int offset, i nt num_bufs, int flags = file::random_access); | |||
int writev(file::iovec_t const* bufs, int slot, int offset, int num_bufs, int flags = file::random_access); | int writev(file::iovec_t const* bufs, int slot, int offset, int num_bufs, int flags = file::random_access); | |||
bool move_slot(int src_slot, int dst_slot) { return false; } | bool move_slot(int, int) { return false; } | |||
bool swap_slots(int slot1, int slot2) { return false; } | bool swap_slots(int, int) { return false; } | |||
bool swap_slots3(int slot1, int slot2, int slot3) { return f | bool swap_slots3(int, int, int) { return false; } | |||
alse; } | bool verify_resume_data(lazy_entry const&, error_code&) { re | |||
bool verify_resume_data(lazy_entry const& rd, error_code& er | turn false; } | |||
ror) { return false; } | bool write_resume_data(entry&) const { return false; } | |||
bool write_resume_data(entry& rd) const { return false; } | ||||
int m_piece_size; | int m_piece_size; | |||
}; | }; | |||
// flags for async_move_storage | ||||
enum move_flags_t | ||||
{ | ||||
// replace any files in the destination when copying | ||||
// or moving the storage | ||||
always_replace_files, | ||||
// if any files that we want to copy exist in the destinatio | ||||
n | ||||
// exist, fail the whole operation and don't perform | ||||
// any copy or move. There is an inherent race condition | ||||
// in this mode. The files are checked for existence before | ||||
// the operation starts. In between the check and performing | ||||
// the copy, the destination files may be created, in which | ||||
// case they are replaced. | ||||
fail_if_exist, | ||||
// if any file exist in the target, take those files instead | ||||
// of the ones we may have in the source. | ||||
dont_replace | ||||
}; | ||||
struct disk_io_thread; | struct disk_io_thread; | |||
class TORRENT_EXTRA_EXPORT piece_manager | class TORRENT_EXTRA_EXPORT piece_manager | |||
: public intrusive_ptr_base<piece_manager> | : public intrusive_ptr_base<piece_manager> | |||
, boost::noncopyable | , boost::noncopyable | |||
{ | { | |||
friend class invariant_access; | friend class invariant_access; | |||
friend struct disk_io_thread; | friend struct disk_io_thread; | |||
public: | public: | |||
skipping to change at line 366 | skipping to change at line 634 | |||
void abort_disk_io(); | void abort_disk_io(); | |||
void async_clear_read_cache( | void async_clear_read_cache( | |||
boost::function<void(int, disk_io_job const&)> const & handler | boost::function<void(int, disk_io_job const&)> const & handler | |||
= boost::function<void(int, disk_io_job const&)>()); | = boost::function<void(int, disk_io_job const&)>()); | |||
void async_delete_files( | void async_delete_files( | |||
boost::function<void(int, disk_io_job const&)> const & handler | boost::function<void(int, disk_io_job const&)> const & handler | |||
= boost::function<void(int, disk_io_job const&)>()); | = boost::function<void(int, disk_io_job const&)>()); | |||
void async_move_storage(std::string const& p | void async_move_storage(std::string const& p, int flags | |||
, boost::function<void(int, disk_io_job const&)> con | ||||
st& handler); | ||||
void async_set_file_priority( | ||||
std::vector<boost::uint8_t> const& prios | ||||
, boost::function<void(int, disk_io_job const&)> con st& handler); | , boost::function<void(int, disk_io_job const&)> con st& handler); | |||
void async_save_resume_data( | void async_save_resume_data( | |||
boost::function<void(int, disk_io_job const&)> const & handler); | boost::function<void(int, disk_io_job const&)> const & handler); | |||
enum return_t | enum return_t | |||
{ | { | |||
// return values from check_fastresume and check_fil es | // return values from check_fastresume and check_fil es | |||
no_error = 0, | no_error = 0, | |||
need_full_check = -1, | need_full_check = -1, | |||
fatal_disk_error = -2, | fatal_disk_error = -2, | |||
disk_check_aborted = -3 | disk_check_aborted = -3, | |||
file_exist = -4 | ||||
}; | }; | |||
storage_interface* get_storage_impl() { return m_storage.get (); } | storage_interface* get_storage_impl() { return m_storage.get (); } | |||
private: | private: | |||
std::string save_path() const; | std::string save_path() const; | |||
bool verify_resume_data(lazy_entry const& rd, error_code& e) | bool verify_resume_data(lazy_entry const& rd, error_code& e) | |||
{ return m_storage->verify_resume_data(rd, e); } | { return m_storage->verify_resume_data(rd, e); } | |||
skipping to change at line 466 | skipping to change at line 739 | |||
, sha1_hash const& small_hash | , sha1_hash const& small_hash | |||
, int current_slot); | , int current_slot); | |||
void switch_to_full_mode(); | void switch_to_full_mode(); | |||
sha1_hash hash_for_piece_impl(int piece, int* readback = 0); | sha1_hash hash_for_piece_impl(int piece, int* readback = 0); | |||
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(); } | |||
int rename_file_impl(int index, std::string const& new_filen ame) | int rename_file_impl(int index, std::string const& new_filen ame) | |||
{ return m_storage->rename_file(index, new_filename); } | { return m_storage->rename_file(index, new_filename); } | |||
void set_file_priority_impl(std::vector<boost::uint8_t> cons | ||||
t& p) | ||||
{ m_storage->set_file_priority(p); } | ||||
int move_storage_impl(std::string const& save_path); | int move_storage_impl(std::string const& save_path, int flag s); | |||
int allocate_slot_for_piece(int piece_index); | int allocate_slot_for_piece(int piece_index); | |||
#ifdef TORRENT_DEBUG | #if TORRENT_USE_INVARIANT_CHECKS | |||
void check_invariant() const; | void check_invariant() const; | |||
#endif | ||||
#ifdef TORRENT_STORAGE_DEBUG | #ifdef TORRENT_STORAGE_DEBUG | |||
void debug_log() const; | void debug_log() const; | |||
#endif | #endif | |||
#endif | ||||
boost::intrusive_ptr<torrent_info const> m_info; | boost::intrusive_ptr<torrent_info const> m_info; | |||
file_storage const& m_files; | file_storage const& m_files; | |||
boost::scoped_ptr<storage_interface> m_storage; | boost::scoped_ptr<storage_interface> m_storage; | |||
storage_mode_t m_storage_mode; | storage_mode_t m_storage_mode; | |||
// slots that haven't had any file storage allocated | // slots that haven't had any file storage allocated | |||
std::vector<int> m_unallocated_slots; | std::vector<int> m_unallocated_slots; | |||
// slots that have file storage, but isn't assigned to a pie ce | // slots that have file storage, but isn't assigned to a pie ce | |||
End of changes. 47 change blocks. | ||||
70 lines changed or deleted | 453 lines changed or added | |||
storage_defs.hpp | storage_defs.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2003, Arvid Norberg | Copyright (c) 2003-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 46 | skipping to change at line 46 | |||
#include "libtorrent/config.hpp" | #include "libtorrent/config.hpp" | |||
#include <boost/function.hpp> | #include <boost/function.hpp> | |||
#include <string> | #include <string> | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
struct storage_interface; | struct storage_interface; | |||
class file_storage; | class file_storage; | |||
struct file_pool; | struct file_pool; | |||
// types of storage allocation used for add_torrent_params::storage_ mode. | ||||
enum storage_mode_t | enum storage_mode_t | |||
{ | { | |||
storage_mode_allocate = 0, | // All pieces will be written to their final position, all f | |||
iles will be | ||||
// allocated in full when the torrent is first started. This | ||||
is done with | ||||
// ``fallocate()`` and similar calls. This mode minimizes fr | ||||
agmentation. | ||||
storage_mode_allocate, | ||||
// All pieces will be written to the place where they belong | ||||
and sparse files | ||||
// will be used. This is the recommended, and default mode. | ||||
storage_mode_sparse, | storage_mode_sparse, | |||
// this is here for internal use | ||||
// internal | ||||
internal_storage_mode_compact_deprecated, | internal_storage_mode_compact_deprecated, | |||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
storage_mode_compact = internal_storage_mode_compact_depreca ted | storage_mode_compact = internal_storage_mode_compact_depreca ted | |||
#endif | #endif | |||
}; | }; | |||
typedef boost::function<storage_interface*(file_storage const&, file _storage const* | typedef boost::function<storage_interface*(file_storage const&, file _storage const* | |||
, std::string const&, file_pool&, std::vector<boost::uint8_t > const&)> storage_constructor_type; | , std::string const&, file_pool&, std::vector<boost::uint8_t > const&)> storage_constructor_type; | |||
// the constructor function for the regular file storage. This is th | ||||
e | ||||
// default value for add_torrent_params::storage. | ||||
TORRENT_EXPORT storage_interface* default_storage_constructor( | TORRENT_EXPORT storage_interface* default_storage_constructor( | |||
file_storage const&, file_storage const* mapped, std::string const&, file_pool& | file_storage const&, file_storage const* mapped, std::string const&, file_pool& | |||
, std::vector<boost::uint8_t> const&); | , std::vector<boost::uint8_t> const&); | |||
// the constructor function for the disabled storage. This can be us | ||||
ed for | ||||
// testing and benchmarking. It will throw away any data written to | ||||
// it and return garbage for anything read from it. | ||||
TORRENT_EXPORT storage_interface* disabled_storage_constructor( | TORRENT_EXPORT storage_interface* disabled_storage_constructor( | |||
file_storage const&, file_storage const* mapped, std::string const&, file_pool& | file_storage const&, file_storage const* mapped, std::string const&, file_pool& | |||
, std::vector<boost::uint8_t> const&); | , std::vector<boost::uint8_t> const&); | |||
} | } | |||
#endif | #endif | |||
End of changes. 6 change blocks. | ||||
3 lines changed or deleted | 22 lines changed or added | |||
string_util.hpp | string_util.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2012, Arvid Norberg | Copyright (c) 2012-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 36 | skipping to change at line 36 | |||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 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 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||
POSSIBILITY OF SUCH DAMAGE. | POSSIBILITY OF SUCH DAMAGE. | |||
*/ | */ | |||
#ifndef TORRENT_STRING_UTIL_HPP_INCLUDED | #ifndef TORRENT_STRING_UTIL_HPP_INCLUDED | |||
#define TORRENT_STRING_UTIL_HPP_INCLUDED | #define TORRENT_STRING_UTIL_HPP_INCLUDED | |||
#include "libtorrent/config.hpp" | ||||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
TORRENT_EXTRA_EXPORT bool is_alpha(char c); | TORRENT_EXTRA_EXPORT bool is_alpha(char c); | |||
// this is used by bdecode_recursive's header file | ||||
TORRENT_EXPORT bool is_digit(char c); | TORRENT_EXPORT bool is_digit(char c); | |||
TORRENT_EXTRA_EXPORT bool is_print(char c); | TORRENT_EXTRA_EXPORT bool is_print(char c); | |||
TORRENT_EXTRA_EXPORT bool is_space(char c); | TORRENT_EXTRA_EXPORT bool is_space(char c); | |||
TORRENT_EXTRA_EXPORT char to_lower(char c); | TORRENT_EXTRA_EXPORT char to_lower(char c); | |||
TORRENT_EXTRA_EXPORT int split_string(char const** tags, int buf_siz e, char* in); | TORRENT_EXTRA_EXPORT int split_string(char const** tags, int buf_siz e, char* in); | |||
TORRENT_EXTRA_EXPORT bool string_begins_no_case(char const* s1, char const* s2); | TORRENT_EXTRA_EXPORT bool string_begins_no_case(char const* s1, char const* s2); | |||
TORRENT_EXTRA_EXPORT bool string_equal_no_case(char const* s1, char const* s2); | TORRENT_EXTRA_EXPORT bool string_equal_no_case(char const* s1, char const* s2); | |||
TORRENT_EXTRA_EXPORT void url_random(char* begin, char* end); | TORRENT_EXTRA_EXPORT void url_random(char* begin, char* end); | |||
// strdup is not part of the C standard. Some systems | // strdup is not part of the C standard. Some systems | |||
// don't have it and it won't be available when building | // don't have it and it won't be available when building | |||
// in strict ansi mode | // in strict ansi mode | |||
char* allocate_string_copy(char const* str); | char* allocate_string_copy(char const* str); | |||
// returns p + x such that the pointer is 8 bytes aligned | // returns p + x such that the pointer is 8 bytes aligned | |||
// x cannot be greater than 7 | // x cannot be greater than 7 | |||
void* align_pointer(void* p); | void* align_pointer(void* p); | |||
// searches for separator in the string 'last'. the pointer last poi | ||||
nts to | ||||
// is set to point to the first character following the separator. | ||||
// returns a pointer to a null terminated string starting at last, e | ||||
nding | ||||
// at the separator (the string is mutated to replace the separator | ||||
with | ||||
// a '\0' character). If there is no separator, but the end of the s | ||||
tring, | ||||
// the pointer next points to is set to the last null terminator, wh | ||||
ich will | ||||
// make the following invocation return NULL, to indicate the end of | ||||
the | ||||
// string. | ||||
TORRENT_EXTRA_EXPORT char* string_tokenize(char* last, char sep, cha | ||||
r** next); | ||||
} | } | |||
#endif | #endif | |||
End of changes. 4 change blocks. | ||||
1 lines changed or deleted | 20 lines changed or added | |||
thread.hpp | thread.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2009, Arvid Norberg | Copyright (c) 2009-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 37 | skipping to change at line 37 | |||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 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 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||
POSSIBILITY OF SUCH DAMAGE. | POSSIBILITY OF SUCH DAMAGE. | |||
*/ | */ | |||
#ifndef TORRENT_THREAD_HPP_INCLUDED | #ifndef TORRENT_THREAD_HPP_INCLUDED | |||
#define TORRENT_THREAD_HPP_INCLUDED | #define TORRENT_THREAD_HPP_INCLUDED | |||
#include "libtorrent/config.hpp" | #include "libtorrent/config.hpp" | |||
#include "libtorrent/time.hpp" | ||||
#if defined TORRENT_WINDOWS || defined TORRENT_CYGWIN | #if defined TORRENT_WINDOWS || defined TORRENT_CYGWIN | |||
// asio assumes that the windows error codes are defined already | // asio assumes that the windows error codes are defined already | |||
#include <winsock2.h> | #include <winsock2.h> | |||
#endif | #endif | |||
#if defined TORRENT_BEOS | #if defined TORRENT_BEOS | |||
#include <kernel/OS.h> | #include <kernel/OS.h> | |||
#endif | #endif | |||
skipping to change at line 59 | skipping to change at line 60 | |||
#include <boost/asio/detail/thread.hpp> | #include <boost/asio/detail/thread.hpp> | |||
#include <boost/asio/detail/mutex.hpp> | #include <boost/asio/detail/mutex.hpp> | |||
#include <boost/asio/detail/event.hpp> | #include <boost/asio/detail/event.hpp> | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
typedef boost::asio::detail::thread thread; | typedef boost::asio::detail::thread thread; | |||
typedef boost::asio::detail::mutex mutex; | typedef boost::asio::detail::mutex mutex; | |||
typedef boost::asio::detail::event event; | typedef boost::asio::detail::event event; | |||
// pauses the calling thread at least for the specified | ||||
// number of milliseconds | ||||
TORRENT_EXPORT void sleep(int milliseconds); | TORRENT_EXPORT void sleep(int milliseconds); | |||
struct TORRENT_EXTRA_EXPORT condition | struct TORRENT_EXTRA_EXPORT condition_variable | |||
{ | { | |||
condition(); | condition_variable(); | |||
~condition(); | ~condition_variable(); | |||
void wait(mutex::scoped_lock& l); | void wait(mutex::scoped_lock& l); | |||
void signal_all(mutex::scoped_lock& l); | void wait_for(mutex::scoped_lock& l, time_duration rel_time) | |||
; | ||||
void notify_all(); | ||||
private: | private: | |||
#ifdef BOOST_HAS_PTHREADS | #ifdef BOOST_HAS_PTHREADS | |||
pthread_cond_t m_cond; | pthread_cond_t m_cond; | |||
#elif defined TORRENT_WINDOWS || defined TORRENT_CYGWIN | #elif defined TORRENT_WINDOWS || defined TORRENT_CYGWIN | |||
HANDLE m_sem; | HANDLE m_sem; | |||
mutex m_mutex; | mutex m_mutex; | |||
int m_num_waiters; | int m_num_waiters; | |||
#elif defined TORRENT_BEOS | #elif defined TORRENT_BEOS | |||
sem_id m_sem; | sem_id m_sem; | |||
mutex m_mutex; | mutex m_mutex; | |||
End of changes. 6 change blocks. | ||||
5 lines changed or deleted | 10 lines changed or added | |||
time.hpp | time.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2007, Arvid Norberg | Copyright (c) 2007-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 42 | skipping to change at line 42 | |||
#ifndef TORRENT_TIME_HPP_INCLUDED | #ifndef TORRENT_TIME_HPP_INCLUDED | |||
#define TORRENT_TIME_HPP_INCLUDED | #define TORRENT_TIME_HPP_INCLUDED | |||
#include <boost/version.hpp> | #include <boost/version.hpp> | |||
#include "libtorrent/config.hpp" | #include "libtorrent/config.hpp" | |||
#include "libtorrent/ptime.hpp" | #include "libtorrent/ptime.hpp" | |||
#include <boost/cstdint.hpp> | #include <boost/cstdint.hpp> | |||
#include <string> | #include <string> | |||
// OVERVIEW | ||||
// | ||||
// This section contains fundamental time types used internally by | ||||
// libtorrent and exposed through various places in the API. The two | ||||
// basic types are ``ptime`` and ``time_duration``. The first represents | ||||
// a point in time and the second the difference between two points | ||||
// in time. | ||||
// | ||||
// The internal representation of these types is implementation defined | ||||
// and they can only be constructed via one of the construction functions | ||||
// that take a well defined time unit (seconds, minutes, etc.). They can | ||||
// only be turned into well defined time units by the accessor functions | ||||
// (total_microseconds(), etc.). | ||||
// | ||||
// .. note:: | ||||
// In a future version of libtorrent, these types will be replaced | ||||
// by the standard timer types from ``std::chrono``. | ||||
// | ||||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
TORRENT_EXPORT char const* time_now_string(); | TORRENT_EXTRA_EXPORT char const* time_now_string(); | |||
TORRENT_EXPORT std::string log_time(); | std::string log_time(); | |||
// returns the current time, as represented by ptime. The | ||||
// resolution of this timer is about 100 ms. | ||||
TORRENT_EXPORT ptime const& time_now(); | ||||
// returns the current time as represented by ptime. This is | ||||
// more expensive than time_now(), but provides as high resolution | ||||
// as the operating system can provide. | ||||
TORRENT_EXPORT ptime time_now_hires(); | TORRENT_EXPORT ptime time_now_hires(); | |||
// the earliest and latest possible time points | ||||
// representable by ptime. | ||||
TORRENT_EXPORT ptime min_time(); | TORRENT_EXPORT ptime min_time(); | |||
TORRENT_EXPORT ptime max_time(); | TORRENT_EXPORT ptime max_time(); | |||
#if defined TORRENT_USE_BOOST_DATE_TIME | #if defined TORRENT_USE_BOOST_DATE_TIME || defined TORRENT_USE_QUERY_PERFOR MANCE_TIMER | |||
TORRENT_EXPORT time_duration seconds(int s); | // returns a time_duration representing the specified number of seco | |||
TORRENT_EXPORT time_duration milliseconds(int s); | nds, milliseconds | |||
TORRENT_EXPORT time_duration microsec(int s); | // microseconds, minutes and hours. | |||
TORRENT_EXPORT time_duration minutes(int s); | TORRENT_EXPORT time_duration seconds(boost::int64_t s); | |||
TORRENT_EXPORT time_duration hours(int s); | TORRENT_EXPORT time_duration milliseconds(boost::int64_t s); | |||
TORRENT_EXPORT time_duration microsec(boost::int64_t s); | ||||
TORRENT_EXPORT int total_seconds(time_duration td); | TORRENT_EXPORT time_duration minutes(boost::int64_t s); | |||
TORRENT_EXPORT int total_milliseconds(time_duration td); | TORRENT_EXPORT time_duration hours(boost::int64_t s); | |||
// returns the number of seconds, milliseconds and microseconds | ||||
// a time_duration represents. | ||||
TORRENT_EXPORT boost::int64_t total_seconds(time_duration td); | ||||
TORRENT_EXPORT boost::int64_t total_milliseconds(time_duration td); | ||||
TORRENT_EXPORT boost::int64_t total_microseconds(time_duration td); | TORRENT_EXPORT boost::int64_t total_microseconds(time_duration td); | |||
#elif defined TORRENT_USE_QUERY_PERFORMANCE_TIMER | ||||
namespace aux | ||||
{ | ||||
TORRENT_EXPORT boost::int64_t performance_counter_to_microse | ||||
conds(boost::int64_t pc); | ||||
TORRENT_EXPORT boost::int64_t microseconds_to_performance_co | ||||
unter(boost::int64_t ms); | ||||
} | ||||
inline int total_seconds(time_duration td) | ||||
{ | ||||
return boost::int64_t(aux::performance_counter_to_microsecon | ||||
ds(td.diff) | ||||
/ 1000000); | ||||
} | ||||
inline int total_milliseconds(time_duration td) | ||||
{ | ||||
return boost::int64_t(aux::performance_counter_to_microsecon | ||||
ds(td.diff) | ||||
/ 1000); | ||||
} | ||||
inline boost::int64_t total_microseconds(time_duration td) | ||||
{ | ||||
return aux::performance_counter_to_microseconds(td.diff); | ||||
} | ||||
inline time_duration microsec(boost::int64_t s) | ||||
{ | ||||
return time_duration(aux::microseconds_to_performance_counte | ||||
r(s)); | ||||
} | ||||
inline time_duration milliseconds(boost::int64_t s) | ||||
{ | ||||
return time_duration(aux::microseconds_to_performance_counte | ||||
r( | ||||
s * 1000)); | ||||
} | ||||
inline time_duration seconds(boost::int64_t s) | ||||
{ | ||||
return time_duration(aux::microseconds_to_performance_counte | ||||
r( | ||||
s * 1000000)); | ||||
} | ||||
inline time_duration minutes(boost::int64_t s) | ||||
{ | ||||
return time_duration(aux::microseconds_to_performance_counte | ||||
r( | ||||
s * 1000000 * 60)); | ||||
} | ||||
inline time_duration hours(boost::int64_t s) | ||||
{ | ||||
return time_duration(aux::microseconds_to_performance_counte | ||||
r( | ||||
s * 1000000 * 60 * 60)); | ||||
} | ||||
#elif TORRENT_USE_CLOCK_GETTIME || TORRENT_USE_SYSTEM_TIME || TORRENT_USE_A BSOLUTE_TIME | #elif TORRENT_USE_CLOCK_GETTIME || TORRENT_USE_SYSTEM_TIME || TORRENT_USE_A BSOLUTE_TIME | |||
// hidden | ||||
inline int total_seconds(time_duration td) | inline int total_seconds(time_duration td) | |||
{ return td.diff / 1000000; } | { return td.diff / 1000000; } | |||
// hidden | ||||
inline int total_milliseconds(time_duration td) | inline int total_milliseconds(time_duration td) | |||
{ return td.diff / 1000; } | { return td.diff / 1000; } | |||
// hidden | ||||
inline boost::int64_t total_microseconds(time_duration td) | inline boost::int64_t total_microseconds(time_duration td) | |||
{ return td.diff; } | { return td.diff; } | |||
// hidden | ||||
inline time_duration microsec(boost::int64_t s) | inline time_duration microsec(boost::int64_t s) | |||
{ return time_duration(s); } | { return time_duration(s); } | |||
// hidden | ||||
inline time_duration milliseconds(boost::int64_t s) | inline time_duration milliseconds(boost::int64_t s) | |||
{ return time_duration(s * 1000); } | { return time_duration(s * 1000); } | |||
// hidden | ||||
inline time_duration seconds(boost::int64_t s) | inline time_duration seconds(boost::int64_t s) | |||
{ return time_duration(s * 1000000); } | { return time_duration(s * 1000000); } | |||
// hidden | ||||
inline time_duration minutes(boost::int64_t s) | inline time_duration minutes(boost::int64_t s) | |||
{ return time_duration(s * 1000000 * 60); } | { return time_duration(s * 1000000 * 60); } | |||
// hidden | ||||
inline time_duration hours(boost::int64_t s) | inline time_duration hours(boost::int64_t s) | |||
{ return time_duration(s * 1000000 * 60 * 60); } | { return time_duration(s * 1000000 * 60 * 60); } | |||
#endif // TORRENT_USE_CLOCK_GETTIME | #endif // TORRENT_USE_CLOCK_GETTIME | |||
} | } | |||
#endif // TORRENT_TIME_HPP_INCLUDED | #endif // TORRENT_TIME_HPP_INCLUDED | |||
End of changes. 16 change blocks. | ||||
69 lines changed or deleted | 54 lines changed or added | |||
timestamp_history.hpp | timestamp_history.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2009, Arvid Norberg | Copyright (c) 2009-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
torrent.hpp | torrent.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2003, Arvid Norberg | Copyright (c) 2003-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 83 | skipping to change at line 83 | |||
#include "libtorrent/assert.hpp" | #include "libtorrent/assert.hpp" | |||
#include "libtorrent/bitfield.hpp" | #include "libtorrent/bitfield.hpp" | |||
#include "libtorrent/aux_/session_impl.hpp" | #include "libtorrent/aux_/session_impl.hpp" | |||
#include "libtorrent/deadline_timer.hpp" | #include "libtorrent/deadline_timer.hpp" | |||
#include "libtorrent/union_endpoint.hpp" | #include "libtorrent/union_endpoint.hpp" | |||
#if TORRENT_COMPLETE_TYPES_REQUIRED | #if TORRENT_COMPLETE_TYPES_REQUIRED | |||
#include "libtorrent/peer_connection.hpp" | #include "libtorrent/peer_connection.hpp" | |||
#endif | #endif | |||
// define as 0 to disable. 1 enables debug output of the pieces and request | ||||
ed | ||||
// blocks. 2 also enables trace output of the time critical piece picking | ||||
// logic | ||||
#define TORRENT_DEBUG_STREAMING 0 | ||||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
class http_parser; | class http_parser; | |||
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T ORRENT_ERROR_LOGGING | #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T ORRENT_ERROR_LOGGING | |||
struct logger; | struct logger; | |||
#endif | #endif | |||
class piece_manager; | class piece_manager; | |||
struct torrent_plugin; | struct torrent_plugin; | |||
skipping to change at line 107 | skipping to change at line 112 | |||
struct storage_interface; | struct storage_interface; | |||
class bt_peer_connection; | class bt_peer_connection; | |||
struct listen_socket_t; | struct listen_socket_t; | |||
namespace aux | namespace aux | |||
{ | { | |||
struct session_impl; | struct session_impl; | |||
struct piece_checker_data; | struct piece_checker_data; | |||
} | } | |||
struct time_critical_piece | ||||
{ | ||||
// when this piece was first requested | ||||
ptime first_requested; | ||||
// when this piece was last requested | ||||
ptime last_requested; | ||||
// by what time we want this piece | ||||
ptime deadline; | ||||
// 1 = send alert with piece data when available | ||||
int flags; | ||||
// how many peers it's been requested from | ||||
int peers; | ||||
// the piece index | ||||
int piece; | ||||
#if TORRENT_DEBUG_STREAMING > 0 | ||||
// the number of multiple requests are allowed | ||||
// to blocks still not downloaded (debugging only) | ||||
int timed_out; | ||||
#endif | ||||
bool operator<(time_critical_piece const& rhs) const | ||||
{ return deadline < rhs.deadline; } | ||||
}; | ||||
// a torrent is a class that holds information | // a torrent is a class that holds information | |||
// for a specific download. It updates itself against | // for a specific download. It updates itself against | |||
// the tracker | // the tracker | |||
class TORRENT_EXTRA_EXPORT torrent: public request_callback | class TORRENT_EXTRA_EXPORT torrent: public request_callback | |||
, public boost::enable_shared_from_this<torrent> | , public boost::enable_shared_from_this<torrent> | |||
{ | { | |||
public: | public: | |||
torrent(aux::session_impl& ses, tcp::endpoint const& net_int erface | torrent(aux::session_impl& ses, tcp::endpoint const& net_int erface | |||
, int block_size, int seq, add_torrent_params const& p | , int block_size, int seq, add_torrent_params const& p | |||
skipping to change at line 131 | skipping to change at line 159 | |||
sha1_hash const& obfuscated_hash() const | sha1_hash const& obfuscated_hash() const | |||
{ return m_obfuscated_hash; } | { return m_obfuscated_hash; } | |||
#endif | #endif | |||
sha1_hash const& info_hash() const | sha1_hash const& info_hash() const | |||
{ | { | |||
static sha1_hash empty; | static sha1_hash empty; | |||
return m_torrent_file ? m_torrent_file->info_hash() : empty; | return m_torrent_file ? m_torrent_file->info_hash() : empty; | |||
} | } | |||
bool is_deleted() const { return m_deleted; } | ||||
// starts the announce timer | // starts the announce timer | |||
void start(); | void start(); | |||
void start_download_url(); | void start_download_url(); | |||
#ifndef TORRENT_DISABLE_EXTENSIONS | #ifndef TORRENT_DISABLE_EXTENSIONS | |||
void add_extension(boost::shared_ptr<torrent_plugin>); | void add_extension(boost::shared_ptr<torrent_plugin>); | |||
void add_extension(boost::function<boost::shared_ptr<torrent _plugin>(torrent*, void*)> const& ext | void add_extension(boost::function<boost::shared_ptr<torrent _plugin>(torrent*, void*)> const& ext | |||
, void* userdata); | , void* userdata); | |||
void notify_extension_add_peer(tcp::endpoint const& ip, int src, int flags); | void notify_extension_add_peer(tcp::endpoint const& ip, int src, int flags); | |||
#endif | #endif | |||
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS | peer_connection* find_lowest_ranking_peer() const; | |||
#if TORRENT_USE_ASSERTS | ||||
bool has_peer(peer_connection* p) const | bool has_peer(peer_connection* p) const | |||
{ return m_connections.find(p) != m_connections.end(); } | { return m_connections.find(p) != m_connections.end(); } | |||
#endif | #endif | |||
// this is called when the torrent has metadata. | // this is called when the torrent has metadata. | |||
// it will initialize the storage and the piece-picker | // it will initialize the storage and the piece-picker | |||
void init(); | void init(); | |||
// find the peer that introduced us to the given endpoint. T his is | // find the peer that introduced us to the given endpoint. T his is | |||
// used when trying to holepunch. We need the introducer so that we | // used when trying to holepunch. We need the introducer so that we | |||
skipping to change at line 196 | skipping to change at line 228 | |||
void on_disk_write_complete(int ret, disk_io_job const& j | void on_disk_write_complete(int ret, disk_io_job const& j | |||
, peer_request p); | , peer_request p); | |||
void on_disk_cache_complete(int ret, disk_io_job const& j); | void on_disk_cache_complete(int ret, disk_io_job const& j); | |||
void set_progress_ppm(int p) { m_progress_ppm = p; } | void set_progress_ppm(int p) { m_progress_ppm = p; } | |||
struct read_piece_struct | struct read_piece_struct | |||
{ | { | |||
boost::shared_array<char> piece_data; | boost::shared_array<char> piece_data; | |||
int blocks_left; | int blocks_left; | |||
bool fail; | bool fail; | |||
error_code error; | ||||
}; | }; | |||
void read_piece(int piece); | void read_piece(int piece); | |||
void on_disk_read_complete(int ret, disk_io_job const& j, pe er_request r, read_piece_struct* rp); | void on_disk_read_complete(int ret, disk_io_job const& j, pe er_request r, read_piece_struct* rp); | |||
storage_mode_t storage_mode() const { return (storage_mode_t )m_storage_mode; } | storage_mode_t storage_mode() const { return (storage_mode_t )m_storage_mode; } | |||
storage_interface* get_storage() | storage_interface* get_storage() | |||
{ | { | |||
if (!m_owning_storage) return 0; | if (!m_owning_storage) return 0; | |||
return m_owning_storage->get_storage_impl(); | return m_owning_storage->get_storage_impl(); | |||
} | } | |||
// this will flag the torrent as aborted. The main | // this will flag the torrent as aborted. The main | |||
// loop in session_impl will check for this state | // loop in session_impl will check for this state | |||
// on all torrents once every second, and take | // on all torrents once every second, and take | |||
// the necessary actions then. | // the necessary actions then. | |||
void abort(); | void abort(); | |||
bool is_aborted() const { return m_abort; } | bool is_aborted() const { return m_abort; } | |||
void new_external_ip(); | ||||
torrent_status::state_t state() const { return (torrent_stat us::state_t)m_state; } | torrent_status::state_t state() const { return (torrent_stat us::state_t)m_state; } | |||
void set_state(torrent_status::state_t s); | void set_state(torrent_status::state_t s); | |||
session_settings const& settings() const; | session_settings const& settings() const; | |||
aux::session_impl& session() { return m_ses; } | aux::session_impl& session() { return m_ses; } | |||
void set_sequential_download(bool sd); | void set_sequential_download(bool sd); | |||
bool is_sequential_download() const | bool is_sequential_download() const | |||
{ return m_sequential_download; } | { return m_sequential_download; } | |||
void queue_up(); | void queue_up(); | |||
void queue_down(); | void queue_down(); | |||
void set_queue_position(int p); | void set_queue_position(int p); | |||
int queue_position() const { return m_sequence_number; } | int queue_position() const { return m_sequence_number; } | |||
void second_tick(stat& accumulator, int tick_interval_ms); | void second_tick(stat& accumulator, int tick_interval_ms); | |||
// see if we need to connect to web seeds, and if so, | ||||
// connect to them | ||||
void maybe_connect_web_seeds(); | ||||
std::string name() const; | std::string name() const; | |||
stat statistics() const { return m_stat; } | stat statistics() const { return m_stat; } | |||
void add_stats(stat const& s); | void add_stats(stat const& s); | |||
size_type bytes_left() const; | size_type bytes_left() const; | |||
int block_bytes_wanted(piece_block const& p) const; | int block_bytes_wanted(piece_block const& p) const; | |||
void bytes_done(torrent_status& st, bool accurate) const; | void bytes_done(torrent_status& st, bool accurate) const; | |||
size_type quantized_bytes_done() const; | size_type quantized_bytes_done() const; | |||
void ip_filter_updated() { m_policy.ip_filter_updated(); } | void ip_filter_updated() { m_policy.ip_filter_updated(); } | |||
skipping to change at line 267 | skipping to change at line 306 | |||
ptime started() const { return m_started; } | ptime started() const { return m_started; } | |||
void do_pause(); | void do_pause(); | |||
void do_resume(); | void do_resume(); | |||
bool is_paused() const; | bool is_paused() const; | |||
bool allows_peers() const { return m_allow_peers; } | bool allows_peers() const { return m_allow_peers; } | |||
bool is_torrent_paused() const { return !m_allow_peers || m_ graceful_pause_mode; } | bool is_torrent_paused() const { return !m_allow_peers || m_ graceful_pause_mode; } | |||
void force_recheck(); | void force_recheck(); | |||
void save_resume_data(int flags); | void save_resume_data(int flags); | |||
bool is_active_download() const; | ||||
bool is_active_finished() const; | ||||
void update_guage(); | ||||
bool need_save_resume_data() const | bool need_save_resume_data() const | |||
{ | { | |||
// save resume data every 15 minutes regardless, jus t to | // save resume data every 15 minutes regardless, jus t to | |||
// keep stats up to date | // keep stats up to date | |||
return m_need_save_resume_data || time(0) - m_last_s aved_resume > 15 * 60; | return m_need_save_resume_data || time(0) - m_last_s aved_resume > 15 * 60; | |||
} | } | |||
bool is_auto_managed() const { return m_auto_managed; } | bool is_auto_managed() const { return m_auto_managed; } | |||
void auto_managed(bool a); | void auto_managed(bool a); | |||
bool should_check_files() const; | bool should_check_files() const; | |||
void delete_files(); | bool delete_files(); | |||
// ============ start deprecation ============= | // ============ start deprecation ============= | |||
void filter_piece(int index, bool filter); | void filter_piece(int index, bool filter); | |||
void filter_pieces(std::vector<bool> const& bitmask); | void filter_pieces(std::vector<bool> const& bitmask); | |||
bool is_piece_filtered(int index) const; | bool is_piece_filtered(int index) const; | |||
void filtered_pieces(std::vector<bool>& bitmask) const; | void filtered_pieces(std::vector<bool>& bitmask) const; | |||
void filter_files(std::vector<bool> const& files); | void filter_files(std::vector<bool> const& files); | |||
#if !TORRENT_NO_FPU | #if !TORRENT_NO_FPU | |||
void file_progress(std::vector<float>& fp) const; | void file_progress(std::vector<float>& fp) const; | |||
#endif | #endif | |||
skipping to change at line 306 | skipping to change at line 349 | |||
void prioritize_pieces(std::vector<int> const& pieces); | void prioritize_pieces(std::vector<int> const& pieces); | |||
void piece_priorities(std::vector<int>*) const; | void piece_priorities(std::vector<int>*) const; | |||
void set_file_priority(int index, int priority); | void set_file_priority(int index, int priority); | |||
int file_priority(int index) const; | int file_priority(int index) const; | |||
void prioritize_files(std::vector<int> const& files); | void prioritize_files(std::vector<int> const& files); | |||
void file_priorities(std::vector<int>*) const; | void file_priorities(std::vector<int>*) const; | |||
void cancel_non_critical(); | ||||
void set_piece_deadline(int piece, int t, int flags); | void set_piece_deadline(int piece, int t, int flags); | |||
void reset_piece_deadline(int piece); | void reset_piece_deadline(int piece); | |||
void clear_time_critical(); | ||||
void update_piece_priorities(); | void update_piece_priorities(); | |||
void status(torrent_status* st, boost::uint32_t flags); | void status(torrent_status* st, boost::uint32_t flags); | |||
// this torrent changed state, if the user is subscribing to | // this torrent changed state, if the user is subscribing to | |||
// it, add it to the m_state_updates list in session_impl | // it, add it to the m_state_updates list in session_impl | |||
void state_updated(); | void state_updated(); | |||
void file_progress(std::vector<size_type>& fp, int flags = 0 ) const; | void file_progress(std::vector<size_type>& fp, int flags = 0 ) const; | |||
void use_interface(std::string net_interface); | void use_interface(std::string net_interface); | |||
tcp::endpoint get_interface() const; | tcp::endpoint get_interface() const; | |||
void connect_to_url_seed(std::list<web_seed_entry>::iterator url); | void connect_to_url_seed(std::list<web_seed_entry>::iterator url); | |||
bool connect_to_peer(policy::peer* peerinfo, bool ignore_lim it = false); | bool connect_to_peer(policy::peer* peerinfo, bool ignore_lim it = false); | |||
void set_ratio(float r) | ||||
{ TORRENT_ASSERT(r >= 0.0f); m_ratio = r; } | ||||
float ratio() const | ||||
{ return m_ratio; } | ||||
int priority() const { return m_priority; } | int priority() const { return m_priority; } | |||
void set_priority(int prio) | void set_priority(int prio) | |||
{ | { | |||
TORRENT_ASSERT(prio <= 255 && prio >= 0); | TORRENT_ASSERT(prio <= 255 && prio >= 0); | |||
if (prio > 255) prio = 255; | if (prio > 255) prio = 255; | |||
else if (prio < 0) prio = 0; | else if (prio < 0) prio = 0; | |||
m_priority = prio; | m_priority = prio; | |||
state_updated(); | state_updated(); | |||
} | } | |||
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES | #ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES | |||
void resolve_countries(bool r) | void resolve_countries(bool r) | |||
{ m_resolve_countries = r; } | { m_resolve_countries = r; } | |||
bool resolving_countries() const | bool resolving_countries() const | |||
{ | { | |||
return m_resolve_countries && !m_ses.settings().anon ymous_mode; | return m_resolve_countries && !m_ses.settings().forc e_proxy; | |||
} | } | |||
#endif | #endif | |||
// -------------------------------------------- | // -------------------------------------------- | |||
// BANDWIDTH MANAGEMENT | // BANDWIDTH MANAGEMENT | |||
bandwidth_channel m_bandwidth_channel[2]; | bandwidth_channel m_bandwidth_channel[2]; | |||
int bandwidth_throttle(int channel) const; | int bandwidth_throttle(int channel) const; | |||
skipping to change at line 438 | skipping to change at line 477 | |||
// these are callbacks called by the tracker_connection inst ance | // these are callbacks called by the tracker_connection inst ance | |||
// (either http_tracker_connection or udp_tracker_connection ) | // (either http_tracker_connection or udp_tracker_connection ) | |||
// when this torrent got a response from its tracker request | // when this torrent got a response from its tracker request | |||
// or when a failure occured | // or when a failure occured | |||
virtual void tracker_response( | virtual void tracker_response( | |||
tracker_request const& r | tracker_request const& r | |||
, address const& tracker_ip | , address const& tracker_ip | |||
, std::list<address> const& ip_list | , std::list<address> const& ip_list | |||
, std::vector<peer_entry>& e, int interval, int min_ interval | , std::vector<peer_entry>& e, int interval, int min_ interval | |||
, int complete, int incomplete, address const& exter | , int complete, int incomplete, int downloaded | |||
nal_ip | , address const& external_ip, std::string const& tra | |||
, std::string const& trackerid); | ckerid); | |||
virtual void tracker_request_error(tracker_request const& r | virtual void tracker_request_error(tracker_request const& r | |||
, int response_code, error_code const& ec, const std ::string& msg | , int response_code, error_code const& ec, const std ::string& msg | |||
, int retry_interval); | , int retry_interval); | |||
virtual void tracker_warning(tracker_request const& req | virtual void tracker_warning(tracker_request const& req | |||
, std::string const& msg); | , std::string const& msg); | |||
virtual void tracker_scrape_response(tracker_request const& req | virtual void tracker_scrape_response(tracker_request const& req | |||
, int complete, int incomplete, int downloaded, int downloaders); | , int complete, int incomplete, int downloaded, int downloaders); | |||
void update_scrape_state(); | ||||
// if no password and username is set | // if no password and username is set | |||
// this will return an empty string, otherwise | // this will return an empty string, otherwise | |||
// it will concatenate the login and password | // it will concatenate the login and password | |||
// ready to be sent over http (but without | // ready to be sent over http (but without | |||
// base64 encoding). | // base64 encoding). | |||
std::string tracker_login() const; | std::string tracker_login() const; | |||
// generate the tracker key for this torrent. | // generate the tracker key for this torrent. | |||
// The key is passed to http trackers as ``&key=``. | // The key is passed to http trackers as ``&key=``. | |||
boost::uint32_t tracker_key() const; | boost::uint32_t tracker_key() const; | |||
// if we need a connect boost, connect some peers | ||||
// immediately | ||||
void do_connect_boost(); | ||||
// returns the absolute time when the next tracker | // returns the absolute time when the next tracker | |||
// announce will take place. | // announce will take place. | |||
ptime next_announce() const; | ptime next_announce() const; | |||
// forcefully sets next_announce to the current time | // forcefully sets next_announce to the current time | |||
void force_tracker_request(); | void force_tracker_request(ptime, int tracker_idx); | |||
void force_tracker_request(ptime); | ||||
void scrape_tracker(); | void scrape_tracker(); | |||
void announce_with_tracker(tracker_request::event_t e | void announce_with_tracker(tracker_request::event_t e | |||
= tracker_request::none | = tracker_request::none | |||
, address const& bind_interface = address_v4::any()) ; | , address const& bind_interface = address_v4::any()) ; | |||
int seconds_since_last_scrape() const { return m_last_scrape ; } | int seconds_since_last_scrape() const { return m_last_scrape ; } | |||
#ifndef TORRENT_DISABLE_DHT | #ifndef TORRENT_DISABLE_DHT | |||
void dht_announce(); | void dht_announce(); | |||
#endif | #endif | |||
skipping to change at line 496 | skipping to change at line 540 | |||
// -------------------------------------------- | // -------------------------------------------- | |||
// PIECE MANAGEMENT | // PIECE MANAGEMENT | |||
void recalc_share_mode(); | void recalc_share_mode(); | |||
void update_sparse_piece_prio(int piece, int cursor, int rev erse_cursor); | void update_sparse_piece_prio(int piece, int cursor, int rev erse_cursor); | |||
void get_suggested_pieces(std::vector<int>& s) const; | void get_suggested_pieces(std::vector<int>& s) const; | |||
bool super_seeding() const | bool super_seeding() const | |||
{ return m_super_seeding; } | { | |||
// we're not super seeding if we're not a seed | ||||
return m_super_seeding && is_seed(); | ||||
} | ||||
void super_seeding(bool on); | void super_seeding(bool on); | |||
int get_piece_to_super_seed(bitfield const&); | int get_piece_to_super_seed(bitfield const&); | |||
// returns true if we have downloaded the given piece | // returns true if we have downloaded the given piece | |||
bool have_piece(int index) const | bool have_piece(int index) const | |||
{ | { | |||
if (!valid_metadata()) return false; | if (!valid_metadata()) return false; | |||
if (!has_picker()) return true; | if (!has_picker()) return true; | |||
return m_picker->have_piece(index); | return m_picker->have_piece(index); | |||
} | } | |||
// 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); | |||
int num_have() const | int num_have() const | |||
{ | { | |||
// pretend we have every piece when in seed mode | ||||
if (m_seed_mode) { | ||||
return m_torrent_file->num_pieces(); | ||||
} | ||||
return has_picker() | return has_picker() | |||
? m_picker->num_have() | ? m_picker->num_have() | |||
: m_torrent_file->num_pieces(); | : m_torrent_file->num_pieces(); | |||
} | } | |||
// when we get a have message, this is called for that piece | // when we get a have message, this is called for that piece | |||
void peer_has(int index) | void peer_has(int index, peer_connection const* peer) | |||
{ | { | |||
if (m_picker.get()) | if (has_picker()) | |||
{ | { | |||
TORRENT_ASSERT(!is_seed()); | m_picker->inc_refcount(index, peer); | |||
m_picker->inc_refcount(index); | ||||
} | } | |||
#ifdef TORRENT_DEBUG | #ifdef TORRENT_DEBUG | |||
else | else | |||
{ | { | |||
TORRENT_ASSERT(is_seed()); | TORRENT_ASSERT(is_seed()); | |||
} | } | |||
#endif | #endif | |||
} | } | |||
// when we get a bitfield message, this is called for that p iece | // when we get a bitfield message, this is called for that p iece | |||
void peer_has(bitfield const& bits) | void peer_has(bitfield const& bits, peer_connection const* p eer) | |||
{ | { | |||
if (m_picker.get()) | if (has_picker()) | |||
{ | { | |||
TORRENT_ASSERT(!is_seed()); | if (bits.all_set() && bits.size() > 0) | |||
m_picker->inc_refcount(bits); | m_picker->inc_refcount_all(peer); | |||
else | ||||
m_picker->inc_refcount(bits, peer); | ||||
} | } | |||
#ifdef TORRENT_DEBUG | #ifdef TORRENT_DEBUG | |||
else | else | |||
{ | { | |||
TORRENT_ASSERT(is_seed()); | TORRENT_ASSERT(is_seed()); | |||
} | } | |||
#endif | #endif | |||
} | } | |||
void peer_has_all() | void peer_has_all(peer_connection const* peer) | |||
{ | { | |||
if (m_picker.get()) | if (has_picker()) | |||
{ | { | |||
TORRENT_ASSERT(!is_seed()); | m_picker->inc_refcount_all(peer); | |||
m_picker->inc_refcount_all(); | ||||
} | } | |||
#ifdef TORRENT_DEBUG | #ifdef TORRENT_DEBUG | |||
else | else | |||
{ | { | |||
TORRENT_ASSERT(is_seed()); | TORRENT_ASSERT(is_seed()); | |||
} | } | |||
#endif | #endif | |||
} | } | |||
void peer_lost(int index) | void peer_lost(bitfield const& bits, peer_connection const* peer) | |||
{ | { | |||
if (m_picker.get()) | if (has_picker()) | |||
{ | { | |||
TORRENT_ASSERT(!is_seed()); | if (bits.all_set() && bits.size() > 0) | |||
m_picker->dec_refcount(index); | m_picker->dec_refcount_all(peer); | |||
else | ||||
m_picker->dec_refcount(bits, peer); | ||||
} | ||||
#ifdef TORRENT_DEBUG | ||||
else | ||||
{ | ||||
TORRENT_ASSERT(is_seed()); | ||||
} | ||||
#endif | ||||
} | ||||
void peer_lost(int index, peer_connection const* peer) | ||||
{ | ||||
if (has_picker()) | ||||
{ | ||||
m_picker->dec_refcount(index, peer); | ||||
} | } | |||
#ifdef TORRENT_DEBUG | #ifdef TORRENT_DEBUG | |||
else | else | |||
{ | { | |||
TORRENT_ASSERT(is_seed()); | TORRENT_ASSERT(is_seed()); | |||
} | } | |||
#endif | #endif | |||
} | } | |||
int block_size() const { TORRENT_ASSERT(m_block_size_shift > 0); return 1 << m_block_size_shift; } | int block_size() const { TORRENT_ASSERT(m_block_size_shift > 0); return 1 << m_block_size_shift; } | |||
skipping to change at line 676 | skipping to change at line 744 | |||
} | } | |||
// this is true if we have all the pieces that we want | // this is true if we have all the pieces that we want | |||
bool is_finished() const | bool is_finished() const | |||
{ | { | |||
if (is_seed()) return true; | if (is_seed()) return true; | |||
return valid_metadata() && m_torrent_file->num_piece s() | return valid_metadata() && m_torrent_file->num_piece s() | |||
- m_picker->num_have() - m_picker->num_filte red() == 0; | - m_picker->num_have() - m_picker->num_filte red() == 0; | |||
} | } | |||
bool is_inactive() const | ||||
{ return m_inactive; } | ||||
std::string save_path() const; | std::string save_path() const; | |||
alert_manager& alerts() const; | alert_manager& alerts() const; | |||
piece_picker& picker() | piece_picker& picker() | |||
{ | { | |||
TORRENT_ASSERT(m_picker.get()); | TORRENT_ASSERT(m_picker.get()); | |||
return *m_picker; | return *m_picker; | |||
} | } | |||
bool has_picker() const | bool has_picker() const | |||
{ | { | |||
return m_picker.get() != 0; | return m_picker.get() != 0; | |||
} | } | |||
policy& get_policy() { return m_policy; } | policy& get_policy() { return m_policy; } | |||
piece_manager& filesystem(); | piece_manager& filesystem(); | |||
torrent_info const& torrent_file() const | torrent_info const& torrent_file() const | |||
{ return *m_torrent_file; } | { return *m_torrent_file; } | |||
boost::intrusive_ptr<torrent_info const> get_torrent_copy(); | ||||
std::string const& uuid() const { return m_uuid; } | std::string const& uuid() const { return m_uuid; } | |||
void set_uuid(std::string const& s) { m_uuid = s; } | void set_uuid(std::string const& s) { m_uuid = s; } | |||
std::string const& url() const { return m_url; } | std::string const& url() const { return m_url; } | |||
void set_url(std::string const& s) { m_url = s; } | void set_url(std::string const& s) { m_url = s; } | |||
std::string const& source_feed_url() const { return m_source _feed_url; } | std::string const& source_feed_url() const { return m_source _feed_url; } | |||
void set_source_feed_url(std::string const& s) { m_source_fe ed_url = s; } | void set_source_feed_url(std::string const& s) { m_source_fe ed_url = s; } | |||
std::vector<announce_entry> const& trackers() const | std::vector<announce_entry> const& trackers() const | |||
{ return m_trackers; } | { return m_trackers; } | |||
skipping to change at line 724 | skipping to change at line 797 | |||
void seen_complete() { m_last_seen_complete = time(0); } | void seen_complete() { m_last_seen_complete = time(0); } | |||
int time_since_complete() const { return int(time(0) - m_las t_seen_complete); } | int time_since_complete() const { return int(time(0) - m_las t_seen_complete); } | |||
time_t last_seen_complete() const { return m_last_seen_compl ete; } | time_t last_seen_complete() const { return m_last_seen_compl ete; } | |||
// LOGGING | // LOGGING | |||
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T ORRENT_ERROR_LOGGING | #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T ORRENT_ERROR_LOGGING | |||
virtual void debug_log(const char* fmt, ...) const; | virtual void debug_log(const char* fmt, ...) const; | |||
#endif | #endif | |||
// DEBUG | // DEBUG | |||
#ifdef TORRENT_DEBUG | #if TORRENT_USE_INVARIANT_CHECKS | |||
void check_invariant() const; | void check_invariant() const; | |||
#endif | #endif | |||
// -------------------------------------------- | // -------------------------------------------- | |||
// RESOURCE MANAGEMENT | // RESOURCE MANAGEMENT | |||
void add_free_upload(size_type diff) | ||||
{ | ||||
TORRENT_ASSERT(diff >= 0); | ||||
if (UINT_MAX - m_available_free_upload > diff) | ||||
m_available_free_upload += boost::uint32_t(d | ||||
iff); | ||||
else | ||||
m_available_free_upload = UINT_MAX; | ||||
} | ||||
int get_peer_upload_limit(tcp::endpoint ip) const; | int get_peer_upload_limit(tcp::endpoint ip) const; | |||
int get_peer_download_limit(tcp::endpoint ip) const; | int get_peer_download_limit(tcp::endpoint ip) const; | |||
void set_peer_upload_limit(tcp::endpoint ip, int limit); | void set_peer_upload_limit(tcp::endpoint ip, int limit); | |||
void set_peer_download_limit(tcp::endpoint ip, int limit); | void set_peer_download_limit(tcp::endpoint ip, int limit); | |||
void set_upload_limit(int limit); | void set_upload_limit(int limit, bool state_update = true); | |||
int upload_limit() const; | int upload_limit() const; | |||
void set_download_limit(int limit); | void set_download_limit(int limit, bool state_update = true) ; | |||
int download_limit() const; | int download_limit() const; | |||
void set_max_uploads(int limit); | void set_max_uploads(int limit, bool state_update = true); | |||
int max_uploads() const { return m_max_uploads; } | int max_uploads() const { return m_max_uploads; } | |||
void set_max_connections(int limit); | void set_max_connections(int limit, bool state_update = true ); | |||
int max_connections() const { return m_max_connections; } | int max_connections() const { return m_max_connections; } | |||
void move_storage(std::string const& save_path); | // flags are defined in storage.hpp | |||
void move_storage(std::string const& save_path, int flags); | ||||
// renames the file with the given index to the new name | // renames the file with the given index to the new name | |||
// the name may include a directory path | // the name may include a directory path | |||
// returns false on failure | // returns false on failure | |||
bool rename_file(int index, std::string const& name); | bool rename_file(int index, std::string const& name); | |||
// unless this returns true, new connections must wait | // unless this returns true, new connections must wait | |||
// with their initialization. | // with their initialization. | |||
bool ready_for_connections() const | bool ready_for_connections() const | |||
{ return m_connections_initialized; } | { return m_connections_initialized; } | |||
skipping to change at line 784 | skipping to change at line 849 | |||
// of the storage. | // of the storage. | |||
// a return value of false indicates an error | // a return value of false indicates an error | |||
bool set_metadata(char const* metadata_buf, int metadata_siz e); | bool set_metadata(char const* metadata_buf, int metadata_siz e); | |||
void on_torrent_download(error_code const& ec, http_parser c onst& parser | void on_torrent_download(error_code const& ec, http_parser c onst& parser | |||
, char const* data, int size); | , char const* data, int size); | |||
int sequence_number() const { return m_sequence_number; } | int sequence_number() const { return m_sequence_number; } | |||
bool seed_mode() const { return m_seed_mode; } | bool seed_mode() const { return m_seed_mode; } | |||
void leave_seed_mode(bool seed) | void leave_seed_mode(bool seed); | |||
{ | ||||
if (!m_seed_mode) return; | ||||
m_seed_mode = false; | ||||
// seed is false if we turned out not | ||||
// to be a seed after all | ||||
if (!seed) force_recheck(); | ||||
m_num_verified = 0; | ||||
m_verified.free(); | ||||
} | ||||
bool all_verified() const | bool all_verified() const | |||
{ return int(m_num_verified) == m_torrent_file->num_pieces() ; } | { return int(m_num_verified) == m_torrent_file->num_pieces() ; } | |||
bool verified_piece(int piece) const | bool verified_piece(int piece) const | |||
{ | { | |||
TORRENT_ASSERT(piece < int(m_verified.size())); | TORRENT_ASSERT(piece < int(m_verified.size())); | |||
TORRENT_ASSERT(piece >= 0); | TORRENT_ASSERT(piece >= 0); | |||
return m_verified.get_bit(piece); | return m_verified.get_bit(piece); | |||
} | } | |||
void verified(int piece) | void verified(int piece); | |||
{ | ||||
TORRENT_ASSERT(piece < int(m_verified.size())); | ||||
TORRENT_ASSERT(piece >= 0); | ||||
TORRENT_ASSERT(m_verified.get_bit(piece) == false); | ||||
++m_num_verified; | ||||
m_verified.set_bit(piece); | ||||
} | ||||
bool add_merkle_nodes(std::map<int, sha1_hash> const& n, int piece); | bool add_merkle_nodes(std::map<int, sha1_hash> const& n, int piece); | |||
// this is called once periodically for torrents | // this is called once periodically for torrents | |||
// that are not private | // that are not private | |||
void lsd_announce(); | void lsd_announce(); | |||
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T | ||||
ORRENT_ERROR_LOGGING | ||||
static void print_size(logger& l); | ||||
#endif | ||||
void update_last_upload() { m_last_upload = 0; } | void update_last_upload() { m_last_upload = 0; } | |||
void set_apply_ip_filter(bool b); | void set_apply_ip_filter(bool b); | |||
bool apply_ip_filter() const { return m_apply_ip_filter; } | bool apply_ip_filter() const { return m_apply_ip_filter; } | |||
void queue_torrent_check(); | void queue_torrent_check(); | |||
void dequeue_torrent_check(); | void dequeue_torrent_check(); | |||
void clear_in_state_update() | void clear_in_state_update() | |||
{ m_in_state_updates = false; } | { m_in_state_updates = false; } | |||
skipping to change at line 846 | skipping to change at line 892 | |||
TORRENT_ASSERT(m_num_connecting > 0); | TORRENT_ASSERT(m_num_connecting > 0); | |||
--m_num_connecting; | --m_num_connecting; | |||
} | } | |||
bool is_ssl_torrent() const { return m_ssl_torrent; } | bool is_ssl_torrent() const { return m_ssl_torrent; } | |||
#ifdef TORRENT_USE_OPENSSL | #ifdef TORRENT_USE_OPENSSL | |||
void set_ssl_cert(std::string const& certificate | void set_ssl_cert(std::string const& certificate | |||
, std::string const& private_key | , std::string const& private_key | |||
, std::string const& dh_params | , std::string const& dh_params | |||
, std::string const& passphrase); | , std::string const& passphrase); | |||
void set_ssl_cert_buffer(std::string const& certificate | ||||
, std::string const& private_key | ||||
, std::string const& dh_params); | ||||
boost::asio::ssl::context* ssl_ctx() const { return m_ssl_ct x.get(); } | boost::asio::ssl::context* ssl_ctx() const { return m_ssl_ct x.get(); } | |||
#endif | #endif | |||
int num_time_critical_pieces() const | ||||
{ return m_time_critical_pieces.size(); } | ||||
private: | private: | |||
void on_files_deleted(int ret, disk_io_job const& j); | void on_files_deleted(int ret, disk_io_job const& j); | |||
void on_files_released(int ret, disk_io_job const& j); | void on_files_released(int ret, disk_io_job const& j); | |||
void on_torrent_paused(int ret, disk_io_job const& j); | void on_torrent_paused(int ret, disk_io_job const& j); | |||
void on_storage_moved(int ret, disk_io_job const& j); | void on_storage_moved(int ret, disk_io_job const& j); | |||
void on_save_resume_data(int ret, disk_io_job const& j); | void on_save_resume_data(int ret, disk_io_job const& j); | |||
void on_file_renamed(int ret, disk_io_job const& j); | void on_file_renamed(int ret, disk_io_job const& j); | |||
void on_cache_flushed(int ret, disk_io_job const& j); | void on_cache_flushed(int ret, disk_io_job const& j); | |||
skipping to change at line 942 | skipping to change at line 994 | |||
#ifdef TORRENT_USE_OPENSSL | #ifdef TORRENT_USE_OPENSSL | |||
boost::shared_ptr<asio::ssl::context> m_ssl_ctx; | boost::shared_ptr<asio::ssl::context> m_ssl_ctx; | |||
#if BOOST_VERSION >= 104700 | #if BOOST_VERSION >= 104700 | |||
bool verify_peer_cert(bool preverified, boost::asio::ssl::ve rify_context& ctx); | bool verify_peer_cert(bool preverified, boost::asio::ssl::ve rify_context& ctx); | |||
#endif | #endif | |||
void init_ssl(std::string const& cert); | void init_ssl(std::string const& cert); | |||
#endif | #endif | |||
#ifdef TORRENT_DEBUG | ||||
public: | ||||
#endif | ||||
std::set<peer_connection*> m_connections; | std::set<peer_connection*> m_connections; | |||
#ifdef TORRENT_DEBUG | ||||
private: | ||||
#endif | ||||
// of all peers in m_connections, this is the number | // of all peers in m_connections, this is the number | |||
// of peers that are outgoing and still waiting to | // of peers that are outgoing and still waiting to | |||
// complete the connection. This is used to possibly | // complete the connection. This is used to possibly | |||
// kick out these connections when we get incoming | // kick out these connections when we get incoming | |||
// connections (if we've reached the connection limit) | // connections (if we've reached the connection limit) | |||
int m_num_connecting; | int m_num_connecting; | |||
// The list of web seeds in this torrent. Seeds | // The list of web seeds in this torrent. Seeds | |||
// with fatal errors are removed from the set | // with fatal errors are removed from the set | |||
skipping to change at line 994 | skipping to change at line 1040 | |||
// this vector contains the number of bytes completely | // this vector contains the number of bytes completely | |||
// downloaded (as in passed-hash-check) in each file. | // downloaded (as in passed-hash-check) in each file. | |||
// this lets us trigger on individual files completing | // this lets us trigger on individual files completing | |||
std::vector<size_type> m_file_progress; | std::vector<size_type> m_file_progress; | |||
boost::scoped_ptr<piece_picker> m_picker; | boost::scoped_ptr<piece_picker> m_picker; | |||
std::vector<announce_entry> m_trackers; | std::vector<announce_entry> m_trackers; | |||
// this is an index into m_trackers | // this is an index into m_trackers | |||
struct time_critical_piece | ||||
{ | ||||
// when this piece was first requested | ||||
ptime first_requested; | ||||
// when this piece was last requested | ||||
ptime last_requested; | ||||
// by what time we want this piece | ||||
ptime deadline; | ||||
// 1 = send alert with piece data when available | ||||
int flags; | ||||
// how many peers it's been requested from | ||||
int peers; | ||||
// the piece index | ||||
int piece; | ||||
bool operator<(time_critical_piece const& rhs) const | ||||
{ return deadline < rhs.deadline; } | ||||
}; | ||||
// this list is sorted by time_critical_piece::deadline | // this list is sorted by time_critical_piece::deadline | |||
std::deque<time_critical_piece> m_time_critical_pieces; | std::deque<time_critical_piece> m_time_critical_pieces; | |||
std::string m_trackerid; | std::string m_trackerid; | |||
std::string m_username; | std::string m_username; | |||
std::string m_password; | std::string m_password; | |||
// the network interfaces outgoing connections | // the network interfaces outgoing connections | |||
// are opened through. If there is more then one, | // are opened through. If there is more then one, | |||
// they are used in a round-robin fasion | // they are used in a round-robin fasion | |||
skipping to change at line 1070 | skipping to change at line 1098 | |||
// longer be used and will be reset | // longer be used and will be reset | |||
boost::scoped_ptr<std::string> m_name; | boost::scoped_ptr<std::string> m_name; | |||
storage_constructor_type m_storage_constructor; | storage_constructor_type m_storage_constructor; | |||
// the posix time this torrent was added and when | // the posix time this torrent was added and when | |||
// it was completed. If the torrent isn't yet | // it was completed. If the torrent isn't yet | |||
// completed, m_completed_time is 0 | // completed, m_completed_time is 0 | |||
time_t m_added_time; | time_t m_added_time; | |||
time_t m_completed_time; | time_t m_completed_time; | |||
time_t m_last_seen_complete; | ||||
time_t m_last_saved_resume; | time_t m_last_saved_resume; | |||
// this was the last time _we_ saw a seed in this swarm | ||||
time_t m_last_seen_complete; | ||||
// this is the time last any of our peers saw a seed | ||||
// in this swarm | ||||
time_t m_swarm_last_seen_complete; | ||||
// m_num_verified = m_verified.count() | ||||
boost::uint32_t m_num_verified; | ||||
#ifndef TORRENT_DISABLE_ENCRYPTION | #ifndef TORRENT_DISABLE_ENCRYPTION | |||
// this is SHA1("req2" + info-hash), used for | // this is SHA1("req2" + info-hash), used for | |||
// encrypted hand shakes | // encrypted hand shakes | |||
sha1_hash m_obfuscated_hash; | sha1_hash m_obfuscated_hash; | |||
#endif | #endif | |||
// the upload/download ratio that each peer | ||||
// tries to maintain. | ||||
// 0 is infinite | ||||
float m_ratio; | ||||
// free download we have got that hasn't | ||||
// been distributed yet. | ||||
boost::uint32_t m_available_free_upload; | ||||
// the average time it takes to download one time critical p iece | // the average time it takes to download one time critical p iece | |||
boost::uint32_t m_average_piece_time; | boost::uint32_t m_average_piece_time; | |||
// the average piece download time deviation | // the average piece download time deviation | |||
boost::uint32_t m_piece_time_deviation; | boost::uint32_t m_piece_time_deviation; | |||
// the number of bytes that has been | // the number of bytes that has been | |||
// downloaded that failed the hash-test | // downloaded that failed the hash-test | |||
boost::uint32_t m_total_failed_bytes; | boost::uint32_t m_total_failed_bytes; | |||
boost::uint32_t m_total_redundant_bytes; | boost::uint32_t m_total_redundant_bytes; | |||
skipping to change at line 1133 | skipping to change at line 1161 | |||
// is in use. i.e. one or more trackers are waiting | // is in use. i.e. one or more trackers are waiting | |||
// for a reannounce | // for a reannounce | |||
bool m_waiting_tracker:1; | bool m_waiting_tracker:1; | |||
// this means we haven't verified the file content | // this means we haven't verified the file content | |||
// of the files we're seeding. the m_verified bitfield | // of the files we're seeding. the m_verified bitfield | |||
// indicates which pieces have been verified and which | // indicates which pieces have been verified and which | |||
// haven't | // haven't | |||
bool m_seed_mode:1; | bool m_seed_mode:1; | |||
// ---- | ||||
// total time we've been available on this torrent | // total time we've been available on this torrent | |||
// does not count when the torrent is stopped or paused | // does not count when the torrent is stopped or paused | |||
// in seconds | // in seconds | |||
unsigned int m_active_time:24; | unsigned int m_active_time:24; | |||
// the index to the last tracker that worked | // the index to the last tracker that worked | |||
boost::int8_t m_last_working_tracker; | boost::int8_t m_last_working_tracker; | |||
// ---- | ||||
// total time we've been finished with this torrent | // total time we've been finished with this torrent | |||
// does not count when the torrent is stopped or paused | // does not count when the torrent is stopped or paused | |||
unsigned int m_finished_time:24; | unsigned int m_finished_time:24; | |||
// in case the piece picker hasn't been constructed | // in case the piece picker hasn't been constructed | |||
// when this settings is set, this variable will keep | // when this settings is set, this variable will keep | |||
// its value until the piece picker is created | // its value until the piece picker is created | |||
bool m_sequential_download:1; | bool m_sequential_download:1; | |||
// is false by default and set to | // is false by default and set to | |||
skipping to change at line 1174 | skipping to change at line 1206 | |||
bool m_connections_initialized:1; | bool m_connections_initialized:1; | |||
// if this is true, we're currently super seeding this | // if this is true, we're currently super seeding this | |||
// torrent. | // torrent. | |||
bool m_super_seeding:1; | bool m_super_seeding:1; | |||
// this is set when we don't want to load seed_mode, | // this is set when we don't want to load seed_mode, | |||
// paused or auto_managed from the resume data | // paused or auto_managed from the resume data | |||
bool m_override_resume_data:1; | bool m_override_resume_data:1; | |||
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES | ||||
// this is true while there is a country | // this is true while there is a country | |||
// resolution in progress. To avoid flodding | // resolution in progress. To avoid flodding | |||
// the DNS request queue, only one ip is resolved | // the DNS request queue, only one ip is resolved | |||
// at a time. | // at a time. | |||
mutable bool m_resolving_country:1; | mutable bool m_resolving_country:1; | |||
// this is true if the user has enabled | // this is true if the user has enabled | |||
// country resolution in this torrent | // country resolution in this torrent | |||
bool m_resolve_countries:1; | bool m_resolve_countries:1; | |||
#else | ||||
unsigned int m_dummy_padding_bits_to_align:2; | ||||
#endif | ||||
// set to false when saving resume data. Set to true | // set to false when saving resume data. Set to true | |||
// whenever something is downloaded | // whenever something is downloaded | |||
bool m_need_save_resume_data:1; | bool m_need_save_resume_data:1; | |||
// ---- | ||||
// total time we've been available as a seed on this torrent | // total time we've been available as a seed on this torrent | |||
// does not count when the torrent is stopped or paused | // does not count when the torrent is stopped or paused | |||
unsigned int m_seeding_time:24; | unsigned int m_seeding_time:24; | |||
// this is a counter that is decreased every | // this is a counter that is decreased every | |||
// second, and when it reaches 0, the policy::pulse() | // second, and when it reaches 0, the policy::pulse() | |||
// is called and the time scaler is reset to 10. | // is called and the time scaler is reset to 10. | |||
boost::int8_t m_time_scaler; | boost::int8_t m_time_scaler; | |||
// ---- | ||||
// the maximum number of uploads for this torrent | // the maximum number of uploads for this torrent | |||
unsigned int m_max_uploads:24; | unsigned int m_max_uploads:24; | |||
// these are the flags sent in on a call to save_resume_data | // these are the flags sent in on a call to save_resume_data | |||
// we need to save them to check them in write_resume_data | // we need to save them to check them in write_resume_data | |||
boost::uint8_t m_save_resume_flags; | boost::uint8_t m_save_resume_flags; | |||
// ---- | ||||
// the number of unchoked peers in this torrent | // the number of unchoked peers in this torrent | |||
unsigned int m_num_uploads:24; | unsigned int m_num_uploads:24; | |||
// the size of a request block | // the size of a request block | |||
// each piece is divided into these | // each piece is divided into these | |||
// blocks when requested. The block size is | // blocks when requested. The block size is | |||
// 1 << m_block_size_shift | // 1 << m_block_size_shift | |||
unsigned int m_block_size_shift:5; | unsigned int m_block_size_shift:5; | |||
// is set to true every time there is an incoming | // is set to true every time there is an incoming | |||
skipping to change at line 1230 | skipping to change at line 1264 | |||
// this is set to true when the files are checked | // this is set to true when the files are checked | |||
// before the files are checked, we don't try to | // before the files are checked, we don't try to | |||
// connect to peers | // connect to peers | |||
bool m_files_checked:1; | bool m_files_checked:1; | |||
// this is true if the torrent has been added to | // this is true if the torrent has been added to | |||
// checking queue in the session | // checking queue in the session | |||
bool m_queued_for_checking:1; | bool m_queued_for_checking:1; | |||
// ---- | ||||
// the maximum number of connections for this torrent | // the maximum number of connections for this torrent | |||
unsigned int m_max_connections:24; | unsigned int m_max_connections:24; | |||
// the number of bytes of padding files | // set to true when this torrent has been paused but | |||
unsigned int m_padding:24; | // is waiting to finish all current download requests | |||
// before actually closing all connections | ||||
bool m_graceful_pause_mode:1; | ||||
// the scrape data from the tracker response, this | // this is set to true when the torrent starts up | |||
// is optional and may be 0xffffff | // The first tracker response, when this is true, | |||
unsigned int m_complete:24; | // will attempt to connect to a bunch of peers immediately | |||
// and set this to false. We only do this once to get | ||||
// the torrent kick-started | ||||
bool m_need_connect_boost:1; | ||||
// rotating sequence number for LSD announces sent out. | ||||
// used to only use IP broadcast for every 8th lsd announce | ||||
boost::uint8_t m_lsd_seq:3; | ||||
// this is set to true if the torrent was started without | ||||
// metadata. It is used to save metadata in the resume file | ||||
// by default for such torrents. It does not necessarily | ||||
// have to be a magnet link. | ||||
bool m_magnet_link:1; | ||||
// set to true if the session IP filter applies to this | ||||
// torrent or not. Defaults to true. | ||||
bool m_apply_ip_filter:1; | ||||
// if set to true, add tracker URLs loaded from resume | ||||
// data into this torrent instead of replacing them | ||||
bool m_merge_resume_trackers:1; | ||||
// ---- | ||||
// the number of bytes of padding files | ||||
boost::uint32_t m_padding:24; | ||||
// this is the priority of the torrent. The higher | // this is the priority of the torrent. The higher | |||
// the value is, the more bandwidth is assigned to | // the value is, the more bandwidth is assigned to | |||
// the torrent's peers | // the torrent's peers | |||
boost::uint8_t m_priority; | boost::uint32_t m_priority:8; | |||
// ---- | ||||
// the scrape data from the tracker response, this | // the scrape data from the tracker response, this | |||
// is optional and may be 0xffffff | // is optional and may be 0xffffff | |||
unsigned int m_incomplete:24; | boost::uint32_t m_complete:24; | |||
// progress parts per million (the number of | // state subscription. If set, a pointer to this torrent | |||
// millionths of completeness) | // will be added to the m_state_updates set in session_impl | |||
unsigned int m_progress_ppm:20; | // whenever this torrent's state changes (any state). | |||
bool m_state_subscription:1; | ||||
// in state_updates list. When adding a torrent to the | ||||
// session_impl's m_state_update list, this bit is set | ||||
// to never add the same torrent twice | ||||
bool m_in_state_updates:1; | ||||
// these represent whether or not this torrent is counted | ||||
// in the total counters of active seeds and downloads | ||||
// in the session. | ||||
bool m_is_active_download:1; | ||||
bool m_is_active_finished:1; | ||||
// even if we're not built to support SSL torrents, | ||||
// remember that this is an SSL torrent, so that we don't | ||||
// accidentally start seeding it without any authentication. | ||||
bool m_ssl_torrent:1; | ||||
// this is set to true if we're trying to delete the | ||||
// files belonging to it. When set, don't write any | ||||
// more blocks to disk! | ||||
bool m_deleted:1; | ||||
// set to true while moving the storage | ||||
bool m_moving_storage:1; | ||||
// this is true if this torrent is considered inactive from | ||||
the | ||||
// queuing mechanism's point of view. If a torrent doesn't t | ||||
ransfer | ||||
// at high enough rates, it's inactive. | ||||
bool m_inactive:1; | ||||
// ---- | ||||
// the scrape data from the tracker response, this | ||||
// is optional and may be 0xffffff | ||||
boost::uint32_t m_incomplete:24; | ||||
// is set to true when the torrent has | // is set to true when the torrent has | |||
// been aborted. | // been aborted. | |||
bool m_abort:1; | bool m_abort:1; | |||
// true when the torrent should announce to | // true when the torrent should announce to | |||
// the DHT | // the DHT | |||
bool m_announce_to_dht:1; | bool m_announce_to_dht:1; | |||
// true when this torrent should anncounce to | // true when this torrent should anncounce to | |||
skipping to change at line 1285 | skipping to change at line 1387 | |||
// if this is true, libtorrent may pause and resume | // if this is true, libtorrent may pause and resume | |||
// this torrent depending on queuing rules. Torrents | // this torrent depending on queuing rules. Torrents | |||
// started with auto_managed flag set may be added in | // started with auto_managed flag set may be added in | |||
// a paused state in case there are no available | // a paused state in case there are no available | |||
// slots. | // slots. | |||
bool m_auto_managed:1; | bool m_auto_managed:1; | |||
// this is set when the torrent is in share-mode | // this is set when the torrent is in share-mode | |||
bool m_share_mode:1; | bool m_share_mode:1; | |||
// m_num_verified = m_verified.count() | // ---- | |||
boost::uint32_t m_num_verified; | ||||
// the number of seconds since the last scrape request to | ||||
// one of the trackers in this torrent | ||||
boost::uint32_t m_last_scrape; | ||||
// the number of seconds since the last piece passed for | // the number of seconds since the last piece passed for | |||
// this torrent | // this torrent | |||
boost::uint32_t m_last_download; | boost::uint64_t m_last_download:24; | |||
// the number of seconds since the last scrape request to | ||||
// one of the trackers in this torrent | ||||
boost::uint64_t m_last_scrape:16; | ||||
// the number of seconds since the last byte was uploaded | // the number of seconds since the last byte was uploaded | |||
// from this torrent | // from this torrent | |||
boost::uint32_t m_last_upload; | boost::uint64_t m_last_upload:24; | |||
// ---- | ||||
// the scrape data from the tracker response, this | // the scrape data from the tracker response, this | |||
// is optional and may be 0xffffff | // is optional and may be 0xffffff | |||
unsigned int m_downloaders:24; | unsigned int m_downloaded:24; | |||
// round-robin index into m_interfaces | // round-robin index into m_interfaces | |||
mutable boost::uint8_t m_interface_index; | mutable boost::uint8_t m_interface_index; | |||
// set to true when this torrent has been paused but | // ---- | |||
// is waiting to finish all current download requests | ||||
// before actually closing all connections | ||||
bool m_graceful_pause_mode:1; | ||||
// this is set to true when the torrent starts up | ||||
// The first tracker response, when this is true, | ||||
// will attempt to connect to a bunch of peers immediately | ||||
// and set this to false. We only do this once to get | ||||
// the torrent kick-started | ||||
bool m_need_connect_boost:1; | ||||
// rotating sequence number for LSD announces sent out. | ||||
// used to only use IP broadcast for every 8th lsd announce | ||||
boost::uint8_t m_lsd_seq:3; | ||||
// this is set to true if the torrent was started without | ||||
// metadata. It is used to save metadata in the resume file | ||||
// by default for such torrents. It does not necessarily | ||||
// have to be a magnet link. | ||||
bool m_magnet_link:1; | ||||
// set to true if the session IP filter applies to this | ||||
// torrent or not. Defaults to true. | ||||
bool m_apply_ip_filter:1; | ||||
// if set to true, add tracker URLs loaded from resume | ||||
// data into this torrent instead of replacing them | ||||
bool m_merge_resume_trackers:1; | ||||
// state subscription. If set, a pointer to this torrent | ||||
// will be added to the m_state_updates set in session_impl | ||||
// whenever this torrent's state changes (any state). | ||||
bool m_state_subscription:1; | ||||
// in state_updates list. When adding a torrent to the | // progress parts per million (the number of | |||
// session_impl's m_state_update list, this bit is set | // millionths of completeness) | |||
// to never add the same torrent twice | unsigned int m_progress_ppm:20; | |||
bool m_in_state_updates:1; | ||||
// even if we're not built to support SSL torrents, | // the number of seconds this torrent has been under the ina | |||
// remember that this is an SSL torrent, so that we don't | ctive | |||
// accidentally start seeding it without any authentication. | // threshold in terms of sending and receiving data. When th | |||
bool m_ssl_torrent:1; | is counter | |||
// reaches the settings.inactive_torrent_timeout it will be | ||||
considered | ||||
// inactive and possibly open up another queue slot, to star | ||||
t another, | ||||
// queued, torrent. Every second it's above the threshold | ||||
boost::int16_t m_inactive_counter; | ||||
// if this is set, accept the save path saved in the resume | ||||
data, if | ||||
// present | ||||
bool m_use_resume_save_path:1; | ||||
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS | #if TORRENT_USE_ASSERTS | |||
public: | public: | |||
// set to false until we've loaded resume data | // set to false until we've loaded resume data | |||
bool m_resume_data_loaded; | bool m_resume_data_loaded; | |||
#endif | #endif | |||
}; | }; | |||
} | } | |||
#endif // TORRENT_TORRENT_HPP_INCLUDED | #endif // TORRENT_TORRENT_HPP_INCLUDED | |||
End of changes. 73 change blocks. | ||||
171 lines changed or deleted | 252 lines changed or added | |||
torrent_handle.hpp | torrent_handle.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2003, Arvid Norberg | Copyright (c) 2003-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 47 | skipping to change at line 47 | |||
#include <set> | #include <set> | |||
#ifdef _MSC_VER | #ifdef _MSC_VER | |||
#pragma warning(push, 1) | #pragma warning(push, 1) | |||
#endif | #endif | |||
#include <boost/assert.hpp> | #include <boost/assert.hpp> | |||
#include <boost/date_time/posix_time/posix_time_duration.hpp> | #include <boost/date_time/posix_time/posix_time_duration.hpp> | |||
#include <boost/shared_ptr.hpp> | #include <boost/shared_ptr.hpp> | |||
#include <boost/weak_ptr.hpp> | #include <boost/weak_ptr.hpp> | |||
#include <boost/cstdint.hpp> | ||||
#ifdef _MSC_VER | #ifdef _MSC_VER | |||
#pragma warning(pop) | #pragma warning(pop) | |||
#endif | #endif | |||
#include "libtorrent/peer_id.hpp" | #include "libtorrent/peer_id.hpp" | |||
#include "libtorrent/piece_picker.hpp" | #include "libtorrent/piece_picker.hpp" | |||
#include "libtorrent/torrent_info.hpp" | #include "libtorrent/torrent_info.hpp" | |||
#include "libtorrent/ptime.hpp" | #include "libtorrent/ptime.hpp" | |||
#include "libtorrent/config.hpp" | #include "libtorrent/config.hpp" | |||
skipping to change at line 75 | skipping to change at line 76 | |||
{ | { | |||
struct session_impl; | struct session_impl; | |||
} | } | |||
struct torrent_plugin; | struct torrent_plugin; | |||
struct peer_info; | struct peer_info; | |||
struct peer_list_entry; | struct peer_list_entry; | |||
struct torrent_status; | struct torrent_status; | |||
class torrent; | class torrent; | |||
// allows torrent_handle to be used in unordered_map and unordered_s et. | ||||
TORRENT_EXPORT std::size_t hash_value(torrent_status const& ts); | TORRENT_EXPORT std::size_t hash_value(torrent_status const& ts); | |||
#ifndef BOOST_NO_EXCEPTIONS | #ifndef BOOST_NO_EXCEPTIONS | |||
// for compatibility with 0.14 | // for compatibility with 0.14 | |||
typedef libtorrent_exception duplicate_torrent; | typedef libtorrent_exception duplicate_torrent; | |||
typedef libtorrent_exception invalid_handle; | typedef libtorrent_exception invalid_handle; | |||
void throw_invalid_handle(); | void throw_invalid_handle(); | |||
#endif | #endif | |||
// holds the state of a block in a piece. Who we requested | ||||
// it from and how far along we are at downloading it. | ||||
struct TORRENT_EXPORT block_info | struct TORRENT_EXPORT block_info | |||
{ | { | |||
// this is the enum used for the block_info::state field. | ||||
enum block_state_t | enum block_state_t | |||
{ none, requested, writing, finished }; | { | |||
// This block has not been downloaded or requested f | ||||
orm any peer. | ||||
none, | ||||
// The block has been requested, but not completely | ||||
downloaded yet. | ||||
requested, | ||||
// The block has been downloaded and is currently qu | ||||
eued for being | ||||
// written to disk. | ||||
writing, | ||||
// The block has been written to disk. | ||||
finished | ||||
}; | ||||
private: | private: | |||
TORRENT_UNION addr_t | TORRENT_UNION addr_t | |||
{ | { | |||
address_v4::bytes_type v4; | address_v4::bytes_type v4; | |||
#if TORRENT_USE_IPV6 | #if TORRENT_USE_IPV6 | |||
address_v6::bytes_type v6; | address_v6::bytes_type v6; | |||
#endif | #endif | |||
} addr; | } addr; | |||
boost::uint16_t port; | boost::uint16_t port; | |||
public: | public: | |||
// The peer is the ip address of the peer this block was dow nloaded from. | ||||
void set_peer(tcp::endpoint const& ep) | void set_peer(tcp::endpoint const& ep) | |||
{ | { | |||
#if TORRENT_USE_IPV6 | #if TORRENT_USE_IPV6 | |||
is_v6_addr = ep.address().is_v6(); | is_v6_addr = ep.address().is_v6(); | |||
if (is_v6_addr) | if (is_v6_addr) | |||
addr.v6 = ep.address().to_v6().to_bytes(); | addr.v6 = ep.address().to_v6().to_bytes(); | |||
else | else | |||
#endif | #endif | |||
addr.v4 = ep.address().to_v4().to_bytes(); | addr.v4 = ep.address().to_v4().to_bytes(); | |||
port = ep.port(); | port = ep.port(); | |||
} | } | |||
tcp::endpoint peer() const | tcp::endpoint peer() const | |||
{ | { | |||
#if TORRENT_USE_IPV6 | #if TORRENT_USE_IPV6 | |||
if (is_v6_addr) | if (is_v6_addr) | |||
return tcp::endpoint(address_v6(addr.v6), po rt); | return tcp::endpoint(address_v6(addr.v6), po rt); | |||
else | else | |||
#endif | #endif | |||
return tcp::endpoint(address_v4(addr.v4), po rt); | return tcp::endpoint(address_v4(addr.v4), po rt); | |||
} | } | |||
// number of bytes downloaded in this block | // the number of bytes that have been received for this bloc k | |||
unsigned bytes_progress:15; | unsigned bytes_progress:15; | |||
// the total number of bytes in this block | ||||
// the total number of bytes in this block. | ||||
unsigned block_size:15; | unsigned block_size:15; | |||
private: | ||||
// the type of the addr union | ||||
unsigned is_v6_addr:1; | ||||
unsigned unused:1; | ||||
public: | ||||
// the state this block is in (see block_state_t) | // the state this block is in (see block_state_t) | |||
unsigned state:2; | unsigned state:2; | |||
// the number of peers that has requested this block | ||||
// typically 0 or 1. If > 1, this block is in | // the number of peers that is currently requesting this blo | |||
// end game mode | ck. Typically | |||
// this is 0 or 1, but at the end of the torrent blocks may | ||||
be requested | ||||
// by more peers in parallel to speed things up. | ||||
unsigned num_peers:14; | unsigned num_peers:14; | |||
private: | ||||
#if TORRENT_USE_IPV6 | ||||
// the type of the addr union | ||||
unsigned is_v6_addr:1; | ||||
#endif | ||||
}; | }; | |||
// This class holds information about pieces that have outstanding r | ||||
equests | ||||
// or outstanding writes | ||||
struct TORRENT_EXPORT partial_piece_info | struct TORRENT_EXPORT partial_piece_info | |||
{ | { | |||
// the index of the piece in question. ``blocks_in_piece`` i | ||||
s the number | ||||
// of blocks in this particular piece. This number will be t | ||||
he same for | ||||
// most pieces, but | ||||
// the last piece may have fewer blocks than the standard pi | ||||
eces. | ||||
int piece_index; | int piece_index; | |||
// the number of blocks in this piece | ||||
int blocks_in_piece; | int blocks_in_piece; | |||
// the number of blocks in the finished state | ||||
// the number of blocks that are in the finished state | ||||
int finished; | int finished; | |||
// the number of blocks in the writing state | ||||
// the number of blocks that are in the writing state | ||||
int writing; | int writing; | |||
// the number of blocks in the requested state | ||||
// the number of blocks that are in the requested state | ||||
int requested; | int requested; | |||
// this is an array of ``blocks_in_piece`` number of | ||||
// items. One for each block in the piece. | ||||
// | ||||
// .. warning:: This is a pointer that points to an array | ||||
// that's owned by the session object. The next time | ||||
// get_download_queue() is called, it will be invalidat | ||||
ed. | ||||
block_info* blocks; | block_info* blocks; | |||
// the speed classes. These may be used by the piece picker | ||||
to | ||||
// coalesce requests of similar download rates | ||||
enum state_t { none, slow, medium, fast }; | enum state_t { none, slow, medium, fast }; | |||
// the download speed class this piece falls into. | ||||
// this is used internally to cluster peers of the same | ||||
// speed class together when requesting blocks. | ||||
// | ||||
// set to either ``fast``, ``medium``, ``slow`` or ``none``. | ||||
It tells | ||||
// which download rate category the peers downloading this p | ||||
iece falls | ||||
// into. ``none`` means that no peer is currently downloadin | ||||
g any part of | ||||
// the piece. Peers prefer picking pieces from the same cate | ||||
gory as | ||||
// themselves. The reason for this is to keep the number of | ||||
partially | ||||
// downloaded pieces down. Pieces set to ``none`` can be con | ||||
verted into | ||||
// any of ``fast``, ``medium`` or ``slow`` as soon as a peer | ||||
want to | ||||
// download from it. | ||||
state_t piece_state; | state_t piece_state; | |||
}; | }; | |||
// You will usually have to store your torrent handles somewhere, si | ||||
nce it's | ||||
// the object through which you retrieve information about the torre | ||||
nt and | ||||
// aborts the torrent. | ||||
// | ||||
// .. warning:: | ||||
// Any member function that returns a value or fills in a value | ||||
has to be | ||||
// made synchronously. This means it has to wait for the main t | ||||
hread to | ||||
// complete the query before it can return. This might potentia | ||||
lly be | ||||
// expensive if done from within a GUI thread that needs to sta | ||||
y | ||||
// responsive. Try to avoid quering for information you don't n | ||||
eed, and | ||||
// try to do it in as few calls as possible. You can get most o | ||||
f the | ||||
// interesting information about a torrent from the | ||||
// torrent_handle::status() call. | ||||
// | ||||
// The default constructor will initialize the handle to an invalid | ||||
state. | ||||
// Which means you cannot perform any operation on it, unless you fi | ||||
rst | ||||
// assign it a valid handle. If you try to perform any operation on | ||||
an | ||||
// uninitialized handle, it will throw ``invalid_handle``. | ||||
// | ||||
// .. warning:: | ||||
// All operations on a torrent_handle may throw libtorrent_exce | ||||
ption | ||||
// exception, in case the handle is no longer refering to a tor | ||||
rent. | ||||
// There is one exception is_valid() will never throw. Since th | ||||
e torrents | ||||
// are processed by a background thread, there is no guarantee | ||||
that a | ||||
// handle will remain valid between two calls. | ||||
// | ||||
struct TORRENT_EXPORT torrent_handle | struct TORRENT_EXPORT torrent_handle | |||
{ | { | |||
friend class invariant_access; | friend class invariant_access; | |||
friend struct aux::session_impl; | friend struct aux::session_impl; | |||
friend struct feed; | friend struct feed; | |||
friend class torrent; | friend class torrent; | |||
friend std::size_t hash_value(torrent_handle const& th); | friend std::size_t hash_value(torrent_handle const& th); | |||
// constructs a torrent handle that does not refer to a torr | ||||
ent. | ||||
// i.e. is_valid() will return false. | ||||
torrent_handle() {} | torrent_handle() {} | |||
// flags for add_piece(). | ||||
enum flags_t { overwrite_existing = 1 }; | enum flags_t { overwrite_existing = 1 }; | |||
// This function will write ``data`` to the storage as piece | ||||
``piece``, | ||||
// as if it had been downloaded from a peer. ``data`` is exp | ||||
ected to | ||||
// point to a buffer of as many bytes as the size of the spe | ||||
cified piece. | ||||
// The data in the buffer is copied and passed on to the dis | ||||
k IO thread | ||||
// to be written at a later point. | ||||
// | ||||
// By default, data that's already been downloaded is not ov | ||||
erwritten by | ||||
// this buffer. If you trust this data to be correct (and pa | ||||
ss the piece | ||||
// hash check) you may pass the overwrite_existing flag. Thi | ||||
s will | ||||
// instruct libtorrent to overwrite any data that may alread | ||||
y have been | ||||
// downloaded with this data. | ||||
// | ||||
// Since the data is written asynchronously, you may know th | ||||
at is passed | ||||
// or failed the hash check by waiting for piece_finished_al | ||||
ert or | ||||
// hash_failed_alert. | ||||
void add_piece(int piece, char const* data, int flags = 0) c onst; | void add_piece(int piece, char const* data, int flags = 0) c onst; | |||
// This function starts an asynchronous read operation of th | ||||
e specified | ||||
// piece from this torrent. You must have completed the down | ||||
load of the | ||||
// specified piece before calling this function. | ||||
// | ||||
// When the read operation is completed, it is passed back t | ||||
hrough an | ||||
// alert, read_piece_alert. Since this alert is a reponse to | ||||
an explicit | ||||
// call, it will always be posted, regardless of the alert m | ||||
ask. | ||||
// | ||||
// Note that if you read multiple pieces, the read operation | ||||
s are not | ||||
// guaranteed to finish in the same order as you initiated t | ||||
hem. | ||||
void read_piece(int piece) const; | void read_piece(int piece) const; | |||
// Returns true if this piece has been completely downloaded | ||||
, and false | ||||
// otherwise. | ||||
bool have_piece(int piece) const; | bool have_piece(int piece) const; | |||
// internal | ||||
void get_full_peer_list(std::vector<peer_list_entry>& v) con st; | void get_full_peer_list(std::vector<peer_list_entry>& v) con st; | |||
// takes a reference to a vector that will be cleared and fi | ||||
lled with one | ||||
// entry for each peer connected to this torrent, given the | ||||
handle is | ||||
// valid. If the torrent_handle is invalid, it will throw | ||||
// libtorrent_exception exception. Each entry in the vector | ||||
contains | ||||
// information about that particular peer. See peer_info. | ||||
void get_peer_info(std::vector<peer_info>& v) const; | void get_peer_info(std::vector<peer_info>& v) const; | |||
// flags to pass in to status() to specify which properties | ||||
of the | ||||
// torrent to query for. By default all flags are set. | ||||
enum status_flags_t | enum status_flags_t | |||
{ | { | |||
// calculates ``distributed_copies``, ``distributed_ | ||||
full_copies`` and | ||||
// ``distributed_fraction``. | ||||
query_distributed_copies = 1, | query_distributed_copies = 1, | |||
// includes partial downloaded blocks in ``total_don | ||||
e`` and | ||||
// ``total_wanted_done``. | ||||
query_accurate_download_counters = 2, | query_accurate_download_counters = 2, | |||
// includes ``last_seen_complete``. | ||||
query_last_seen_complete = 4, | query_last_seen_complete = 4, | |||
// includes ``pieces``. | ||||
query_pieces = 8, | query_pieces = 8, | |||
query_verified_pieces = 16 | // includes ``verified_pieces`` (only applies to tor | |||
rents in *seed | ||||
// mode*). | ||||
query_verified_pieces = 16, | ||||
// includes ``torrent_file``, which is all the stati | ||||
c information from | ||||
// the .torrent file. | ||||
query_torrent_file = 32, | ||||
// includes ``name``, the name of the torrent. This | ||||
is either derived | ||||
// from the .torrent file, or from the ``&dn=`` magn | ||||
et link argument | ||||
// or possibly some other source. If the name of the | ||||
torrent is not | ||||
// known, this is an empty string. | ||||
query_name = 64, | ||||
// includes ``save_path``, the path to the directory | ||||
the files of the | ||||
// torrent are saved to. | ||||
query_save_path = 128 | ||||
}; | }; | |||
// the flags specify which fields are calculated. By default | // ``status()`` will return a structure with information abo | |||
everything | ut the status | |||
// is included, you may save CPU by not querying fields you | // of this torrent. If the torrent_handle is invalid, it wil | |||
don't need | l throw | |||
// libtorrent_exception exception. See torrent_status. The ` | ||||
`flags`` | ||||
// argument filters what information is returned in the torr | ||||
ent_status. | ||||
// Some information in there is relatively expensive to calc | ||||
ulate, and if | ||||
// you're not interested in it (and see performance issues), | ||||
you can | ||||
// filter them out. | ||||
// | ||||
// By default everything is included. The flags you can use | ||||
to decide | ||||
// what to *include* are defined in the status_flags_t enum. | ||||
torrent_status status(boost::uint32_t flags = 0xffffffff) co nst; | torrent_status status(boost::uint32_t flags = 0xffffffff) co nst; | |||
// ``get_download_queue()`` takes a non-const reference to a | ||||
vector which | ||||
// it will fill with information about pieces that are parti | ||||
ally | ||||
// downloaded or not downloaded at all but partially request | ||||
ed. See | ||||
// partial_piece_info for the fields in the returned vector. | ||||
void get_download_queue(std::vector<partial_piece_info>& que ue) const; | void get_download_queue(std::vector<partial_piece_info>& que ue) const; | |||
// flags for set_piece_deadline(). | ||||
enum deadline_flags { alert_when_available = 1 }; | enum deadline_flags { alert_when_available = 1 }; | |||
// This function sets or resets the deadline associated with | ||||
a specific | ||||
// piece index (``index``). libtorrent will attempt to downl | ||||
oad this | ||||
// entire piece before the deadline expires. This is not nec | ||||
essarily | ||||
// possible, but pieces with a more recent deadline will alw | ||||
ays be | ||||
// prioritized over pieces with a deadline further ahead in | ||||
time. The | ||||
// deadline (and flags) of a piece can be changed by calling | ||||
this | ||||
// function again. | ||||
// | ||||
// The ``flags`` parameter can be used to ask libtorrent to | ||||
send an alert | ||||
// once the piece has been downloaded, by passing alert_when | ||||
_available. | ||||
// When set, the read_piece_alert alert will be delivered, w | ||||
ith the piece | ||||
// data, when it's downloaded. | ||||
// | ||||
// If the piece is already downloaded when this call is made | ||||
, nothing | ||||
// happens, unless the alert_when_available flag is set, in | ||||
which case it | ||||
// will do the same thing as calling read_piece() for ``inde | ||||
x``. | ||||
// | ||||
// ``deadline`` is the number of milliseconds until this pie | ||||
ce should be | ||||
// completed. | ||||
// | ||||
// ``reset_piece_deadline`` removes the deadline from the pi | ||||
ece. If it | ||||
// hasn't already been downloaded, it will no longer be cons | ||||
idered a | ||||
// priority. | ||||
// | ||||
// ``clear_piece_deadlines()`` removes deadlines on all piec | ||||
es in | ||||
// the torrent. As if reset_piece_deadline() was called on a | ||||
ll pieces. | ||||
void set_piece_deadline(int index, int deadline, int flags = 0) const; | void set_piece_deadline(int index, int deadline, int flags = 0) const; | |||
void reset_piece_deadline(int index) const; | void reset_piece_deadline(int index) const; | |||
void clear_piece_deadlines() const; | ||||
// This sets the bandwidth priority of this torrent. The pri | ||||
ority of a | ||||
// torrent determines how much bandwidth its peers are assig | ||||
ned when | ||||
// distributing upload and download rate quotas. A high numb | ||||
er gives more | ||||
// bandwidth. The priority must be within the range [0, 255] | ||||
. | ||||
// | ||||
// The default priority is 0, which is the lowest priority. | ||||
// | ||||
// To query the priority of a torrent, use the | ||||
// ``torrent_handle::status()`` call. | ||||
// | ||||
// Torrents with higher priority will not nececcarily get as | ||||
much | ||||
// bandwidth as they can consume, even if there's is more qu | ||||
ota. Other | ||||
// peers will still be weighed in when bandwidth is being di | ||||
stributed. | ||||
// With other words, bandwidth is not distributed strictly i | ||||
n order of | ||||
// priority, but the priority is used as a weight. | ||||
// | ||||
// Peers whose Torrent has a higher priority will take prece | ||||
dence when | ||||
// distributing unchoke slots. This is a strict prioritizati | ||||
on where | ||||
// every interested peer on a high priority torrent will be | ||||
unchoked | ||||
// before any other, lower priority, torrents have any peers | ||||
unchoked. | ||||
void set_priority(int prio) const; | void set_priority(int prio) const; | |||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
#if !TORRENT_NO_FPU | #if !TORRENT_NO_FPU | |||
// fills the specified vector with the download progress [0, 1] | // fills the specified vector with the download progress [0, 1] | |||
// of each file in the torrent. The files are ordered as in | // of each file in the torrent. The files are ordered as in | |||
// the torrent_info. | // the torrent_info. | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
void file_progress(std::vector<float>& progress) const TORRE NT_DEPRECATED; | void file_progress(std::vector<float>& progress) const TORRE NT_DEPRECATED; | |||
#endif | #endif | |||
#endif | #endif | |||
// flags to be passed in file_progress(). | ||||
enum file_progress_flags_t | enum file_progress_flags_t | |||
{ | { | |||
// only calculate file progress at piece granularity | ||||
. This makes | ||||
// the file_progress() call cheaper and also only ta | ||||
kes bytes that | ||||
// have passed the hash check into account, so progr | ||||
ess cannot | ||||
// regress in this mode. | ||||
piece_granularity = 1 | piece_granularity = 1 | |||
}; | }; | |||
// This function fills in the supplied vector with the the n | ||||
umber of | ||||
// bytes downloaded of each file in this torrent. The progre | ||||
ss values are | ||||
// ordered the same as the files in the torrent_info. This o | ||||
peration is | ||||
// not very cheap. Its complexity is *O(n + mj)*. Where *n* | ||||
is the number | ||||
// of files, *m* is the number of downloading pieces and *j* | ||||
is the | ||||
// number of blocks in a piece. | ||||
// | ||||
// The ``flags`` parameter can be used to specify the granul | ||||
arity of the | ||||
// file progress. If left at the default value of 0, the pro | ||||
gress will be | ||||
// as accurate as possible, but also more expensive to calcu | ||||
late. If | ||||
// ``torrent_handle::piece_granularity`` is specified, the p | ||||
rogress will | ||||
// be specified in piece granularity. i.e. only pieces that | ||||
have been | ||||
// fully downloaded and passed the hash check count. When sp | ||||
ecifying | ||||
// piece granularity, the operation is a lot cheaper, since | ||||
libtorrent | ||||
// already keeps track of this internally and no calculation | ||||
is required. | ||||
void file_progress(std::vector<size_type>& progress, int fla gs = 0) const; | void file_progress(std::vector<size_type>& progress, int fla gs = 0) const; | |||
// If the torrent is in an error state (i.e. ``torrent_statu | ||||
s::error`` is | ||||
// non-empty), this will clear the error and start the torre | ||||
nt again. | ||||
void clear_error() const; | void clear_error() const; | |||
// ``trackers()`` will return the list of trackers for this | ||||
torrent. The | ||||
// announce entry contains both a string ``url`` which speci | ||||
fy the | ||||
// announce url for the tracker as well as an int ``tier``, | ||||
which is | ||||
// specifies the order in which this tracker is tried. If yo | ||||
u want | ||||
// libtorrent to use another list of trackers for this torre | ||||
nt, you can | ||||
// use ``replace_trackers()`` which takes a list of the same | ||||
form as the | ||||
// one returned from ``trackers()`` and will replace it. If | ||||
you want an | ||||
// immediate effect, you have to call force_reannounce(). Se | ||||
e | ||||
// announce_entry. | ||||
// | ||||
// ``add_tracker()`` will look if the specified tracker is a | ||||
lready in the | ||||
// set. If it is, it doesn't do anything. If it's not in the | ||||
current set | ||||
// of trackers, it will insert it in the tier specified in t | ||||
he | ||||
// announce_entry. | ||||
// | ||||
// The updated set of trackers will be saved in the resume d | ||||
ata, and when | ||||
// a torrent is started with resume data, the trackers from | ||||
the resume | ||||
// data will replace the original ones. | ||||
std::vector<announce_entry> trackers() const; | std::vector<announce_entry> trackers() const; | |||
void replace_trackers(std::vector<announce_entry> const&) co nst; | void replace_trackers(std::vector<announce_entry> const&) co nst; | |||
void add_tracker(announce_entry const&) const; | void add_tracker(announce_entry const&) const; | |||
// ``add_url_seed()`` adds another url to the torrent's list | ||||
of url | ||||
// seeds. If the given url already exists in that list, the | ||||
call has no | ||||
// effect. The torrent will connect to the server and try to | ||||
download | ||||
// pieces from it, unless it's paused, queued, checking or s | ||||
eeding. | ||||
// ``remove_url_seed()`` removes the given url if it exists | ||||
already. | ||||
// ``url_seeds()`` return a set of the url seeds currently i | ||||
n this | ||||
// torrent. Note that urls that fails may be removed automat | ||||
ically from | ||||
// the list. | ||||
// | ||||
// See http-seeding_ for more information. | ||||
void add_url_seed(std::string const& url) const; | void add_url_seed(std::string const& url) const; | |||
void remove_url_seed(std::string const& url) const; | void remove_url_seed(std::string const& url) const; | |||
std::set<std::string> url_seeds() const; | std::set<std::string> url_seeds() const; | |||
// These functions are identical as the ``*_url_seed()`` var | ||||
iants, but | ||||
// they operate on `BEP 17`_ web seeds instead of `BEP 19`_. | ||||
// | ||||
// See http-seeding_ for more information. | ||||
void add_http_seed(std::string const& url) const; | void add_http_seed(std::string const& url) const; | |||
void remove_http_seed(std::string const& url) const; | void remove_http_seed(std::string const& url) const; | |||
std::set<std::string> http_seeds() const; | std::set<std::string> http_seeds() const; | |||
#ifndef TORRENT_DISABLE_EXTENSIONS | // add the specified extension to this torrent. The ``ext`` | |||
void add_extension(boost::function<boost::shared_ptr<torrent | argument is | |||
_plugin>(torrent*, void*)> const& ext | // a function that will be called from within libtorrent's c | |||
ontext | ||||
// passing in the internal torrent object and the specified | ||||
userdata | ||||
// pointer. The function is expected to return a shared poin | ||||
ter to | ||||
// a torrent_plugin instance. | ||||
void add_extension( | ||||
boost::function<boost::shared_ptr<torrent_plugin>(to | ||||
rrent*, void*)> const& ext | ||||
, void* userdata = 0); | , void* userdata = 0); | |||
#endif | ||||
// ``set_metadata`` expects the *info* section of metadata. | ||||
i.e. The | ||||
// buffer passed in will be hashed and verified against the | ||||
info-hash. If | ||||
// it fails, a ``metadata_failed_alert`` will be generated. | ||||
If it passes, | ||||
// a ``metadata_received_alert`` is generated. The function | ||||
returns true | ||||
// if the metadata is successfully set on the torrent, and f | ||||
alse | ||||
// otherwise. If the torrent already has metadata, this func | ||||
tion will not | ||||
// affect the torrent, and false will be returned. | ||||
bool set_metadata(char const* metadata, int size) const; | bool set_metadata(char const* metadata, int size) const; | |||
const torrent_info& get_torrent_info() const; | ||||
// Returns true if this handle refers to a valid torrent and | ||||
false if it | ||||
// hasn't been initialized or if the torrent it refers to ha | ||||
s been | ||||
// aborted. Note that a handle may become invalid after it h | ||||
as been added | ||||
// to the session. Usually this is because the storage for t | ||||
he torrent is | ||||
// somehow invalid or if the filenames are not allowed (and | ||||
hence cannot | ||||
// be opened/created) on your filesystem. If such an error o | ||||
ccurs, a | ||||
// file_error_alert is generated and all handles that refers | ||||
to that | ||||
// torrent will become invalid. | ||||
bool is_valid() const; | bool is_valid() const; | |||
// flags for torrent_session::pause() | ||||
enum pause_flags_t { graceful_pause = 1 }; | enum pause_flags_t { graceful_pause = 1 }; | |||
// ``pause()``, and ``resume()`` will disconnect all peers a | ||||
nd reconnect | ||||
// all peers respectively. When a torrent is paused, it will | ||||
however | ||||
// remember all share ratios to all peers and remember all p | ||||
otential (not | ||||
// connected) peers. Torrents may be paused automatically if | ||||
there is a | ||||
// file error (e.g. disk full) or something similar. See | ||||
// file_error_alert. | ||||
// | ||||
// To know if a torrent is paused or not, call | ||||
// ``torrent_handle::status()`` and inspect ``torrent_status | ||||
::paused``. | ||||
// | ||||
// The ``flags`` argument to pause can be set to | ||||
// ``torrent_handle::graceful_pause`` which will delay the d | ||||
isconnect of | ||||
// peers that we're still downloading outstanding requests f | ||||
rom. The | ||||
// torrent will not accept any more requests and will discon | ||||
nect all idle | ||||
// peers. As soon as a peer is done transferring the blocks | ||||
that were | ||||
// requested from it, it is disconnected. This is a graceful | ||||
shut down of | ||||
// the torrent in the sense that no downloaded bytes are was | ||||
ted. | ||||
// | ||||
// torrents that are auto-managed may be automatically resum | ||||
ed again. It | ||||
// does not make sense to pause an auto-managed torrent with | ||||
out making it | ||||
// not automanaged first. Torrents are auto-managed by defau | ||||
lt when added | ||||
// to the session. For more information, see queuing_. | ||||
void pause(int flags = 0) const; | void pause(int flags = 0) const; | |||
void resume() const; | void resume() const; | |||
// Explicitly sets the upload mode of the torrent. In upload | ||||
mode, the | ||||
// torrent will not request any pieces. If the torrent is au | ||||
to managed, | ||||
// it will automatically be taken out of upload mode periodi | ||||
cally (see | ||||
// ``session_settings::optimistic_disk_retry``). Torrents ar | ||||
e | ||||
// automatically put in upload mode whenever they encounter | ||||
a disk write | ||||
// error. | ||||
// | ||||
// ``m`` should be true to enter upload mode, and false to l | ||||
eave it. | ||||
// | ||||
// To test if a torrent is in upload mode, call | ||||
// ``torrent_handle::status()`` and inspect | ||||
// ``torrent_status::upload_mode``. | ||||
void set_upload_mode(bool b) const; | void set_upload_mode(bool b) const; | |||
// Enable or disable share mode for this torrent. When in sh | ||||
are mode, the | ||||
// torrent will not necessarily be downloaded, especially no | ||||
t the whole | ||||
// of it. Only parts that are likely to be distributed to mo | ||||
re than 2 | ||||
// other peers are downloaded, and only if the previous pred | ||||
iction was | ||||
// correct. | ||||
void set_share_mode(bool b) const; | void set_share_mode(bool b) const; | |||
// Instructs libtorrent to flush all the disk caches for thi | ||||
s torrent and | ||||
// close all file handles. This is done asynchronously and y | ||||
ou will be | ||||
// notified that it's complete through cache_flushed_alert. | ||||
// | ||||
// Note that by the time you get the alert, libtorrent may h | ||||
ave cached | ||||
// more data for the torrent, but you are guaranteed that wh | ||||
atever cached | ||||
// data libtorrent had by the time you called | ||||
// ``torrent_handle::flush_cache()`` has been written to dis | ||||
k. | ||||
void flush_cache() const; | void flush_cache() const; | |||
// Set to true to apply the session global IP filter to this | ||||
torrent | ||||
// (which is the default). Set to false to make this torrent | ||||
ignore the | ||||
// IP filter. | ||||
void apply_ip_filter(bool b) const; | void apply_ip_filter(bool b) const; | |||
// ``force_recheck`` puts the torrent back in a state where | ||||
it assumes to | ||||
// have no resume data. All peers will be disconnected and t | ||||
he torrent | ||||
// will stop announcing to the tracker. The torrent will be | ||||
added to the | ||||
// checking queue, and will be checked (all the files will b | ||||
e read and | ||||
// compared to the piece hashes). Once the check is complete | ||||
, the torrent | ||||
// will start connecting to peers again, as normal. | ||||
void force_recheck() const; | void force_recheck() const; | |||
enum save_resume_flags_t { flush_disk_cache = 1, save_info_d | // flags used in the save_resume_data call to control additi | |||
ict = 2 }; | onal | |||
// actions or fields to save. | ||||
enum save_resume_flags_t | ||||
{ | ||||
// the disk cache will be flushed before creating th | ||||
e resume data. | ||||
// This avoids a problem with file timestamps in the | ||||
resume data in | ||||
// case the cache hasn't been flushed yet. | ||||
flush_disk_cache = 1, | ||||
// the resume data will contain the metadata from th | ||||
e torrent file as | ||||
// well. This is default for any torrent that's adde | ||||
d without a | ||||
// torrent file (such as a magnet link or a URL). | ||||
save_info_dict = 2 | ||||
}; | ||||
// ``save_resume_data()`` generates fast-resume data and ret | ||||
urns it as an | ||||
// entry. This entry is suitable for being bencoded. For mor | ||||
e information | ||||
// about how fast-resume works, see fast-resume_. | ||||
// | ||||
// The ``flags`` argument is a bitmask of flags ORed togethe | ||||
r. see | ||||
// save_resume_flags_t | ||||
// | ||||
// This operation is asynchronous, ``save_resume_data`` will | ||||
return | ||||
// immediately. The resume data is delivered when it's done | ||||
through an | ||||
// save_resume_data_alert. | ||||
// | ||||
// The fast resume data will be empty in the following cases | ||||
: | ||||
// | ||||
// 1. The torrent handle is invalid. | ||||
// 2. The torrent is checking (or is queued for checkin | ||||
g) its storage, it | ||||
// will obviously not be ready to write resume data. | ||||
// 3. The torrent hasn't received valid metadata and wa | ||||
s started without | ||||
// metadata (see libtorrent's metadata-from-peers_ e | ||||
xtension) | ||||
// | ||||
// Note that by the time you receive the fast resume data, i | ||||
t may already | ||||
// be invalid if the torrent is still downloading! The recom | ||||
mended | ||||
// practice is to first pause the session, then generate the | ||||
fast resume | ||||
// data, and then close it down. Make sure to not remove_tor | ||||
rent() before | ||||
// you receive the save_resume_data_alert though. There's no | ||||
need to | ||||
// pause when saving intermittent resume data. | ||||
// | ||||
//.. warning:: | ||||
// If you pause every torrent individually instead of paus | ||||
ing the | ||||
// session, every torrent will have its paused state saved | ||||
in the | ||||
// resume data! | ||||
// | ||||
//.. warning:: | ||||
// The resume data contains the modification timestamps fo | ||||
r all files. | ||||
// If one file has been modified when the torrent is added | ||||
again, the | ||||
// will be rechecked. When shutting down, make sure to flu | ||||
sh the disk | ||||
// cache before saving the resume data. This will make sur | ||||
e that the | ||||
// file timestamps are up to date and won't be modified af | ||||
ter saving | ||||
// the resume data. The recommended way to do this is to p | ||||
ause the | ||||
// torrent, which will flush the cache and disconnect all | ||||
peers. | ||||
// | ||||
//.. note:: | ||||
// It is typically a good idea to save resume data wheneve | ||||
r a torrent | ||||
// is completed or paused. In those cases you don't need t | ||||
o pause the | ||||
// torrent or the session, since the torrent will do no mo | ||||
re writing to | ||||
// its files. If you save resume data for torrents when th | ||||
ey are | ||||
// paused, you can accelerate the shutdown process by not | ||||
saving resume | ||||
// data again for paused torrents. Completed torrents shou | ||||
ld have their | ||||
// resume data saved when they complete and on exit, since | ||||
their | ||||
// statistics might be updated. | ||||
// | ||||
// In full allocation mode the reume data is never inva | ||||
lidated by | ||||
// subsequent writes to the files, since pieces won't m | ||||
ove around. This | ||||
// means that you don't need to pause before writing re | ||||
sume data in full | ||||
// or sparse mode. If you don't, however, any data writ | ||||
ten to disk after | ||||
// you saved resume data and before the session closed | ||||
is lost. | ||||
// | ||||
// It also means that if the resume data is out dated, libto | ||||
rrent will | ||||
// not re-check the files, but assume that it is fairly rece | ||||
nt. The | ||||
// assumption is that it's better to loose a little bit than | ||||
to re-check | ||||
// the entire file. | ||||
// | ||||
// It is still a good idea to save resume data periodically | ||||
during | ||||
// download as well as when closing down. | ||||
// | ||||
// Example code to pause and save resume data for all torren | ||||
ts and wait | ||||
// for the alerts:: | ||||
// | ||||
// extern int outstanding_resume_data; // global counte | ||||
r of outstanding resume data | ||||
// std::vector<torrent_handle> handles = ses.get_torren | ||||
ts(); | ||||
// ses.pause(); | ||||
// for (std::vector<torrent_handle>::iterator i = handl | ||||
es.begin(); | ||||
// i != handles.end(); ++i) | ||||
// { | ||||
// torrent_handle& h = *i; | ||||
// if (!h.is_valid()) continue; | ||||
// torrent_status s = h.status(); | ||||
// if (!s.has_metadata) continue; | ||||
// if (!s.need_save_resume_data()) continue; | ||||
// | ||||
// h.save_resume_data(); | ||||
// ++outstanding_resume_data; | ||||
// } | ||||
// | ||||
// while (outstanding_resume_data > 0) | ||||
// { | ||||
// alert const* a = ses.wait_for_alert(seconds( | ||||
10)); | ||||
// | ||||
// // if we don't get an alert within 10 second | ||||
s, abort | ||||
// if (a == 0) break; | ||||
// | ||||
// std::auto_ptr<alert> holder = ses.pop_alert( | ||||
); | ||||
// | ||||
// if (alert_cast<save_resume_data_failed_alert | ||||
>(a)) | ||||
// { | ||||
// process_alert(a); | ||||
// --outstanding_resume_data; | ||||
// continue; | ||||
// } | ||||
// | ||||
// save_resume_data_alert const* rd = alert_cas | ||||
t<save_resume_data_alert>(a); | ||||
// if (rd == 0) | ||||
// { | ||||
// process_alert(a); | ||||
// continue; | ||||
// } | ||||
// | ||||
// torrent_handle h = rd->handle; | ||||
// torrent_status st = h.status(torrent_handle: | ||||
:query_save_path | torrent_handle::query_name); | ||||
// std::ofstream out((st.save_path | ||||
// + "/" + st.name + ".fastresume").c_s | ||||
tr() | ||||
// , std::ios_base::binary); | ||||
// out.unsetf(std::ios_base::skipws); | ||||
// bencode(std::ostream_iterator<char>(out), *r | ||||
d->resume_data); | ||||
// --outstanding_resume_data; | ||||
// } | ||||
// | ||||
//.. note:: | ||||
// Note how ``outstanding_resume_data`` is a global cou | ||||
nter in this | ||||
// example. This is deliberate, otherwise there is a ra | ||||
ce condition for | ||||
// torrents that was just asked to save their resume da | ||||
ta, they posted | ||||
// the alert, but it has not been received yet. Those t | ||||
orrents would | ||||
// report that they don't need to save resume data agai | ||||
n, and skipped by | ||||
// the initial loop, and thwart the counter otherwise. | ||||
void save_resume_data(int flags = 0) const; | void save_resume_data(int flags = 0) const; | |||
// This function returns true if any whole chunk has been do | ||||
wnloaded | ||||
// since the torrent was first loaded or since the last time | ||||
the resume | ||||
// data was saved. When saving resume data periodically, it | ||||
makes sense | ||||
// to skip any torrent which hasn't downloaded anything sinc | ||||
e the last | ||||
// time. | ||||
// | ||||
//.. note:: | ||||
// A torrent's resume data is considered saved as soon | ||||
as the alert is | ||||
// posted. It is important to make sure this alert is r | ||||
eceived and | ||||
// handled in order for this function to be meaningful. | ||||
bool need_save_resume_data() const; | bool need_save_resume_data() const; | |||
// changes whether the torrent is auto managed or not. For m | ||||
ore info, | ||||
// see queuing_. | ||||
void auto_managed(bool m) const; | void auto_managed(bool m) const; | |||
// Every torrent that is added is assigned a queue position | ||||
exactly one | ||||
// greater than the greatest queue position of all existing | ||||
torrents. | ||||
// Torrents that are being seeded have -1 as their queue pos | ||||
ition, since | ||||
// they're no longer in line to be downloaded. | ||||
// | ||||
// When a torrent is removed or turns into a seed, all torre | ||||
nts with | ||||
// greater queue positions have their positions decreased to | ||||
fill in the | ||||
// space in the sequence. | ||||
// | ||||
// ``queue_position()`` returns the torrent's position in th | ||||
e download | ||||
// queue. The torrents with the smallest numbers are the one | ||||
s that are | ||||
// being downloaded. The smaller number, the closer the torr | ||||
ent is to the | ||||
// front of the line to be started. | ||||
// | ||||
// The queue position is also available in the torrent_statu | ||||
s. | ||||
// | ||||
// The ``queue_position_*()`` functions adjust the torrents | ||||
position in | ||||
// the queue. Up means closer to the front and down means cl | ||||
oser to the | ||||
// back of the queue. Top and bottom refers to the front and | ||||
the back of | ||||
// the queue respectively. | ||||
int queue_position() const; | int queue_position() const; | |||
void queue_position_up() const; | void queue_position_up() const; | |||
void queue_position_down() const; | void queue_position_down() const; | |||
void queue_position_top() const; | void queue_position_top() const; | |||
void queue_position_bottom() const; | void queue_position_bottom() const; | |||
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES | // Sets or gets the flag that derermines if countries should | |||
be resolved | ||||
// for the peers of this torrent. It defaults to false. If i | ||||
t is set to | ||||
// true, the peer_info structure for the peers in this torre | ||||
nt will have | ||||
// their ``country`` member set. See peer_info for more info | ||||
rmation on | ||||
// how to interpret this field. | ||||
void resolve_countries(bool r); | void resolve_countries(bool r); | |||
bool resolve_countries() const; | bool resolve_countries() const; | |||
#endif | ||||
// For SSL torrents, use this to specify a path to a .pem fi | ||||
le to use as | ||||
// this client's certificate. The certificate must be signed | ||||
by the | ||||
// certificate in the .torrent file to be valid. | ||||
// | ||||
// The set_ssl_certificate_buffer() overload takes the actua | ||||
l certificate, | ||||
// private key and DH params as strings, rather than paths t | ||||
o files. This | ||||
// overload is only available when libtorrent is built again | ||||
st boost | ||||
// 1.54 or later. | ||||
// | ||||
// ``cert`` is a path to the (signed) certificate in .pem fo | ||||
rmat | ||||
// corresponding to this torrent. | ||||
// | ||||
// ``private_key`` is a path to the private key for the spec | ||||
ified | ||||
// certificate. This must be in .pem format. | ||||
// | ||||
// ``dh_params`` is a path to the Diffie-Hellman parameter f | ||||
ile, which | ||||
// needs to be in .pem format. You can generate this file us | ||||
ing the | ||||
// openssl command like this: ``openssl dhparam -outform PEM | ||||
-out | ||||
// dhparams.pem 512``. | ||||
// | ||||
// ``passphrase`` may be specified if the private key is enc | ||||
rypted and | ||||
// requires a passphrase to be decrypted. | ||||
// | ||||
// Note that when a torrent first starts up, and it needs a | ||||
certificate, | ||||
// it will suspend connecting to any peers until it has one. | ||||
It's | ||||
// typically desirable to resume the torrent after setting t | ||||
he ssl | ||||
// certificate. | ||||
// | ||||
// If you receive a torrent_need_cert_alert, you need to cal | ||||
l this to | ||||
// provide a valid cert. If you don't have a cert you won't | ||||
be allowed to | ||||
// connect to any peers. | ||||
void set_ssl_certificate(std::string const& certificate | void set_ssl_certificate(std::string const& certificate | |||
, std::string const& private_key | , std::string const& private_key | |||
, std::string const& dh_params | , std::string const& dh_params | |||
, std::string const& passphrase = ""); | , std::string const& passphrase = ""); | |||
void set_ssl_certificate_buffer(std::string const& certifica | ||||
te | ||||
, std::string const& private_key | ||||
, std::string const& dh_params); | ||||
// Returns the storage implementation for this torrent. This | ||||
depends on the | ||||
// storage contructor function that was passed to add_torren | ||||
t. | ||||
storage_interface* get_storage_impl() const; | storage_interface* get_storage_impl() const; | |||
// all these are deprecated, use piece | // Returns a pointer to the torrent_info object associated w | |||
// priority functions instead | ith this | |||
// torrent. The torrent_info object may be a copy of the int | ||||
ernal object. | ||||
// If the torrent doesn't have metadata, the pointer will no | ||||
t be | ||||
// initialized (i.e. a NULL pointer). The torrent may be in | ||||
a state | ||||
// without metadata only if it was started without a .torren | ||||
t file, e.g. | ||||
// by using the libtorrent extension of just supplying a tra | ||||
cker and | ||||
// info-hash. | ||||
boost::intrusive_ptr<torrent_info const> torrent_file() cons | ||||
t; | ||||
#ifndef TORRENT_NO_DEPRECATE | ||||
// ================ start deprecation ============ | // ================ start deprecation ============ | |||
#ifndef TORRENT_NO_DEPRECATE | // deprecated in 1.0 | |||
// use status() instead (with query_save_path) | ||||
TORRENT_DEPRECATED_PREFIX | ||||
std::string save_path() const TORRENT_DEPRECATED; | ||||
// deprecated in 1.0 | ||||
// use status() instead (with query_name) | ||||
// returns the name of this torrent, in case it doesn't | ||||
// have metadata it returns the name assigned to it | ||||
// when it was added. | ||||
TORRENT_DEPRECATED_PREFIX | ||||
std::string name() const TORRENT_DEPRECATED; | ||||
// use torrent_file() instead | ||||
TORRENT_DEPRECATED_PREFIX | ||||
const torrent_info& get_torrent_info() const TORRENT_DEPRECA | ||||
TED; | ||||
// deprecated in 0.16, feature will be removed | // deprecated in 0.16, feature will be removed | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
int get_peer_upload_limit(tcp::endpoint ip) const TORRENT_DE PRECATED; | int get_peer_upload_limit(tcp::endpoint ip) const TORRENT_DE PRECATED; | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
int get_peer_download_limit(tcp::endpoint ip) const TORRENT_ DEPRECATED; | int get_peer_download_limit(tcp::endpoint ip) const TORRENT_ DEPRECATED; | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
void set_peer_upload_limit(tcp::endpoint ip, int limit) cons t TORRENT_DEPRECATED; | void set_peer_upload_limit(tcp::endpoint ip, int limit) cons t TORRENT_DEPRECATED; | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
void set_peer_download_limit(tcp::endpoint ip, int limit) co nst TORRENT_DEPRECATED; | void set_peer_download_limit(tcp::endpoint ip, int limit) co nst TORRENT_DEPRECATED; | |||
skipping to change at line 304 | skipping to change at line 873 | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
bool is_auto_managed() const TORRENT_DEPRECATED; | bool is_auto_managed() const TORRENT_DEPRECATED; | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
bool is_sequential_download() const TORRENT_DEPRECATED; | bool is_sequential_download() const TORRENT_DEPRECATED; | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
bool has_metadata() const TORRENT_DEPRECATED; | bool has_metadata() const TORRENT_DEPRECATED; | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
bool super_seeding() const TORRENT_DEPRECATED; | bool super_seeding() const TORRENT_DEPRECATED; | |||
// deprecated in 0.13 | // deprecated in 0.13 | |||
// all these are deprecated, use piece | ||||
// priority functions instead | ||||
// marks the piece with the given index as filtered | // marks the piece with the given index as filtered | |||
// it will not be downloaded | // it will not be downloaded | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
void filter_piece(int index, bool filter) const TORRENT_DEPR ECATED; | void filter_piece(int index, bool filter) const TORRENT_DEPR ECATED; | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
void filter_pieces(std::vector<bool> const& pieces) const TO RRENT_DEPRECATED; | void filter_pieces(std::vector<bool> const& pieces) const TO RRENT_DEPRECATED; | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
bool is_piece_filtered(int index) const TORRENT_DEPRECATED; | bool is_piece_filtered(int index) const TORRENT_DEPRECATED; | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
std::vector<bool> filtered_pieces() const TORRENT_DEPRECATED ; | std::vector<bool> filtered_pieces() const TORRENT_DEPRECATED ; | |||
// marks the file with the given index as filtered | // marks the file with the given index as filtered | |||
// it will not be downloaded | // it will not be downloaded | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
void filter_files(std::vector<bool> const& files) const TORR ENT_DEPRECATED; | void filter_files(std::vector<bool> const& files) const TORR ENT_DEPRECATED; | |||
// deprecated in 0.14 | ||||
// use save_resume_data() instead. It is async. and | ||||
// will return the resume data in an alert | ||||
TORRENT_DEPRECATED_PREFIX | ||||
entry write_resume_data() const TORRENT_DEPRECATED; | ||||
// ================ end deprecation ============ | // ================ end deprecation ============ | |||
#endif | #endif | |||
// ``use_interface()`` sets the network interface this torre | ||||
nt will use | ||||
// when it opens outgoing connections. By default, it uses t | ||||
he same | ||||
// interface as the session uses to listen on. The parameter | ||||
must be a | ||||
// string containing one or more, comma separated, ip-addres | ||||
s (either an | ||||
// IPv4 or IPv6 address). When specifying multiple interface | ||||
s, the | ||||
// torrent will round-robin which interface to use for each | ||||
outgoing | ||||
// conneciton. This is useful for clients that are multi-hom | ||||
ed. | ||||
void use_interface(const char* net_interface) const; | ||||
// Fills the specified ``std::vector<int>`` with the availab | ||||
ility for | ||||
// each piece in this torrent. libtorrent does not keep trac | ||||
k of | ||||
// availability for seeds, so if the torrent is seeding the | ||||
availability | ||||
// for all pieces is reported as 0. | ||||
// | ||||
// The piece availability is the number of peers that we are | ||||
connected | ||||
// that has advertized having a particular piece. This is th | ||||
e information | ||||
// that libtorrent uses in order to prefer picking rare piec | ||||
es. | ||||
void piece_availability(std::vector<int>& avail) const; | void piece_availability(std::vector<int>& avail) const; | |||
// priority must be within the range [0, 7] | // These functions are used to set and get the prioritiy of | |||
individual | ||||
// pieces. By default all pieces have priority 1. That means | ||||
that the | ||||
// random rarest first algorithm is effectively active for a | ||||
ll pieces. | ||||
// You may however change the priority of individual pieces. | ||||
There are 8 | ||||
// different priority levels: | ||||
// | ||||
// 0. piece is not downloaded at all | ||||
// 1. normal priority. Download order is dependent on avail | ||||
ability | ||||
// 2. higher than normal priority. Pieces are preferred ove | ||||
r pieces with | ||||
// the same availability, but not over pieces with lower | ||||
availability | ||||
// 3. pieces are as likely to be picked as partial pieces. | ||||
// 4. pieces are preferred over partial pieces, but not ove | ||||
r pieces with | ||||
// lower availability | ||||
// 5. *currently the same as 4* | ||||
// 6. piece is as likely to be picked as any piece with ava | ||||
ilability 1 | ||||
// 7. maximum priority, availability is disregarded, the pi | ||||
ece is | ||||
// preferred over any other piece with lower priority | ||||
// | ||||
// The exact definitions of these priorities are implementat | ||||
ion details, | ||||
// and subject to change. The interface guarantees that high | ||||
er number | ||||
// means higher priority, and that 0 means do not download. | ||||
// | ||||
// ``piece_priority`` sets or gets the priority for an indiv | ||||
idual piece, | ||||
// specified by ``index``. | ||||
// | ||||
// ``prioritize_pieces`` takes a vector of integers, one int | ||||
eger per | ||||
// piece in the torrent. All the piece priorities will be up | ||||
dated with | ||||
// the priorities in the vector. | ||||
// | ||||
// ``piece_priorities`` returns a vector with one element fo | ||||
r each piece | ||||
// in the torrent. Each element is the current priority of t | ||||
hat piece. | ||||
void piece_priority(int index, int priority) const; | void piece_priority(int index, int priority) const; | |||
int piece_priority(int index) const; | int piece_priority(int index) const; | |||
void prioritize_pieces(std::vector<int> const& pieces) const ; | void prioritize_pieces(std::vector<int> const& pieces) const ; | |||
std::vector<int> piece_priorities() const; | std::vector<int> piece_priorities() const; | |||
// priority must be within the range [0, 7] | // ``index`` must be in the range [0, number_of_files). | |||
// | ||||
// ``file_priority()`` queries or sets the priority of file | ||||
``index``. | ||||
// | ||||
// ``prioritize_files()`` takes a vector that has at as many | ||||
elements as | ||||
// there are files in the torrent. Each entry is the priorit | ||||
y of that | ||||
// file. The function sets the priorities of all the pieces | ||||
in the | ||||
// torrent based on the vector. | ||||
// | ||||
// ``file_priorities()`` returns a vector with the prioritie | ||||
s of all | ||||
// files. | ||||
// | ||||
// The priority values are the same as for piece_priority(). | ||||
// | ||||
// Whenever a file priority is changed, all other piece prio | ||||
rities are | ||||
// reset to match the file priorities. In order to maintain | ||||
sepcial | ||||
// priorities for particular pieces, piece_priority() has to | ||||
be called | ||||
// again for those pieces. | ||||
// | ||||
// You cannot set the file priorities on a torrent that does | ||||
not yet have | ||||
// metadata or a torrent that is a seed. ``file_priority(int | ||||
, int)`` and | ||||
// prioritize_files() are both no-ops for such torrents. | ||||
void file_priority(int index, int priority) const; | void file_priority(int index, int priority) const; | |||
int file_priority(int index) const; | int file_priority(int index) const; | |||
void prioritize_files(std::vector<int> const& files) const; | void prioritize_files(std::vector<int> const& files) const; | |||
std::vector<int> file_priorities() const; | std::vector<int> file_priorities() const; | |||
// set the interface to bind outgoing connections | // ``force_reannounce()`` will force this torrent to do anot | |||
// to. | her tracker | |||
void use_interface(const char* net_interface) const; | // request, to receive new peers. The ``seconds`` argument s | |||
pecifies how | ||||
#ifndef TORRENT_NO_DEPRECATE | // many seconds from now to issue the tracker announces. | |||
// deprecated in 0.14 | // | |||
// use save_resume_data() instead. It is async. and | // If the tracker's ``min_interval`` has not passed since th | |||
// will return the resume data in an alert | e last | |||
TORRENT_DEPRECATED_PREFIX | // announce, the forced announce will be scheduled to happen | |||
entry write_resume_data() const TORRENT_DEPRECATED; | immediately | |||
#endif | // as the ``min_interval`` expires. This is to honor tracker | |||
s minimum | ||||
// forces this torrent to reannounce | // re-announce interval settings. | |||
// (make a rerequest from the tracker) | // | |||
void force_reannounce() const; | // The ``tracker_index`` argument specifies which tracker to | |||
#ifndef TORRENT_DISABLE_DHT | re-announce. | |||
// announces this torrent to the DHT immediately | // If set to -1 (which is the default), all trackers are re- | |||
announce. | ||||
// | ||||
// ``force_dht_announce`` will announce the torrent to the D | ||||
HT | ||||
// immediately. | ||||
void force_reannounce(int seconds = 0, int tracker_index = - | ||||
1) const; | ||||
void force_dht_announce() const; | void force_dht_announce() const; | |||
#endif | ||||
#ifndef TORRENT_NO_DEPRECATE | ||||
// forces a reannounce in the specified amount of time. | // forces a reannounce in the specified amount of time. | |||
// This overrides the default announce interval, and no | // This overrides the default announce interval, and no | |||
// announce will take place until the given time has | // announce will take place until the given time has | |||
// timed out. | // timed out. | |||
void force_reannounce(boost::posix_time::time_duration) cons | TORRENT_DEPRECATED_PREFIX | |||
t; | void force_reannounce(boost::posix_time::time_duration) cons | |||
t TORRENT_DEPRECATED; | ||||
#endif | ||||
// performs a scrape request | // ``scrape_tracker()`` will send a scrape request to the tr | |||
acker. A | ||||
// scrape request queries the tracker for statistics such as | ||||
total number | ||||
// of incomplete peers, complete peers, number of downloads | ||||
etc. | ||||
// | ||||
// This request will specifically update the ``num_complete` | ||||
` and | ||||
// ``num_incomplete`` fields in the torrent_status struct on | ||||
ce it | ||||
// completes. When it completes, it will generate a scrape_r | ||||
eply_alert. | ||||
// If it fails, it will generate a scrape_failed_alert. | ||||
void scrape_tracker() const; | void scrape_tracker() const; | |||
// returns the name of this torrent, in case it doesn't | // ``set_upload_limit`` will limit the upload bandwidth used | |||
// have metadata it returns the name assigned to it | by this | |||
// when it was added. | // particular torrent to the limit you set. It is given as t | |||
std::string name() const; | he number of | |||
// bytes per second the torrent is allowed to upload. | ||||
// TODO: add a feature where the user can tell the torrent | // ``set_download_limit`` works the same way but for downloa | |||
// to finish all pieces currently in the pipeline, and then | d bandwidth | |||
// abort the torrent. | // instead of upload bandwidth. Note that setting a higher l | |||
imit on a | ||||
// torrent then the global limit | ||||
// (``session_settings::upload_rate_limit``) will not overri | ||||
de the global | ||||
// rate limit. The torrent can never upload more than the gl | ||||
obal rate | ||||
// limit. | ||||
// | ||||
// ``upload_limit`` and ``download_limit`` will return the c | ||||
urrent limit | ||||
// setting, for upload and download, respectively. | ||||
void set_upload_limit(int limit) const; | void set_upload_limit(int limit) const; | |||
int upload_limit() const; | int upload_limit() const; | |||
void set_download_limit(int limit) const; | void set_download_limit(int limit) const; | |||
int download_limit() const; | int download_limit() const; | |||
// ``set_sequential_download()`` enables or disables *sequen | ||||
tial | ||||
// download*. When enabled, the piece picker will pick piece | ||||
s in sequence | ||||
// instead of rarest first. In this mode, piece priorities a | ||||
re ignored, | ||||
// with the exception of priority 7, which are still preferr | ||||
ed over the | ||||
// sequential piece order. | ||||
// | ||||
// Enabling sequential download will affect the piece distri | ||||
bution | ||||
// negatively in the swarm. It should be used sparingly. | ||||
void set_sequential_download(bool sd) const; | void set_sequential_download(bool sd) const; | |||
// manually connect a peer | // ``connect_peer()`` is a way to manually connect to peers | |||
that one | ||||
// believe is a part of the torrent. If the peer does not re | ||||
spond, or is | ||||
// not a member of this torrent, it will simply be disconnec | ||||
ted. No harm | ||||
// can be done by using this other than an unnecessary conne | ||||
ction attempt | ||||
// is made. If the torrent is uninitialized or in queued or | ||||
checking | ||||
// mode, this will throw libtorrent_exception. The second (o | ||||
ptional) | ||||
// argument will be bitwised ORed into the source mask of th | ||||
is peer. | ||||
// Typically this is one of the source flags in peer_info. i | ||||
.e. | ||||
// ``tracker``, ``pex``, ``dht`` etc. | ||||
void connect_peer(tcp::endpoint const& adr, int source = 0) const; | void connect_peer(tcp::endpoint const& adr, int source = 0) const; | |||
std::string save_path() const; | // ``set_max_uploads()`` sets the maximum number of peers th | |||
at's unchoked | ||||
// -1 means unlimited unchokes | // at the same time on this torrent. If you set this to -1, | |||
there will be | ||||
// no limit. This defaults to infinite. The primary setting | ||||
controlling | ||||
// this is the global unchoke slots limit, set by unchoke_sl | ||||
ots_limit in | ||||
// session_settings. | ||||
// | ||||
// ``max_uploads()`` returns the current settings. | ||||
void set_max_uploads(int max_uploads) const; | void set_max_uploads(int max_uploads) const; | |||
int max_uploads() const; | int max_uploads() const; | |||
// -1 means unlimited connections | // ``set_max_connections()`` sets the maximum number of conn | |||
ection this | ||||
// torrent will open. If all connections are used up, incomi | ||||
ng | ||||
// connections may be refused or poor connections may be clo | ||||
sed. This | ||||
// must be at least 2. The default is unlimited number of co | ||||
nnections. If | ||||
// -1 is given to the function, it means unlimited. There is | ||||
also a | ||||
// global limit of the number of connections, set by | ||||
// ``connections_limit`` in session_settings. | ||||
// | ||||
// ``max_connections()`` returns the current settings. | ||||
void set_max_connections(int max_connections) const; | void set_max_connections(int max_connections) const; | |||
int max_connections() const; | int max_connections() const; | |||
// sets a username and password that will be sent along in t | ||||
he HTTP-request | ||||
// of the tracker announce. Set this if the tracker requires | ||||
authorization. | ||||
void set_tracker_login(std::string const& name | void set_tracker_login(std::string const& name | |||
, std::string const& password) const; | , std::string const& password) const; | |||
// post condition: save_path() == save_path if true is retur | // Moves the file(s) that this torrent are currently seeding | |||
ned | from or | |||
void move_storage(std::string const& save_path) const; | // downloading to. If the given ``save_path`` is not located | |||
on the same | ||||
// drive as the original save path, the files will be copied | ||||
to the new | ||||
// drive and removed from their original location. This will | ||||
block all | ||||
// other disk IO, and other torrents download and upload rat | ||||
es may drop | ||||
// while copying the file. | ||||
// | ||||
// Since disk IO is performed in a separate thread, this ope | ||||
ration is | ||||
// also asynchronous. Once the operation completes, the | ||||
// ``storage_moved_alert`` is generated, with the new path a | ||||
s the | ||||
// message. If the move fails for some reason, | ||||
// ``storage_moved_failed_alert`` is generated instead, cont | ||||
aining the | ||||
// error message. | ||||
// | ||||
// The ``flags`` argument determines the behavior of the cop | ||||
ying/moving | ||||
// of the files in the torrent. see move_flags_t. | ||||
// | ||||
// * always_replace_files = 0 | ||||
// * fail_if_exist = 1 | ||||
// * dont_replace = 2 | ||||
// | ||||
// ``always_replace_files`` is the default and replaces any | ||||
file that | ||||
// exist in both the source directory and the target directo | ||||
ry. | ||||
// | ||||
// ``fail_if_exist`` first check to see that none of the cop | ||||
y operations | ||||
// would cause an overwrite. If it would, it will fail. Othe | ||||
rwise it will | ||||
// proceed as if it was in ``always_replace_files`` mode. No | ||||
te that there | ||||
// is an inherent race condition here. If the files in the t | ||||
arget | ||||
// directory appear after the check but before the copy or m | ||||
ove | ||||
// completes, they will be overwritten. When failing because | ||||
of files | ||||
// already existing in the target path, the ``error`` of | ||||
// ``move_storage_failed_alert`` is set to | ||||
// ``boost::system::errc::file_exists``. | ||||
// | ||||
// The intention is that a client may use this as a probe, a | ||||
nd if it | ||||
// fails, ask the user which mode to use. The client may the | ||||
n re-issue | ||||
// the ``move_storage`` call with one of the other modes. | ||||
// | ||||
// ``dont_replace`` always takes the existing file in the ta | ||||
rget | ||||
// directory, if there is one. The source files will still b | ||||
e removed in | ||||
// that case. | ||||
// | ||||
// Files that have been renamed to have absolute pahts are n | ||||
ot moved by | ||||
// this function. Keep in mind that files that don't belong | ||||
to the | ||||
// torrent but are stored in the torrent's directory may be | ||||
moved as | ||||
// well. This goes for files that have been renamed to absol | ||||
ute paths | ||||
// that still end up inside the save path. | ||||
void move_storage(std::string const& save_path, int flags = | ||||
0) const; | ||||
// Renames the file with the given index asynchronously. The | ||||
rename | ||||
// operation is complete when either a file_renamed_alert or | ||||
// file_rename_failed_alert is posted. | ||||
void rename_file(int index, std::string const& new_name) con st; | void rename_file(int index, std::string const& new_name) con st; | |||
#if TORRENT_USE_WSTRING | ||||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
#if TORRENT_USE_WSTRING | ||||
// all wstring APIs are deprecated since 0.16.11 | // all wstring APIs are deprecated since 0.16.11 | |||
// instead, use the wchar -> utf8 conversion functions | // instead, use the wchar -> utf8 conversion functions | |||
// and pass in utf8 strings | // and pass in utf8 strings | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
void move_storage(std::wstring const& save_path) const TORRE NT_DEPRECATED; | void move_storage(std::wstring const& save_path, int flags = 0) const TORRENT_DEPRECATED; | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
void rename_file(int index, std::wstring const& new_name) co nst TORRENT_DEPRECATED; | void rename_file(int index, std::wstring const& new_name) co nst TORRENT_DEPRECATED; | |||
#endif // TORRENT_NO_DEPRECATE | ||||
#endif // TORRENT_USE_WSTRING | #endif // TORRENT_USE_WSTRING | |||
#endif // TORRENT_NO_DEPRECATE | ||||
// Enables or disabled super seeding/initial seeding for thi | ||||
s torrent. The torrent | ||||
// needs to be a seed for this to take effect. | ||||
void super_seeding(bool on) const; | void super_seeding(bool on) const; | |||
// ``info_hash()`` returns the info-hash for the torrent. | ||||
sha1_hash info_hash() const; | sha1_hash info_hash() const; | |||
// comparison operators. The order of the torrents is unspec | ||||
ified | ||||
// but stable. | ||||
bool operator==(const torrent_handle& h) const | bool operator==(const torrent_handle& h) const | |||
{ return m_torrent.lock() == h.m_torrent.lock(); } | { return m_torrent.lock() == h.m_torrent.lock(); } | |||
bool operator!=(const torrent_handle& h) const | bool operator!=(const torrent_handle& h) const | |||
{ return m_torrent.lock() != h.m_torrent.lock(); } | { return m_torrent.lock() != h.m_torrent.lock(); } | |||
bool operator<(const torrent_handle& h) const | bool operator<(const torrent_handle& h) const | |||
{ return m_torrent.lock() < h.m_torrent.lock(); } | { return m_torrent.lock() < h.m_torrent.lock(); } | |||
// This function is intended only for use by plugins and the | ||||
alert | ||||
// dispatch function. Any code that runs in libtorrent's net | ||||
work thread | ||||
// may not use the public API of torrent_handle. Doing so re | ||||
sults in a | ||||
// dead-lock. For such routines, the ``native_handle`` gives | ||||
access to | ||||
// the underlying type representing the torrent. This type d | ||||
oes not have | ||||
// a stable API and should be relied on as little as possibl | ||||
e. | ||||
boost::shared_ptr<torrent> native_handle() const; | boost::shared_ptr<torrent> native_handle() const; | |||
private: | private: | |||
torrent_handle(boost::weak_ptr<torrent> const& t) | torrent_handle(boost::weak_ptr<torrent> const& t) | |||
: m_torrent(t) | : m_torrent(t) | |||
{} | {} | |||
#ifdef TORRENT_DEBUG | ||||
void check_invariant() const; | ||||
#endif | ||||
boost::weak_ptr<torrent> m_torrent; | boost::weak_ptr<torrent> m_torrent; | |||
}; | }; | |||
// holds a snapshot of the status of a torrent, as queried by | ||||
// torrent_handle::status(). | ||||
struct TORRENT_EXPORT torrent_status | struct TORRENT_EXPORT torrent_status | |||
{ | { | |||
// hidden | ||||
torrent_status(); | torrent_status(); | |||
~torrent_status(); | ~torrent_status(); | |||
// compres if the torrent status objects come from the same | ||||
torrent. i.e. | ||||
// only the torrent_handle field is compared. | ||||
bool operator==(torrent_status const& st) const | bool operator==(torrent_status const& st) const | |||
{ return handle == st.handle; } | { return handle == st.handle; } | |||
// handle to the torrent | // a handle to the torrent whose status the object represent s. | |||
torrent_handle handle; | torrent_handle handle; | |||
// the different overall states a torrent can be in | ||||
enum state_t | enum state_t | |||
{ | { | |||
// The torrent is in the queue for being checked. Bu | ||||
t there | ||||
// currently is another torrent that are being check | ||||
ed. | ||||
// This torrent will wait for its turn. | ||||
queued_for_checking, | queued_for_checking, | |||
// The torrent has not started its download yet, and | ||||
is | ||||
// currently checking existing files. | ||||
checking_files, | checking_files, | |||
// The torrent is trying to download metadata from p | ||||
eers. | ||||
// This assumes the metadata_transfer extension is i | ||||
n use. | ||||
downloading_metadata, | downloading_metadata, | |||
// The torrent is being downloaded. This is the stat | ||||
e | ||||
// most torrents will be in most of the time. The pr | ||||
ogress | ||||
// meter will tell how much of the files that has be | ||||
en | ||||
// downloaded. | ||||
downloading, | downloading, | |||
// In this state the torrent has finished downloadin | ||||
g but | ||||
// still doesn't have the entire torrent. i.e. some | ||||
pieces | ||||
// are filtered and won't get downloaded. | ||||
finished, | finished, | |||
// In this state the torrent has finished downloadin | ||||
g and | ||||
// is a pure seeder. | ||||
seeding, | seeding, | |||
// If the torrent was started in full allocation mod | ||||
e, this | ||||
// indicates that the (disk) storage for the torrent | ||||
is | ||||
// allocated. | ||||
allocating, | allocating, | |||
// The torrent is currently checking the fastresume | ||||
data and | ||||
// comparing it to the files on disk. This is typica | ||||
lly | ||||
// completed in a fraction of a second, but if you a | ||||
dd a | ||||
// large number of torrents at once, they will queue | ||||
up. | ||||
checking_resume_data | checking_resume_data | |||
}; | }; | |||
state_t state; | // may be set to an error message describing why the torrent | |||
bool paused; | // was paused, in case it was paused by an error. If the tor | |||
bool auto_managed; | rent | |||
bool sequential_download; | // is not paused or if it's paused but not because of an err | |||
bool is_seeding; | or, | |||
bool is_finished; | // this string is empty. | |||
bool has_metadata; | ||||
float progress; | ||||
// progress parts per million (progress * 1000000) | ||||
// when disabling floating point operations, this is | ||||
// the only option to query progress | ||||
int progress_ppm; | ||||
std::string error; | std::string error; | |||
// the path to the directory where this torrent's files are | ||||
stored. | ||||
// It's typically the path as was given to async_add_torrent | ||||
() or | ||||
// add_torrent() when this torrent was started. This field i | ||||
s only | ||||
// included if the torrent status is queried with | ||||
// ``torrent_handle::query_save_path``. | ||||
std::string save_path; | ||||
// the name of the torrent. Typically this is derived from t | ||||
he | ||||
// .torrent file. In case the torrent was started without me | ||||
tadata, | ||||
// and hasn't completely received it yet, it returns the nam | ||||
e given | ||||
// to it when added to the session. See ``session::add_torre | ||||
nt``. | ||||
// This field is only included if the torrent status is quer | ||||
ied | ||||
// with ``torrent_handle::query_name``. | ||||
std::string name; | ||||
// set to point to the ``torrent_info`` object for this torr | ||||
ent. It's | ||||
// only included if the torrent status is queried with | ||||
// ``torrent_handle::query_torrent_file``. | ||||
boost::intrusive_ptr<const torrent_info> torrent_file; | ||||
// the time until the torrent will announce itself to the tr | ||||
acker. | ||||
boost::posix_time::time_duration next_announce; | boost::posix_time::time_duration next_announce; | |||
// the time the tracker want us to wait until we announce ou | ||||
rself | ||||
// again the next time. | ||||
boost::posix_time::time_duration announce_interval; | boost::posix_time::time_duration announce_interval; | |||
// the URL of the last working tracker. If no tracker reques | ||||
t has | ||||
// been successful yet, it's set to an empty string. | ||||
std::string current_tracker; | std::string current_tracker; | |||
// transferred this session! | // the number of bytes downloaded and uploaded to all peers, | |||
// total, payload plus protocol | accumulated, | |||
// *this session* only. The session is considered to restart | ||||
when a | ||||
// torrent is paused and restarted again. When a torrent is | ||||
paused, these | ||||
// counters are reset to 0. If you want complete, persistent | ||||
, stats, see | ||||
// ``all_time_upload`` and ``all_time_download``. | ||||
size_type total_download; | size_type total_download; | |||
size_type total_upload; | size_type total_upload; | |||
// payload only | // counts the amount of bytes send and received this session | |||
, but only | ||||
// the actual payload data (i.e the interesting data), these | ||||
counters | ||||
// ignore any protocol overhead. | ||||
size_type total_payload_download; | size_type total_payload_download; | |||
size_type total_payload_upload; | size_type total_payload_upload; | |||
// the amount of payload bytes that | // the number of bytes that has been downloaded and that has | |||
// has failed their hash test | failed the | |||
// piece hash test. In other words, this is just how much cr | ||||
ap that has | ||||
// been downloaded. | ||||
size_type total_failed_bytes; | size_type total_failed_bytes; | |||
// the number of payload bytes that | // the number of bytes that has been downloaded even though | |||
// has been received redundantly. | that data | |||
// already was downloaded. The reason for this is that in so | ||||
me situations | ||||
// the same data can be downloaded by mistake. When libtorre | ||||
nt sends | ||||
// requests to a peer, and the peer doesn't send a response | ||||
within a | ||||
// certain timeout, libtorrent will re-request that block. A | ||||
nother | ||||
// situation when libtorrent may re-request blocks is when t | ||||
he requests | ||||
// it sends out are not replied in FIFO-order (it will re-re | ||||
quest blocks | ||||
// that are skipped by an out of order block). This is suppo | ||||
sed to be as | ||||
// low as possible. | ||||
size_type total_redundant_bytes; | size_type total_redundant_bytes; | |||
// current transfer rate | // a bitmask that represents which pieces we have (set to tr | |||
// payload plus protocol | ue) and the | |||
// pieces we don't have. It's a pointer and may be set to 0 | ||||
if the | ||||
// torrent isn't downloading or seeding. | ||||
bitfield pieces; | ||||
// a bitmask representing which pieces has had their hash ch | ||||
ecked. This | ||||
// only applies to torrents in *seed mode*. If the torrent i | ||||
s not in seed | ||||
// mode, this bitmask may be empty. | ||||
bitfield verified_pieces; | ||||
// the total number of bytes of the file(s) that we have. Al | ||||
l this does | ||||
// not necessarily has to be downloaded during this session | ||||
(that's | ||||
// ``total_payload_download``). | ||||
size_type total_done; | ||||
// the number of bytes we have downloaded, only counting the | ||||
pieces that | ||||
// we actually want to download. i.e. excluding any pieces t | ||||
hat we have | ||||
// but have priority 0 (i.e. not wanted). | ||||
size_type total_wanted_done; | ||||
// The total number of bytes we want to download. This may b | ||||
e smaller | ||||
// than the total torrent size in case any pieces are priori | ||||
tized to 0, | ||||
// i.e. not wanted | ||||
size_type total_wanted; | ||||
// are accumulated upload and download payload byte counters | ||||
. They are | ||||
// saved in and restored from resume data to keep totals acr | ||||
oss sessions. | ||||
size_type all_time_upload; | ||||
size_type all_time_download; | ||||
// the posix-time when this torrent was added. i.e. what ``t | ||||
ime(NULL)`` | ||||
// returned at the time. | ||||
time_t added_time; | ||||
// the posix-time when this torrent was finished. If the tor | ||||
rent is not | ||||
// yet finished, this is 0. | ||||
time_t completed_time; | ||||
// the time when we, or one of our peers, last saw a complet | ||||
e copy of | ||||
// this torrent. | ||||
time_t last_seen_complete; | ||||
// The allocation mode for the torrent. See storage_mode_t f | ||||
or the | ||||
// options. For more information, see storage-allocation_. | ||||
storage_mode_t storage_mode; | ||||
// a value in the range [0, 1], that represents the progress | ||||
of the | ||||
// torrent's current task. It may be checking files or downl | ||||
oading. | ||||
float progress; | ||||
// progress parts per million (progress * 1000000) when disa | ||||
bling | ||||
// floating point operations, this is the only option to que | ||||
ry progress | ||||
// reflects the same value as ``progress``, but instead in a | ||||
range [0, | ||||
// 1000000] (ppm = parts per million). When floating point o | ||||
perations are | ||||
// disabled, this is the only alternative to the floating po | ||||
int value in | ||||
// progress. | ||||
int progress_ppm; | ||||
// the position this torrent has in the download | ||||
// queue. If the torrent is a seed or finished, this is -1. | ||||
int queue_position; | ||||
// the total rates for all peers for this torrent. These wil | ||||
l usually | ||||
// have better precision than summing the rates from all pee | ||||
rs. The rates | ||||
// are given as the number of bytes per second. | ||||
int download_rate; | int download_rate; | |||
int upload_rate; | int upload_rate; | |||
// the rate of payload that is | // the total transfer rate of payload only, not counting pro | |||
// sent and received | tocol | |||
// chatter. This might be slightly smaller than the other ra | ||||
tes, but if | ||||
// projected over a long time (e.g. when calculating ETA:s) | ||||
the | ||||
// difference may be noticeable. | ||||
int download_payload_rate; | int download_payload_rate; | |||
int upload_payload_rate; | int upload_payload_rate; | |||
// the number of peers this torrent is connected to | // the number of peers that are seeding that this client is | |||
// that are seeding. | // currently connected to. | |||
int num_seeds; | int num_seeds; | |||
// the number of peers this torrent | // the number of peers this torrent currently is connected t | |||
// is connected to (including seeds). | o. Peer | |||
// connections that are in the half-open state (is attemptin | ||||
g to connect) | ||||
// or are queued for later connection attempt do not count. | ||||
Although they | ||||
// are visible in the peer list when you call get_peer_info( | ||||
). | ||||
int num_peers; | int num_peers; | |||
// if the tracker sends scrape info in its | // if the tracker sends scrape info in its announce reply, t | |||
// announce reply, these fields will be | hese fields | |||
// set to the total number of peers that | // will be set to the total number of peers that have the wh | |||
// have the whole file and the total number | ole file and | |||
// of peers that are still downloading | // the total number of peers that are still downloading. set | |||
to -1 if the | ||||
// tracker did not send any scrape data in its announce repl | ||||
y. | ||||
int num_complete; | int num_complete; | |||
int num_incomplete; | int num_incomplete; | |||
// this is the number of seeds whose IP we know | // the number of seeds in our peer list and the total number | |||
// but are not necessarily connected to | of peers | |||
// (including seeds). We are not necessarily connected to al | ||||
l the peers | ||||
// in our peer list. This is the number of peers we know of | ||||
in total, | ||||
// including banned peers and peers that we have failed to c | ||||
onnect to. | ||||
int list_seeds; | int list_seeds; | |||
// this is the number of peers whose IP we know | ||||
// (including seeds), but are not necessarily | ||||
// connected to | ||||
int list_peers; | int list_peers; | |||
// the number of peers in our peerlist that | // the number of peers in this torrent's peer list that is a | |||
// we potentially could connect to | candidate to | |||
// be connected to. i.e. It has fewer connect attempts than | ||||
the max fail | ||||
// count, it is not a seed if we are a seed, it is not banne | ||||
d etc. If | ||||
// this is 0, it means we don't know of any more peers that | ||||
we can try. | ||||
int connect_candidates; | int connect_candidates; | |||
bitfield pieces; | // the number of pieces that has been downloaded. It is equi | |||
bitfield verified_pieces; | valent to: | |||
// ``std::accumulate(pieces->begin(), pieces->end())``. So y | ||||
// this is the number of pieces the client has | ou don't have | |||
// downloaded. it is equal to: | // to count yourself. This can be used to see if anything ha | |||
// std::accumulate(pieces->begin(), pieces->end()); | s updated | |||
// since last time if you want to keep a graph of the pieces | ||||
up to date. | ||||
int num_pieces; | int num_pieces; | |||
// the number of bytes of the file we have | // the number of distributed copies of the torrent. Note tha | |||
// including pieces that may have been filtered | t one copy | |||
// after we downloaded them | // may be spread out among many peers. It tells how many cop | |||
size_type total_done; | ies there are | |||
// currently of the rarest piece(s) among the peers this cli | ||||
// the number of bytes we have of those that we | ent is | |||
// want. i.e. not counting bytes from pieces that | // connected to. | |||
// are filtered as not wanted. | int distributed_full_copies; | |||
size_type total_wanted_done; | ||||
// the total number of bytes we want to download | // tells the share of pieces that have more copies than the | |||
// this may be smaller than the total torrent size | rarest | |||
// in case any pieces are filtered as not wanted | // piece(s). Divide this number by 1000 to get the fraction. | |||
size_type total_wanted; | // | |||
// For example, if ``distributed_full_copies`` is 2 and | ||||
// ``distrbuted_fraction`` is 500, it means that the rarest | ||||
pieces have | ||||
// only 2 copies among the peers this torrent is connected t | ||||
o, and that | ||||
// 50% of all the pieces have more than two copies. | ||||
// | ||||
// If we are a seed, the piece picker is deallocated as an o | ||||
ptimization, | ||||
// and piece availability is no longer tracked. In this case | ||||
the | ||||
// distributed copies members are set to -1. | ||||
int distributed_fraction; | ||||
// the number of distributed copies of the file. | // the number of distributed copies of the file. note that o | |||
// note that one copy may be spread out among many peers. | ne copy may | |||
// be spread out among many peers. This is a floating point | ||||
// representation of the distributed copies. | ||||
// | // | |||
// the integer part tells how many copies | // the integer part tells how many copies | |||
// there are of the rarest piece(s) | // there are of the rarest piece(s) | |||
// | // | |||
// the fractional part tells the fraction of pieces that | // the fractional part tells the fraction of pieces that | |||
// have more copies than the rarest piece(s). | // have more copies than the rarest piece(s). | |||
// the number of full distributed copies (i.e. the number | ||||
// of peers that have the rarest piece) | ||||
int distributed_full_copies; | ||||
// the fraction of pieces that more peers has than the | ||||
// rarest pieces. This indicates how close the swarm is | ||||
// to have one more full distributed copy | ||||
int distributed_fraction; | ||||
float distributed_copies; | float distributed_copies; | |||
// the block size that is used in this torrent. i.e. | // the size of a block, in bytes. A block is a sub piece, it | |||
// the number of bytes each piece request asks for | is the | |||
// and each bit in the download queue bitfield represents | // number of bytes that each piece request asks for and the | |||
number of | ||||
// bytes that each bit in the ``partial_piece_info``'s bitse | ||||
t represents, | ||||
// see get_download_queue(). This is typically 16 kB, but it | ||||
may be | ||||
// larger if the pieces are larger. | ||||
int block_size; | int block_size; | |||
// the number of unchoked peers in this torrent. | ||||
int num_uploads; | int num_uploads; | |||
// the number of peer connections this torrent has, includin | ||||
g half-open | ||||
// connections that hasn't completed the bittorrent handshak | ||||
e yet. This | ||||
// is always >= ``num_peers``. | ||||
int num_connections; | int num_connections; | |||
// the set limit of upload slots (unchoked peers) for this t | ||||
orrent. | ||||
int uploads_limit; | int uploads_limit; | |||
int connections_limit; | ||||
// true if the torrent is saved in compact mode | // the set limit of number of connections for this torrent. | |||
// false if it is saved in full allocation mode | int connections_limit; | |||
storage_mode_t storage_mode; | ||||
// the number of peers in this torrent that are waiting for | ||||
more | ||||
// bandwidth quota from the torrent rate limiter. This can d | ||||
etermine if | ||||
// the rate you get from this torrent is bound by the torren | ||||
ts limit or | ||||
// not. If there is no limit set on this torrent, the peers | ||||
might still | ||||
// be waiting for bandwidth quota from the global limiter, b | ||||
ut then they | ||||
// are counted in the ``session_status`` object. | ||||
int up_bandwidth_queue; | int up_bandwidth_queue; | |||
int down_bandwidth_queue; | int down_bandwidth_queue; | |||
// number of bytes downloaded since torrent was started | // the number of seconds since any peer last uploaded from t | |||
// saved and restored from resume data | his torrent | |||
size_type all_time_upload; | // and the last time a downloaded piece passed the hash chec | |||
size_type all_time_download; | k, | |||
// respectively. | ||||
int time_since_upload; | ||||
int time_since_download; | ||||
// the number of seconds of being active | // These keep track of the number of seconds this torrent ha | |||
// and as being a seed, saved and restored | s been active | |||
// from resume data | // (not paused) and the number of seconds it has been active | |||
while being | ||||
// finished and active while being a seed. ``seeding_time`` | ||||
should be <= | ||||
// ``finished_time`` which should be <= ``active_time``. The | ||||
y are all | ||||
// saved in and restored from resume data, to keep totals ac | ||||
ross | ||||
// sessions. | ||||
int active_time; | int active_time; | |||
int finished_time; | int finished_time; | |||
int seeding_time; | int seeding_time; | |||
// higher value means more important to seed | // A rank of how important it is to seed the torrent, it is | |||
used to | ||||
// determine which torrents to seed and which to queue. It i | ||||
s based on | ||||
// the peer to seed ratio from the tracker scrape. For more | ||||
information, | ||||
// see queuing_. Higher value means more important to seed | ||||
int seed_rank; | int seed_rank; | |||
// number of seconds since last scrape, or -1 if | // the number of seconds since this torrent acquired scrape | |||
// there hasn't been a scrape | data. | |||
// If it has never done that, this value is -1. | ||||
int last_scrape; | int last_scrape; | |||
// true if there are incoming connections to this | // the number of regions of non-downloaded pieces in the tor | |||
// torrent | rent. This is | |||
bool has_incoming; | // an interesting metric on windows vista, since there is a | |||
limit on the | ||||
// the number of "holes" in the torrent | // number of sparse regions in a single file there. | |||
int sparse_regions; | int sparse_regions; | |||
// is true if this torrent is (still) in seed_mode | // the priority of this torrent | |||
bool seed_mode; | int priority; | |||
// the main state the torrent is in. See torrent_status::sta | ||||
te_t. | ||||
state_t state; | ||||
// true if this torrent has unsaved changes | ||||
// to its download state and statistics since the last resum | ||||
e data | ||||
// was saved. | ||||
bool need_save_resume; | ||||
// true if the session global IP filter applies | ||||
// to this torrent. This defaults to true. | ||||
bool ip_filter_applies; | ||||
// this is set to true when the torrent is blocked | // true if the torrent is blocked from downloading. This typ | |||
// from downloading, typically caused by a file | ically | |||
// write operation failing | // happens when a disk write operation fails. If the torrent | |||
is | ||||
// auto-managed, it will periodically be taken out of this s | ||||
tate, in the | ||||
// hope that the disk condition (be it disk full or permissi | ||||
on errors) | ||||
// has been resolved. If the torrent is not auto-managed, yo | ||||
u have to | ||||
// explicitly take it out of the upload mode by calling set_ | ||||
upload_mode() | ||||
// on the torrent_handle. | ||||
bool upload_mode; | bool upload_mode; | |||
// this is true if the torrent is in share-mode | // true if the torrent is currently in share-mode, i.e. not | |||
downloading | ||||
// the torrent, but just helping the swarm out. | ||||
bool share_mode; | bool share_mode; | |||
// true if the torrent is in super seeding mode | // true if the torrent is in super seeding mode | |||
bool super_seeding; | bool super_seeding; | |||
// the priority of this torrent | // set to true if the torrent is paused and false otherwise. | |||
int priority; | It's only | |||
// true if the torrent itself is paused. If the torrent is n | ||||
ot running | ||||
// because the session is paused, this is still false. To kn | ||||
ow if a | ||||
// torrent is active or not, you need to inspect both | ||||
// ``torrent_status::paused`` and ``session::is_paused()``. | ||||
bool paused; | ||||
// the time this torrent was added and completed | // set to true if the torrent is auto managed, i.e. libtorre | |||
time_t added_time; | nt is | |||
time_t completed_time; | // responsible for determining whether it should be started | |||
time_t last_seen_complete; | or queued. | |||
// For more info see queuing_ | ||||
bool auto_managed; | ||||
// number of seconds since last upload or download activity | // true when the torrent is in sequential download mode. In | |||
int time_since_upload; | this mode | |||
int time_since_download; | // pieces are downloaded in order rather than rarest first. | |||
bool sequential_download; | ||||
// the position in the download queue where this torrent is | // true if all pieces have been downloaded. | |||
// this is -1 for seeds and finished torrents | bool is_seeding; | |||
int queue_position; | ||||
// true if this torrent has had changes since the last | // true if all pieces that have a priority > 0 are downloade | |||
// time resume data was saved | d. There is | |||
bool need_save_resume; | // only a distinction between finished and seeding if some p | |||
ieces or | ||||
// files have been set to priority 0, i.e. are not downloade | ||||
d. | ||||
bool is_finished; | ||||
// defaults to true. Determines whether the session | // true if this torrent has metadata (either it was started | |||
// IP filter applies to this torrent or not | from a | |||
bool ip_filter_applies; | // .torrent file or the metadata has been downloaded). The o | |||
nly scenario | ||||
// where this can be false is when the torrent was started t | ||||
orrent-less | ||||
// (i.e. with just an info-hash and tracker ip, a magnet lin | ||||
k for | ||||
// instance). | ||||
bool has_metadata; | ||||
// true if there has ever been an incoming connection attemp | ||||
t to this | ||||
// torrent. | ||||
bool has_incoming; | ||||
// true if the torrent is in seed_mode. If the torrent was s | ||||
tarted in | ||||
// seed mode, it will leave seed mode once all pieces have b | ||||
een checked | ||||
// or as soon as one piece fails the hash check. | ||||
bool seed_mode; | ||||
// this is true if this torrent's storage is currently being | ||||
moved from | ||||
// one location to another. This may potentially be a long o | ||||
peration | ||||
// if a large file ends up being copied from one drive to an | ||||
other. | ||||
bool moving_storage; | ||||
// the info-hash for this torrent | // the info-hash for this torrent | |||
sha1_hash info_hash; | sha1_hash info_hash; | |||
// if this torrent has its own listen socket, this is | ||||
// the port it's listening on. Otherwise it's 0 | ||||
int listen_port; | ||||
}; | }; | |||
} | } | |||
#endif // TORRENT_TORRENT_HANDLE_HPP_INCLUDED | #endif // TORRENT_TORRENT_HANDLE_HPP_INCLUDED | |||
End of changes. 158 change blocks. | ||||
207 lines changed or deleted | 1703 lines changed or added | |||
torrent_info.hpp | torrent_info.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2003-2008, Arvid Norberg | Copyright (c) 2003-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 81 | skipping to change at line 81 | |||
tracker_retry_delay_min = 5 | tracker_retry_delay_min = 5 | |||
// when tracker_failed_max trackers | // when tracker_failed_max trackers | |||
// has failed, wait 60 minutes instead | // has failed, wait 60 minutes instead | |||
, tracker_retry_delay_max = 60 * 60 | , tracker_retry_delay_max = 60 * 60 | |||
}; | }; | |||
TORRENT_EXTRA_EXPORT int merkle_num_leafs(int); | TORRENT_EXTRA_EXPORT int merkle_num_leafs(int); | |||
TORRENT_EXTRA_EXPORT int merkle_num_nodes(int); | TORRENT_EXTRA_EXPORT int merkle_num_nodes(int); | |||
TORRENT_EXTRA_EXPORT int merkle_get_parent(int); | TORRENT_EXTRA_EXPORT int merkle_get_parent(int); | |||
TORRENT_EXTRA_EXPORT int merkle_get_sibling(int); | TORRENT_EXTRA_EXPORT int merkle_get_sibling(int); | |||
TORRENT_EXTRA_EXPORT void trim_path_element(std::string& path_elemen t); | ||||
// this class holds information about one bittorrent tracker, as it | ||||
// relates to a specific torrent. | ||||
struct TORRENT_EXPORT announce_entry | struct TORRENT_EXPORT announce_entry | |||
{ | { | |||
// constructs a tracker announce entry with ``u`` as the URL . | ||||
announce_entry(std::string const& u); | announce_entry(std::string const& u); | |||
announce_entry(); | announce_entry(); | |||
~announce_entry(); | ~announce_entry(); | |||
// tracker URL as it appeared in the torrent file | // tracker URL as it appeared in the torrent file | |||
std::string url; | std::string url; | |||
// the current ``&trackerid=`` argument passed to the tracke | ||||
r. | ||||
// this is optional and is normally empty (in which case no | ||||
// trackerid is sent). | ||||
std::string trackerid; | std::string trackerid; | |||
// if this tracker has returned an error or warning message | // if this tracker has returned an error or warning message | |||
// that message is stored here | // that message is stored here | |||
std::string message; | std::string message; | |||
// if this tracker failed the last time it was contacted | // if this tracker failed the last time it was contacted | |||
// this error code specifies what error occurred | // this error code specifies what error occurred | |||
error_code last_error; | error_code last_error; | |||
// returns the number of seconds to the next announce on | ||||
// this tracker. ``min_announce_in()`` returns the number of | ||||
seconds until we are | ||||
// allowed to force another tracker update with this tracker | ||||
. | ||||
// | ||||
// If the last time this tracker was contacted failed, ``las | ||||
t_error`` is the error | ||||
// code describing what error occurred. | ||||
int next_announce_in() const; | int next_announce_in() const; | |||
int min_announce_in() const; | int min_announce_in() const; | |||
// the time of next tracker announce | // the time of next tracker announce | |||
ptime next_announce; | ptime next_announce; | |||
// no announces before this time | // no announces before this time | |||
ptime min_announce; | ptime min_announce; | |||
// TODO: include the number of peers received from this trac | ||||
ker, at last announce | ||||
// these are either -1 or the scrape information this tracke | ||||
r last responded with. *incomplete* is | ||||
// the current number of downloaders in the swarm, *complete | ||||
* is the current number | ||||
// of seeds in the swarm and *downloaded* is the cumulative | ||||
number of completed | ||||
// downloads of this torrent, since the beginning of time (f | ||||
rom this tracker's point | ||||
// of view). | ||||
// if this tracker has returned scrape data, these fields ar | ||||
e filled | ||||
// in with valid numbers. Otherwise they are set to -1. | ||||
// the number of current downloaders | ||||
int scrape_incomplete; | ||||
int scrape_complete; | ||||
int scrape_downloaded; | ||||
// the tier this tracker belongs to | // the tier this tracker belongs to | |||
boost::uint8_t tier; | boost::uint8_t tier; | |||
// the number of times this tracker can fail | // the max number of failures to announce to this tracker in | |||
// in a row before it's removed. 0 means unlimited | // a row, before this tracker is not used anymore. 0 means u | |||
nlimited | ||||
boost::uint8_t fail_limit; | boost::uint8_t fail_limit; | |||
// the number of times in a row this tracker has failed | // the number of times in a row we have failed to announce t | |||
o this | ||||
// tracker. | ||||
boost::uint8_t fails:7; | boost::uint8_t fails:7; | |||
// true if we're currently trying to announce with | // true while we're waiting for a response from the tracker. | |||
// this tracker | ||||
bool updating:1; | bool updating:1; | |||
// flags for the source bitmask, each indicating where | ||||
// we heard about this tracker | ||||
enum tracker_source | enum tracker_source | |||
{ | { | |||
// the tracker was part of the .torrent file | ||||
source_torrent = 1, | source_torrent = 1, | |||
// the tracker was added programatically via the add _troacker()_ function | ||||
source_client = 2, | source_client = 2, | |||
// the tracker was part of a magnet link | ||||
source_magnet_link = 4, | source_magnet_link = 4, | |||
// the tracker was received from the swarm via track er exchange | ||||
source_tex = 8 | source_tex = 8 | |||
}; | }; | |||
// where did we get this tracker from | // a bitmask specifying which sources we got this tracker fr om. | |||
boost::uint8_t source:4; | boost::uint8_t source:4; | |||
// is set to true if we have ever received a response from | // set to true the first time we receive a valid response | |||
// this tracker | // from this tracker. | |||
bool verified:1; | bool verified:1; | |||
// this is true if event start has been sent to the tracker | // set to true when we get a valid response from an announce | |||
// with event=started. If it is set, we won't send start in | ||||
the subsequent | ||||
// announces. | ||||
bool start_sent:1; | bool start_sent:1; | |||
// this is true if event completed has been sent to the trac ker | // set to true when we send a event=completed. | |||
bool complete_sent:1; | bool complete_sent:1; | |||
// this is false the stats sent to this tracker will be 0 | // this is false the stats sent to this tracker will be 0 | |||
bool send_stats:1; | bool send_stats:1; | |||
// reset announce counters and clears the started sent flag. | ||||
// The announce_entry will look like we've never talked to | ||||
// the tracker. | ||||
void reset() | void reset() | |||
{ | { | |||
start_sent = false; | start_sent = false; | |||
next_announce = min_time(); | next_announce = min_time(); | |||
min_announce = min_time(); | min_announce = min_time(); | |||
} | } | |||
// updates the failure counter and time-outs for re-trying. | ||||
// This is called when the tracker announce fails. | ||||
void failed(session_settings const& sett, int retry_interval = 0); | void failed(session_settings const& sett, int retry_interval = 0); | |||
bool will_announce(ptime now) const | #ifndef TORRENT_NO_DEPRECATE | |||
// deprecated in 1.0 | ||||
TORRENT_DEPRECATED_PREFIX | ||||
bool will_announce(ptime now) const TORRENT_DEPRECATED | ||||
{ | { | |||
return now <= next_announce | return now <= next_announce | |||
&& (fails < fail_limit || fail_limit == 0) | && (fails < fail_limit || fail_limit == 0) | |||
&& !updating; | && !updating; | |||
} | } | |||
#endif | ||||
// returns true if we can announec to this tracker now. | ||||
// The current time is passed in as ``now``. The ``is_seed`` | ||||
// argument is necessary because once we become a seed, we | ||||
// need to announce right away, even if the re-announce time | ||||
r | ||||
// hasn't expired yet. | ||||
bool can_announce(ptime now, bool is_seed) const; | bool can_announce(ptime now, bool is_seed) const; | |||
// returns true if the last time we tried to announce to thi | ||||
s | ||||
// tracker succeeded, or if we haven't tried yet. | ||||
bool is_working() const | bool is_working() const | |||
{ return fails == 0; } | { return fails == 0; } | |||
// trims whitespace characters from the beginning of the URL . | ||||
void trim(); | void trim(); | |||
}; | }; | |||
// the web_seed_entry holds information about a web seed (also known | ||||
// as URL seed or HTTP seed). It is essentially a URL with some stat | ||||
e | ||||
// associated with it. For more information, see `BEP 17`_ and `BEP | ||||
19`_. | ||||
struct web_seed_entry | struct web_seed_entry | |||
{ | { | |||
// http seeds are different from url seeds in the | // http seeds are different from url seeds in the | |||
// protocol they use. http seeds follows the original | // protocol they use. http seeds follows the original | |||
// http seed spec. by John Hoffman | // http seed spec. by John Hoffman | |||
enum type_t { url_seed, http_seed }; | enum type_t { url_seed, http_seed }; | |||
typedef std::vector<std::pair<std::string, std::string> > he aders_t; | typedef std::vector<std::pair<std::string, std::string> > he aders_t; | |||
web_seed_entry(std::string const& url_, type_t type_ | web_seed_entry(std::string const& url_, type_t type_ | |||
, std::string const& auth_ = std::string() | , std::string const& auth_ = std::string() | |||
, headers_t const& extra_headers_ = headers_t()); | , headers_t const& extra_headers_ = headers_t()); | |||
// URL and type comparison | ||||
bool operator==(web_seed_entry const& e) const | bool operator==(web_seed_entry const& e) const | |||
{ return url == e.url && type == e.type; } | { return url == e.url && type == e.type; } | |||
// URL and type less-than comparison | ||||
bool operator<(web_seed_entry const& e) const | bool operator<(web_seed_entry const& e) const | |||
{ | { | |||
if (url < e.url) return true; | if (url < e.url) return true; | |||
if (url > e.url) return false; | if (url > e.url) return false; | |||
return type < e.type; | return type < e.type; | |||
} | } | |||
// The URL of the web seed | ||||
std::string url; | std::string url; | |||
// The type of web seed (see type_t) | ||||
type_t type; | type_t type; | |||
// Optional authentication. If this is set, it's passed | ||||
// in as HTTP basic auth to the web seed. The format is: | ||||
// username:password. | ||||
std::string auth; | std::string auth; | |||
// Any extra HTTP headers that need to be passed to the web | ||||
seed | ||||
headers_t extra_headers; | headers_t extra_headers; | |||
// if this is > now, we can't reconnect yet | // if this is > now, we can't reconnect yet | |||
ptime retry; | ptime retry; | |||
// this is initialized to true, but if we discover the | ||||
// server not to support it, it's set to false, and we | ||||
// make larger requests. | ||||
bool supports_keepalive; | ||||
// this indicates whether or not we're resolving the | // this indicates whether or not we're resolving the | |||
// hostname of this URL | // hostname of this URL | |||
bool resolving; | bool resolving; | |||
// if the user wanted to remove this while | // if the user wanted to remove this while | |||
// we were resolving it. In this case, we set | // we were resolving it. In this case, we set | |||
// the removed flag to true, to make the resolver | // the removed flag to true, to make the resolver | |||
// callback remove it | // callback remove it | |||
bool removed; | bool removed; | |||
// if the hostname of the web seed has been resolved, | ||||
// this is its IP address | ||||
tcp::endpoint endpoint; | tcp::endpoint endpoint; | |||
// this is the peer_info field used for the | // this is the peer_info field used for the | |||
// connection, just to count hash failures | // connection, just to count hash failures | |||
// it's also used to hold the peer_connection | // it's also used to hold the peer_connection | |||
// pointer, when the web seed is connected | // pointer, when the web seed is connected | |||
policy::peer peer_info; | policy::ipv4_peer peer_info; | |||
// if the web server doesn't support keepalive or a block re | ||||
quest was | ||||
// interrupted, the block received so far is kept here for t | ||||
he next | ||||
// connection to pick up | ||||
peer_request restart_request; | ||||
std::vector<char> restart_piece; | ||||
}; | }; | |||
#ifndef BOOST_NO_EXCEPTIONS | #ifndef BOOST_NO_EXCEPTIONS | |||
// for backwards compatibility with 0.14 | // for backwards compatibility with 0.14 | |||
typedef libtorrent_exception invalid_torrent_file; | typedef libtorrent_exception invalid_torrent_file; | |||
#endif | #endif | |||
int TORRENT_EXPORT load_file(std::string const& filename | // This class represents the information stored in a .torrent file | |||
, std::vector<char>& v, error_code& ec, int limit = 8000000) | ||||
; | ||||
class TORRENT_EXPORT torrent_info : public intrusive_ptr_base<torren t_info> | class TORRENT_EXPORT torrent_info : public intrusive_ptr_base<torren t_info> | |||
{ | { | |||
public: | public: | |||
#ifdef TORRENT_DEBUG | // The constructor that takes an info-hash will initialize | |||
void check_invariant() const; | the info-hash to the given value, | |||
#endif | // but leave all other fields empty. This is used internally | |||
when downloading torrents without | ||||
// the metadata. The metadata will be created by libtorrent | ||||
as soon as it has been downloaded | ||||
// from the swarm. | ||||
// | ||||
// The constructor that takes a lazy_entry will create a tor | ||||
rent_info object from the | ||||
// information found in the given torrent_file. The lazy_ent | ||||
ry represents a tree node in | ||||
// an bencoded file. To load an ordinary .torrent file | ||||
// into a lazy_entry, use lazy_bdecode(). | ||||
// | ||||
// The version that takes a buffer pointer and a size will d | ||||
ecode it as a .torrent file and | ||||
// initialize the torrent_info object for you. | ||||
// | ||||
// The version that takes a filename will simply load the to | ||||
rrent file and decode it inside | ||||
// the constructor, for convenience. This might not be the m | ||||
ost suitable for applications that | ||||
// want to be able to report detailed errors on what might g | ||||
o wrong. | ||||
// | ||||
// The overloads that takes an ``error_code const&`` never t | ||||
hrows if an error occur, they | ||||
// will simply set the error code to describe what went wron | ||||
g and not fully initialize the | ||||
// torrent_info object. The overloads that do not take the e | ||||
xtra error_code parameter will | ||||
// always throw if an error occurs. These overloads are not | ||||
available when building without | ||||
// exception support. | ||||
// | ||||
// The ``flags`` argument is currently unused. | ||||
#ifndef BOOST_NO_EXCEPTIONS | #ifndef BOOST_NO_EXCEPTIONS | |||
torrent_info(lazy_entry const& torrent_file, int flags = 0); | torrent_info(lazy_entry const& torrent_file, int flags = 0); | |||
torrent_info(char const* buffer, int size, int flags = 0); | torrent_info(char const* buffer, int size, int flags = 0); | |||
torrent_info(std::string const& filename, int flags = 0); | torrent_info(std::string const& filename, int flags = 0); | |||
#ifndef TORRENT_NO_DEPRECATE | ||||
#if TORRENT_USE_WSTRING | #if TORRENT_USE_WSTRING | |||
// all wstring APIs are deprecated since 0.16.11 | // all wstring APIs are deprecated since 0.16.11 | |||
// instead, use the wchar -> utf8 conversion functions | // instead, use the wchar -> utf8 conversion functions | |||
// and pass in utf8 strings | // and pass in utf8 strings | |||
#ifndef TORRENT_NO_DEPRECATE | ||||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
torrent_info(std::wstring const& filename, int flags = 0) TO RRENT_DEPRECATED; | torrent_info(std::wstring const& filename, int flags = 0) TO RRENT_DEPRECATED; | |||
#endif // TORRENT_NO_DEPRECATE | ||||
#endif // TORRENT_USE_WSTRING | #endif // TORRENT_USE_WSTRING | |||
#endif // TORRENT_NO_DEPRECATE | ||||
#endif | #endif | |||
torrent_info(torrent_info const& t, int flags = 0); | torrent_info(torrent_info const& t, int flags = 0); | |||
torrent_info(sha1_hash const& info_hash, int flags = 0); | torrent_info(sha1_hash const& info_hash, int flags = 0); | |||
torrent_info(lazy_entry const& torrent_file, error_code& ec, int flags = 0); | torrent_info(lazy_entry const& torrent_file, error_code& ec, int flags = 0); | |||
torrent_info(char const* buffer, int size, error_code& ec, i nt flags = 0); | torrent_info(char const* buffer, int size, error_code& ec, i nt flags = 0); | |||
torrent_info(std::string const& filename, error_code& ec, in t flags = 0); | torrent_info(std::string const& filename, error_code& ec, in t flags = 0); | |||
#ifndef TORRENT_NO_DEPRECATE | ||||
#if TORRENT_USE_WSTRING | #if TORRENT_USE_WSTRING | |||
// all wstring APIs are deprecated since 0.16.11 | // all wstring APIs are deprecated since 0.16.11 | |||
// instead, use the wchar -> utf8 conversion functions | // instead, use the wchar -> utf8 conversion functions | |||
// and pass in utf8 strings | // and pass in utf8 strings | |||
#ifndef TORRENT_NO_DEPRECATE | ||||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
torrent_info(std::wstring const& filename, error_code& ec, i nt flags = 0) TORRENT_DEPRECATED; | torrent_info(std::wstring const& filename, error_code& ec, i nt flags = 0) TORRENT_DEPRECATED; | |||
#endif // TORRENT_NO_DEPRECATE | ||||
#endif // TORRENT_USE_WSTRING | #endif // TORRENT_USE_WSTRING | |||
#endif // TORRENT_NO_DEPRECATE | ||||
// frees all storage associated with this torrent_info objec t | ||||
~torrent_info(); | ~torrent_info(); | |||
// The file_storage object contains the information on how t | ||||
o map the pieces to | ||||
// files. It is separated from the torrent_info object becau | ||||
se when creating torrents | ||||
// a storage object needs to be created without having a tor | ||||
rent file. When renaming files | ||||
// in a storage, the storage needs to make its own copy of t | ||||
he file_storage in order | ||||
// to make its mapping differ from the one in the torrent fi | ||||
le. | ||||
// | ||||
// ``orig_files()`` returns the original (unmodified) file s | ||||
torage for this torrent. This | ||||
// is used by the web server connection, which needs to requ | ||||
est files with the original | ||||
// names. Filename may be chaged using ``torrent_info::renam | ||||
e_file()``. | ||||
// | ||||
// For more information on the file_storage object, see the | ||||
separate document on how | ||||
// to create torrents. | ||||
file_storage const& files() const { return m_files; } | file_storage const& files() const { return m_files; } | |||
file_storage const& orig_files() const { return m_orig_files ? *m_orig_files : m_files; } | file_storage const& orig_files() const { return m_orig_files ? *m_orig_files : m_files; } | |||
// Renames a the file with the specified index to the new na | ||||
me. The new filename is | ||||
// reflected by the ``file_storage`` returned by ``files()`` | ||||
but not by the one | ||||
// returned by ``orig_files()``. | ||||
// | ||||
// If you want to rename the base name of the torrent (for a | ||||
multifile torrent), you | ||||
// can copy the ``file_storage`` (see files() and orig_files | ||||
() ), change the name, and | ||||
// then use `remap_files()`_. | ||||
// | ||||
// The ``new_filename`` can both be a relative path, in whic | ||||
h case the file name | ||||
// is relative to the ``save_path`` of the torrent. If the ` | ||||
`new_filename`` is | ||||
// an absolute path (i.e. ``is_complete(new_filename) == tru | ||||
e``), then the file | ||||
// is detached from the ``save_path`` of the torrent. In thi | ||||
s case the file is | ||||
// not moved when move_storage() is invoked. | ||||
void rename_file(int index, std::string const& new_filename) | void rename_file(int index, std::string const& new_filename) | |||
{ | { | |||
copy_on_write(); | copy_on_write(); | |||
m_files.rename_file(index, new_filename); | m_files.rename_file(index, new_filename); | |||
} | } | |||
#ifndef TORRENT_NO_DEPRECATE | ||||
#if TORRENT_USE_WSTRING | #if TORRENT_USE_WSTRING | |||
// all wstring APIs are deprecated since 0.16.11 | // all wstring APIs are deprecated since 0.16.11 | |||
// instead, use the wchar -> utf8 conversion functions | // instead, use the wchar -> utf8 conversion functions | |||
// and pass in utf8 strings | // and pass in utf8 strings | |||
#ifndef TORRENT_NO_DEPRECATE | ||||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
void rename_file(int index, std::wstring const& new_filename | void rename_file(int index, std::wstring const& new_filename | |||
) TORRENT_DEPRECATED | ) TORRENT_DEPRECATED; | |||
{ | ||||
copy_on_write(); | ||||
m_files.rename_file(index, new_filename); | ||||
} | ||||
#endif // TORRENT_NO_DEPRECATE | ||||
#endif // TORRENT_USE_WSTRING | #endif // TORRENT_USE_WSTRING | |||
#endif // TORRENT_NO_DEPRECATE | ||||
// Remaps the file storage to a new file layout. This can be | ||||
used to, for instance, | ||||
// download all data in a torrent to a single file, or to a | ||||
number of fixed size | ||||
// sector aligned files, regardless of the number and sizes | ||||
of the files in the torrent. | ||||
// | ||||
// The new specified ``file_storage`` must have the exact sa | ||||
me size as the current one. | ||||
void remap_files(file_storage const& f); | void remap_files(file_storage const& f); | |||
// ``add_tracker()`` adds a tracker to the announce-list. Th | ||||
e ``tier`` determines the order in | ||||
// which the trackers are to be tried. | ||||
// | ||||
// The ``trackers()`` function will return a sorted vector o | ||||
f ``announce_entry``. | ||||
// Each announce entry contains a string, which is the track | ||||
er url, and a tier index. The | ||||
// tier index is the high-level priority. No matter which tr | ||||
ackers that works or not, the | ||||
// ones with lower tier will always be tried before the one | ||||
with higher tier number. | ||||
// For more information, see announce_entry_. | ||||
void add_tracker(std::string const& url, int tier = 0); | void add_tracker(std::string const& url, int tier = 0); | |||
std::vector<announce_entry> const& trackers() const { return m_urls; } | std::vector<announce_entry> const& trackers() const { return m_urls; } | |||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
// deprecated in 0.16. Use web_seeds() instead | // deprecated in 0.16. Use web_seeds() instead | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
std::vector<std::string> url_seeds() const TORRENT_DEPRECATE D; | std::vector<std::string> url_seeds() const TORRENT_DEPRECATE D; | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
std::vector<std::string> http_seeds() const TORRENT_DEPRECAT ED; | std::vector<std::string> http_seeds() const TORRENT_DEPRECAT ED; | |||
#endif // TORRENT_NO_DEPRECATE | #endif // TORRENT_NO_DEPRECATE | |||
void add_url_seed(std::string const& url | // ``web_seeds()`` returns all url seeds and http seeds in t | |||
he torrent. Each entry | ||||
// is a ``web_seed_entry`` and may refer to either a url see | ||||
d or http seed. | ||||
// | ||||
// ``add_url_seed()`` and ``add_http_seed()`` adds one url t | ||||
o the list of | ||||
// url/http seeds. Currently, the only transport protocol su | ||||
pported for the url | ||||
// is http. | ||||
// | ||||
// The ``extern_auth`` argument can be used for other athori | ||||
zation schemese than | ||||
// basic HTTP authorization. If set, it will override any us | ||||
ername and password | ||||
// found in the URL itself. The string will be sent as the H | ||||
TTP authorization header's | ||||
// value (without specifying "Basic"). | ||||
// | ||||
// The ``extra_headers`` argument defaults to an empty list, | ||||
but can be used to | ||||
// insert custom HTTP headers in the requests to a specific | ||||
web seed. | ||||
// | ||||
// See http-seeding_ for more information. | ||||
void add_url_seed(std::string const& url | ||||
, std::string const& extern_auth = std::string() | , std::string const& extern_auth = std::string() | |||
, web_seed_entry::headers_t const& extra_headers = w eb_seed_entry::headers_t()); | , web_seed_entry::headers_t const& extra_headers = w eb_seed_entry::headers_t()); | |||
void add_http_seed(std::string const& url | void add_http_seed(std::string const& url | |||
, std::string const& extern_auth = std::string() | , std::string const& extern_auth = std::string() | |||
, web_seed_entry::headers_t const& extra_headers = w eb_seed_entry::headers_t()); | , web_seed_entry::headers_t const& extra_headers = w eb_seed_entry::headers_t()); | |||
std::vector<web_seed_entry> const& web_seeds() const | std::vector<web_seed_entry> const& web_seeds() const | |||
{ return m_web_seeds; } | { return m_web_seeds; } | |||
// ``total_size()``, ``piece_length()`` and ``num_pieces()`` | ||||
returns the total | ||||
// number of bytes the torrent-file represents (all the file | ||||
s in it), the number of byte for | ||||
// each piece and the total number of pieces, respectively. | ||||
The difference between | ||||
// ``piece_size()`` and ``piece_length()`` is that ``piece_s | ||||
ize()`` takes | ||||
// the piece index as argument and gives you the exact size | ||||
of that piece. It will always | ||||
// be the same as ``piece_length()`` except in the case of t | ||||
he last piece, which may | ||||
// be smaller. | ||||
size_type total_size() const { return m_files.total_size(); } | size_type total_size() const { return m_files.total_size(); } | |||
int piece_length() const { return m_files.piece_length(); } | int piece_length() const { return m_files.piece_length(); } | |||
int num_pieces() const { return m_files.num_pieces(); } | int num_pieces() const { return m_files.num_pieces(); } | |||
// returns the info-hash of the torrent | ||||
const sha1_hash& info_hash() const { return m_info_hash; } | const sha1_hash& info_hash() const { return m_info_hash; } | |||
const std::string& name() const { return m_files.name(); } | ||||
#ifndef TORRENT_NO_DEPRECATE | ||||
// deprecated in 1.0. Use the variants that take an index in | ||||
stead | ||||
// internal_file_entry is no longer exposed in the API | ||||
typedef file_storage::iterator file_iterator; | typedef file_storage::iterator file_iterator; | |||
typedef file_storage::reverse_iterator reverse_file_iterator ; | typedef file_storage::reverse_iterator reverse_file_iterator ; | |||
file_iterator begin_files() const { return m_files.begin(); | // This class will need some explanation. First of all, to g | |||
} | et a list of all files | |||
file_iterator end_files() const { return m_files.end(); } | // in the torrent, you can use ``begin_files()``, ``end_file | |||
reverse_file_iterator rbegin_files() const { return m_files. | s()``, | |||
rbegin(); } | // ``rbegin_files()`` and ``rend_files()``. These will give | |||
reverse_file_iterator rend_files() const { return m_files.re | you standard vector | |||
nd(); } | // iterators with the type ``internal_file_entry``, which is | |||
an internal type. | ||||
// | ||||
// You can resolve it into the public representation of a fi | ||||
le (``file_entry``) | ||||
// using the ``file_storage::at`` function, which takes an i | ||||
ndex and an iterator. | ||||
TORRENT_DEPRECATED_PREFIX | ||||
file_iterator begin_files() const TORRENT_DEPRECATED { retur | ||||
n m_files.begin_deprecated(); } | ||||
TORRENT_DEPRECATED_PREFIX | ||||
file_iterator end_files() const TORRENT_DEPRECATED { return | ||||
m_files.end_deprecated(); } | ||||
reverse_file_iterator rbegin_files() const TORRENT_DEPRECATE | ||||
D { return m_files.rbegin_deprecated(); } | ||||
TORRENT_DEPRECATED_PREFIX | ||||
reverse_file_iterator rend_files() const TORRENT_DEPRECATED | ||||
{ return m_files.rend_deprecated(); } | ||||
TORRENT_DEPRECATED_PREFIX | ||||
file_iterator file_at_offset(size_type offset) const TORRENT | ||||
_DEPRECATED | ||||
{ return m_files.file_at_offset_deprecated(offset); } | ||||
#endif // TORRENT_NO_DEPRECATE | ||||
// If you need index-access to files you can use the ``num_f | ||||
iles()`` and ``file_at()`` | ||||
// to access files using indices. | ||||
int num_files() const { return m_files.num_files(); } | int num_files() const { return m_files.num_files(); } | |||
file_entry file_at(int index) const { return m_files.at(inde x); } | file_entry file_at(int index) const { return m_files.at(inde x); } | |||
file_iterator file_at_offset(size_type offset) const | // This function will map a piece index, a byte offset withi | |||
{ return m_files.file_at_offset(offset); } | n that piece and | |||
// a size (in bytes) into the corresponding files with offse | ||||
ts where that data | ||||
// for that piece is supposed to be stored. See file_slice. | ||||
std::vector<file_slice> map_block(int piece, size_type offse t, int size) const | std::vector<file_slice> map_block(int piece, size_type offse t, int size) const | |||
{ return m_files.map_block(piece, offset, size); } | { return m_files.map_block(piece, offset, size); } | |||
// This function will map a range in a specific file into a | ||||
range in the torrent. | ||||
// The ``file_offset`` parameter is the offset in the file, | ||||
given in bytes, where | ||||
// 0 is the start of the file. See peer_request. | ||||
// | ||||
// The input range is assumed to be valid within the torrent | ||||
. ``file_offset`` | ||||
// + ``size`` is not allowed to be greater than the file siz | ||||
e. ``file_index`` | ||||
// must refer to a valid file, i.e. it cannot be >= ``num_fi | ||||
les()``. | ||||
peer_request map_file(int file, size_type offset, int size) const | peer_request map_file(int file, size_type offset, int size) const | |||
{ return m_files.map_file(file, offset, size); } | { return m_files.map_file(file, offset, size); } | |||
#ifndef TORRENT_NO_DEPRECATE | #ifndef TORRENT_NO_DEPRECATE | |||
// ------- start deprecation ------- | // ------- start deprecation ------- | |||
// these functions will be removed in a future version | // these functions will be removed in a future version | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
torrent_info(entry const& torrent_file) TORRENT_DEPRECATED; | torrent_info(entry const& torrent_file) TORRENT_DEPRECATED; | |||
TORRENT_DEPRECATED_PREFIX | TORRENT_DEPRECATED_PREFIX | |||
void print(std::ostream& os) const TORRENT_DEPRECATED; | void print(std::ostream& os) const TORRENT_DEPRECATED; | |||
// ------- end deprecation ------- | // ------- end deprecation ------- | |||
#endif | #endif | |||
#ifdef TORRENT_USE_OPENSSL | // Returns the SSL root certificate for the torrent, if it i | |||
std::string const& ssl_cert() const { return m_ssl_root_cert | s an SSL | |||
; } | // torrent. Otherwise returns an empty string. The certifica | |||
#else | te is | |||
std::string ssl_cert() const | // the the public certificate in x509 format. | |||
{ | std::string ssl_cert() const; | |||
if (m_info_dict.type() != lazy_entry::dict_t) return | ||||
""; | // returns true if this torrent_info object has a torrent lo | |||
return m_info_dict.dict_find_string_value("ssl-cert" | aded. | |||
); | // This is primarily used to determine if a magnet link has | |||
} | had its | |||
#endif | // metadata resolved yet or not. | |||
bool is_valid() const { return m_files.is_valid(); } | bool is_valid() const { return m_files.is_valid(); } | |||
// returns true if this torrent is private. i.e., it should | ||||
not be | ||||
// distributed on the trackerless network (the kademlia DHT) | ||||
. | ||||
bool priv() const { return m_private; } | bool priv() const { return m_private; } | |||
// returns true if this is an i2p torrent. This is determine | ||||
d by whether | ||||
// or not it has a tracker whose URL domain name ends with " | ||||
.i2p". i2p | ||||
// torrents disable the DHT and local peer discovery as well | ||||
as talking | ||||
// to peers over anything other than the i2p network. | ||||
bool is_i2p() const { return m_i2p; } | bool is_i2p() const { return m_i2p; } | |||
// ``hash_for_piece()`` takes a piece-index and returns the | ||||
20-bytes sha1-hash for that | ||||
// piece and ``info_hash()`` returns the 20-bytes sha1-hash | ||||
for the info-section of the | ||||
// torrent file. | ||||
// ``hash_for_piece_ptr()`` returns a pointer to the 20 byte | ||||
sha1 digest for the piece. | ||||
// Note that the string is not null-terminated. | ||||
int piece_size(int index) const { return m_files.piece_size( index); } | int piece_size(int index) const { return m_files.piece_size( index); } | |||
sha1_hash hash_for_piece(int index) const | sha1_hash hash_for_piece(int index) const | |||
{ return sha1_hash(hash_for_piece_ptr(index)); } | { return sha1_hash(hash_for_piece_ptr(index)); } | |||
std::vector<sha1_hash> const& merkle_tree() const { return m | ||||
_merkle_tree; } | ||||
void set_merkle_tree(std::vector<sha1_hash>& h) | ||||
{ TORRENT_ASSERT(h.size() == m_merkle_tree.size() ); m_merkl | ||||
e_tree.swap(h); } | ||||
char const* hash_for_piece_ptr(int index) const | char const* hash_for_piece_ptr(int index) const | |||
{ | { | |||
TORRENT_ASSERT(index >= 0); | TORRENT_ASSERT(index >= 0); | |||
TORRENT_ASSERT(index < m_files.num_pieces()); | TORRENT_ASSERT(index < m_files.num_pieces()); | |||
if (is_merkle_torrent()) | if (is_merkle_torrent()) | |||
{ | { | |||
TORRENT_ASSERT(index < int(m_merkle_tree.siz e() - m_merkle_first_leaf)); | TORRENT_ASSERT(index < int(m_merkle_tree.siz e() - m_merkle_first_leaf)); | |||
return (const char*)&m_merkle_tree[m_merkle_ first_leaf + index][0]; | return (const char*)&m_merkle_tree[m_merkle_ first_leaf + index][0]; | |||
} | } | |||
else | else | |||
{ | { | |||
TORRENT_ASSERT(m_piece_hashes); | TORRENT_ASSERT(m_piece_hashes); | |||
TORRENT_ASSERT(m_piece_hashes >= m_info_sect ion.get()); | TORRENT_ASSERT(m_piece_hashes >= m_info_sect ion.get()); | |||
TORRENT_ASSERT(m_piece_hashes < m_info_secti on.get() + m_info_section_size); | TORRENT_ASSERT(m_piece_hashes < m_info_secti on.get() + m_info_section_size); | |||
TORRENT_ASSERT(index < int(m_info_section_si ze / 20)); | TORRENT_ASSERT(index < int(m_info_section_si ze / 20)); | |||
return &m_piece_hashes[index*20]; | return &m_piece_hashes[index*20]; | |||
} | } | |||
} | } | |||
boost::optional<time_t> creation_date() const; | // ``merkle_tree()`` returns a reference to the merkle tree | |||
for this torrent, if any. | ||||
// | ||||
// ``set_merkle_tree()`` moves the passed in merkle tree int | ||||
o the torrent_info object. | ||||
// i.e. ``h`` will not be identical after the call. You need | ||||
to set the merkle tree for | ||||
// a torrent that you've just created (as a merkle torrent). | ||||
The merkle tree is retrieved | ||||
// from the ``create_torrent::merkle_tree()`` function, and | ||||
need to be saved separately | ||||
// from the torrent file itself. Once it's added to libtorre | ||||
nt, the merkle tree will be | ||||
// persisted in the resume data. | ||||
std::vector<sha1_hash> const& merkle_tree() const { return m | ||||
_merkle_tree; } | ||||
void set_merkle_tree(std::vector<sha1_hash>& h) | ||||
{ TORRENT_ASSERT(h.size() == m_merkle_tree.size() ); m_merkl | ||||
e_tree.swap(h); } | ||||
// ``name()`` returns the name of the torrent. | ||||
// | ||||
// ``comment()`` returns the comment associated with the tor | ||||
rent. If there's no comment, | ||||
// it will return an empty string. ``creation_date()`` retur | ||||
ns the creation date of | ||||
// the torrent as time_t (`posix time`_). If there's no time | ||||
stamp in the torrent file, | ||||
// the optional object will be uninitialized. | ||||
// | ||||
// Both the name and the comment is UTF-8 encoded strings. | ||||
// | ||||
// ``creator()`` returns the creator string in the torrent. | ||||
If there is no creator string | ||||
// it will return an empty string. | ||||
// | ||||
// .. _`posix time`: http://www.opengroup.org/onlinepubs/009 | ||||
695399/functions/time.html | ||||
const std::string& name() const { return m_files.name(); } | ||||
boost::optional<time_t> creation_date() const; | ||||
const std::string& creator() const | const std::string& creator() const | |||
{ return m_created_by; } | { return m_created_by; } | |||
const std::string& comment() const | const std::string& comment() const | |||
{ return m_comment; } | { return m_comment; } | |||
// dht nodes to add to the routing table/bootstrap from | // dht nodes to add to the routing table/bootstrap from | |||
typedef std::vector<std::pair<std::string, int> > nodes_t; | typedef std::vector<std::pair<std::string, int> > nodes_t; | |||
// If this torrent contains any DHT nodes, they are put in t | ||||
his vector in their original | ||||
// form (host name and port number). | ||||
nodes_t const& nodes() const | nodes_t const& nodes() const | |||
{ return m_nodes; } | { return m_nodes; } | |||
// This is used when creating torrent. Use this to add a kno | ||||
wn DHT node. It may | ||||
// be used, by the client, to bootstrap into the DHT network | ||||
. | ||||
void add_node(std::pair<std::string, int> const& node) | void add_node(std::pair<std::string, int> const& node) | |||
{ m_nodes.push_back(node); } | { m_nodes.push_back(node); } | |||
// populates the torrent_info by providing just the info-dic | ||||
t buffer. This is used when | ||||
// loading a torrent from a magnet link for instance, where | ||||
we only have the info-dict. | ||||
// The lazy_entry ``e`` points to a parsed info-dictionary. | ||||
``ec`` returns an error code | ||||
// if something fails (typically if the info dictionary is m | ||||
alformed). ``flags`` are currently | ||||
// unused. | ||||
bool parse_info_section(lazy_entry const& e, error_code& ec, int flags); | bool parse_info_section(lazy_entry const& e, error_code& ec, int flags); | |||
// This function looks up keys from the info-dictionary of t | ||||
he loaded torrent file. | ||||
// It can be used to access extension values put in the .tor | ||||
rent file. If the specified | ||||
// key cannot be found, it returns NULL. | ||||
lazy_entry const* info(char const* key) const | lazy_entry const* info(char const* key) const | |||
{ | { | |||
if (m_info_dict.type() == lazy_entry::none_t) | if (m_info_dict.type() == lazy_entry::none_t) | |||
{ | { | |||
error_code ec; | error_code ec; | |||
lazy_bdecode(m_info_section.get(), m_info_se ction.get() | lazy_bdecode(m_info_section.get(), m_info_se ction.get() | |||
+ m_info_section_size, m_info_dict, ec); | + m_info_section_size, m_info_dict, ec); | |||
if (ec) return NULL; | ||||
} | } | |||
return m_info_dict.dict_find(key); | return m_info_dict.dict_find(key); | |||
} | } | |||
// swap the content of this and ``ti```. | ||||
void swap(torrent_info& ti); | void swap(torrent_info& ti); | |||
// ``metadata()`` returns a the raw info section of the torr | ||||
ent file. The size | ||||
// of the metadata is returned by ``metadata_size()``. | ||||
int metadata_size() const { return m_info_section_size; } | ||||
boost::shared_array<char> metadata() const | boost::shared_array<char> metadata() const | |||
{ return m_info_section; } | { return m_info_section; } | |||
int metadata_size() const { return m_info_section_size; } | // internal | |||
bool add_merkle_nodes(std::map<int, sha1_hash> const& subtre e | bool add_merkle_nodes(std::map<int, sha1_hash> const& subtre e | |||
, int piece); | , int piece); | |||
std::map<int, sha1_hash> build_merkle_list(int piece) const; | std::map<int, sha1_hash> build_merkle_list(int piece) const; | |||
// returns whether or not this is a merkle torrent. | ||||
// see BEP30__. | ||||
// | ||||
// __ http://bittorrent.org/beps/bep_0030.html | ||||
bool is_merkle_torrent() const { return !m_merkle_tree.empty (); } | bool is_merkle_torrent() const { return !m_merkle_tree.empty (); } | |||
// if we're logging member offsets, we need access to them | // if we're logging member offsets, we need access to them | |||
#if defined TORRENT_DEBUG \ | ||||
&& !defined TORRENT_LOGGING \ | ||||
&& !defined TORRENT_VERBOSE_LOGGING \ | ||||
&& !defined TORRENT_ERROR_LOGGING | ||||
private: | private: | |||
#if TORRENT_USE_INVARIANT_CHECKS | ||||
friend class invariant_access; | ||||
void check_invariant() const; | ||||
#endif | #endif | |||
// not assignable | // not assignable | |||
torrent_info const& operator=(torrent_info const&); | torrent_info const& operator=(torrent_info const&); | |||
void copy_on_write(); | void copy_on_write(); | |||
bool parse_torrent_file(lazy_entry const& libtorrent, error_ code& ec, int flags); | bool parse_torrent_file(lazy_entry const& libtorrent, error_ code& ec, int flags); | |||
// the index to the first leaf. This is where the hash for t he | // the index to the first leaf. This is where the hash for t he | |||
// first piece is stored | // first piece is stored | |||
skipping to change at line 478 | skipping to change at line 712 | |||
// this is a copy of the info section from the torrent. | // this is a copy of the info section from the torrent. | |||
// it use maintained in this flat format in order to | // it use maintained in this flat format in order to | |||
// make it available through the metadata extension | // make it available through the metadata extension | |||
boost::shared_array<char> m_info_section; | boost::shared_array<char> m_info_section; | |||
// this is a pointer into the m_info_section buffer | // this is a pointer into the m_info_section buffer | |||
// pointing to the first byte of the first sha-1 hash | // pointing to the first byte of the first sha-1 hash | |||
char const* m_piece_hashes; | char const* m_piece_hashes; | |||
// TODO: these strings could be lazy_entry* to save memory | ||||
// if a comment is found in the torrent file | // if a comment is found in the torrent file | |||
// this will be set to that comment | // this will be set to that comment | |||
std::string m_comment; | std::string m_comment; | |||
// an optional string naming the software used | // an optional string naming the software used | |||
// to create the torrent file | // to create the torrent file | |||
std::string m_created_by; | std::string m_created_by; | |||
#ifdef TORRENT_USE_OPENSSL | ||||
// for ssl-torrens, this contains the root | ||||
// certificate, in .pem format (i.e. ascii | ||||
// base64 encoded with head and tails) | ||||
std::string m_ssl_root_cert; | ||||
#endif | ||||
// the info section parsed. points into m_info_section | // the info section parsed. points into m_info_section | |||
// parsed lazily | // parsed lazily | |||
mutable lazy_entry m_info_dict; | mutable lazy_entry m_info_dict; | |||
// if a creation date is found in the torrent file | // if a creation date is found in the torrent file | |||
// this will be set to that, otherwise it'll be | // this will be set to that, otherwise it'll be | |||
// 1970, Jan 1 | // 1970, Jan 1 | |||
time_t m_creation_date; | time_t m_creation_date; | |||
// the hash that identifies this torrent | // the hash that identifies this torrent | |||
End of changes. 88 change blocks. | ||||
86 lines changed or deleted | 431 lines changed or added | |||
tracker_manager.hpp | tracker_manager.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2003, Arvid Norberg | Copyright (c) 2003-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 66 | skipping to change at line 66 | |||
#include "libtorrent/socket.hpp" | #include "libtorrent/socket.hpp" | |||
#include "libtorrent/address.hpp" | #include "libtorrent/address.hpp" | |||
#include "libtorrent/peer_id.hpp" | #include "libtorrent/peer_id.hpp" | |||
#include "libtorrent/peer.hpp" // peer_entry | #include "libtorrent/peer.hpp" // peer_entry | |||
#include "libtorrent/session_settings.hpp" // proxy_settings | #include "libtorrent/session_settings.hpp" // proxy_settings | |||
#include "libtorrent/deadline_timer.hpp" | #include "libtorrent/deadline_timer.hpp" | |||
#include "libtorrent/connection_queue.hpp" | #include "libtorrent/connection_queue.hpp" | |||
#include "libtorrent/intrusive_ptr_base.hpp" | #include "libtorrent/intrusive_ptr_base.hpp" | |||
#include "libtorrent/size_type.hpp" | #include "libtorrent/size_type.hpp" | |||
#include "libtorrent/union_endpoint.hpp" | #include "libtorrent/union_endpoint.hpp" | |||
#include "libtorrent/udp_socket.hpp" // for udp_socket_observer | ||||
#ifdef TORRENT_USE_OPENSSL | #ifdef TORRENT_USE_OPENSSL | |||
#include <boost/asio/ssl/context.hpp> | #include <boost/asio/ssl/context.hpp> | |||
#endif | #endif | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
struct request_callback; | struct request_callback; | |||
class tracker_manager; | class tracker_manager; | |||
struct timeout_handler; | struct timeout_handler; | |||
struct tracker_connection; | struct tracker_connection; | |||
skipping to change at line 129 | skipping to change at line 130 | |||
size_type uploaded; | size_type uploaded; | |||
size_type left; | size_type left; | |||
size_type corrupt; | size_type corrupt; | |||
size_type redundant; | size_type redundant; | |||
unsigned short listen_port; | unsigned short listen_port; | |||
event_t event; | event_t event; | |||
std::string url; | std::string url; | |||
std::string trackerid; | std::string trackerid; | |||
boost::uint32_t key; | boost::uint32_t key; | |||
int num_want; | int num_want; | |||
std::string ipv6; | ||||
std::string ipv4; | ||||
address bind_ip; | address bind_ip; | |||
bool send_stats; | bool send_stats; | |||
bool apply_ip_filter; | bool apply_ip_filter; | |||
#ifdef TORRENT_USE_OPENSSL | #ifdef TORRENT_USE_OPENSSL | |||
boost::asio::ssl::context* ssl_ctx; | boost::asio::ssl::context* ssl_ctx; | |||
#endif | #endif | |||
}; | }; | |||
struct TORRENT_EXTRA_EXPORT request_callback | struct TORRENT_EXTRA_EXPORT request_callback | |||
{ | { | |||
skipping to change at line 158 | skipping to change at line 157 | |||
, int /*downloaders*/) {} | , int /*downloaders*/) {} | |||
virtual void tracker_response( | virtual void tracker_response( | |||
tracker_request const& req | tracker_request const& req | |||
, address const& tracker_ip | , address const& tracker_ip | |||
, std::list<address> const& ip_list | , std::list<address> const& ip_list | |||
, std::vector<peer_entry>& peers | , std::vector<peer_entry>& peers | |||
, int interval | , int interval | |||
, int min_interval | , int min_interval | |||
, int complete | , int complete | |||
, int incomplete | , int incomplete | |||
, int downloaded | ||||
, address const& external_ip | , address const& external_ip | |||
, std::string const& trackerid) = 0; | , std::string const& trackerid) = 0; | |||
virtual void tracker_request_error( | virtual void tracker_request_error( | |||
tracker_request const& req | tracker_request const& req | |||
, int response_code | , int response_code | |||
, error_code const& ec | , error_code const& ec | |||
, const std::string& msg | , const std::string& msg | |||
, int retry_interval) = 0; | , int retry_interval) = 0; | |||
union_endpoint m_tracker_address; | union_endpoint m_tracker_address; | |||
skipping to change at line 193 | skipping to change at line 193 | |||
void set_timeout(int completion_timeout, int read_timeout); | void set_timeout(int completion_timeout, int read_timeout); | |||
void restart_read_timeout(); | void restart_read_timeout(); | |||
void cancel(); | void cancel(); | |||
bool cancelled() const { return m_abort; } | bool cancelled() const { return m_abort; } | |||
virtual void on_timeout(error_code const& ec) = 0; | virtual void on_timeout(error_code const& ec) = 0; | |||
virtual ~timeout_handler() {} | virtual ~timeout_handler() {} | |||
io_service& get_io_service() { return m_timeout.get_io_servi ce(); } | io_service& get_io_service() { return m_timeout.get_io_servi ce(); } | |||
#if !defined TORRENT_VERBOSE_LOGGING \ | ||||
&& !defined TORRENT_LOGGING \ | ||||
&& !defined TORRENT_ERROR_LOGGING | ||||
// necessary for logging member offsets | ||||
private: | private: | |||
#endif | ||||
void timeout_callback(error_code const&); | void timeout_callback(error_code const&); | |||
boost::intrusive_ptr<timeout_handler> self() | boost::intrusive_ptr<timeout_handler> self() | |||
{ return boost::intrusive_ptr<timeout_handler>(this); } | { return boost::intrusive_ptr<timeout_handler>(this); } | |||
// used for timeouts | // used for timeouts | |||
// this is set when the request has been sent | // this is set when the request has been sent | |||
ptime m_start_time; | ptime m_start_time; | |||
// this is set every time something is received | // this is set every time something is received | |||
skipping to change at line 249 | skipping to change at line 244 | |||
void sent_bytes(int bytes); | void sent_bytes(int bytes); | |||
void received_bytes(int bytes); | void received_bytes(int bytes); | |||
virtual bool on_receive(error_code const& ec, udp::endpoint const& ep | virtual bool on_receive(error_code const& ec, udp::endpoint const& ep | |||
, char const* buf, int size) { return false; } | , char const* buf, int size) { return false; } | |||
virtual bool on_receive_hostname(error_code const& ec, char const* hostname | virtual bool on_receive_hostname(error_code const& ec, char const* hostname | |||
, char const* buf, int size) { return false; } | , char const* buf, int size) { return false; } | |||
boost::intrusive_ptr<tracker_connection> self() | boost::intrusive_ptr<tracker_connection> self() | |||
{ return boost::intrusive_ptr<tracker_connection>(this); } | { return boost::intrusive_ptr<tracker_connection>(this); } | |||
#if !defined TORRENT_VERBOSE_LOGGING \ | ||||
&& !defined TORRENT_LOGGING \ | ||||
&& !defined TORRENT_ERROR_LOGGING | ||||
// necessary for logging member offsets | ||||
protected: | protected: | |||
#endif | ||||
void fail_impl(error_code const& ec, int code = -1, std::str ing msg = std::string() | void fail_impl(error_code const& ec, int code = -1, std::str ing msg = std::string() | |||
, int interval = 0, int min_interval = 0); | , int interval = 0, int min_interval = 0); | |||
boost::weak_ptr<request_callback> m_requester; | boost::weak_ptr<request_callback> m_requester; | |||
tracker_manager& m_man; | tracker_manager& m_man; | |||
#if !defined TORRENT_VERBOSE_LOGGING \ | ||||
&& !defined TORRENT_LOGGING \ | ||||
&& !defined TORRENT_ERROR_LOGGING | ||||
// necessary for logging member offsets | ||||
private: | private: | |||
#endif | ||||
const tracker_request m_req; | const tracker_request m_req; | |||
}; | }; | |||
class TORRENT_EXTRA_EXPORT tracker_manager: boost::noncopyable | class TORRENT_EXTRA_EXPORT tracker_manager: public udp_socket_observ er, boost::noncopyable | |||
{ | { | |||
public: | public: | |||
tracker_manager(aux::session_impl& ses, proxy_settings const & ps) | tracker_manager(aux::session_impl& ses, proxy_settings const & ps) | |||
: m_ses(ses) | : m_ses(ses) | |||
, m_proxy(ps) | , m_proxy(ps) | |||
, m_abort(false) {} | , m_abort(false) {} | |||
~tracker_manager(); | ~tracker_manager(); | |||
void queue_request( | void queue_request( | |||
skipping to change at line 299 | skipping to change at line 284 | |||
= boost::weak_ptr<request_callback>()); | = boost::weak_ptr<request_callback>()); | |||
void abort_all_requests(bool all = false); | void abort_all_requests(bool all = false); | |||
void remove_request(tracker_connection const*); | void remove_request(tracker_connection const*); | |||
bool empty() const; | bool empty() const; | |||
int num_requests() const; | int num_requests() const; | |||
void sent_bytes(int bytes); | void sent_bytes(int bytes); | |||
void received_bytes(int bytes); | void received_bytes(int bytes); | |||
bool incoming_udp(error_code const& e, udp::endpoint const& | virtual bool incoming_packet(error_code const& e, udp::endpo | |||
ep, char const* buf, int size); | int const& ep | |||
, char const* buf, int size); | ||||
// this is only used for SOCKS packets, since | // this is only used for SOCKS packets, since | |||
// they may be addressed to hostname | // they may be addressed to hostname | |||
bool incoming_udp(error_code const& e, char const* hostname, | virtual bool incoming_packet(error_code const& e, char const | |||
char const* buf, int size); | * hostname | |||
, char const* buf, int size); | ||||
private: | private: | |||
typedef mutex mutex_t; | typedef mutex mutex_t; | |||
mutable mutex_t m_mutex; | mutable mutex_t m_mutex; | |||
typedef std::list<boost::intrusive_ptr<tracker_connection> > | typedef std::list<boost::intrusive_ptr<tracker_connection> > | |||
tracker_connections_t; | tracker_connections_t; | |||
tracker_connections_t m_connections; | tracker_connections_t m_connections; | |||
aux::session_impl& m_ses; | aux::session_impl& m_ses; | |||
End of changes. 13 change blocks. | ||||
23 lines changed or deleted | 10 lines changed or added | |||
traversal_algorithm.hpp | traversal_algorithm.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2006, Arvid Norberg & Daniel Wallin | Copyright (c) 2006-2014, Arvid Norberg & Daniel Wallin | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 70 | skipping to change at line 70 | |||
// this class may not be instantiated as a stack object | // this class may not be instantiated as a stack object | |||
struct traversal_algorithm : boost::noncopyable | struct traversal_algorithm : boost::noncopyable | |||
{ | { | |||
void traverse(node_id const& id, udp::endpoint addr); | void traverse(node_id const& id, udp::endpoint addr); | |||
void finished(observer_ptr o); | void finished(observer_ptr o); | |||
enum flags_t { prevent_request = 1, short_timeout = 2 }; | enum flags_t { prevent_request = 1, short_timeout = 2 }; | |||
void failed(observer_ptr o, int flags = 0); | void failed(observer_ptr o, int flags = 0); | |||
virtual ~traversal_algorithm(); | virtual ~traversal_algorithm(); | |||
void status(dht_lookup& l); | void status(dht_lookup& l); | |||
void abort(); | ||||
void* allocate_observer(); | void* allocate_observer(); | |||
void free_observer(void* ptr); | void free_observer(void* ptr); | |||
virtual char const* name() const { return "traversal_algorithm"; } | virtual char const* name() const; | |||
virtual void start(); | virtual void start(); | |||
node_id const& target() const { return m_target; } | node_id const& target() const { return m_target; } | |||
void resort_results(); | ||||
void add_entry(node_id const& id, udp::endpoint addr, unsigned char flags); | void add_entry(node_id const& id, udp::endpoint addr, unsigned char flags); | |||
traversal_algorithm(node_impl& node, node_id target); | traversal_algorithm(node_impl& node, node_id target); | |||
int invoke_count() const { return m_invoke_count; } | ||||
int branch_factor() const { return m_branch_factor; } | ||||
protected: | protected: | |||
void add_requests(); | // returns true if we're done | |||
bool add_requests(); | ||||
void add_router_entries(); | void add_router_entries(); | |||
void init(); | void init(); | |||
virtual void done(); | virtual void done(); | |||
// should construct an algorithm dependent | // should construct an algorithm dependent | |||
// observer in ptr. | // observer in ptr. | |||
virtual observer_ptr new_observer(void* ptr | virtual observer_ptr new_observer(void* ptr | |||
, udp::endpoint const& ep, node_id const& id); | , udp::endpoint const& ep, node_id const& id); | |||
virtual bool invoke(observer_ptr o) { return false; } | virtual bool invoke(observer_ptr o) { return false; } | |||
skipping to change at line 111 | skipping to change at line 117 | |||
friend void intrusive_ptr_release(traversal_algorithm* p) | friend void intrusive_ptr_release(traversal_algorithm* p) | |||
{ | { | |||
if (--p->m_ref_count == 0) | if (--p->m_ref_count == 0) | |||
delete p; | delete p; | |||
} | } | |||
int m_ref_count; | int m_ref_count; | |||
node_impl& m_node; | node_impl& m_node; | |||
node_id m_target; | node_id const m_target; | |||
std::vector<observer_ptr> m_results; | std::vector<observer_ptr> m_results; | |||
int m_invoke_count; | int m_invoke_count; | |||
int m_branch_factor; | int m_branch_factor; | |||
int m_responses; | int m_responses; | |||
int m_timeouts; | int m_timeouts; | |||
int m_num_target_nodes; | int m_num_target_nodes; | |||
}; | }; | |||
struct traversal_observer : observer | ||||
{ | ||||
traversal_observer( | ||||
boost::intrusive_ptr<traversal_algorithm> const& algorithm | ||||
, udp::endpoint const& ep, node_id const& id) | ||||
: observer(algorithm, ep, id) | ||||
{} | ||||
// parses out "nodes" and keeps traversing | ||||
virtual void reply(msg const&); | ||||
}; | ||||
} } // namespace libtorrent::dht | } } // namespace libtorrent::dht | |||
#endif // TRAVERSAL_ALGORITHM_050324_HPP | #endif // TRAVERSAL_ALGORITHM_050324_HPP | |||
End of changes. 8 change blocks. | ||||
4 lines changed or deleted | 22 lines changed or added | |||
udp_socket.hpp | udp_socket.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2007, Arvid Norberg | Copyright (c) 2007-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 45 | skipping to change at line 45 | |||
#include "libtorrent/socket.hpp" | #include "libtorrent/socket.hpp" | |||
#include "libtorrent/io_service.hpp" | #include "libtorrent/io_service.hpp" | |||
#include "libtorrent/error_code.hpp" | #include "libtorrent/error_code.hpp" | |||
#include "libtorrent/session_settings.hpp" | #include "libtorrent/session_settings.hpp" | |||
#include "libtorrent/buffer.hpp" | #include "libtorrent/buffer.hpp" | |||
#include "libtorrent/thread.hpp" | #include "libtorrent/thread.hpp" | |||
#include "libtorrent/deadline_timer.hpp" | #include "libtorrent/deadline_timer.hpp" | |||
#include <deque> | #include <deque> | |||
#include <boost/function/function4.hpp> | ||||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
class connection_queue; | class connection_queue; | |||
struct udp_socket_observer | ||||
{ | ||||
// return true if the packet was handled (it won't be | ||||
// propagated to the next observer) | ||||
virtual bool incoming_packet(error_code const& ec | ||||
, udp::endpoint const&, char const* buf, int size) = | ||||
0; | ||||
virtual bool incoming_packet(error_code const& ec | ||||
, char const* hostname, char const* buf, int size) { | ||||
return false; } | ||||
// called when the socket becomes writeable, after having | ||||
// failed with EWOULDBLOCK | ||||
virtual void writable() {} | ||||
// called every time the socket is drained of packets | ||||
virtual void socket_drained() {} | ||||
}; | ||||
class udp_socket | class udp_socket | |||
{ | { | |||
public: | public: | |||
typedef boost::function<void(error_code const& ec | udp_socket(io_service& ios, connection_queue& cc); | |||
, udp::endpoint const&, char const* buf, int size)> | ||||
callback_t; | ||||
typedef boost::function<void(error_code const& ec | ||||
, char const*, char const* buf, int size)> callback2 | ||||
_t; | ||||
udp_socket(io_service& ios, callback_t const& c, callback2_t | ||||
const& c2, connection_queue& cc); | ||||
~udp_socket(); | ~udp_socket(); | |||
enum flags_t { dont_drop = 1, peer_connection = 2 }; | enum flags_t { dont_drop = 1, peer_connection = 2, dont_queu e = 4 }; | |||
bool is_open() const | bool is_open() const | |||
{ | { | |||
return m_ipv4_sock.is_open() | return m_ipv4_sock.is_open() | |||
#if TORRENT_USE_IPV6 | #if TORRENT_USE_IPV6 | |||
|| m_ipv6_sock.is_open() | || m_ipv6_sock.is_open() | |||
#endif | #endif | |||
; | ; | |||
} | } | |||
io_service& get_io_service() { return m_ipv4_sock.get_io_ser vice(); } | io_service& get_io_service() { return m_ipv4_sock.get_io_ser vice(); } | |||
void subscribe(udp_socket_observer* o); | ||||
void unsubscribe(udp_socket_observer* o); | ||||
// this is only valid when using a socks5 proxy | // this is only valid when using a socks5 proxy | |||
void send_hostname(char const* hostname, int port, char cons | void send_hostname(char const* hostname, int port, char cons | |||
t* p, int len, error_code& ec); | t* p | |||
, int len, error_code& ec, int flags = 0); | ||||
void send(udp::endpoint const& ep, char const* p, int len, e | void send(udp::endpoint const& ep, char const* p, int len | |||
rror_code& ec, int flags = 0); | , error_code& ec, int flags = 0); | |||
void bind(udp::endpoint const& ep, error_code& ec); | void bind(udp::endpoint const& ep, error_code& ec); | |||
void bind(int port); | ||||
void close(); | void close(); | |||
int local_port() const { return m_bind_port; } | int local_port() const { return m_bind_port; } | |||
void set_proxy_settings(proxy_settings const& ps); | void set_proxy_settings(proxy_settings const& ps); | |||
proxy_settings const& get_proxy_settings() { return m_proxy_ settings; } | proxy_settings const& get_proxy_settings() { return m_proxy_ settings; } | |||
void set_force_proxy(bool f) { m_force_proxy = f; } | void set_force_proxy(bool f) { m_force_proxy = f; } | |||
bool is_closed() const { return m_abort; } | bool is_closed() const { return m_abort; } | |||
tcp::endpoint local_endpoint(error_code& ec) const | tcp::endpoint local_endpoint(error_code& ec) const | |||
{ | { | |||
udp::endpoint ep = m_ipv4_sock.local_endpoint(ec); | udp::endpoint ep = m_ipv4_sock.local_endpoint(ec); | |||
return tcp::endpoint(ep.address(), ep.port()); | return tcp::endpoint(ep.address(), ep.port()); | |||
} | } | |||
void set_buf_size(int s); | void set_buf_size(int s); | |||
template <class SocketOption> | template <class SocketOption> | |||
void get_option(SocketOption const& opt, error_code& ec) | ||||
{ | ||||
m_ipv4_sock.get_option(opt, ec); | ||||
#if TORRENT_USE_IPV6 | ||||
m_ipv6_sock.get_option(opt, ec); | ||||
#endif | ||||
} | ||||
template <class SocketOption> | ||||
void set_option(SocketOption const& opt, error_code& ec) | void set_option(SocketOption const& opt, error_code& ec) | |||
{ | { | |||
m_ipv4_sock.set_option(opt, ec); | m_ipv4_sock.set_option(opt, ec); | |||
#if TORRENT_USE_IPV6 | #if TORRENT_USE_IPV6 | |||
m_ipv6_sock.set_option(opt, ec); | m_ipv6_sock.set_option(opt, ec); | |||
#endif | #endif | |||
} | } | |||
template <class SocketOption> | template <class SocketOption> | |||
void get_option(SocketOption& opt, error_code& ec) | void get_option(SocketOption& opt, error_code& ec) | |||
skipping to change at line 135 | skipping to change at line 159 | |||
int num_outstanding() const | int num_outstanding() const | |||
{ | { | |||
return m_v4_outstanding | return m_v4_outstanding | |||
#if TORRENT_USE_IPV6 | #if TORRENT_USE_IPV6 | |||
+ m_v6_outstanding | + m_v6_outstanding | |||
#endif | #endif | |||
; | ; | |||
} | } | |||
private: | private: | |||
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T | ||||
ORRENT_ERROR_LOGGING | ||||
// necessary for logging member offsets | ||||
public: | ||||
#endif | ||||
// callback for regular incoming packets | ||||
callback_t m_callback; | ||||
// callback for proxied incoming packets with a domain | ||||
// name as source | ||||
callback2_t m_callback2; | ||||
void on_read(udp::socket* sock, error_code const& e, std::si | // observers on this udp socket | |||
ze_t bytes_transferred); | std::vector<udp_socket_observer*> m_observers; | |||
std::vector<udp_socket_observer*> m_added_observers; | ||||
// this is true while iterating over the observers | ||||
// vector, invoking observer hooks. We may not | ||||
// add new observers during this time, since it | ||||
// may invalidate the iterator. If this is true, | ||||
// instead add new observers to m_added_observers | ||||
// and they will be added later | ||||
bool m_observers_locked; | ||||
void call_handler(error_code const& ec, udp::endpoint const& | ||||
ep | ||||
, char const* buf, int size); | ||||
void call_handler(error_code const& ec, const char* host | ||||
, char const* buf, int size); | ||||
void call_drained_handler(); | ||||
void call_writable_handler(); | ||||
void on_writable(error_code const& ec, udp::socket* s); | ||||
void setup_read(udp::socket* s); | ||||
void on_read(error_code const& ec, udp::socket* s); | ||||
void on_read_impl(udp::socket* sock, udp::endpoint const& ep | ||||
, error_code const& e, std::size_t bytes_transferred | ||||
); | ||||
void on_name_lookup(error_code const& e, tcp::resolver::iter ator i); | void on_name_lookup(error_code const& e, tcp::resolver::iter ator i); | |||
void on_timeout(); | void on_timeout(); | |||
void on_connect(int ticket); | void on_connect(int ticket); | |||
void on_connected(error_code const& ec, int ticket); | void on_connected(error_code const& ec, int ticket); | |||
void handshake1(error_code const& e); | void handshake1(error_code const& e); | |||
void handshake2(error_code const& e); | void handshake2(error_code const& e); | |||
void handshake3(error_code const& e); | void handshake3(error_code const& e); | |||
void handshake4(error_code const& e); | void handshake4(error_code const& e); | |||
void socks_forward_udp(); | void socks_forward_udp(); | |||
void connect1(error_code const& e); | void connect1(error_code const& e); | |||
void connect2(error_code const& e); | void connect2(error_code const& e); | |||
void hung_up(error_code const& e); | void hung_up(error_code const& e); | |||
void drain_queue(); | void drain_queue(); | |||
void wrap(udp::endpoint const& ep, char const* p, int len, e rror_code& ec); | void wrap(udp::endpoint const& ep, char const* p, int len, e rror_code& ec); | |||
void wrap(char const* hostname, int port, char const* p, int len, error_code& ec); | void wrap(char const* hostname, int port, char const* p, int len, error_code& ec); | |||
void unwrap(error_code const& e, char const* buf, int size); | void unwrap(error_code const& e, char const* buf, int size); | |||
void maybe_realloc_buffers(int which = 3); | #if TORRENT_USE_ASSERTS | |||
bool maybe_clear_callback(); | ||||
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS | ||||
#if defined BOOST_HAS_PTHREADS | #if defined BOOST_HAS_PTHREADS | |||
mutable pthread_t m_thread; | mutable pthread_t m_thread; | |||
#endif | #endif | |||
bool is_single_thread() const | bool is_single_thread() const | |||
{ | { | |||
#if defined BOOST_HAS_PTHREADS | #if defined BOOST_HAS_PTHREADS | |||
if (m_thread == 0) | if (m_thread == 0) | |||
m_thread = pthread_self(); | m_thread = pthread_self(); | |||
return m_thread == pthread_self(); | return m_thread == pthread_self(); | |||
#endif | #endif | |||
return true; | return true; | |||
} | } | |||
#endif | #endif | |||
udp::socket m_ipv4_sock; | udp::socket m_ipv4_sock; | |||
udp::endpoint m_v4_ep; | int m_buf_size; | |||
int m_v4_buf_size; | ||||
char* m_v4_buf; | // if the buffer size is attempted | |||
// this is set to true to indicate that the | // to be changed while the buffer is | |||
// m_v4_buf should be reallocated to the size | // being used, this member is set to | |||
// of the buffer size members the next time their | // the desired size, and it's resized | |||
// read handler gets triggered | // later | |||
bool m_reallocate_buffer4; | int m_new_buf_size; | |||
char* m_buf; | ||||
#if TORRENT_USE_IPV6 | #if TORRENT_USE_IPV6 | |||
udp::socket m_ipv6_sock; | udp::socket m_ipv6_sock; | |||
udp::endpoint m_v6_ep; | ||||
int m_v6_buf_size; | ||||
char* m_v6_buf; | ||||
// this is set to true to indicate that the | ||||
// m_v6_buf should be reallocated to the size | ||||
// of the buffer size members the next time their | ||||
// read handler gets triggered | ||||
bool m_reallocate_buffer6; | ||||
#endif | #endif | |||
boost::uint16_t m_bind_port; | boost::uint16_t m_bind_port; | |||
boost::uint8_t m_v4_outstanding; | boost::uint8_t m_v4_outstanding; | |||
#if TORRENT_USE_IPV6 | #if TORRENT_USE_IPV6 | |||
boost::uint8_t m_v6_outstanding; | boost::uint8_t m_v6_outstanding; | |||
#endif | #endif | |||
tcp::socket m_socks5_sock; | tcp::socket m_socks5_sock; | |||
int m_connection_ticket; | int m_connection_ticket; | |||
skipping to change at line 244 | skipping to change at line 272 | |||
// while we're connecting to the proxy | // while we're connecting to the proxy | |||
// we have to queue the packets, we'll flush | // we have to queue the packets, we'll flush | |||
// them once we're connected | // them once we're connected | |||
std::deque<queued_packet> m_queue; | std::deque<queued_packet> m_queue; | |||
// counts the number of outstanding async | // counts the number of outstanding async | |||
// operations hanging on this socket | // operations hanging on this socket | |||
int m_outstanding_ops; | int m_outstanding_ops; | |||
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS | #if TORRENT_USE_IPV6 | |||
bool m_v6_write_subscribed:1; | ||||
#endif | ||||
bool m_v4_write_subscribed:1; | ||||
#if TORRENT_USE_ASSERTS | ||||
bool m_started; | bool m_started; | |||
int m_magic; | int m_magic; | |||
int m_outstanding_when_aborted; | int m_outstanding_when_aborted; | |||
int m_outstanding_connect; | int m_outstanding_connect; | |||
int m_outstanding_timeout; | int m_outstanding_timeout; | |||
int m_outstanding_resolve; | int m_outstanding_resolve; | |||
int m_outstanding_connect_queue; | int m_outstanding_connect_queue; | |||
int m_outstanding_socks; | int m_outstanding_socks; | |||
char timeout_stack[2000]; | ||||
#endif | #endif | |||
}; | }; | |||
struct rate_limited_udp_socket : public udp_socket | struct rate_limited_udp_socket : public udp_socket | |||
{ | { | |||
rate_limited_udp_socket(io_service& ios, callback_t const& c , callback2_t const& c2, connection_queue& cc); | rate_limited_udp_socket(io_service& ios, connection_queue& c c); | |||
void set_rate_limit(int limit) { m_rate_limit = limit; } | void set_rate_limit(int limit) { m_rate_limit = limit; } | |||
bool send(udp::endpoint const& ep, char const* p, int len, e | bool send(udp::endpoint const& ep, char const* p, int len | |||
rror_code& ec, int flags = 0); | , error_code& ec, int flags = 0); | |||
private: | private: | |||
int m_rate_limit; | int m_rate_limit; | |||
int m_quota; | int m_quota; | |||
ptime m_last_tick; | ptime m_last_tick; | |||
}; | }; | |||
} | } | |||
#endif | #endif | |||
End of changes. 20 change blocks. | ||||
54 lines changed or deleted | 87 lines changed or added | |||
udp_tracker_connection.hpp | udp_tracker_connection.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2003, Arvid Norberg | Copyright (c) 2003-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 81 | skipping to change at line 81 | |||
, connection_queue& cc | , connection_queue& cc | |||
, tracker_manager& man | , tracker_manager& man | |||
, tracker_request const& req | , tracker_request const& req | |||
, boost::weak_ptr<request_callback> c | , boost::weak_ptr<request_callback> c | |||
, aux::session_impl& ses | , aux::session_impl& ses | |||
, proxy_settings const& ps); | , proxy_settings const& ps); | |||
void start(); | void start(); | |||
void close(); | void close(); | |||
#if !defined TORRENT_VERBOSE_LOGGING \ | ||||
&& !defined TORRENT_LOGGING \ | ||||
&& !defined TORRENT_ERROR_LOGGING | ||||
// necessary for logging member offsets | ||||
private: | private: | |||
#endif | ||||
enum action_t | enum action_t | |||
{ | { | |||
action_connect, | action_connect, | |||
action_announce, | action_announce, | |||
action_scrape, | action_scrape, | |||
action_error | action_error | |||
}; | }; | |||
boost::intrusive_ptr<udp_tracker_connection> self() | boost::intrusive_ptr<udp_tracker_connection> self() | |||
skipping to change at line 123 | skipping to change at line 118 | |||
, char const* msg = "", int interval = 0, int min_in terval = 0); | , char const* msg = "", int interval = 0, int min_in terval = 0); | |||
void send_udp_connect(); | void send_udp_connect(); | |||
void send_udp_announce(); | void send_udp_announce(); | |||
void send_udp_scrape(); | void send_udp_scrape(); | |||
virtual void on_timeout(error_code const& ec); | virtual void on_timeout(error_code const& ec); | |||
udp::endpoint pick_target_endpoint() const; | udp::endpoint pick_target_endpoint() const; | |||
// tracker_manager& m_man; | ||||
bool m_abort; | bool m_abort; | |||
std::string m_hostname; | std::string m_hostname; | |||
udp::endpoint m_target; | udp::endpoint m_target; | |||
std::list<tcp::endpoint> m_endpoints; | std::list<tcp::endpoint> m_endpoints; | |||
int m_transaction_id; | int m_transaction_id; | |||
aux::session_impl& m_ses; | aux::session_impl& m_ses; | |||
int m_attempts; | int m_attempts; | |||
struct connection_cache_entry | struct connection_cache_entry | |||
End of changes. 4 change blocks. | ||||
8 lines changed or deleted | 1 lines changed or added | |||
union_endpoint.hpp | union_endpoint.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2010, Arvid Norberg | Copyright (c) 2010-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 49 | skipping to change at line 49 | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
struct union_endpoint | struct union_endpoint | |||
{ | { | |||
union_endpoint(tcp::endpoint const& ep) | union_endpoint(tcp::endpoint const& ep) | |||
{ | { | |||
*this = ep; | *this = ep; | |||
} | } | |||
union_endpoint(udp::endpoint const& ep) | ||||
{ | ||||
*this = ep; | ||||
} | ||||
union_endpoint() | union_endpoint() | |||
{ | { | |||
*this = tcp::endpoint(); | *this = tcp::endpoint(); | |||
} | } | |||
union_endpoint& operator=(udp::endpoint const& ep) | ||||
{ | ||||
#if TORRENT_USE_IPV6 | ||||
v4 = ep.address().is_v4(); | ||||
if (v4) | ||||
addr.v4 = ep.address().to_v4().to_bytes(); | ||||
else | ||||
addr.v6 = ep.address().to_v6().to_bytes(); | ||||
#else | ||||
addr.v4 = ep.address().to_v4().to_bytes(); | ||||
#endif | ||||
port = ep.port(); | ||||
return *this; | ||||
} | ||||
operator udp::endpoint() const | ||||
{ | ||||
#if TORRENT_USE_IPV6 | ||||
if (v4) return udp::endpoint(address_v4(addr.v4), po | ||||
rt); | ||||
else return udp::endpoint(address_v6(addr.v6), port) | ||||
; | ||||
#else | ||||
return udp::endpoint(address_v4(addr.v4), port); | ||||
#endif | ||||
} | ||||
union_endpoint& operator=(tcp::endpoint const& ep) | union_endpoint& operator=(tcp::endpoint const& ep) | |||
{ | { | |||
#if TORRENT_USE_IPV6 | #if TORRENT_USE_IPV6 | |||
v4 = ep.address().is_v4(); | v4 = ep.address().is_v4(); | |||
if (v4) | if (v4) | |||
addr.v4 = ep.address().to_v4().to_bytes(); | addr.v4 = ep.address().to_v4().to_bytes(); | |||
else | else | |||
addr.v6 = ep.address().to_v6().to_bytes(); | addr.v6 = ep.address().to_v6().to_bytes(); | |||
#else | #else | |||
addr.v4 = ep.address().to_v4().to_bytes(); | addr.v4 = ep.address().to_v4().to_bytes(); | |||
#endif | #endif | |||
port = ep.port(); | port = ep.port(); | |||
return *this; | return *this; | |||
} | } | |||
libtorrent::address address() const | ||||
{ | ||||
#if TORRENT_USE_IPV6 | ||||
if (v4) return address_v4(addr.v4); | ||||
else return address_v6(addr.v6); | ||||
#else | ||||
return address_v4(addr.v4); | ||||
#endif | ||||
} | ||||
operator tcp::endpoint() const | operator tcp::endpoint() const | |||
{ | { | |||
#if TORRENT_USE_IPV6 | #if TORRENT_USE_IPV6 | |||
if (v4) return tcp::endpoint(address_v4(addr.v4), po rt); | if (v4) return tcp::endpoint(address_v4(addr.v4), po rt); | |||
else return tcp::endpoint(address_v6(addr.v6), port) ; | else return tcp::endpoint(address_v6(addr.v6), port) ; | |||
#else | #else | |||
return tcp::endpoint(address_v4(addr.v4), port); | return tcp::endpoint(address_v4(addr.v4), port); | |||
#endif | #endif | |||
} | } | |||
End of changes. 4 change blocks. | ||||
1 lines changed or deleted | 43 lines changed or added | |||
upnp.hpp | upnp.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2007, Arvid Norberg | Copyright (c) 2007-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 46 | skipping to change at line 46 | |||
#include "libtorrent/socket.hpp" | #include "libtorrent/socket.hpp" | |||
#include "libtorrent/error_code.hpp" | #include "libtorrent/error_code.hpp" | |||
#include "libtorrent/broadcast_socket.hpp" | #include "libtorrent/broadcast_socket.hpp" | |||
#include "libtorrent/http_connection.hpp" | #include "libtorrent/http_connection.hpp" | |||
#include "libtorrent/connection_queue.hpp" | #include "libtorrent/connection_queue.hpp" | |||
#include "libtorrent/intrusive_ptr_base.hpp" | #include "libtorrent/intrusive_ptr_base.hpp" | |||
#include "libtorrent/thread.hpp" | #include "libtorrent/thread.hpp" | |||
#include "libtorrent/deadline_timer.hpp" | #include "libtorrent/deadline_timer.hpp" | |||
#include <boost/function/function1.hpp> | #include <boost/function/function1.hpp> | |||
#include <boost/function/function3.hpp> | #include <boost/function/function4.hpp> | |||
#include <boost/noncopyable.hpp> | #include <boost/noncopyable.hpp> | |||
#include <boost/shared_ptr.hpp> | #include <boost/shared_ptr.hpp> | |||
#include <set> | #include <set> | |||
#if defined(TORRENT_UPNP_LOGGING) | #if defined(TORRENT_UPNP_LOGGING) | |||
#include <fstream> | #include <fstream> | |||
#endif | #endif | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
namespace upnp_errors | namespace upnp_errors | |||
{ | { | |||
// error codes for the upnp_error_category. They hold error | ||||
codes | ||||
// returned by UPnP routers when mapping ports | ||||
enum error_code_enum | enum error_code_enum | |||
{ | { | |||
// No error | ||||
no_error = 0, | no_error = 0, | |||
// One of the arguments in the request is invalid | ||||
invalid_argument = 402, | invalid_argument = 402, | |||
// The request failed | ||||
action_failed = 501, | action_failed = 501, | |||
// The specified value does not exist in the array | ||||
value_not_in_array = 714, | value_not_in_array = 714, | |||
// The source IP address cannot be wild-carded, but | ||||
// must be fully specified | ||||
source_ip_cannot_be_wildcarded = 715, | source_ip_cannot_be_wildcarded = 715, | |||
// The external port cannot be wildcarded, but must | ||||
// be specified | ||||
external_port_cannot_be_wildcarded = 716, | external_port_cannot_be_wildcarded = 716, | |||
// The port mapping entry specified conflicts with a | ||||
// mapping assigned previously to another client | ||||
port_mapping_conflict = 718, | port_mapping_conflict = 718, | |||
// Internal and external port value must be the same | ||||
internal_port_must_match_external = 724, | internal_port_must_match_external = 724, | |||
// The NAT implementation only supports permanent | ||||
// lease times on port mappings | ||||
only_permanent_leases_supported = 725, | only_permanent_leases_supported = 725, | |||
// RemoteHost must be a wildcard and cannot be a | ||||
// specific IP addres or DNS name | ||||
remote_host_must_be_wildcard = 726, | remote_host_must_be_wildcard = 726, | |||
// ExternalPort must be a wildcard and cannot be a | ||||
// specific port | ||||
external_port_must_be_wildcard = 727 | external_port_must_be_wildcard = 727 | |||
}; | }; | |||
} | ||||
#if BOOST_VERSION < 103500 | ||||
extern asio::error::error_category upnp_category; | ||||
#else | ||||
struct TORRENT_EXPORT upnp_error_category : boost::system::error_cat | // hidden | |||
egory | TORRENT_EXPORT boost::system::error_code make_error_code(err | |||
{ | or_code_enum e); | |||
virtual const char* name() const BOOST_SYSTEM_NOEXCEPT; | } | |||
virtual std::string message(int ev) const BOOST_SYSTEM_NOEXC | ||||
EPT; | ||||
virtual boost::system::error_condition default_error_conditi | ||||
on(int ev) const BOOST_SYSTEM_NOEXCEPT | ||||
{ return boost::system::error_condition(ev, *this); } | ||||
}; | ||||
extern TORRENT_EXPORT upnp_error_category upnp_category; | TORRENT_EXPORT boost::system::error_category& get_upnp_category(); | |||
#endif | ||||
// int: port-mapping index | // int: port-mapping index | |||
// address: external address as queried from router | // address: external address as queried from router | |||
// int: external port | // int: external port | |||
// std::string: error message | // std::string: error message | |||
// an empty string as error means success | // an empty string as error means success | |||
// a port-mapping index of -1 means it's | // a port-mapping index of -1 means it's | |||
// an informational log message | // an informational log message | |||
typedef boost::function<void(int, address, int, error_code const&)> portmap _callback_t; | typedef boost::function<void(int, address, int, error_code const&)> portmap _callback_t; | |||
typedef boost::function<void(char const*)> log_callback_t; | typedef boost::function<void(char const*)> log_callback_t; | |||
class TORRENT_EXPORT upnp : public intrusive_ptr_base<upnp> | // TODO: support using the windows API for UPnP operations as well | |||
class TORRENT_EXTRA_EXPORT upnp : public intrusive_ptr_base<upnp> | ||||
{ | { | |||
public: | public: | |||
upnp(io_service& ios, connection_queue& cc | upnp(io_service& ios, connection_queue& cc | |||
, address const& listen_interface, std::string const& user_a gent | , address const& listen_interface, std::string const& user_a gent | |||
, portmap_callback_t const& cb, log_callback_t const& lcb | , portmap_callback_t const& cb, log_callback_t const& lcb | |||
, bool ignore_nonrouters, void* state = 0); | , bool ignore_nonrouters, void* state = 0); | |||
~upnp(); | ~upnp(); | |||
void* drain_state(); | void* drain_state(); | |||
enum protocol_type { none = 0, udp = 1, tcp = 2 }; | enum protocol_type { none = 0, udp = 1, tcp = 2 }; | |||
// Attempts to add a port mapping for the specified protocol. Valid | ||||
protocols are | ||||
// ``upnp::tcp`` and ``upnp::udp`` for the UPnP class and ``natpmp:: | ||||
tcp`` and | ||||
// ``natpmp::udp`` for the NAT-PMP class. | ||||
// | ||||
// ``external_port`` is the port on the external address that will b | ||||
e mapped. This | ||||
// is a hint, you are not guaranteed that this port will be availabl | ||||
e, and it may | ||||
// end up being something else. In the portmap_alert_ notification, | ||||
the actual | ||||
// external port is reported. | ||||
// | ||||
// ``local_port`` is the port in the local machine that the mapping | ||||
should forward | ||||
// to. | ||||
// | ||||
// The return value is an index that identifies this port mapping. T | ||||
his is used | ||||
// to refer to mappings that fails or succeeds in the portmap_error_ | ||||
alert_ and | ||||
// portmap_alert_ respectively. If The mapping fails immediately, th | ||||
e return value | ||||
// is -1, which means failure. There will not be any error alert not | ||||
ification for | ||||
// mappings that fail with a -1 return value. | ||||
int add_mapping(protocol_type p, int external_port, int local_port); | int add_mapping(protocol_type p, int external_port, int local_port); | |||
// This function removes a port mapping. ``mapping_index`` is the in | ||||
dex that refers | ||||
// to the mapping you want to remove, which was returned from add_ma | ||||
pping(). | ||||
void delete_mapping(int mapping_index); | void delete_mapping(int mapping_index); | |||
bool get_mapping(int mapping_index, int& local_port, int& external_p ort, int& protocol) const; | bool get_mapping(int mapping_index, int& local_port, int& external_p ort, int& protocol) const; | |||
void discover_device(); | void discover_device(); | |||
void close(); | void close(); | |||
// This is only available for UPnP routers. If the model is advertiz | ||||
ed by | ||||
// the router, it can be queried through this function. | ||||
std::string router_model() | std::string router_model() | |||
{ | { | |||
mutex::scoped_lock l(m_mutex); | mutex::scoped_lock l(m_mutex); | |||
return m_model; | return m_model; | |||
} | } | |||
private: | private: | |||
void map_timer(error_code const& ec); | ||||
void try_map_upnp(mutex::scoped_lock& l, bool timer = false); | ||||
void discover_device_impl(mutex::scoped_lock& l); | void discover_device_impl(mutex::scoped_lock& l); | |||
static address_v4 upnp_multicast_address; | static address_v4 upnp_multicast_address; | |||
static udp::endpoint upnp_multicast_endpoint; | static udp::endpoint upnp_multicast_endpoint; | |||
// there are routers that's don't support timed | // there are routers that's don't support timed | |||
// port maps, without returning error 725. It seems | // port maps, without returning error 725. It seems | |||
// safer to always assume that we have to ask for | // safer to always assume that we have to ask for | |||
// permanent leases | // permanent leases | |||
enum { default_lease_time = 0 }; | enum { default_lease_time = 0 }; | |||
skipping to change at line 223 | skipping to change at line 259 | |||
int failcount; | int failcount; | |||
}; | }; | |||
struct rootdevice | struct rootdevice | |||
{ | { | |||
rootdevice(): service_namespace(0) | rootdevice(): service_namespace(0) | |||
, port(0) | , port(0) | |||
, lease_duration(default_lease_time) | , lease_duration(default_lease_time) | |||
, supports_specific_external(true) | , supports_specific_external(true) | |||
, disabled(false) | , disabled(false) | |||
, non_router(false) | ||||
{ | { | |||
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS | #if TORRENT_USE_ASSERTS | |||
magic = 1337; | magic = 1337; | |||
#endif | #endif | |||
} | } | |||
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS | #if TORRENT_USE_ASSERTS | |||
~rootdevice() | ~rootdevice() | |||
{ | { | |||
TORRENT_ASSERT(magic == 1337); | TORRENT_ASSERT(magic == 1337); | |||
magic = 0; | magic = 0; | |||
} | } | |||
#endif | #endif | |||
// the interface url, through which the list of | // the interface url, through which the list of | |||
// supported interfaces are fetched | // supported interfaces are fetched | |||
std::string url; | std::string url; | |||
skipping to change at line 263 | skipping to change at line 300 | |||
std::string path; | std::string path; | |||
address external_ip; | address external_ip; | |||
int lease_duration; | int lease_duration; | |||
// true if the device supports specifying a | // true if the device supports specifying a | |||
// specific external port, false if it doesn't | // specific external port, false if it doesn't | |||
bool supports_specific_external; | bool supports_specific_external; | |||
bool disabled; | bool disabled; | |||
// this is true if the IP of this device is not | ||||
// one of our default routes. i.e. it may be someone | ||||
// else's router, we just happen to have multicast | ||||
// enabled across networks | ||||
// this is only relevant if ignore_non_routers is set. | ||||
bool non_router; | ||||
mutable boost::shared_ptr<http_connection> upnp_connection; | mutable boost::shared_ptr<http_connection> upnp_connection; | |||
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS | #if TORRENT_USE_ASSERTS | |||
int magic; | int magic; | |||
#endif | #endif | |||
void close() const | void close() const | |||
{ | { | |||
TORRENT_ASSERT(magic == 1337); | TORRENT_ASSERT(magic == 1337); | |||
if (!upnp_connection) return; | if (!upnp_connection) return; | |||
upnp_connection->close(); | upnp_connection->close(); | |||
upnp_connection.reset(); | upnp_connection.reset(); | |||
} | } | |||
skipping to change at line 312 | skipping to change at line 356 | |||
// multicast messages on the network | // multicast messages on the network | |||
broadcast_socket m_socket; | broadcast_socket m_socket; | |||
// used to resend udp packets in case | // used to resend udp packets in case | |||
// they time out | // they time out | |||
deadline_timer m_broadcast_timer; | deadline_timer m_broadcast_timer; | |||
// timer used to refresh mappings | // timer used to refresh mappings | |||
deadline_timer m_refresh_timer; | deadline_timer m_refresh_timer; | |||
// this timer fires one second after the last UPnP response. This is | ||||
the | ||||
// point where we assume we have received most or all SSDP reponses. | ||||
If we | ||||
// are ignoring non-routers and at this point we still haven't recei | ||||
ved a | ||||
// response from a router UPnP device, we override the ignoring beha | ||||
vior and | ||||
// map them anyway. | ||||
deadline_timer m_map_timer; | ||||
bool m_disabled; | bool m_disabled; | |||
bool m_closing; | bool m_closing; | |||
bool m_ignore_non_routers; | bool m_ignore_non_routers; | |||
connection_queue& m_cc; | connection_queue& m_cc; | |||
mutex m_mutex; | mutex m_mutex; | |||
std::string m_model; | std::string m_model; | |||
}; | }; | |||
} | } | |||
#if BOOST_VERSION >= 103500 | ||||
namespace boost { namespace system { | ||||
template<> struct is_error_code_enum<libtorrent::upnp_errors::error_ | ||||
code_enum> | ||||
{ static const bool value = true; }; | ||||
template<> struct is_error_condition_enum<libtorrent::upnp_errors::e | ||||
rror_code_enum> | ||||
{ static const bool value = true; }; | ||||
} } | ||||
#endif // BOOST_VERSION | ||||
#endif | #endif | |||
End of changes. 30 change blocks. | ||||
23 lines changed or deleted | 105 lines changed or added | |||
ut_metadata.hpp | ut_metadata.hpp | |||
---|---|---|---|---|
skipping to change at line 36 | skipping to change at line 36 | |||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 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 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||
POSSIBILITY OF SUCH DAMAGE. | POSSIBILITY OF SUCH DAMAGE. | |||
*/ | */ | |||
#ifndef TORRENT_UT_METADATA_HPP_INCLUDED | #ifndef TORRENT_UT_METADATA_HPP_INCLUDED | |||
#define TORRENT_UT_METADATA_HPP_INCLUDED | #define TORRENT_UT_METADATA_HPP_INCLUDED | |||
#ifndef TORRENT_DISABLE_EXTENSIONS | ||||
#ifdef _MSC_VER | #ifdef _MSC_VER | |||
#pragma warning(push, 1) | #pragma warning(push, 1) | |||
#endif | #endif | |||
#include <boost/shared_ptr.hpp> | #include <boost/shared_ptr.hpp> | |||
#include "libtorrent/config.hpp" | #include "libtorrent/config.hpp" | |||
#ifdef _MSC_VER | #ifdef _MSC_VER | |||
#pragma warning(pop) | #pragma warning(pop) | |||
#endif | #endif | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
struct torrent_plugin; | struct torrent_plugin; | |||
class torrent; | class torrent; | |||
// constructor function for the ut_metadata extension. The ut_metada | ||||
ta | ||||
// extension allows peers to request the .torrent file (or more | ||||
// specifically the 'info'-dictionary of the .torrent file) from eac | ||||
h | ||||
// other. This is the main building block in making magnet links wor | ||||
k. | ||||
// This extension is enabled by default unless explicitly disabled i | ||||
n | ||||
// the session constructor. | ||||
// | ||||
// This can either be passed in the add_torrent_params::extensions f | ||||
ield, or | ||||
// via torrent_handle::add_extension(). | ||||
TORRENT_EXPORT boost::shared_ptr<torrent_plugin> create_ut_metadata_ plugin(torrent*, void*); | TORRENT_EXPORT boost::shared_ptr<torrent_plugin> create_ut_metadata_ plugin(torrent*, void*); | |||
} | } | |||
#endif // TORRENT_DISABLE_EXTENSIONS | ||||
#endif // TORRENT_UT_METADATA_HPP_INCLUDED | #endif // TORRENT_UT_METADATA_HPP_INCLUDED | |||
End of changes. 3 change blocks. | ||||
0 lines changed or deleted | 18 lines changed or added | |||
ut_pex.hpp | ut_pex.hpp | |||
---|---|---|---|---|
skipping to change at line 36 | skipping to change at line 36 | |||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 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 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||
POSSIBILITY OF SUCH DAMAGE. | POSSIBILITY OF SUCH DAMAGE. | |||
*/ | */ | |||
#ifndef TORRENT_UT_PEX_EXTENSION_HPP_INCLUDED | #ifndef TORRENT_UT_PEX_EXTENSION_HPP_INCLUDED | |||
#define TORRENT_UT_PEX_EXTENSION_HPP_INCLUDED | #define TORRENT_UT_PEX_EXTENSION_HPP_INCLUDED | |||
#ifndef TORRENT_DISABLE_EXTENSIONS | ||||
#ifdef _MSC_VER | #ifdef _MSC_VER | |||
#pragma warning(push, 1) | #pragma warning(push, 1) | |||
#endif | #endif | |||
#include <boost/shared_ptr.hpp> | #include <boost/shared_ptr.hpp> | |||
#include "libtorrent/config.hpp" | #include "libtorrent/config.hpp" | |||
#ifdef _MSC_VER | #ifdef _MSC_VER | |||
#pragma warning(pop) | #pragma warning(pop) | |||
#endif | #endif | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
struct torrent_plugin; | struct torrent_plugin; | |||
class torrent; | class torrent; | |||
// constructor function for the ut_pex extension. The ut_pex | ||||
// extension allows peers to gossip about their connections, allowin | ||||
g | ||||
// the swarm stay well connected and peers aware of more peers in th | ||||
e | ||||
// swarm. This extension is enabled by default unless explicitly dis | ||||
abled in | ||||
// the session constructor. | ||||
// | ||||
// This can either be passed in the add_torrent_params::extensions f | ||||
ield, or | ||||
// via torrent_handle::add_extension(). | ||||
TORRENT_EXPORT boost::shared_ptr<torrent_plugin> create_ut_pex_plugi n(torrent*, void*); | TORRENT_EXPORT boost::shared_ptr<torrent_plugin> create_ut_pex_plugi n(torrent*, void*); | |||
} | } | |||
#endif // TORRENT_DISABLE_EXTENSIONS | ||||
#endif // TORRENT_UT_PEX_EXTENSION_HPP_INCLUDED | #endif // TORRENT_UT_PEX_EXTENSION_HPP_INCLUDED | |||
End of changes. 3 change blocks. | ||||
0 lines changed or deleted | 17 lines changed or added | |||
utf8.hpp | utf8.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2006, Arvid Norberg | Copyright (c) 2006-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 47 | skipping to change at line 47 | |||
// on windows we need these functions for | // on windows we need these functions for | |||
// convert_to_native and convert_from_native | // convert_to_native and convert_from_native | |||
#if TORRENT_USE_WSTRING || defined TORRENT_WINDOWS | #if TORRENT_USE_WSTRING || defined TORRENT_WINDOWS | |||
#include <string> | #include <string> | |||
#include <cwchar> | #include <cwchar> | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
TORRENT_EXPORT int utf8_wchar(const std::string &utf8, std::wstring | ||||
&wide); | // results from UTF-8 conversion functions utf8_wchar and | |||
TORRENT_EXPORT int wchar_utf8(const std::wstring &wide, std::string | // wchar_utf8 | |||
&utf8); | enum utf8_conv_result_t | |||
{ | ||||
// conversion successful | ||||
conversion_ok, | ||||
// partial character in source, but hit end | ||||
source_exhausted, | ||||
// insuff. room in target for conversion | ||||
target_exhausted, | ||||
// source sequence is illegal/malformed | ||||
source_illegal | ||||
}; | ||||
// ``utf8_wchar`` converts a UTF-8 string (``utf8``) to a wide chara | ||||
cter | ||||
// string (``wide``). ``wchar_utf8`` converts a wide character strin | ||||
g | ||||
// (``wide``) to a UTF-8 string (``utf8``). The return value is one | ||||
of | ||||
// the enumeration values from utf8_conv_result_t. | ||||
TORRENT_EXPORT utf8_conv_result_t utf8_wchar( | ||||
const std::string &utf8, std::wstring &wide); | ||||
TORRENT_EXPORT utf8_conv_result_t wchar_utf8( | ||||
const std::wstring &wide, std::string &utf8); | ||||
} | } | |||
#endif // !BOOST_NO_STD_WSTRING | #endif // !BOOST_NO_STD_WSTRING | |||
#endif | #endif | |||
End of changes. 2 change blocks. | ||||
5 lines changed or deleted | 30 lines changed or added | |||
utp_socket_manager.hpp | utp_socket_manager.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2009, Arvid Norberg | Copyright (c) 2009-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 50 | skipping to change at line 50 | |||
#include "libtorrent/enum_net.hpp" | #include "libtorrent/enum_net.hpp" | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
class udp_socket; | class udp_socket; | |||
class utp_stream; | class utp_stream; | |||
struct utp_socket_impl; | struct utp_socket_impl; | |||
typedef boost::function<void(boost::shared_ptr<socket_type> const&)> incoming_utp_callback_t; | typedef boost::function<void(boost::shared_ptr<socket_type> const&)> incoming_utp_callback_t; | |||
struct utp_socket_manager | struct utp_socket_manager : udp_socket_observer | |||
{ | { | |||
utp_socket_manager(session_settings const& sett, udp_socket& s, incoming_utp_callback_t cb); | utp_socket_manager(session_settings const& sett, udp_socket& s, incoming_utp_callback_t cb); | |||
~utp_socket_manager(); | ~utp_socket_manager(); | |||
void get_status(utp_status& s) const; | void get_status(utp_status& s) const; | |||
// return false if this is not a uTP packet | // return false if this is not a uTP packet | |||
bool incoming_packet(char const* p, int size, udp::endpoint | virtual bool incoming_packet(error_code const& ec, udp::endp | |||
const& ep); | oint const& ep | |||
, char const* p, int size); | ||||
virtual bool incoming_packet(error_code const& ec, char cons | ||||
t* host, char const* p, int size) | ||||
{ return false; } | ||||
virtual void writable(); | ||||
virtual void socket_drained(); | ||||
void tick(ptime now); | void tick(ptime now); | |||
tcp::endpoint local_endpoint(address const& remote, error_co de& ec) const; | tcp::endpoint local_endpoint(address const& remote, error_co de& ec) const; | |||
int local_port(error_code& ec) const; | int local_port(error_code& ec) const; | |||
// flags for send_packet | // flags for send_packet | |||
enum { dont_fragment = 1 }; | enum { dont_fragment = 1 }; | |||
void send_packet(udp::endpoint const& ep, char const* p, int len | void send_packet(udp::endpoint const& ep, char const* p, int len | |||
, error_code& ec, int flags = 0); | , error_code& ec, int flags = 0); | |||
void subscribe_writable(utp_socket_impl* s); | ||||
// internal, used by utp_stream | // internal, used by utp_stream | |||
void remove_socket(boost::uint16_t id); | void remove_socket(boost::uint16_t id); | |||
utp_socket_impl* new_utp_socket(utp_stream* str); | utp_socket_impl* new_utp_socket(utp_stream* str); | |||
int gain_factor() const { return m_sett.utp_gain_factor; } | int gain_factor() const { return m_sett.utp_gain_factor; } | |||
int target_delay() const { return m_sett.utp_target_delay * 1000; } | int target_delay() const { return m_sett.utp_target_delay * 1000; } | |||
int syn_resends() const { return m_sett.utp_syn_resends; } | int syn_resends() const { return m_sett.utp_syn_resends; } | |||
int fin_resends() const { return m_sett.utp_fin_resends; } | int fin_resends() const { return m_sett.utp_fin_resends; } | |||
int num_resends() const { return m_sett.utp_num_resends; } | int num_resends() const { return m_sett.utp_num_resends; } | |||
int connect_timeout() const { return m_sett.utp_connect_time out; } | int connect_timeout() const { return m_sett.utp_connect_time out; } | |||
int delayed_ack() const { return m_sett.utp_delayed_ack; } | ||||
int min_timeout() const { return m_sett.utp_min_timeout; } | int min_timeout() const { return m_sett.utp_min_timeout; } | |||
int loss_multiplier() const { return m_sett.utp_loss_multipl ier; } | int loss_multiplier() const { return m_sett.utp_loss_multipl ier; } | |||
bool allow_dynamic_sock_buf() const { return m_sett.utp_dyna mic_sock_buf; } | bool allow_dynamic_sock_buf() const { return m_sett.utp_dyna mic_sock_buf; } | |||
void mtu_for_dest(address const& addr, int& link_mtu, int& u tp_mtu); | void mtu_for_dest(address const& addr, int& link_mtu, int& u tp_mtu); | |||
void set_sock_buf(int size); | void set_sock_buf(int size); | |||
int num_sockets() const { return m_utp_sockets.size(); } | int num_sockets() const { return m_utp_sockets.size(); } | |||
void defer_ack(utp_socket_impl* s); | ||||
void subscribe_drained(utp_socket_impl* s); | ||||
enum counter_t | ||||
{ | ||||
packet_loss = 0, | ||||
timeout, | ||||
packets_in, | ||||
packets_out, | ||||
fast_retransmit, | ||||
packet_resend, | ||||
samples_above_target, | ||||
samples_below_target, | ||||
payload_pkts_in, | ||||
payload_pkts_out, | ||||
invalid_pkts_in, | ||||
redundant_pkts_in, | ||||
num_counters | ||||
}; | ||||
// used to keep stats of uTP events | ||||
void inc_stats_counter(int counter); | ||||
private: | private: | |||
udp_socket& m_sock; | udp_socket& m_sock; | |||
incoming_utp_callback_t m_cb; | incoming_utp_callback_t m_cb; | |||
// replace with a hash-map | // replace with a hash-map | |||
typedef std::multimap<boost::uint16_t, utp_socket_impl*> soc ket_map_t; | typedef std::multimap<boost::uint16_t, utp_socket_impl*> soc ket_map_t; | |||
socket_map_t m_utp_sockets; | socket_map_t m_utp_sockets; | |||
// this is a list of sockets that needs to send an ack. | ||||
// once the UDP socket is drained, all of these will | ||||
// have a chance to do that. This is to avoid sending | ||||
// an ack for every single packet | ||||
std::vector<utp_socket_impl*> m_deferred_acks; | ||||
// sockets that have received or sent packets this | ||||
// round, may subscribe to the event of draining the | ||||
// UDP socket. At that point they may call the | ||||
// user callback function to indicate bytes have been | ||||
// sent or received. | ||||
std::vector<utp_socket_impl*> m_drained_event; | ||||
// list of sockets that received EWOULDBLOCK from the | ||||
// underlying socket. They are notified when the socket | ||||
// becomes writable again | ||||
std::vector<utp_socket_impl*> m_stalled_sockets; | ||||
// the last socket we received a packet on | // the last socket we received a packet on | |||
utp_socket_impl* m_last_socket; | utp_socket_impl* m_last_socket; | |||
int m_new_connection; | int m_new_connection; | |||
session_settings const& m_sett; | session_settings const& m_sett; | |||
// this is a copy of the routing table, used | // this is a copy of the routing table, used | |||
// to initialize MTU sizes of uTP sockets | // to initialize MTU sizes of uTP sockets | |||
mutable std::vector<ip_route> m_routes; | mutable std::vector<ip_route> m_routes; | |||
skipping to change at line 119 | skipping to change at line 167 | |||
// the routing table | // the routing table | |||
mutable ptime m_last_route_update; | mutable ptime m_last_route_update; | |||
// cache of interfaces | // cache of interfaces | |||
mutable std::vector<ip_interface> m_interfaces; | mutable std::vector<ip_interface> m_interfaces; | |||
mutable ptime m_last_if_update; | mutable ptime m_last_if_update; | |||
// the buffer size of the socket. This is used | // the buffer size of the socket. This is used | |||
// to now lower the buffer size | // to now lower the buffer size | |||
int m_sock_buf_size; | int m_sock_buf_size; | |||
// stats counters | ||||
boost::uint64_t m_counters[num_counters]; | ||||
}; | }; | |||
} | } | |||
#endif | #endif | |||
End of changes. 8 change blocks. | ||||
5 lines changed or deleted | 57 lines changed or added | |||
utp_stream.hpp | utp_stream.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2009, Arvid Norberg | Copyright (c) 2009-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 57 | skipping to change at line 57 | |||
#ifndef BOOST_NO_EXCEPTIONS | #ifndef BOOST_NO_EXCEPTIONS | |||
#include <boost/system/system_error.hpp> | #include <boost/system/system_error.hpp> | |||
#endif | #endif | |||
#define CCONTROL_TARGET 100 | #define CCONTROL_TARGET 100 | |||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
struct utp_socket_manager; | struct utp_socket_manager; | |||
// some MTU and protocol header sizes constants | // internal: some MTU and protocol header sizes constants | |||
enum | enum | |||
{ | { | |||
TORRENT_IPV4_HEADER = 20, | TORRENT_IPV4_HEADER = 20, | |||
TORRENT_IPV6_HEADER = 40, | TORRENT_IPV6_HEADER = 40, | |||
TORRENT_UDP_HEADER = 8, | TORRENT_UDP_HEADER = 8, | |||
TORRENT_SOCKS5_HEADER = 6, // plus the size of the destinati on address | TORRENT_SOCKS5_HEADER = 6, // plus the size of the destinati on address | |||
TORRENT_ETHERNET_MTU = 1500, | TORRENT_ETHERNET_MTU = 1500, | |||
TORRENT_TEREDO_MTU = 1280, | TORRENT_TEREDO_MTU = 1280, | |||
TORRENT_INET_MIN_MTU = 576, | TORRENT_INET_MIN_MTU = 576, | |||
TORRENT_INET_MAX_MTU = 0xffff | TORRENT_INET_MAX_MTU = 0xffff | |||
}; | }; | |||
// the point of the bif_endian_int is two-fold | // internal: the point of the bif_endian_int is two-fold | |||
// one purpuse is to not have any alignment requirements | // one purpuse is to not have any alignment requirements | |||
// so that any byffer received from the network can be cast | // so that any byffer received from the network can be cast | |||
// to it and read as an integer of various sizes without | // to it and read as an integer of various sizes without | |||
// triggering a bus error. The other purpose is to convert | // triggering a bus error. The other purpose is to convert | |||
// from network byte order to host byte order when read and | // from network byte order to host byte order when read and | |||
// written, to offer a convenient interface to both interpreting | // written, to offer a convenient interface to both interpreting | |||
// and writing network packets | // and writing network packets | |||
template <class T> struct big_endian_int | template <class T> struct big_endian_int | |||
{ | { | |||
big_endian_int& operator=(T v) | big_endian_int& operator=(T v) | |||
skipping to change at line 121 | skipping to change at line 121 | |||
+---------------+---------------+---------------+---------------+ | +---------------+---------------+---------------+---------------+ | |||
| timestamp_difference_microseconds | | | timestamp_difference_microseconds | | |||
+---------------+---------------+---------------+---------------+ | +---------------+---------------+---------------+---------------+ | |||
| wnd_size | | | wnd_size | | |||
+---------------+---------------+---------------+---------------+ | +---------------+---------------+---------------+---------------+ | |||
| seq_nr | ack_nr | | | seq_nr | ack_nr | | |||
+---------------+---------------+---------------+---------------+ | +---------------+---------------+---------------+---------------+ | |||
*/ | */ | |||
enum type { ST_DATA = 0, ST_FIN, ST_STATE, ST_RESET, ST_SYN, NUM_TYP | // internal: the different kinds of uTP packets | |||
ES }; | enum utp_socket_state_t | |||
{ ST_DATA, ST_FIN, ST_STATE, ST_RESET, ST_SYN, NUM_TYPES }; | ||||
struct utp_header | struct utp_header | |||
{ | { | |||
unsigned char type_ver; | unsigned char type_ver; | |||
unsigned char extension; | unsigned char extension; | |||
be_uint16 connection_id; | be_uint16 connection_id; | |||
be_uint32 timestamp_microseconds; | be_uint32 timestamp_microseconds; | |||
be_uint32 timestamp_difference_microseconds; | be_uint32 timestamp_difference_microseconds; | |||
be_uint32 wnd_size; | be_uint32 wnd_size; | |||
be_uint16 seq_nr; | be_uint16 seq_nr; | |||
be_uint16 ack_nr; | be_uint16 ack_nr; | |||
int get_type() const { return type_ver >> 4; } | int get_type() const { return type_ver >> 4; } | |||
int get_version() const { return type_ver & 0xf; } | int get_version() const { return type_ver & 0xf; } | |||
}; | }; | |||
struct utp_socket_impl; | struct utp_socket_impl; | |||
utp_socket_impl* construct_utp_impl(boost::uint16_t recv_id | utp_socket_impl* construct_utp_impl(boost::uint16_t recv_id | |||
, boost::uint16_t send_id, void* userdata | , boost::uint16_t send_id, void* userdata | |||
, utp_socket_manager* sm); | , utp_socket_manager* sm); | |||
void detach_utp_impl(utp_socket_impl* s); | void detach_utp_impl(utp_socket_impl* s); | |||
void delete_utp_impl(utp_socket_impl* s); | void delete_utp_impl(utp_socket_impl* s); | |||
bool should_delete(utp_socket_impl* s); | bool should_delete(utp_socket_impl* s); | |||
void tick_utp_impl(utp_socket_impl* s, ptime const& now); | void tick_utp_impl(utp_socket_impl* s, ptime const& now); | |||
void utp_init_mtu(utp_socket_impl* s, int link_mtu, int utp_mtu); | void utp_init_mtu(utp_socket_impl* s, int link_mtu, int utp_mtu); | |||
bool utp_incoming_packet(utp_socket_impl* s, char const* p | bool utp_incoming_packet(utp_socket_impl* s, char const* p | |||
, int size, udp::endpoint const& ep, ptime receive_time); | , int size, udp::endpoint const& ep, ptime receive_time); | |||
bool utp_match(utp_socket_impl* s, udp::endpoint const& ep, boost::uint16_t id); | bool utp_match(utp_socket_impl* s, udp::endpoint const& ep, boost::uint16_t id); | |||
udp::endpoint utp_remote_endpoint(utp_socket_impl* s); | udp::endpoint utp_remote_endpoint(utp_socket_impl* s); | |||
boost::uint16_t utp_receive_id(utp_socket_impl* s); | boost::uint16_t utp_receive_id(utp_socket_impl* s); | |||
int utp_socket_state(utp_socket_impl const* s); | int utp_socket_state(utp_socket_impl const* s); | |||
void utp_send_ack(utp_socket_impl* s); | ||||
void utp_socket_drained(utp_socket_impl* s); | ||||
void utp_writable(utp_socket_impl* s); | ||||
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T ORRENT_ERROR_LOGGING | #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T ORRENT_ERROR_LOGGING | |||
int socket_impl_size(); | int socket_impl_size(); | |||
#endif | #endif | |||
// this is the user-level stream interface to utp sockets. | // this is the user-level stream interface to utp sockets. | |||
// the reason why it's split up in a utp_stream class and | // the reason why it's split up in a utp_stream class and | |||
// an implementation class is because the socket state has | // an implementation class is because the socket state has | |||
// to be able to out-live the user level socket. For instance | // to be able to out-live the user level socket. For instance | |||
// when sending data on a stream and then closing it, the | // when sending data on a stream and then closing it, the | |||
skipping to change at line 208 | skipping to change at line 213 | |||
void bind(endpoint_type const& endpoint, error_code& ec); | void bind(endpoint_type const& endpoint, error_code& ec); | |||
#ifndef BOOST_NO_EXCEPTIONS | #ifndef BOOST_NO_EXCEPTIONS | |||
template <class SettableSocketOption> | template <class SettableSocketOption> | |||
void set_option(SettableSocketOption const& opt) {} | void set_option(SettableSocketOption const& opt) {} | |||
#endif | #endif | |||
template <class SettableSocketOption> | template <class SettableSocketOption> | |||
error_code set_option(SettableSocketOption const& opt, error_code& e c) { return ec; } | error_code set_option(SettableSocketOption const& opt, error_code& e c) { return ec; } | |||
#ifndef BOOST_NO_EXCEPTIONS | ||||
template <class GettableSocketOption> | ||||
void get_option(GettableSocketOption& opt) {} | ||||
#endif | ||||
template <class GettableSocketOption> | ||||
error_code get_option(GettableSocketOption& opt, error_code& ec) { r | ||||
eturn ec; } | ||||
void close(); | void close(); | |||
void close(error_code const& /*ec*/) { close(); } | void close(error_code const& /*ec*/) { close(); } | |||
bool is_open() const { return m_open; } | bool is_open() const { return m_open; } | |||
int read_buffer_size() const; | int read_buffer_size() const; | |||
static void on_read(void* self, size_t bytes_transferred, error_code const& ec, bool kill); | static void on_read(void* self, size_t bytes_transferred, error_code const& ec, bool kill); | |||
static void on_write(void* self, size_t bytes_transferred, error_cod e const& ec, bool kill); | static void on_write(void* self, size_t bytes_transferred, error_cod e const& ec, bool kill); | |||
static void on_connect(void* self, error_code const& ec, bool kill); | static void on_connect(void* self, error_code const& ec, bool kill); | |||
typedef void(*handler_t)(void*, size_t, error_code const&, bool); | typedef void(*handler_t)(void*, size_t, error_code const&, bool); | |||
skipping to change at line 271 | skipping to change at line 284 | |||
if (m_impl == 0) | if (m_impl == 0) | |||
{ | { | |||
m_io_service.post(boost::bind<void>(handler, asio::e rror::not_connected, 0)); | m_io_service.post(boost::bind<void>(handler, asio::e rror::not_connected, 0)); | |||
return; | return; | |||
} | } | |||
m_connect_handler = handler; | m_connect_handler = handler; | |||
do_connect(endpoint, &utp_stream::on_connect); | do_connect(endpoint, &utp_stream::on_connect); | |||
} | } | |||
template <class Handler> | ||||
void async_read_some(boost::asio::null_buffers const& buffers, Handl | ||||
er const& handler) | ||||
{ | ||||
TORRENT_ASSERT(false); | ||||
} | ||||
template <class Mutable_Buffers, class Handler> | template <class Mutable_Buffers, class Handler> | |||
void async_read_some(Mutable_Buffers const& buffers, Handler const& handler) | void async_read_some(Mutable_Buffers const& buffers, Handler const& handler) | |||
{ | { | |||
if (m_impl == 0) | if (m_impl == 0) | |||
{ | { | |||
m_io_service.post(boost::bind<void>(handler, asio::e rror::not_connected, 0)); | m_io_service.post(boost::bind<void>(handler, asio::e rror::not_connected, 0)); | |||
return; | return; | |||
} | } | |||
TORRENT_ASSERT(!m_read_handler); | TORRENT_ASSERT(!m_read_handler); | |||
if (m_read_handler) | if (m_read_handler) | |||
{ | { | |||
m_io_service.post(boost::bind<void>(handler, asio::e rror::operation_not_supported, 0)); | m_io_service.post(boost::bind<void>(handler, asio::e rror::operation_not_supported, 0)); | |||
return; | return; | |||
} | } | |||
int bytes_added = 0; | ||||
for (typename Mutable_Buffers::const_iterator i = buffers.be gin() | for (typename Mutable_Buffers::const_iterator i = buffers.be gin() | |||
, end(buffers.end()); i != end; ++i) | , end(buffers.end()); i != end; ++i) | |||
{ | { | |||
TORRENT_ASSERT(buffer_size(*i) > 0); | if (buffer_size(*i) == 0) continue; | |||
using asio::buffer_cast; | using asio::buffer_cast; | |||
using asio::buffer_size; | using asio::buffer_size; | |||
add_read_buffer(buffer_cast<void*>(*i), buffer_size( *i)); | add_read_buffer(buffer_cast<void*>(*i), buffer_size( *i)); | |||
bytes_added += buffer_size(*i); | ||||
} | } | |||
if (bytes_added == 0) | ||||
{ | ||||
// if we're reading 0 bytes, post handler immediatel | ||||
y | ||||
// asio's SSL layer depends on this behavior | ||||
m_io_service.post(boost::bind<void>(handler, error_c | ||||
ode(), 0)); | ||||
return; | ||||
} | ||||
m_read_handler = handler; | m_read_handler = handler; | |||
set_read_handler(&utp_stream::on_read); | set_read_handler(&utp_stream::on_read); | |||
} | } | |||
void do_async_connect(endpoint_type const& ep | void do_async_connect(endpoint_type const& ep | |||
, boost::function<void(error_code const&)> const& handler); | , boost::function<void(error_code const&)> const& handler); | |||
template <class Protocol> | template <class Protocol> | |||
void open(Protocol const& p, error_code& ec) | void open(Protocol const& p, error_code& ec) | |||
{ m_open = true; } | { m_open = true; } | |||
skipping to change at line 324 | skipping to change at line 353 | |||
{ | { | |||
ec = asio::error::not_connected; | ec = asio::error::not_connected; | |||
return 0; | return 0; | |||
} | } | |||
if (read_buffer_size() == 0) | if (read_buffer_size() == 0) | |||
{ | { | |||
ec = asio::error::would_block; | ec = asio::error::would_block; | |||
return 0; | return 0; | |||
} | } | |||
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS | #if TORRENT_USE_ASSERTS | |||
size_t buf_size = 0; | size_t buf_size = 0; | |||
#endif | #endif | |||
for (typename Mutable_Buffers::const_iterator i = buffers.be gin() | for (typename Mutable_Buffers::const_iterator i = buffers.be gin() | |||
, end(buffers.end()); i != end; ++i) | , end(buffers.end()); i != end; ++i) | |||
{ | { | |||
using asio::buffer_cast; | using asio::buffer_cast; | |||
using asio::buffer_size; | using asio::buffer_size; | |||
add_read_buffer(buffer_cast<void*>(*i), buffer_size( *i)); | add_read_buffer(buffer_cast<void*>(*i), buffer_size( *i)); | |||
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS | #if TORRENT_USE_ASSERTS | |||
buf_size += buffer_size(*i); | buf_size += buffer_size(*i); | |||
#endif | #endif | |||
} | } | |||
std::size_t ret = read_some(true); | std::size_t ret = read_some(true); | |||
TORRENT_ASSERT(ret <= buf_size); | TORRENT_ASSERT(ret <= buf_size); | |||
TORRENT_ASSERT(ret > 0); | TORRENT_ASSERT(ret > 0); | |||
return ret; | return ret; | |||
} | } | |||
template <class Const_Buffers> | template <class Const_Buffers> | |||
std::size_t write_some(Const_Buffers const& buffers, error_code& ec) | std::size_t write_some(Const_Buffers const& buffers, error_code& ec) | |||
{ | { | |||
TORRENT_ASSERT(false && "not implemented!"); | TORRENT_ASSERT(false && "not implemented!"); | |||
// TODO: implement | // TODO: implement blocking write. Low priority since it's n ot used (yet) | |||
return 0; | return 0; | |||
} | } | |||
#ifndef BOOST_NO_EXCEPTIONS | #ifndef BOOST_NO_EXCEPTIONS | |||
template <class Mutable_Buffers> | template <class Mutable_Buffers> | |||
std::size_t read_some(Mutable_Buffers const& buffers) | std::size_t read_some(Mutable_Buffers const& buffers) | |||
{ | { | |||
error_code ec; | error_code ec; | |||
std::size_t ret = read_some(buffers, ec); | std::size_t ret = read_some(buffers, ec); | |||
if (ec) | if (ec) | |||
skipping to change at line 374 | skipping to change at line 403 | |||
std::size_t write_some(Const_Buffers const& buffers) | std::size_t write_some(Const_Buffers const& buffers) | |||
{ | { | |||
error_code ec; | error_code ec; | |||
std::size_t ret = write_some(buffers, ec); | std::size_t ret = write_some(buffers, ec); | |||
if (ec) | if (ec) | |||
boost::throw_exception(boost::system::system_error(e c)); | boost::throw_exception(boost::system::system_error(e c)); | |||
return ret; | return ret; | |||
} | } | |||
#endif | #endif | |||
template <class Handler> | ||||
void async_write_some(boost::asio::null_buffers const& buffers, Hand | ||||
ler const& handler) | ||||
{ | ||||
TORRENT_ASSERT(false); | ||||
} | ||||
template <class Const_Buffers, class Handler> | template <class Const_Buffers, class Handler> | |||
void async_write_some(Const_Buffers const& buffers, Handler const& h andler) | void async_write_some(Const_Buffers const& buffers, Handler const& h andler) | |||
{ | { | |||
if (m_impl == 0) | if (m_impl == 0) | |||
{ | { | |||
m_io_service.post(boost::bind<void>(handler, asio::e rror::not_connected, 0)); | m_io_service.post(boost::bind<void>(handler, asio::e rror::not_connected, 0)); | |||
return; | return; | |||
} | } | |||
TORRENT_ASSERT(!m_write_handler); | TORRENT_ASSERT(!m_write_handler); | |||
if (m_write_handler) | if (m_write_handler) | |||
{ | { | |||
m_io_service.post(boost::bind<void>(handler, asio::e rror::operation_not_supported, 0)); | m_io_service.post(boost::bind<void>(handler, asio::e rror::operation_not_supported, 0)); | |||
return; | return; | |||
} | } | |||
int bytes_added = 0; | ||||
for (typename Const_Buffers::const_iterator i = buffers.begi n() | for (typename Const_Buffers::const_iterator i = buffers.begi n() | |||
, end(buffers.end()); i != end; ++i) | , end(buffers.end()); i != end; ++i) | |||
{ | { | |||
TORRENT_ASSERT(buffer_size(*i) > 0); | if (buffer_size(*i) == 0) continue; | |||
using asio::buffer_cast; | using asio::buffer_cast; | |||
using asio::buffer_size; | using asio::buffer_size; | |||
add_write_buffer((void*)buffer_cast<void const*>(*i) , buffer_size(*i)); | add_write_buffer((void*)buffer_cast<void const*>(*i) , buffer_size(*i)); | |||
bytes_added += buffer_size(*i); | ||||
} | ||||
if (bytes_added == 0) | ||||
{ | ||||
// if we're reading 0 bytes, post handler immediatel | ||||
y | ||||
// asio's SSL layer depends on this behavior | ||||
m_io_service.post(boost::bind<void>(handler, error_c | ||||
ode(), 0)); | ||||
return; | ||||
} | } | |||
m_write_handler = handler; | m_write_handler = handler; | |||
set_write_handler(&utp_stream::on_write); | set_write_handler(&utp_stream::on_write); | |||
} | } | |||
//private: | //private: | |||
void cancel_handlers(error_code const&); | void cancel_handlers(error_code const&); | |||
boost::function1<void, error_code const&> m_connect_handler; | boost::function1<void, error_code const&> m_connect_handler; | |||
boost::function2<void, error_code const&, std::size_t> m_read_handle r; | boost::function2<void, error_code const&, std::size_t> m_read_handle r; | |||
boost::function2<void, error_code const&, std::size_t> m_write_handl er; | boost::function2<void, error_code const&, std::size_t> m_write_handl er; | |||
asio::io_service& m_io_service; | asio::io_service& m_io_service; | |||
utp_socket_impl* m_impl; | utp_socket_impl* m_impl; | |||
// this field requires another 8 bytes (including padding) | ||||
bool m_open; | bool m_open; | |||
}; | }; | |||
} | } | |||
#endif | #endif | |||
End of changes. 21 change blocks. | ||||
23 lines changed or deleted | 75 lines changed or added | |||
version.hpp | version.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2003, Arvid Norberg | Copyright (c) 2003-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 36 | skipping to change at line 36 | |||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 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 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||
POSSIBILITY OF SUCH DAMAGE. | POSSIBILITY OF SUCH DAMAGE. | |||
*/ | */ | |||
#ifndef TORRENT_VERSION_HPP_INCLUDED | #ifndef TORRENT_VERSION_HPP_INCLUDED | |||
#define TORRENT_VERSION_HPP_INCLUDED | #define TORRENT_VERSION_HPP_INCLUDED | |||
#define LIBTORRENT_VERSION_MAJOR 0 | #define LIBTORRENT_VERSION_MAJOR 1 | |||
#define LIBTORRENT_VERSION_MINOR 16 | #define LIBTORRENT_VERSION_MINOR 0 | |||
#define LIBTORRENT_VERSION_TINY 19 | #define LIBTORRENT_VERSION_TINY 1 | |||
// the format of this version is: MMmmtt | // the format of this version is: MMmmtt | |||
// M = Major version, m = minor version, t = tiny version | // M = Major version, m = minor version, t = tiny version | |||
#define LIBTORRENT_VERSION_NUM ((LIBTORRENT_VERSION_MAJOR * 10000) + (LIBTO RRENT_VERSION_MINOR * 100) + LIBTORRENT_VERSION_TINY) | #define LIBTORRENT_VERSION_NUM ((LIBTORRENT_VERSION_MAJOR * 10000) + (LIBTO RRENT_VERSION_MINOR * 100) + LIBTORRENT_VERSION_TINY) | |||
#define LIBTORRENT_VERSION "0.16.19.0" | #define LIBTORRENT_VERSION "1.0.1.0" | |||
#define LIBTORRENT_REVISION "$Rev: 10584 $" | #define LIBTORRENT_REVISION "$Rev: 10111 $" | |||
#endif | #endif | |||
End of changes. 3 change blocks. | ||||
6 lines changed or deleted | 6 lines changed or added | |||
web_connection_base.hpp | web_connection_base.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2003, Arvid Norberg | Copyright (c) 2003-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 98 | skipping to change at line 98 | |||
public: | public: | |||
// this is the constructor where the we are the active part. | // this is the constructor where the we are the active part. | |||
// The peer_conenction should handshake and verify that the | // The peer_conenction should handshake and verify that the | |||
// other end has the correct id | // other end has the correct id | |||
web_connection_base( | web_connection_base( | |||
aux::session_impl& ses | aux::session_impl& ses | |||
, boost::weak_ptr<torrent> t | , boost::weak_ptr<torrent> t | |||
, boost::shared_ptr<socket_type> s | , boost::shared_ptr<socket_type> s | |||
, tcp::endpoint const& remote | , tcp::endpoint const& remote | |||
, std::string const& url | , web_seed_entry& web); | |||
, policy::peer* peerinfo | ||||
, std::string const& ext_auth | ||||
, web_seed_entry::headers_t const& ext_headers); | ||||
void start(); | void start(); | |||
~web_connection_base(); | ~web_connection_base(); | |||
// called from the main loop when this connection has any | // called from the main loop when this connection has any | |||
// work to do. | // work to do. | |||
void on_sent(error_code const& error | void on_sent(error_code const& error | |||
, std::size_t bytes_transferred); | , std::size_t bytes_transferred); | |||
virtual std::string const& url() const = 0; | virtual std::string const& url() const = 0; | |||
skipping to change at line 131 | skipping to change at line 128 | |||
virtual void write_request(peer_request const& r) = 0; | virtual void write_request(peer_request const& r) = 0; | |||
void write_cancel(peer_request const& r) {} | void write_cancel(peer_request const& r) {} | |||
void write_have(int index) {} | void write_have(int index) {} | |||
void write_piece(peer_request const& r, disk_buffer_holder& buffer) { TORRENT_ASSERT(false); } | void write_piece(peer_request const& r, disk_buffer_holder& buffer) { TORRENT_ASSERT(false); } | |||
void write_keepalive() {} | void write_keepalive() {} | |||
void on_connected(); | void on_connected(); | |||
void write_reject_request(peer_request const&) {} | void write_reject_request(peer_request const&) {} | |||
void write_allow_fast(int) {} | void write_allow_fast(int) {} | |||
void write_suggest(int piece) {} | void write_suggest(int piece) {} | |||
#ifdef TORRENT_DEBUG | #if TORRENT_USE_INVARIANT_CHECKS | |||
void check_invariant() const; | void check_invariant() const; | |||
#endif | #endif | |||
virtual void get_specific_peer_info(peer_info& p) const; | virtual void get_specific_peer_info(peer_info& p) const; | |||
protected: | protected: | |||
virtual void add_headers(std::string& request | virtual void add_headers(std::string& request | |||
, proxy_settings const& ps, bool using_proxy) const; | , proxy_settings const& ps, bool using_proxy) const; | |||
End of changes. 3 change blocks. | ||||
6 lines changed or deleted | 3 lines changed or added | |||
web_peer_connection.hpp | web_peer_connection.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2003, Arvid Norberg | Copyright (c) 2003-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 87 | skipping to change at line 87 | |||
public: | public: | |||
// this is the constructor where the we are the active part. | // this is the constructor where the we are the active part. | |||
// The peer_conenction should handshake and verify that the | // The peer_conenction should handshake and verify that the | |||
// other end has the correct id | // other end has the correct id | |||
web_peer_connection( | web_peer_connection( | |||
aux::session_impl& ses | aux::session_impl& ses | |||
, boost::weak_ptr<torrent> t | , boost::weak_ptr<torrent> t | |||
, boost::shared_ptr<socket_type> s | , boost::shared_ptr<socket_type> s | |||
, tcp::endpoint const& remote | , tcp::endpoint const& remote | |||
, std::string const& url | , web_seed_entry& web); | |||
, policy::peer* peerinfo | ||||
, std::string const& ext_auth | virtual void on_connected(); | |||
, web_seed_entry::headers_t const& ext_headers); | ||||
virtual int type() const { return peer_connection::url_seed_ connection; } | virtual int type() const { return peer_connection::url_seed_ connection; } | |||
// called from the main loop when this connection has any | // called from the main loop when this connection has any | |||
// work to do. | // work to do. | |||
void on_receive(error_code const& error | void on_receive(error_code const& error | |||
, std::size_t bytes_transferred); | , std::size_t bytes_transferred); | |||
std::string const& url() const { return m_url; } | std::string const& url() const { return m_url; } | |||
virtual void get_specific_peer_info(peer_info& p) const; | virtual void get_specific_peer_info(peer_info& p) const; | |||
virtual void disconnect(error_code const& ec, int error = 0) ; | virtual void disconnect(error_code const& ec, int error = 0) ; | |||
void write_request(peer_request const& r); | virtual void write_request(peer_request const& r); | |||
virtual bool received_invalid_data(int index, bool single_pe | ||||
er); | ||||
private: | private: | |||
bool maybe_harvest_block(); | bool maybe_harvest_block(); | |||
// returns the block currently being | // returns the block currently being | |||
// downloaded. And the progress of that | // downloaded. And the progress of that | |||
// block. If the peer isn't downloading | // block. If the peer isn't downloading | |||
// a piece for the moment, the boost::optional | // a piece for the moment, the boost::optional | |||
// will be invalid. | // will be invalid. | |||
boost::optional<piece_block_progress> downloading_piece_prog ress() const; | boost::optional<piece_block_progress> downloading_piece_prog ress() const; | |||
void handle_padfile(buffer::const_interval& recv_buffer); | ||||
// this has one entry per http-request | // this has one entry per http-request | |||
// (might be more than the bt requests) | // (might be more than the bt requests) | |||
std::deque<int> m_file_requests; | std::deque<int> m_file_requests; | |||
std::string m_url; | std::string m_url; | |||
web_seed_entry* m_web; | ||||
// this is used for intermediate storage of pieces | // this is used for intermediate storage of pieces | |||
// that are received in more than one HTTP response | // that are received in more than one HTTP response | |||
// TODO: if we make this be a disk_buffer_holder instead | // TODO: 1 if we make this be a disk_buffer_holder instead | |||
// we would save a copy sometimes | // we would save a copy sometimes | |||
// use allocate_disk_receive_buffer and release_disk_receive _buffer | // use allocate_disk_receive_buffer and release_disk_receive _buffer | |||
std::vector<char> m_piece; | std::vector<char> m_piece; | |||
// the number of bytes received in the current HTTP | // the number of bytes received in the current HTTP | |||
// response. used to know where in the buffer the | // response. used to know where in the buffer the | |||
// next response starts | // next response starts | |||
size_type m_received_body; | size_type m_received_body; | |||
// position in the current range response | // position in the current range response | |||
skipping to change at line 152 | skipping to change at line 157 | |||
// buffer where the next chunk header will be. | // buffer where the next chunk header will be. | |||
// this is updated for each chunk header that's | // this is updated for each chunk header that's | |||
// parsed. It does not necessarily point to a valid | // parsed. It does not necessarily point to a valid | |||
// offset in the receive buffer, if we haven't received | // offset in the receive buffer, if we haven't received | |||
// it yet. This offset never includes the HTTP header | // it yet. This offset never includes the HTTP header | |||
size_type m_chunk_pos; | size_type m_chunk_pos; | |||
// this is the number of bytes we've already received | // this is the number of bytes we've already received | |||
// from the next chunk header we're waiting for | // from the next chunk header we're waiting for | |||
int m_partial_chunk_header; | int m_partial_chunk_header; | |||
// the number of responses we've received so far on | ||||
// this connection | ||||
int m_num_responses; | ||||
}; | }; | |||
} | } | |||
#endif // TORRENT_WEB_PEER_CONNECTION_HPP_INCLUDED | #endif // TORRENT_WEB_PEER_CONNECTION_HPP_INCLUDED | |||
End of changes. 7 change blocks. | ||||
7 lines changed or deleted | 17 lines changed or added | |||
xml_parse.hpp | xml_parse.hpp | |||
---|---|---|---|---|
/* | /* | |||
Copyright (c) 2007, Arvid Norberg | Copyright (c) 2007-2014, Arvid Norberg | |||
All rights reserved. | All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
are met: | are met: | |||
* Redistributions of source code must retain the above copyright | * Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
* Redistributions in binary form must reproduce the above copyright | * Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in | notice, this list of conditions and the following disclaimer in | |||
skipping to change at line 39 | skipping to change at line 39 | |||
POSSIBILITY OF SUCH DAMAGE. | POSSIBILITY OF SUCH DAMAGE. | |||
*/ | */ | |||
#ifndef TORRENT_XML_PARSE_HPP | #ifndef TORRENT_XML_PARSE_HPP | |||
#define TORRENT_XML_PARSE_HPP | #define TORRENT_XML_PARSE_HPP | |||
#include <cctype> | #include <cctype> | |||
#include <cstring> | #include <cstring> | |||
#include "libtorrent/config.hpp" | ||||
#include "libtorrent/assert.hpp" | ||||
#include "libtorrent/escape_string.hpp" | #include "libtorrent/escape_string.hpp" | |||
#include <boost/function.hpp> | ||||
namespace libtorrent | namespace libtorrent | |||
{ | { | |||
enum | enum | |||
{ | { | |||
xml_start_tag, | xml_start_tag, | |||
xml_end_tag, | xml_end_tag, | |||
xml_empty_tag, | xml_empty_tag, | |||
xml_declaration_tag, | xml_declaration_tag, | |||
xml_string, | xml_string, | |||
xml_attribute, | xml_attribute, | |||
xml_comment, | xml_comment, | |||
xml_parse_error, | xml_parse_error, | |||
// used for tags that don't follow the convention of | // used for tags that don't follow the convention of | |||
// key-value pairs inside the tag brackets. Like !DOCTYPE | // key-value pairs inside the tag brackets. Like !DOCTYPE | |||
xml_tag_content | xml_tag_content | |||
}; | }; | |||
// callback(int type, char const* name, char const* val) | // callback(int type, char const* name, char const* val) | |||
// str2 is only used for attributes. name is element or attribute | // str2 is only used for attributes. name is element or attribute | |||
// name and val is attribute value | // name and val is attribute value | |||
TORRENT_EXTRA_EXPORT void xml_parse(char* p, char* end | ||||
template <class CallbackType> | , boost::function<void(int,char const*,char const*)> callbac | |||
void xml_parse(char* p, char* end, CallbackType callback) | k); | |||
{ | ||||
for(;p != end; ++p) | ||||
{ | ||||
char const* start = p; | ||||
char const* val_start = 0; | ||||
int token; | ||||
// look for tag start | ||||
for(; p != end && *p != '<'; ++p); | ||||
if (p != start) | ||||
{ | ||||
if (p != end) | ||||
{ | ||||
TORRENT_ASSERT(*p == '<'); | ||||
*p = 0; | ||||
} | ||||
token = xml_string; | ||||
callback(token, start, val_start); | ||||
if (p != end) *p = '<'; | ||||
} | ||||
if (p == end) break; | ||||
// skip '<' | ||||
++p; | ||||
if (p != end && p+8 < end && string_begins_no_case(" | ||||
![CDATA[", p)) | ||||
{ | ||||
// CDATA. match '![CDATA[' | ||||
p += 8; | ||||
start = p; | ||||
while (p != end && !string_begins_no_case("] | ||||
]>", p-2)) ++p; | ||||
// parse error | ||||
if (p == end) | ||||
{ | ||||
token = xml_parse_error; | ||||
start = "unexpected end of file"; | ||||
callback(token, start, val_start); | ||||
break; | ||||
} | ||||
token = xml_string; | ||||
char tmp = p[-2]; | ||||
p[-2] = 0; | ||||
callback(token, start, val_start); | ||||
p[-2] = tmp; | ||||
continue; | ||||
} | ||||
// parse the name of the tag. | ||||
for (start = p; p != end && *p != '>' && !is_space(* | ||||
p); ++p); | ||||
char* tag_name_end = p; | ||||
// skip the attributes for now | ||||
for (; p != end && *p != '>'; ++p); | ||||
// parse error | ||||
if (p == end) | ||||
{ | ||||
token = xml_parse_error; | ||||
start = "unexpected end of file"; | ||||
callback(token, start, val_start); | ||||
break; | ||||
} | ||||
TORRENT_ASSERT(*p == '>'); | ||||
// save the character that terminated the tag name | ||||
// it could be both '>' and ' '. | ||||
char save = *tag_name_end; | ||||
*tag_name_end = 0; | ||||
char* tag_end = p; | ||||
if (*start == '/') | ||||
{ | ||||
++start; | ||||
token = xml_end_tag; | ||||
callback(token, start, val_start); | ||||
} | ||||
else if (*(p-1) == '/') | ||||
{ | ||||
*(p-1) = 0; | ||||
token = xml_empty_tag; | ||||
callback(token, start, val_start); | ||||
*(p-1) = '/'; | ||||
tag_end = p - 1; | ||||
} | ||||
else if (*start == '?' && *(p-1) == '?') | ||||
{ | ||||
*(p-1) = 0; | ||||
++start; | ||||
token = xml_declaration_tag; | ||||
callback(token, start, val_start); | ||||
*(p-1) = '?'; | ||||
tag_end = p - 1; | ||||
} | ||||
else if (start + 5 < p && std::memcmp(start, "!--", | ||||
3) == 0 && std::memcmp(p-2, "--", 2) == 0) | ||||
{ | ||||
start += 3; | ||||
*(p-2) = 0; | ||||
token = xml_comment; | ||||
callback(token, start, val_start); | ||||
*(p-2) = '-'; | ||||
tag_end = p - 2; | ||||
} | ||||
else | ||||
{ | ||||
token = xml_start_tag; | ||||
callback(token, start, val_start); | ||||
} | ||||
*tag_name_end = save; | ||||
// parse attributes | ||||
for (char* i = tag_name_end; i < tag_end; ++i) | ||||
{ | ||||
// find start of attribute name | ||||
for (; i != tag_end && is_space(*i); ++i); | ||||
if (i == tag_end) break; | ||||
start = i; | ||||
// find end of attribute name | ||||
for (; i != tag_end && *i != '=' && !is_spac | ||||
e(*i); ++i); | ||||
char* name_end = i; | ||||
// look for equality sign | ||||
for (; i != tag_end && *i != '='; ++i); | ||||
// no equality sign found. Report this as xm | ||||
l_tag_content | ||||
// instead of a series of key value pairs | ||||
if (i == tag_end) | ||||
{ | ||||
char tmp = *i; | ||||
*i = 0; // null terminate the conten | ||||
t string | ||||
token = xml_tag_content; | ||||
val_start = 0; | ||||
callback(token, start, val_start); | ||||
*i = tmp; | ||||
break; | ||||
} | ||||
++i; | ||||
for (; i != tag_end && is_space(*i); ++i); | ||||
// check for parse error (values must be quo | ||||
ted) | ||||
if (i == tag_end || (*i != '\'' && *i != '\" | ||||
')) | ||||
{ | ||||
token = xml_parse_error; | ||||
val_start = 0; | ||||
start = "unquoted attribute value"; | ||||
callback(token, start, val_start); | ||||
break; | ||||
} | ||||
char quote = *i; | ||||
++i; | ||||
val_start = i; | ||||
for (; i != tag_end && *i != quote; ++i); | ||||
// parse error (missing end quote) | ||||
if (i == tag_end) | ||||
{ | ||||
token = xml_parse_error; | ||||
val_start = 0; | ||||
start = "missing end quote on attrib | ||||
ute"; | ||||
callback(token, start, val_start); | ||||
break; | ||||
} | ||||
save = *i; | ||||
*i = 0; | ||||
*name_end = 0; | ||||
token = xml_attribute; | ||||
callback(token, start, val_start); | ||||
*name_end = '='; | ||||
*i = save; | ||||
} | ||||
} | ||||
} | ||||
} | } | |||
#endif | #endif | |||
End of changes. 4 change blocks. | ||||
189 lines changed or deleted | 8 lines changed or added | |||