From 175fb8770b87f0df8fb229f43b8a5f7c9e67d912 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Wed, 28 Jun 2006 23:27:44 +0000 Subject: [PATCH] added peer_timeout and urlseed_timeout to session_settings, they control the timeout for peers and web seeds respectively. Added BitSlug to the projects page. Added more debug logging when resolving web seed hostnames. Updated documentation. --- COPYING | 2 +- docs/bitslug_thumb.png | Bin 0 -> 26204 bytes docs/manual.html | 533 ++++++++++++------------ docs/manual.rst | 13 +- docs/projects.rst | 8 + examples/client_test.cpp | 4 +- include/libtorrent/peer_connection.hpp | 2 + include/libtorrent/peer_id.hpp | 24 +- include/libtorrent/session_settings.hpp | 14 +- src/peer_connection.cpp | 6 +- src/torrent.cpp | 17 + src/web_peer_connection.cpp | 3 + 12 files changed, 355 insertions(+), 271 deletions(-) create mode 100644 docs/bitslug_thumb.png diff --git a/COPYING b/COPYING index a446aa68a..c7ade855b 100644 --- a/COPYING +++ b/COPYING @@ -1,4 +1,4 @@ -Copyright (c) 2003 - 2005, Arvid Norberg +Copyright (c) 2003 - 2006, Arvid Norberg All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/docs/bitslug_thumb.png b/docs/bitslug_thumb.png new file mode 100644 index 0000000000000000000000000000000000000000..d7a04a4e634cc1247995f77db7fca01894d7f4e1 GIT binary patch literal 26204 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

&#OQr>VOQPx+9Mc%^KQ>ATtDVM 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 eFw`-uFa!V*g97OW#L6fD0000 - + libtorrent manual @@ -169,8 +169,8 @@
  • acknowledgments
  • -
    -

    introduction

    +
    +

    introduction

    libtorrent is a C++ library that aims to be a good alternative to all the other bittorrent implementations around. It is a library and not a full featured client, although it comes with a working @@ -250,16 +250,16 @@ to the author of the library by including the libtorrent license in your software or documentation.

    Here's a list of some projects that uses libtorrent.

    -
    -

    downloading and building

    +
    +

    downloading and building

    To acquire the latest version of libtorrent, you'll have to grab it from CVS. You'll find instructions on how to do this here (see Anonymous CVS access).

    The build systems supported "out of the box" in libtorrent are boost-build v2 (BBv2) and autotools (for unix-like systems). If you still can't build after following these instructions, you can usually get help in the #libtorrent IRC channel on irc.freenode.net.

    -
    -

    building with BBv2

    +
    +

    building with BBv2

    The primary reason to use boost-build is that it will automatically build the dependent boost libraries with the correct compiler settings, in order to ensure that the build targets are link compatible (see boost guidelines @@ -268,8 +268,8 @@ for some details on this issue).

    source package. Having boost installed via some package system is usually not enough (and even if it is enough, the necessary environment variables are usually not set by the package installer).

    -
    -

    Step 1: Download boost

    +
    +

    Step 1: Download boost

    You'll find boost here.

    Extract the archive to some directory where you want it. For the sake of this guide, let's assume you extract the package to c:\boost_1_33_1 (I'm using @@ -279,8 +279,8 @@ in order to build libtorrent.

    If you use 1.32, you need to download BBv2 separately, so for now, let's assume you will use version 1.33.1.

    -
    -

    Step 2: Setup BBv2

    +
    +

    Step 2: Setup BBv2

    First you need to build bjam. You do this by opening a terminal (In windows, run cmd). Change directory to c:\boost_1_33_1\tools\build\jam_src. Then run the script called @@ -331,8 +331,8 @@ using darwin : 4.0 : g++-4.0 ;

    Note that the spaces around the semi-colons and colons are important!

    -
    -

    Step 3: Building libtorrent

    +
    +

    Step 3: Building libtorrent

    When building libtorrent, the Jamfile expects the environment variable BOOST_ROOT to be set to the boost installation directory. It uses this to find the boost libraries it depends on, so they can be built and their headers @@ -395,12 +395,12 @@ boost.program-options symbols.

    For more information, see the Boost build v2 documentation.

    -
    -

    building with autotools

    +
    +

    building with autotools

    First of all, you need to install automake and autoconf. Many unix/linux systems comes with these preinstalled.

    -
    -

    Step 1: Running configure

    +
    +

    Step 1: Running configure

    In your shell, change directory to the libtorrent directory and run ./configure. This will look for libraries and C++ features that libtorrent is dependent on. If something is missing or can't be found it will print an @@ -440,8 +440,8 @@ checking for main in -lboost_thread... yes directory contains spaces. Make sure you either rename the directories with spaces in their names to remove the spaces or move the libtorrent directory.

    -
    -

    Creating a debug build

    +
    +

    Creating a debug build

    To tell configure to build a debug version (with debug info, asserts and invariant checks enabled), you have to run the configure script with the following option:

    @@ -449,8 +449,8 @@ with the following option:

    ./configure --enable-debug=yes
    -
    -

    Creating a release build

    +
    +

    Creating a release build

    To tell the configure to build a release version (without debug info, asserts and invariant checks), you have to run the configure script with the following option:

    @@ -459,8 +459,8 @@ with the following option:

    The above option make use of -DNDEBUG, which is used throughout libtorrent.

    -
    -

    Step 2: Building libtorrent

    +
    +

    Step 2: Building libtorrent

    Once the configure script is run successfully, you just type make and libtorrent, the examples and the tests will be built.

    When libtorrent is built it may be a good idea to run the tests, you do this @@ -473,8 +473,8 @@ make clean make

    -
    -

    generating the build system

    +
    +

    generating the build system

    No build system is present if libtorrent is checked out from CVS - it needs to be generated first.

    Execute the following commands to generate the build system:

    @@ -489,8 +489,8 @@ needs to be generated first.

    libtorrent. This was described earlier.

    -
    -

    building with other build systems

    +
    +

    building with other build systems

    If you're making your own project file, note that there are two versions of the file abstraction. There's one file_win.cpp which relies on windows file API that supports files larger than 2 Gigabytes. This does not work in @@ -504,8 +504,8 @@ filenames, so if your target is Windows 2000 and up, you may want to use options "force conformance in for loop scope", "treat wchar_t as built-in type" and "Enable Run-Time Type Info" to Yes.

    -
    -

    build configurations

    +
    +

    build configurations

    By default libtorrent is built In debug mode, and will have pretty expensive invariant checks and asserts built into it. If you want to disable such checks (you want to do that in a release build) you can see the table below for which @@ -584,8 +584,8 @@ definitely help to define NDEBUG< within the library.

    -
    -

    overview

    +
    +

    overview

    The interface of libtorrent consists of a few classes. The main class is the session, it contains the main loop that serves all torrents.

    The basic usage is as follows:

    @@ -611,8 +611,8 @@ the session, it conta

    Each class and function is described in this manual.

    -
    -

    session

    +
    +

    session

    The session class has the following synopsis:

     class session: public boost::noncopyable
    @@ -671,8 +671,8 @@ class session: public boost::noncopyable
     

    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 any torrents to participate in.

    -
    -

    session()

    +
    +

    session()

     session(fingerprint const& print = libtorrent::fingerprint("LT", 0, 1, 0, 0));
    @@ -690,16 +690,16 @@ The other constructor, that takes a port range and an interface as well as the f
     will automatically try to listen on a port on the given interface. For more information about
     the parameters, see listen_on() function.

    -
    -

    ~session()

    +
    +

    ~session()

    The destructor of session will notify all trackers that our 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 before destructing the session object. Because it can take a few second for it to finish. The timeout can be set with set_settings().

    -
    -

    add_torrent()

    +
    +

    add_torrent()

     torrent_handle add_torrent(
    @@ -745,8 +745,8 @@ about the torrent's progress, its peers etc. It is also used to abort a torrent.
     the metadata extension. For the overload to be available, libtorrent must be built
     with extensions enabled (TORRENT_ENABLE_EXTENSIONS defined).

    -
    -

    remove_torrent()

    +
    +

    remove_torrent()

     void remove_torrent(torrent_handle const& h);
    @@ -755,8 +755,8 @@ void remove_torrent(torrent_handle const& h);
     

    remove_torrent() will close all peer connections associated with the torrent and tell the tracker that we've stopped participating in the swarm.

    -
    -

    disable_extensions() enable_extension()

    +
    +

    disable_extensions() enable_extension()

     void disable_extensions();
    @@ -780,8 +780,8 @@ enum extension_index
     

    By default, all extensions are enabled. For more information about the extensions, see the extensions section.

    -
    -

    set_upload_rate_limit() set_download_rate_limit()

    +
    +

    set_upload_rate_limit() set_download_rate_limit()

     void set_upload_rate_limit(int bytes_per_second);
    @@ -794,8 +794,8 @@ you don't want to limit upload rate, you can set this to -1 (the default).
     set_download_rate_limit() works the same way but for download rate instead
     of upload rate.

    -
    -

    set_max_uploads() set_max_connections()

    +
    +

    set_max_uploads() set_max_connections()

     void set_max_uploads(int limit);
    @@ -808,8 +808,8 @@ minimum of at least two connections per torrent, so if you set a too low
     connections limit, and open too many torrents, the limit will not be met. The
     number of uploads is at least one per torrent.

    -
    -

    set_max_half_open_connections()

    +
    +

    set_max_half_open_connections()

     void set_max_half_open_connections(int limit);
    @@ -825,8 +825,8 @@ and passing -1 as the limit, means to have no limit. When limiting the number
     of simultaneous connection attempts, peers will be put in a queue waiting for
     their turn to get connected.

    -
    -

    set_ip_filter()

    +
    +

    set_ip_filter()

     void set_ip_filter(ip_filter const& filter);
    @@ -837,8 +837,8 @@ connections based on their originating ip address. The default filter will allow
     connections to any ip address. To build a set of rules for which addresses are
     accepted and not, see ip_filter.

    -
    -

    status()

    +
    +

    status()

     session_status status() const;
    @@ -877,8 +877,8 @@ uploaded to and from all torrents. num_peers is the total number of peer connections this session have.

    -
    -

    is_listening() listen_port() listen_on()

    + -
    -

    pop_alert() set_severity_level()

    +
    +

    pop_alert() set_severity_level()

     std::auto_ptr<alert> pop_alert();
    @@ -919,8 +919,8 @@ void set_severity_level(alert::severity_t s);
     receive it through pop_alert(). For information, see alerts.

    -
    -

    entry

    +
    +

    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. This is its synopsis:

    @@ -971,20 +971,20 @@ public: dictionary_type const& dict() const; // these functions requires that the entry - // is a dictionary, otherwise they will throw + // is a dictionary, otherwise they will throw entry& operator[](char const* key); entry& operator[](std::string const& key); entry const& operator[](char const* key) const; entry const& operator[](std::string const& key) const; entry* find_key(char const* key); entry const* find_key(char const* key) const; - + void print(std::ostream& os, int indent = 0) const; };

    TODO: finish documentation of entry.

    -
    -

    integer() string() list() dict() type()

    +
    +

    integer() string() list() dict() type()

     integer_type& integer();
    @@ -1036,8 +1036,8 @@ if (entry* i = torrent_file.find_key("announce"))
     

    To make it easier to extract information from a torrent file, the class torrent_info exists.

    -
    -

    operator[]

    +
    +

    operator[]

     entry& operator[](char const* key);
    @@ -1055,8 +1055,8 @@ given key, a reference to a newly inserted element at that key.

    existing element at the given key. If the key is not found, it will throw libtorrent::type_error.

    -
    -

    find_key()

    +
    +

    find_key()

     entry* find_key(char const* key);
    @@ -1070,8 +1070,8 @@ element cannot be found, they will return 0. If an element with the given
     key is found, the return a pointer to it.

    -
    -

    torrent_info

    +
    +

    torrent_info

    The torrent_info has the following synopsis:

     class torrent_info
    @@ -1129,8 +1129,8 @@ public:
             sha1_hash const& hash_for_piece(unsigned int index) const;
     };
     
    -
    -

    torrent_info()

    +
    +

    torrent_info()

     torrent_info();
    @@ -1153,8 +1153,8 @@ object from the information found in the given torrent_file. The entry, use bdecode(),
     see bdecode() bencode().

    -
    -

    set_comment() set_piece_size() set_creator() set_hash() add_tracker() add_file()

    +
    +

    set_comment() set_piece_size() set_creator() set_hash() add_tracker() add_file()

     void set_comment(char const* str);
    @@ -1186,8 +1186,8 @@ of the torrent. The sizecreate_torrent().

    For a complete example of how to create a torrent from a file structure, see make_torrent.

    -
    -

    create_torrent()

    +
    +

    create_torrent()

     entry create_torrent();
    @@ -1199,8 +1199,8 @@ complete example, see make_torrent
     

    This function is not const because it will also set the info-hash of the torrent_info object.

    -
    -

    begin_files() end_files() rbegin_files() rend_files()

    +
    +

    begin_files() end_files() rbegin_files() rend_files()

     file_iterator begin_files() const;
    @@ -1228,8 +1228,8 @@ struct file_entry
     };
     
    -
    -

    num_files() file_at()

    +
    +

    num_files() file_at()

     int num_files() const;
    @@ -1239,8 +1239,8 @@ file_entry const& file_at(int index) const;
     

    If you need index-access to files you can use the num_files() and file_at() to access files using indices.

    -
    -

    map_block()

    +
    +

    map_block()

     std::vector<file_slice> map_block(int piece, size_type offset
    @@ -1265,8 +1265,8 @@ as argument. The offsetsize is the number of bytes this range is. The size + offset
     will never be greater than the file size.

    -
    -

    map_file()

    +
    +

    map_file()

     peer_request map_file(int file_index, size_type file_offset
    @@ -1293,8 +1293,8 @@ struct peer_request
     + size is not allowed to be greater than the file size. file_index
     must refer to a valid file, i.e. it cannot be >= num_files().

    -
    -

    url_seeds()

    +
    +

    url_seeds()

     std::vector<std::string> const& url_seeds() const;
    @@ -1307,8 +1307,8 @@ adds one url to the list of url-seeds. Currently, the only transport protocol
     supported for the url is http.

    See HTTP seeding for more information.

    -
    -

    print()

    +
    +

    print()

     void print(std::ostream& os) const;
    @@ -1317,8 +1317,8 @@ void print(std::ostream& os) const;
     

    The print() function is there for debug purposes only. It will print the info from the torrent file to the given outstream.

    -
    -

    trackers()

    +
    +

    trackers()

     std::vector<announce_entry> const& trackers() const;
    @@ -1337,8 +1337,8 @@ struct announce_entry
     };
     
    -
    -

    total_size() piece_length() piece_size() num_pieces()

    +
    +

    total_size() piece_length() piece_size() num_pieces()

     size_type total_size() const;
    @@ -1355,8 +1355,8 @@ the piece index as argument and gives you the exact size of that piece. It will
     be the same as piece_length() except in the case of the last piece, which may
     be smaller.

    -
    -

    hash_for_piece() info_hash()

    +
    +

    hash_for_piece() info_hash()

     size_type piece_size(unsigned int index) const;
    @@ -1369,8 +1369,8 @@ torrent file. For more information on the info_hash() will only return a valid hash if the torrent_info was read from a
     .torrent file or if an entry was created from it (through create_torrent).

    -
    -

    name() comment() creation_date() creator()

    +
    +

    name() comment() creation_date() creator()

     std::string const& name() const;
    @@ -1388,8 +1388,8 @@ in the torrent file, this will return a date of January 1:st 1970.

    it will return an empty string.

    -
    -

    torrent_handle

    +
    +

    torrent_handle

    You will usually have to store your torrent handles somewhere, since it's the object through which you retrieve information about the torrent and aborts the torrent. Its declaration looks like this:

    @@ -1457,8 +1457,8 @@ struct torrent_handle perform any operation on it, unless you first assign it a valid handle. If you try to perform any operation on an uninitialized handle, it will throw invalid_handle.

    TODO: document filter_piece(), filter_pieces(), is_piece_filtered(), filtered_pieces() and filter_files()

    -
    -

    file_progress()

    +
    +

    file_progress()

     void file_progress(std::vector<float>& fp);
    @@ -1469,8 +1469,8 @@ range [0, 1]) describing the download progress of each file in this torrent.
     The progress values are ordered the same as the files in the torrent_info.
     This operation is not very cheap.

    -
    -

    save_path()

    +
    +

    save_path()

     boost::filesystem::path save_path() const;
    @@ -1479,8 +1479,8 @@ boost::filesystem::path save_path() const;
     

    save_path() returns the path that was given to add_torrent() when this torrent was started.

    -
    -

    move_storage()

    +
    +

    move_storage()

     bool move_storage(boost::filesystem::path const& save_path) const;
    @@ -1492,8 +1492,8 @@ the same drive as the original save path. If the move operation fails, this func
     returns false, otherwise true. Post condition for successful operation is:
     save_path() == save_path.

    -
    -

    force_reannounce()

    +
    +

    force_reannounce()

     void force_reannounce() const;
    @@ -1503,8 +1503,8 @@ void force_reannounce() const;
     peers. If the torrent is invalid, queued or in checking mode, this functions will throw
     invalid_handle.

    -
    -

    connect_peer()

    +
    +

    connect_peer()

     void connect_peer(asio::ip::tcp::endpoint const& adr) const;
    @@ -1516,8 +1516,8 @@ be disconnected. No harm can be done by using this other than an unnecessary con
     attempt is made. If the torrent is uninitialized or in queued or checking mode, this
     will throw invalid_handle.

    -
    -

    set_ratio()

    +
    +

    set_ratio()

     void set_ratio(float ratio) const;
    @@ -1531,8 +1531,8 @@ attempt to upload in return for each download. e.g. if set to 2, the client will
     2 bytes for every byte received. The default setting for this is 0, which will make it work
     as a standard client.

    -
    -

    set_upload_limit() set_download_limit()

    +
    +

    set_upload_limit() set_download_limit()

     void set_upload_limit(int limit) const;
    @@ -1546,8 +1546,8 @@ Note that setting a higher limit on a torrent then the global limit (
    -

    set_peer_upload_limit() set_peer_download_limit()

    +
    +

    set_peer_upload_limit() set_peer_download_limit()

     void set_peer_upload_limit(asio::ip::tcp::endpoint ip, int limit) const;
    @@ -1557,8 +1557,8 @@ void set_peer_download_limit(asio::ip::tcp::endpoint ip, int limit) const;
     

    Works like set_upload_limit and set_download_limit respectively, but controls individual peer instead of the whole torrent.

    -
    -

    pause() resume() is_paused()

    +
    +

    pause() resume() is_paused()

     void pause() const;
    @@ -1572,8 +1572,8 @@ all potential (not connected) peers. You can use file_error_alert.

    -
    -

    is_seed()

    +
    +

    is_seed()

     bool is_seed() const;
    @@ -1581,8 +1581,8 @@ bool is_seed() const;
     

    Returns true if the torrent is in seed mode (i.e. if it has finished downloading).

    -
    -

    has_metadata()

    +
    +

    has_metadata()

     bool has_metadata() const;
    @@ -1593,8 +1593,8 @@ metadata has been downloaded). The only scenario where this can return false is
     was started torrent-less (i.e. with just an info-hash and tracker ip). Note that if the torrent
     doesn't have metadata, the member get_torrent_info() will throw.

    -
    -

    set_tracker_login()

    +
    +

    set_tracker_login()

     void set_tracker_login(std::string const& username
    @@ -1604,8 +1604,8 @@ void set_tracker_login(std::string const& username
     

    set_tracker_login() sets a username and password that will be sent along in the HTTP-request of the tracker announce. Set this if the tracker requires authorization.

    -
    -

    trackers() replace_trackers()

    +
    +

    trackers() replace_trackers()

     std::vector<announce_entry> const& trackers() const;
    @@ -1621,8 +1621,8 @@ a list of the same form as the one returned from force_reannounce().

    -
    -

    add_url_seed()

    +
    +

    add_url_seed()

     void add_url_seed(std::string const& url);
    @@ -1634,8 +1634,8 @@ will connect to the server and try to download pieces from it, unless it's
     paused, queued, checking or seeding.

    See HTTP seeding for more information.

    -
    -

    use_interface()

    +
    +

    use_interface()

     void use_interface(char const* net_interface) const;
    @@ -1645,8 +1645,8 @@ void use_interface(char const* net_interface) const;
     connections. By default, it uses the same interface as the session uses to listen on. The
     parameter can be a string containing an ip-address or a hostname.

    -
    -

    info_hash()

    +
    +

    info_hash()

     sha1_hash info_hash() const;
    @@ -1654,8 +1654,8 @@ sha1_hash info_hash() const;
     

    info_hash() returns the info-hash for the torrent.

    -
    -

    set_max_uploads() set_max_connections()

    +
    +

    set_max_uploads() set_max_connections()

     void set_max_uploads(int max_uploads) const;
    @@ -1669,8 +1669,8 @@ connections are used up, incoming connections may be refused or poor connections
     This must be at least 2. The default is unlimited number of connections. If -1 is given to the
     function, it means unlimited.

    -
    -

    write_resume_data()

    +
    +

    write_resume_data()

     entry write_resume_data() const;
    @@ -1692,8 +1692,8 @@ not be ready to write resume data.
     is still downloading! The recommended practice is to first pause the torrent, then generate the
     fast resume data, and then close it down.

    -
    -

    metadata()

    +
    +

    metadata()

     std::vector<char> const& metadata() const;
    @@ -1703,8 +1703,8 @@ std::vector<char> const& metadata() const;
     .torrent file. This buffer will be valid as long as the torrent is still running. When hashed,
     it will produce the same hash as the info-hash.

    -
    -

    status()

    +
    +

    status()

     torrent_status status() const;
    @@ -1714,8 +1714,8 @@ torrent_status status() const;
     torrent. If the torrent_handle is invalid, it will throw invalid_handle exception.
     See torrent_status.

    -
    -

    get_download_queue()

    +
    +

    get_download_queue()

     void get_download_queue(std::vector<partial_piece_info>& queue) const;
    @@ -1751,8 +1751,8 @@ or not. And the num_downloads
     
    -
    -

    get_peer_info()

    +
    +

    get_peer_info()

     void get_peer_info(std::vector<peer_info>&) const;
    @@ -1763,8 +1763,8 @@ with one entry for each peer connected to this torrent, given the handle is vali
     torrent_handle is invalid, it will throw invalid_handle exception. Each entry in
     the vector contains information about that particular peer. See peer_info.

    -
    -

    get_torrent_info()

    +
    +

    get_torrent_info()

     torrent_info const& get_torrent_info() const;
    @@ -1777,8 +1777,8 @@ exception will be thrown. The torrent may be in a state without metadata only if
     it was started without a .torrent file, i.e. by using the libtorrent extension of
     just supplying a tracker and info-hash.

    -
    -

    is_valid()

    +
    +

    is_valid()

     bool is_valid() const;
    @@ -1793,8 +1793,8 @@ that refers to that torrent will become invalid.

    TODO: document storage

    -
    -

    torrent_status

    +
    +

    torrent_status

    It contains the following fields:

     struct torrent_status
    @@ -1964,8 +1964,8 @@ bytes that each bit in the partia
     (see get_download_queue()). This is typically 16 kB, but it may be
     larger if the pieces are larger.

    -
    -

    peer_info

    +
    +

    peer_info

    It contains the following fields:

     struct peer_info
    @@ -2109,8 +2109,8 @@ string.

    connection_type can currently be one of standard_bittorrent or web_seed. These are currently the only implemented protocols.

    -
    -

    session_settings

    +
    +

    session_settings

    You have some control over tracker requests through the session_settings object. You create it and fill it with your settings and then use session::set_settings() to apply them. You have control over proxy and authorization settings and also the user-agent @@ -2134,6 +2134,8 @@ struct session_settings int max_allowed_in_request_queue; int max_out_request_queue; int whole_pieces_threshold; + int peer_timeout; + int urlseed_timeout; };

    proxy_ip may be a hostname or ip to a http proxy to use. If this is @@ -2172,7 +2174,7 @@ actual number of requests depends on the download rate and this number.

    (popular == inverse of rarity) to be downloaded in sequence instead of in random (rarest first) order. It can be used to tweak disk performance in settings where the random download property is less necessary. For example, if -the threshold is 7, all pieces which 7 or more peers have, will be downloaded +the threshold is 10, all pieces which 10 or more peers have, will be downloaded in index order.

    max_allowed_in_request_queue is the number of outstanding block requests a peer is allowed to queue up in the client. If a peer sends more requests @@ -2189,9 +2191,16 @@ peer_connection will prefer requesting whole pieces at a time from this peer. The benefit of this is to better utilize disk caches by doing localized accesses and also to make it easier to identify bad peers if a piece fails the hash check.

    +

    peer_timeout is the number of seconds the peer connection should +wait (for any activity on the peer connection) before closing it due +to time out. This defaults to 120 seconds, since that's what's specified +in the protocol specification. After half the time out, a keep alive message +is sent.

    +

    urlseed_timeout is the same as peer_timeout but applies only to +url seeds. This value defaults to 20 seconds.

    -
    -

    ip_filter

    +
    +

    ip_filter

    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). @@ -2219,8 +2228,8 @@ public: }; -

    -

    ip_filter()

    +
    +

    ip_filter()

     ip_filter()
    @@ -2230,8 +2239,8 @@ ip_filter()
     

    postcondition: access(x) == 0 for every x

    -
    -

    add_rule()

    +
    +

    add_rule()

     void add_rule(address first, address last, int flags);
    @@ -2246,8 +2255,8 @@ means disallowed.

    This means that in a case of overlapping ranges, the last one applied takes precedence.

    -
    -

    access()

    +
    +

    access()

     int access(address const& addr) const;
    @@ -2258,8 +2267,8 @@ can currently be 0 or ip_filter::
     is O(log n), where n is the minimum number of non-overlapping ranges to describe
     the current filter.

    -
    -

    export_filter()

    +
    +

    export_filter()

     std::vector<ip_range> export_filter() const;
    @@ -2271,8 +2280,8 @@ entry in the returned vector is a range with the access control specified in its
     flags field.

    -
    -

    big_number

    +
    +

    big_number

    Both the peer_id and sha1_hash types are typedefs of the class big_number. It represents 20 bytes of data. Its synopsis follows:

    @@ -2292,8 +2301,8 @@ public:
     

    The iterators gives you access to individual bytes.

    -
    -

    hasher

    +
    +

    hasher

    This class creates sha1-hashes. Its declaration looks like this:

     class hasher
    @@ -2319,8 +2328,8 @@ call reset() to reini
     

    The sha1-algorithm used was implemented by Steve Reid and released as public domain. For more info, see src/sha1.cpp.

    -
    -

    fingerprint

    +
    +

    fingerprint

    The fingerprint class represents information about a client and its version. It is used to encode this information into the client's peer id.

    This is the class declaration:

    @@ -2382,10 +2391,10 @@ sure not to clash with anybody else. Here are some taken id's:

    version of your client. All these numbers must be within the range [0, 9].

    to_string() will generate the actual string put in the peer-id, and return it.

    -
    -

    free functions

    -
    -

    identify_client()

    +
    +

    free functions

    +
    +

    identify_client()

     std::string identify_client(peer_id const& id);
    @@ -2395,8 +2404,8 @@ std::string identify_client(peer_id const& id);
     to extract a string describing a client version from its peer-id. It will recognize most clients
     that have this kind of identification in the peer-id.

    -
    -

    client_fingerprint()

    +
    +

    client_fingerprint()

     boost::optional<fingerprint> client_fingerprint(peer_id const& p);
    @@ -2407,8 +2416,8 @@ to automate the identification of clients. It will not be able to identify peers
     standard encodings. Only Azureus style, Shadow's style and Mainline style. This function is
     declared in the header <libtorrent/identify_client.hpp>.

    -
    -

    bdecode() bencode()

    +
    +

    bdecode() bencode()

     template<class InIt> entry bdecode(InIt start, InIt end);
    @@ -2448,8 +2457,8 @@ entry e = bdecode(buf, buf + data_size);
     it will throw invalid_encoding.

    -
    -

    alerts

    +
    +

    alerts

    The pop_alert() function on session is the interface for retrieving alerts, warnings, messages and errors from libtorrent. If there hasn't occurred any errors (matching your severity level) pop_alert() will @@ -2530,8 +2539,8 @@ public: have a severity level that can be used to sort them or present them to the user in different ways.

    The specific alerts, that all derives from alert, are:

    -
    -

    listen_failed_alert

    +
    +

    listen_failed_alert

    This alert is generated when none of the ports, given in the port range, to session can be opened for listening. This alert is generated as severity level fatal.

    @@ -2543,8 +2552,8 @@ struct listen_failed_alert: alert };
    -
    -

    file_error_alert

    +
    +

    file_error_alert

    If the storage fails to read or write files that it needs access to, this alert is generated and the torrent is paused. It is generated as severity level fatal.

    @@ -2553,14 +2562,14 @@ struct file_error_alert: alert
             file_error_alert(
                     const torrent_handle& h
                     , const std::string& msg);
    -
    +                
             virtual std::auto_ptr<alert> clone() const;
             torrent_handle handle;
     };
     
    -
    -

    tracker_announce_alert

    +
    +

    tracker_announce_alert

    This alert is generated each time a tracker announce is sent (or attempted to be sent). It is generated at severity level info.

    @@ -2569,14 +2578,14 @@ struct tracker_announce_alert: alert
             tracker_announce_alert(
                     const torrent_handle& h
                     , const std::string& msg);
    -
    +                
             virtual std::auto_ptr<alert> clone() const;
             torrent_handle handle;
     };
     
    -
    -

    tracker_alert

    +
    +

    tracker_alert

    This alert is generated on tracker time outs, premature disconnects, invalid response or a HTTP response other than "200 OK". From the alert you can get the handle to the torrent the tracker belongs to. This alert is generated as severity level warning.

    @@ -2597,8 +2606,8 @@ struct tracker_alert: alert };
    -
    -

    tracker_reply_alert

    +
    +

    tracker_reply_alert

    This alert is only for informational purpose. It is generated when a tracker announce succeeds. It is generated with severity level info.

    @@ -2612,8 +2621,8 @@ struct tracker_reply_alert: alert
     };
     
    -
    -

    tracker_warning_alert

    +
    +

    tracker_warning_alert

    This alert is triggered if the tracker reply contains a warning field. Usually this means that the tracker announce was successful, but the tracker has a message to the client. The message string in the alert will contain the warning message from @@ -2629,8 +2638,8 @@ struct tracker_warning_alert: alert };

    -
    -

    url_seed_alert

    +
    +

    url_seed_alert

    This alert is generated when a HTTP seed name lookup fails. This alert is generated as severity level warning.

    It contains url to the HTTP seed that failed along with an error message.

    @@ -2644,8 +2653,8 @@ struct url_seed_alert: alert };
    -
    -

    hash_failed_alert

    +
    +

    hash_failed_alert

    This alert is generated when a finished piece fails its hash check. You can get the handle to the torrent which got the failed piece and the index of the piece itself from the alert. This alert is generated as severity level info.

    @@ -2663,8 +2672,8 @@ struct hash_failed_alert: alert };
    -
    -

    peer_ban_alert

    +
    +

    peer_ban_alert

    This alert is generated when a peer is banned because it has sent too many corrupt pieces to us. It is generated at severity level info. The handle member is a torrent_handle to the torrent that this peer was a member of.

    @@ -2682,8 +2691,8 @@ struct peer_ban_alert: alert };
    -
    -

    peer_error_alert

    +
    +

    peer_error_alert

    This alert is generated when a peer sends invalid data over the peer-peer protocol. The peer will be disconnected, but you get its ip address from the alert, to identify it. This alert is generated as severity level debug.

    @@ -2701,10 +2710,10 @@ struct peer_error_alert: alert };
    -
    -

    invalid_request_alert

    +
    +

    invalid_request_alert

    This is a debug alert that is generated by an incoming invalid piece request. The handle -is a handle to the torrent the peer is a member of. ìp is the address of the peer and the +is a handle to the torrent the peer is a member of. Ïp is the address of the peer and the request is the actual incoming request from the peer. The alert is generated as severity level debug.

    @@ -2737,8 +2746,8 @@ struct peer_request
     the index of the piece it want data from, start is the offset within the piece where the data
     should be read, and length is the amount of data it wants.

    -
    -

    torrent_finished_alert

    +
    +

    torrent_finished_alert

    This alert is generated when a torrent switches from being a downloader to a seed. It will only be generated once per torrent. It contains a torrent_handle to the torrent in question. This alert is generated as severity level info.

    @@ -2754,8 +2763,8 @@ struct torrent_finished_alert: alert };
    -
    -

    metadata_failed_alert

    +
    +

    metadata_failed_alert

    This alert is generated when the metadata has been completely received and the info-hash failed to match it. i.e. the metadata that was received was corrupt. libtorrent will automatically retry to fetch it in this case. This is only relevant when running a @@ -2767,14 +2776,14 @@ struct metadata_received_alert: alert metadata_received_alert( const torrent_handle& h , const std::string& msg); - + virtual std::auto_ptr<alert> clone() const; torrent_handle handle; };

    -
    -

    metadata_received_alert

    +
    +

    metadata_received_alert

    This alert is generated when the metadata has been completely received and the torrent can start downloading. It is not generated on torrents that are started with metadata, but only those that needs to download it from peers (when utilizing the libtorrent extension). @@ -2785,14 +2794,14 @@ struct metadata_received_alert: alert metadata_received_alert( const torrent_handle& h , const std::string& msg); - + virtual std::auto_ptr<alert> clone() const; torrent_handle handle; };

    -
    -

    fastresume_rejected_alert

    +
    +

    fastresume_rejected_alert

    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 string explains the reason why the resume file was rejected. It is generated at severity level warning.

    @@ -2830,17 +2839,17 @@ of the sending peer. address ip; }; -->
    -
    -

    dispatcher

    +
    +

    dispatcher

    TODO: describe the dispatcher mechanism

    -
    -

    exceptions

    +
    +

    exceptions

    There are a number of exceptions that can be thrown from different places in libtorrent, here's a complete list with description.

    -
    -

    invalid_handle

    +
    +

    invalid_handle

    This exception is thrown when querying information from a torrent_handle that hasn't been initialized or that has become invalid.

    @@ -2850,8 +2859,8 @@ struct invalid_handle: std::exception
     };
     
    -
    -

    duplicate_torrent

    +
    +

    duplicate_torrent

    This is thrown by add_torrent() if the torrent already has been added to the session.

    @@ -2861,8 +2870,8 @@ struct duplicate_torrent: std::exception
     };
     
    -
    -

    invalid_encoding

    +
    +

    invalid_encoding

    This is thrown by bdecode() if the input data is not a valid bencoding.

     struct invalid_encoding: std::exception
    @@ -2871,8 +2880,8 @@ struct invalid_encoding: std::exception
     };
     
    -
    -

    type_error

    +
    +

    type_error

    This is thrown from the accessors of entry if the data type of the entry doesn't match the type you want to extract from it.

    @@ -2882,8 +2891,8 @@ struct type_error: std::runtime_error
     };
     
    -
    -

    invalid_torrent_file

    +
    +

    invalid_torrent_file

    This exception is thrown from the constructor of torrent_info if the given bencoded information doesn't meet the requirements on what information has to be present in a torrent file.

    @@ -2894,13 +2903,13 @@ struct invalid_torrent_file: std::exception
     
    -
    -

    examples

    +
    +

    examples

    Except for the example programs in this manual, there's also a bigger example of a (little bit) more complete client, client_test. There are separate instructions for how to use it here if you'd like to try it.

    -
    -

    dump_torrent

    +
    +

    dump_torrent

    This is an example of a program that will take a torrent-file as a parameter and print information about it to std out:

    @@ -2956,7 +2965,7 @@ int main(int argc, char* argv[])
                             std::cout << "  " << std::setw(11) << i->size
                                     << " " << i->path.string() << "\n";
                     }
    -
    +                
             }
             catch (std::exception& e)
             {
    @@ -2967,8 +2976,8 @@ int main(int argc, char* argv[])
     }
     
    -
    -

    simple client

    +
    +

    simple client

    This is a simple client. It doesn't have much output to keep it simple:

     #include <iostream>
    @@ -3004,7 +3013,7 @@ int main(int argc, char* argv[])
                     entry e = bdecode(std::istream_iterator<char>(in)
                             , std::istream_iterator<char>());
                     s.add_torrent(torrent_info(e), "");
    -
    +                        
                     // wait for the user to end
                     char a;
                     std::cin.unsetf(std::ios_base::skipws);
    @@ -3018,8 +3027,8 @@ int main(int argc, char* argv[])
     }
     
    -
    -

    make_torrent

    +
    +

    make_torrent

    Shows how to create a torrent from a directory tree:

     #include <iostream>
    @@ -3115,8 +3124,8 @@ int main(int argc, char* argv[])
     
    -
    -

    fast resume

    +
    +

    fast resume

    The fast resume mechanism is a way to remember which pieces are downloaded and where they are put between sessions. You can generate fast resume data by calling torrent_handle::write_resume_data() on torrent_handle. You can @@ -3129,8 +3138,8 @@ start from scratch on the partially downloaded pieces.

    will skip the time consuming checks. It may have to do the checking anyway, if the fast-resume data is corrupt or doesn't fit the storage for that torrent, then it will not trust the fast-resume data and just do the checking.

    -
    -

    file format

    +
    +

    file format

    The file format is a bencoded dictionary containing the following fields:

    @@ -3225,8 +3234,8 @@ re-check is issued.
    -
    -

    threads

    +
    +

    threads

    libtorrent starts 2 or 3 threads.

      @@ -3244,8 +3253,8 @@ non-blocking host name resolution to simulate non-blocking behavior.
    -
    -

    storage allocation

    +
    +

    storage allocation

    There are two modes in which storage (files on disk) are allocated in libtorrent.

      @@ -3258,8 +3267,8 @@ pieces that have been downloaded. This is the default allocation mode in libtorr

      The allocation mode is selected when a torrent is started. It is passed as a boolean argument to session::add_torrent() (see add_torrent()). These two modes have different drawbacks and benefits.

      -
      -

      full allocation

      +
      +

      full allocation

      When a torrent is started in full allocation mode, the checker thread (see threads) will make sure that the entire storage is allocated, and fill any gaps with zeros. It will of course still check for existing pieces and fast resume data. The main @@ -3283,8 +3292,8 @@ filesystems' file allocation, and reduce fragmentation.

    -
    -

    compact allocation

    +
    +

    compact allocation

    The compact allocation will only allocate as much storage as it needs to keep the pieces downloaded so far. This means that pieces will be moved around to be placed at their final position in the files while downloading (to make sure the completed @@ -3330,8 +3339,8 @@ contain any piece), return that slot index.

    -
    -

    extensions

    +
    +

    extensions

    These extensions all operates within the extension protocol. The name of the extension is the name used in the extension-list packets, and the payload is the data in the extended message (not counting the @@ -3340,8 +3349,8 @@ length-prefix, message-id nor extension-id).

    handshake, it may be incompatible with future versions of the mainline bittorrent client.

    These are the extensions that are currently implemented.

    -
    -

    chat messages

    +
    +

    chat messages

    Extension name: "chat"

    The payload in the packet is a bencoded dictionary with any combination of the following entries:

    @@ -3368,8 +3377,8 @@ Any unrecognized strings should be ignored.
    -
    -

    metadata from peers

    +
    +

    metadata from peers

    Extension name: "metadata"

    The point with this extension is that you don't have to distribute the metadata (.torrent-file) separately. The metadata can be distributed @@ -3493,8 +3502,8 @@ doesn't have any metadata.

    -
    -

    HTTP seeding

    +
    +

    HTTP seeding

    The HTTP seed extension implements this specification.

    The libtorrent implementation assumes that, if the URL ends with a slash ('/'), the filename should be appended to it in order to request pieces from @@ -3504,8 +3513,8 @@ torrent's name '/' the file name is appended. This is the same directory structure that libtorrent will download torrents into.

    -
    -

    filename checks

    +
    +

    filename checks

    Boost.Filesystem will by default check all its paths to make sure they conform to filename requirements on many platforms. If you don't want this check, you can set it to either only check for native filesystem requirements or turn it off @@ -3515,15 +3524,15 @@ boost::filesystem::path::default_name_check(boost::filesystem::native);

    for example. For more information, see the Boost.Filesystem docs.

    -
    -

    acknowledgments

    +
    +

    acknowledgments

    Written by Arvid Norberg. Copyright © 2003-2005

    Contributions by Magnus Jonsson, Daniel Wallin and Cory Nelson

    Lots of testing, suggestions and contributions by Massaroddel and Tianhao Qiu.

    Big thanks to Michael Wojciechowski and Peter Koeleman for making the autotools scripts.

    Thanks to Reimond Retz for bugfixes, suggestions and testing

    -

    Thanks to University of Umeå for providing development and test hardware.

    +

    Thanks to University of Ume for providing development and test hardware.

    Project is hosted by sourceforge.

    sf_logo

    diff --git a/docs/manual.rst b/docs/manual.rst index db8b9ab26..01cb99fac 100755 --- a/docs/manual.rst +++ b/docs/manual.rst @@ -2136,6 +2136,8 @@ that will be sent to the tracker. The user-agent is a good way to identify your int max_allowed_in_request_queue; int max_out_request_queue; int whole_pieces_threshold; + int peer_timeout; + int urlseed_timeout; }; ``proxy_ip`` may be a hostname or ip to a http proxy to use. If this is @@ -2184,7 +2186,7 @@ actual number of requests depends on the download rate and this number. (popular == inverse of rarity) to be downloaded in sequence instead of in random (rarest first) order. It can be used to tweak disk performance in settings where the random download property is less necessary. For example, if -the threshold is 7, all pieces which 7 or more peers have, will be downloaded +the threshold is 10, all pieces which 10 or more peers have, will be downloaded in index order. ``max_allowed_in_request_queue`` is the number of outstanding block requests @@ -2205,6 +2207,15 @@ The benefit of this is to better utilize disk caches by doing localized accesses and also to make it easier to identify bad peers if a piece fails the hash check. +``peer_timeout`` is the number of seconds the peer connection should +wait (for any activity on the peer connection) before closing it due +to time out. This defaults to 120 seconds, since that's what's specified +in the protocol specification. After half the time out, a keep alive message +is sent. + +``urlseed_timeout`` is the same as ``peer_timeout`` but applies only to +url seeds. This value defaults to 20 seconds. + ip_filter ========= diff --git a/docs/projects.rst b/docs/projects.rst index 105b61890..6752738a6 100644 --- a/docs/projects.rst +++ b/docs/projects.rst @@ -34,6 +34,14 @@ MooPolice_ is a windows bittorrent client with a quite unique look. .. _MooPolice: http://www.massaroddel.de/MooPolice/ +**BitSlug** + +.. image:: bitslug_thumb.png + +BitSlug_ is a MacOSX cocoa client. + +.. _BitSlug: http://bitslug.sourceforge.net/ + **BitBuddy** .. image:: bitbuddy_thumb.jpg diff --git a/examples/client_test.cpp b/examples/client_test.cpp index a7d678452..0cc282994 100755 --- a/examples/client_test.cpp +++ b/examples/client_test.cpp @@ -39,10 +39,10 @@ POSSIBILITY OF SUCH DAMAGE. #pragma warning(push, 1) #endif -#include +#include #include #include -#include +#include #include #include #include diff --git a/include/libtorrent/peer_connection.hpp b/include/libtorrent/peer_connection.hpp index 3e58a475f..990b8c5d0 100755 --- a/include/libtorrent/peer_connection.hpp +++ b/include/libtorrent/peer_connection.hpp @@ -369,6 +369,8 @@ namespace libtorrent // or if the extended handshake sets a limit. int m_max_out_request_queue; + void set_timeout(int s) { m_timeout = s; } + private: void fill_send_buffer(); diff --git a/include/libtorrent/peer_id.hpp b/include/libtorrent/peer_id.hpp index 3cdfcdc83..d3bf624b7 100755 --- a/include/libtorrent/peer_id.hpp +++ b/include/libtorrent/peer_id.hpp @@ -80,13 +80,35 @@ namespace libtorrent bool operator<(big_number const& n) const { - for(int i = 0; i < number_size; ++i) + 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 false; } 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) + { + 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) { assert(i >= 0 && i < number_size); return m_number[i]; } diff --git a/include/libtorrent/session_settings.hpp b/include/libtorrent/session_settings.hpp index bd5418785..18ee3a7a7 100644 --- a/include/libtorrent/session_settings.hpp +++ b/include/libtorrent/session_settings.hpp @@ -50,10 +50,12 @@ namespace libtorrent , tracker_maximum_response_length(1024*1024) , piece_timeout(120) , request_queue_time(3.f) - , sequenced_download_threshold(7) + , sequenced_download_threshold(10) , max_allowed_in_request_queue(250) , max_out_request_queue(200) , whole_pieces_threshold(20) + , peer_timeout(120) + , urlseed_timeout(20) {} std::string proxy_ip; @@ -124,6 +126,16 @@ namespace libtorrent // doing localized accesses and also to make it easier // to identify bad peers if a piece fails the hash check. int whole_pieces_threshold; + + // the number of seconds to wait for any activity on + // the peer wire before closing the connectiong due + // to time out. + int peer_timeout; + + // same as peer_timeout, but only applies to url-seeds. + // this is usually set lower, because web servers are + // expected to be more reliable. + int urlseed_timeout; }; } diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp index 1800f62b8..1fb6407cc 100755 --- a/src/peer_connection.cpp +++ b/src/peer_connection.cpp @@ -82,7 +82,7 @@ namespace libtorrent #endif m_ses(ses) , m_max_out_request_queue(m_ses.m_settings.max_out_request_queue) - , m_timeout(120) + , m_timeout(m_ses.m_settings.peer_timeout) , m_last_piece(second_clock::universal_time()) , m_packet_size(0) , m_recv_pos(0) @@ -173,7 +173,7 @@ namespace libtorrent #endif m_ses(ses) , m_max_out_request_queue(m_ses.m_settings.max_out_request_queue) - , m_timeout(120) + , m_timeout(m_ses.m_settings.peer_timeout) , m_last_piece(second_clock::universal_time()) , m_packet_size(0) , m_recv_pos(0) @@ -1961,7 +1961,7 @@ namespace libtorrent bool peer_connection::has_timed_out() const { - // TODO: the timeout should be set by an event rather + // TODO: the timeout should be called by an event INVARIANT_CHECK; using namespace boost::posix_time; diff --git a/src/torrent.cpp b/src/torrent.cpp index f20ac44ae..2f0f7eeac 100755 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -947,6 +947,11 @@ namespace libtorrent { INVARIANT_CHECK; +#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) + std::string now(to_simple_string(second_clock::universal_time())); + (*m_ses.m_logger) << now << " resolving: " << url << "\n"; +#endif + std::string protocol; std::string hostname; int port; @@ -967,6 +972,11 @@ namespace libtorrent detail::session_impl::mutex_t::scoped_lock l(m_ses.m_mutex); INVARIANT_CHECK; + +#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) + std::string now(to_simple_string(second_clock::universal_time())); + (*m_ses.m_logger) << now << " completed resolve: " << url << "\n"; +#endif std::set::iterator i = m_resolving_web_seeds.find(url); if (i != m_resolving_web_seeds.end()) m_resolving_web_seeds.erase(i); @@ -980,6 +990,9 @@ namespace libtorrent m_ses.m_alerts.post_alert( url_seed_alert(url, msg.str())); } +#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) + (*m_ses.m_logger) << " ** HOSTNAME LOOKUP FAILED!**: " << url << "\n"; +#endif // the name lookup failed for the http host. Don't try // this host again @@ -1019,6 +1032,10 @@ namespace libtorrent } catch (std::exception& e) { +#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) + (*m_ses.m_logger) << " ** HOSTNAME LOOKUP FAILED!**: " << e.what() << "\n"; +#endif + // TODO: post an error alert! std::map::iterator i = m_connections.find(a); if (i != m_connections.end()) m_connections.erase(i); diff --git a/src/web_peer_connection.cpp b/src/web_peer_connection.cpp index 746007d8d..43a9f70bf 100755 --- a/src/web_peer_connection.cpp +++ b/src/web_peer_connection.cpp @@ -66,6 +66,9 @@ namespace libtorrent { INVARIANT_CHECK; + // since this is a web seed, change the timeout + // according to the settings. + set_timeout(ses.m_settings.urlseed_timeout); #ifdef TORRENT_VERBOSE_LOGGING (*m_logger) << "*** web_peer_connection\n"; #endif