diff --git a/docs/index.html b/docs/index.html index 4877cf037..44f7bb3c4 100755 --- a/docs/index.html +++ b/docs/index.html @@ -59,8 +59,8 @@ example client.

Aknowledgements

-

Written by Arvid Norberg and Daniel Wallin. Copyright (c) 2003

-

Contributions by Magnus Jonsson

+

Written by Arvid Norberg. Copyright (c) 2003

+

Contributions by Magnus Jonsson and Daniel Wallin

Thanks to Reimond Retz for bugfixes, suggestions and testing

Project is hosted by sourceforge.

sf_logo

diff --git a/docs/index.rst b/docs/index.rst index ac6d8f27a..1de2da43b 100755 --- a/docs/index.rst +++ b/docs/index.rst @@ -60,9 +60,9 @@ You can usually find me as hydri in ``#btports @ irc.freenode.net``. Aknowledgements =============== -Written by Arvid Norberg and Daniel Wallin. Copyright (c) 2003 +Written by Arvid Norberg. Copyright (c) 2003 -Contributions by Magnus Jonsson +Contributions by Magnus Jonsson and Daniel Wallin Thanks to Reimond Retz for bugfixes, suggestions and testing diff --git a/docs/manual.html b/docs/manual.html index 4ed7e59bc..ab70e0ca5 100755 --- a/docs/manual.html +++ b/docs/manual.html @@ -13,57 +13,57 @@

Contents

@@ -103,6 +103,7 @@ peers in a separate fast-resume file.
  • Supports the extension protocol described by Nolar. See extensions.
  • Supports files > 2 gigabytes (currently only on windows).
  • Supports the no_peer_id=1 extension that will ease the load off trackers.
  • +
  • Supports the udp-tracker protocol.
  • Functions that are yet to be implemented:

    @@ -223,7 +224,7 @@ The main thread will be idle as long it doesn't have any torrents to participate You add torrents through the add_torrent()-function where you give an object representing the information found in the torrent file and the path where you want to save the files. The save_path will be prepended to the directory- -structure in the torrent-file. add_torrent will throw duplicate_torrent exception +structure in the torrent-file. add_torrent will throw duplicate_torrent exception if the torrent already exists in the session.

    The optional last parameter, resume_data can be given if up to date fast-resume data is available. The fast-resume data can be acquired from a running torrent by calling @@ -232,7 +233,7 @@ is available. The fast-resume data can be acquired from a running torrent by cal the tracker that we've stopped participating in the swarm.

    If the torrent you are trying to add already exists in the session (is either queued for checking, being checked or downloading) add_torrent() will throw -duplicate_torrent which derives from std::exception.

    +duplicate_torrent which derives from std::exception.

    The difference between the two constructors is that one of them takes a fingerprint as argument. If this is ommited, the client will get a default fingerprint stating the version of libtorrent. The fingerprint is a short string that will be used in @@ -246,7 +247,6 @@ If some trackers are down, they will timout. All this before the destructor of s returns. So, it's adviced that any kind of interface (such as windows) are closed before destructing the sessoin object. Because it can take a few second for it to finish. The timeout can be set with set_http_settings().

    -

    How to parse a torrent file and create a torrent_info object is described below.

    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.

    The constructor takes a listen port as argument, if the given port is busy it will @@ -486,6 +486,7 @@ struct torrent_handle boost::filsystem::path save_path() const; void set_max_uploads(int max_uploads); + void set_max_connections(int max_connections); sha1_hash info_hash() const; @@ -517,6 +518,10 @@ as a standard client.

    info_hash() returns the info hash for the torrent.

    set_max_uploads() sets the maximum number of peers that's unchoked at the same time on this torrent. If you set this to -1, there will be no limit.

    +

    set_max_connections() sets the maximum number of connection this torrent will open. If all +connections are used up, incoming connections may be refused or poor connections may be closed. +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() generates fast-resume data and returns it as an entry. This entry is suitable for being bencoded. For more information about how fast-resume works, see fast resume. It may throw invalid_handle if the torrent handle is invalid.

    @@ -752,7 +757,7 @@ the total number of bytes in this block.

    get_torrent_info()

    -

    Returns a const reference to the torrent_info object associated with this torrent. +

    Returns a const reference to the torrent_info object associated with this torrent. This reference is valid as long as the torrent_handle is valid, no longer. If the torrent_handle is invalid, invalid_handle exception will be thrown.

    @@ -1440,8 +1445,8 @@ with future versions of bittorrent.

    Aknowledgements

    -

    Written by Arvid Norberg and Daniel Wallin. Copyright (c) 2003

    -

    Contributions by Magnus Jonsson

    +

    Written by Arvid Norberg. Copyright (c) 2003

    +

    Contributions by Magnus Jonsson and Daniel Wallin

    Thanks to Reimond Retz for bugfixes, suggestions and testing

    Project is hosted by sourceforge.

    sf_logo

    diff --git a/docs/manual.rst b/docs/manual.rst index 8c5143a45..ec6ff858b 100755 --- a/docs/manual.rst +++ b/docs/manual.rst @@ -40,10 +40,13 @@ The current state includes the following features: * Supports the extension protocol `described by Nolar`__. See extensions_. * Supports files > 2 gigabytes (currently only on windows). * Supports the ``no_peer_id=1`` extension that will ease the load off trackers. + * Supports the `udp-tracker protocol`__. __ http://home.elp.rr.com/tur/multitracker-spec.txt .. _Azureus: http://azureus.sourceforge.net __ http://nolar.com/azureus/extended.htm +__ udp_tracker_protocol.html + Functions that are yet to be implemented: @@ -171,7 +174,7 @@ The main thread will be idle as long it doesn't have any torrents to participate You add torrents through the ``add_torrent()``-function where you give an object representing the information found in the torrent file and the path where you want to save the files. The ``save_path`` will be prepended to the directory- -structure in the torrent-file. ``add_torrent`` will throw ``duplicate_torrent`` exception +structure in the torrent-file. ``add_torrent`` will throw duplicate_torrent_ exception if the torrent already exists in the session. The optional last parameter, ``resume_data`` can be given if up to date fast-resume data @@ -183,7 +186,7 @@ the tracker that we've stopped participating in the swarm. If the torrent you are trying to add already exists in the session (is either queued for checking, being checked or downloading) ``add_torrent()`` will throw -``duplicate_torrent`` which derives from ``std::exception``. +duplicate_torrent_ which derives from ``std::exception``. The difference between the two constructors is that one of them takes a fingerprint as argument. If this is ommited, the client will get a default fingerprint stating @@ -201,8 +204,6 @@ returns. So, it's adviced that any kind of interface (such as windows) are close destructing the sessoin object. Because it can take a few second for it to finish. The timeout can be set with ``set_http_settings()``. -How to parse a torrent file and create a ``torrent_info`` object is described below. - 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. @@ -487,6 +488,7 @@ Its declaration looks like this:: boost::filsystem::path save_path() const; void set_max_uploads(int max_uploads); + void set_max_connections(int max_connections); sha1_hash info_hash() const; @@ -526,6 +528,11 @@ as a standard client. ``set_max_uploads()`` sets the maximum number of peers that's unchoked at the same time on this torrent. If you set this to -1, there will be no limit. +``set_max_connections()`` sets the maximum number of connection this torrent will open. If all +connections are used up, incoming connections may be refused or poor connections may be closed. +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()`` generates fast-resume data and returns it as an entry. This entry is suitable for being bencoded. For more information about how fast-resume works, see `fast resume`_. It may throw invalid_handle_ if the torrent handle is invalid. @@ -772,7 +779,7 @@ the total number of bytes in this block. get_torrent_info() ------------------ -Returns a const reference to the ``torrent_info`` object associated with this torrent. +Returns a const reference to the torrent_info_ object associated with this torrent. This reference is valid as long as the torrent_handle_ is valid, no longer. If the torrent_handle_ is invalid, invalid_handle_ exception will be thrown. @@ -1514,9 +1521,9 @@ with future versions of bittorrent. Aknowledgements =============== -Written by Arvid Norberg and Daniel Wallin. Copyright (c) 2003 +Written by Arvid Norberg. Copyright (c) 2003 -Contributions by Magnus Jonsson +Contributions by Magnus Jonsson and Daniel Wallin Thanks to Reimond Retz for bugfixes, suggestions and testing diff --git a/docs/udp_tracker_protocol.html b/docs/udp_tracker_protocol.html new file mode 100644 index 000000000..921f5f490 --- /dev/null +++ b/docs/udp_tracker_protocol.html @@ -0,0 +1,381 @@ + + + + + + +Bittorrent udp-tracker protocol extension + + + +
    +

    Bittorrent udp-tracker protocol extension

    +

    A tracker with the protocol "udp://" in its URI +is supposed to be contacted using this protocol.

    +

    This protocol is supported by +xbt-tracker.

    +

    For additional information and descritptions of +the terminology used in this document, see +the protocol specification

    +

    All values are sent in network byte order (big endian). The sizes +are specified with ANSI-C standard types.

    +

    If no response to a request is received within 15 seconds, resend +the request. If no reply has been received after 60 seconds, stop +retrying.

    +
    +

    connecting

    +

    Client sends packet:

    + +++++ + + + + + + + + + + + + + + + + + + + + +
    sizenamedescription
    int64_tconnection_idNot used, ignored by tracker.
    int32_taction0 for a connection request
    int32_ttransaction_idRandomized by client.
    +

    Server replies with packet:

    + +++++ + + + + + + + + + + + + + + + + + + + + +
    sizenamedescription
    int32_tactionDescribes the type of packet, in this +case it should be 0, for connect. +If 3 (for error) see errors.
    int32_ttransaction_idMust match the transaction_id sent +from the client.
    int64_tconnection_idA connection id, this is used when +further information is exchanged with +the tracker, to identify you. +This connection id can be reused for +multiple requests, but if it's cached +for too long, it will not be valid +anymore.
    +
    +
    +

    announcing

    +

    Client sends packet:

    + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    sizenamedescription
    int64_tconnection_idThe connection id acquired from +establishing the connection.
    int32_tactionAction. in this case, 1 for announce.
    int32_ttransaction_idRandomized by client.
    int8_t[20]info_hashThe info-hash of the torrent you want +announce yourself in.
    int8_t[20]peer_idYour peer id.
    int64_tdownloadedThe number of byte you've downloaded +in this session.
    int64_tleftThe number of bytes you have left to +download until you're finished.
    int64_tuploadedThe number of bytes you have uploaded +in this session.
    int32_tevent

    The event, one of

    +
    +
      +
    • none = 0
    • +
    • completed = 1
    • +
    • started = 2
    • +
    • stopped = 3
    • +
    +
    +
    uint32_tipYour ip address. Set to 0 if you want +the tracker to use the sender of +this udp packet.
    int32_tnum_wantThe maximum number of peers you want +in the reply. Use -1 for default.
    uint16_tportThe port you're listening on.
    +

    Server replies with packet:

    + +++++ + + + + + + + + + + + + + + + + + + + + +
    sizenamedescription
    int32_tactionThe action this is a reply to. Should +in this case be 1 for announce. +If 3 (for error) see errors.
    int32_ttransaction_idMust match the transaction_id sent +in the announce request.
    int32_tintervalthe number of seconds you should wait +until reannouncing yourself.
    +

    The rest of the server reply is a variable number of the following structure:

    + +++++ + + + + + + + + + + + + + + + + +
    sizenamedescription
    int32_tipThe ip of a peer in the swarm.
    uint16_tportThe peers listen port.
    +
    +
    +

    scraping

    +

    Client sends packet:

    + +++++ + + + + + + + + + + + + + + + + + + + + + + + + +
    sizenamedescription
    int64_tconnection_idThe connection id retreived from the +establishing of the connection.
    int32_tactionThe action, in this case, 2 for +scrape.
    int32_ttransaction_idRandomized by client.
    int8[20]info_hashThe info hash that is to be scraped.
    +

    Server replies with packet:

    + +++++ + + + + + + + + + + + + + + + + +
    sizenamedescription
    int32_tactionThe action, should in this case be +2 for scrape. +If 3 (for error) see errors.
    int32_ttransaction_idMust match the sent transaction id.
    +

    The rest of the packet contains a variable number of the following structures:

    + +++++ + + + + + + + + + + + + + + + + + + + + + + + + +
    sizenamedescription
    int8_t[20]info_hashThe info hash of this info.
    int32_tcompleteThe total number of completed +downloads.
    int32_tdownloadedThe current number of connected seeds.
    int32_tincompleteThe current number of connected +leechers.
    +
    +
    +

    errors

    +

    In case of a tracker error, the server replies with this packet:

    + +++++ + + + + + + + + + + + + + + + + + + + + +
    sizenamedescription
    int32_tactionThe action, in this case 3, for error.
    int32_ttransaction_idMust match the transaction_id sent +from the client.
    int8[]error_stringThe rest of the packet is a string +describing the error.
    +
    +
    +

    actions

    +

    The action fields has the followinf encoding:

    +
    +
      +
    • connect = 0
    • +
    • announce = 1
    • +
    • scrape = 2
    • +
    • error = 3 (only in server replies)
    • +
    +
    +
    +
    +

    credits

    +

    Protocol designed by Olaf van der Spek

    +
    +
    + + diff --git a/docs/udp_tracker_protocol.rst b/docs/udp_tracker_protocol.rst new file mode 100755 index 000000000..a49c60be3 --- /dev/null +++ b/docs/udp_tracker_protocol.rst @@ -0,0 +1,218 @@ +========================================= +Bittorrent udp-tracker protocol extension +========================================= + +A tracker with the protocol "udp://" in its URI +is supposed to be contacted using this protocol. + +This protocol is supported by +xbt-tracker_. + + +.. _xbt-tracker: http://xbtt.sourceforge.net + +For additional information and descritptions of +the terminology used in this document, see +the `protocol specification`__ + +__ http://wiki.theory.org/index.php/BitTorrentSpecification + +All values are sent in network byte order (big endian). The sizes +are specified with ANSI-C standard types. + +If no response to a request is received within 15 seconds, resend +the request. If no reply has been received after 60 seconds, stop +retrying. + + +connecting +---------- + +Client sends packet: + ++-------------+---------------------+----------------------------------------+ +| size | name | description | ++=============+=====================+========================================+ +| int64_t | connection_id | Not used, ignored by tracker. | ++-------------+---------------------+----------------------------------------+ +| int32_t | action | 0 for a connection request | ++-------------+---------------------+----------------------------------------+ +| int32_t | transaction_id | Randomized by client. | ++-------------+---------------------+----------------------------------------+ + +Server replies with packet: + ++-------------+---------------------+----------------------------------------+ +| size | name | description | ++=============+=====================+========================================+ +| int32_t | action | Describes the type of packet, in this | +| | | case it should be 0, for connect. | +| | | If 3 (for error) see errors_. | ++-------------+---------------------+----------------------------------------+ +| int32_t | transaction_id | Must match the transaction_id sent | +| | | from the client. | ++-------------+---------------------+----------------------------------------+ +| int64_t | connection_id | A connection id, this is used when | +| | | further information is exchanged with | +| | | the tracker, to identify you. | +| | | This connection id can be reused for | +| | | multiple requests, but if it's cached | +| | | for too long, it will not be valid | +| | | anymore. | ++-------------+---------------------+----------------------------------------+ + + +announcing +---------- + +Client sends packet: + ++-------------+---------------------+----------------------------------------+ +| size | name | description | ++=============+=====================+========================================+ +| int64_t | connection_id | The connection id acquired from | +| | | establishing the connection. | ++-------------+---------------------+----------------------------------------+ +| int32_t | action | Action. in this case, 1 for announce. | ++-------------+---------------------+----------------------------------------+ +| int32_t | transaction_id | Randomized by client. | ++-------------+---------------------+----------------------------------------+ +| int8_t[20] | info_hash | The info-hash of the torrent you want | +| | | announce yourself in. | ++-------------+---------------------+----------------------------------------+ +| int8_t[20] | peer_id | Your peer id. | ++-------------+---------------------+----------------------------------------+ +| int64_t | downloaded | The number of byte you've downloaded | +| | | in this session. | ++-------------+---------------------+----------------------------------------+ +| int64_t | left | The number of bytes you have left to | +| | | download until you're finished. | ++-------------+---------------------+----------------------------------------+ +| int64_t | uploaded | The number of bytes you have uploaded | +| | | in this session. | ++-------------+---------------------+----------------------------------------+ +| int32_t | event | The event, one of | +| | | | +| | | * none = 0 | +| | | * completed = 1 | +| | | * started = 2 | +| | | * stopped = 3 | ++-------------+---------------------+----------------------------------------+ +| uint32_t | ip | Your ip address. Set to 0 if you want | +| | | the tracker to use the ``sender`` of | +| | | this udp packet. | ++-------------+---------------------+----------------------------------------+ +| int32_t | num_want | The maximum number of peers you want | +| | | in the reply. Use -1 for default. | ++-------------+---------------------+----------------------------------------+ +| uint16_t | port | The port you're listening on. | ++-------------+---------------------+----------------------------------------+ + +Server replies with packet: + ++-------------+---------------------+----------------------------------------+ +| size | name | description | ++=============+=====================+========================================+ +| int32_t | action | The action this is a reply to. Should | +| | | in this case be 1 for announce. | +| | | If 3 (for error) see errors_. | ++-------------+---------------------+----------------------------------------+ +| int32_t | transaction_id | Must match the transaction_id sent | +| | | in the announce request. | ++-------------+---------------------+----------------------------------------+ +| int32_t | interval | the number of seconds you should wait | +| | | until reannouncing yourself. | ++-------------+---------------------+----------------------------------------+ + +The rest of the server reply is a variable number of the following structure: + ++-------------+---------------------+----------------------------------------+ +| size | name | description | ++=============+=====================+========================================+ +| int32_t | ip | The ip of a peer in the swarm. | ++-------------+---------------------+----------------------------------------+ +| uint16_t | port | The peers listen port. | ++-------------+---------------------+----------------------------------------+ + + +scraping +-------- + +Client sends packet: + ++-------------+---------------------+----------------------------------------+ +| size | name | description | ++=============+=====================+========================================+ +| int64_t | connection_id | The connection id retreived from the | +| | | establishing of the connection. | ++-------------+---------------------+----------------------------------------+ +| int32_t | action | The action, in this case, 2 for | +| | | scrape. | ++-------------+---------------------+----------------------------------------+ +| int32_t | transaction_id | Randomized by client. | ++-------------+---------------------+----------------------------------------+ +| int8[20] | info_hash | The info hash that is to be scraped. | ++-------------+---------------------+----------------------------------------+ + +Server replies with packet: + ++-------------+---------------------+----------------------------------------+ +| size | name | description | ++=============+=====================+========================================+ +| int32_t | action | The action, should in this case be | +| | | 2 for scrape. | +| | | If 3 (for error) see errors_. | ++-------------+---------------------+----------------------------------------+ +| int32_t | transaction_id | Must match the sent transaction id. | ++-------------+---------------------+----------------------------------------+ + +The rest of the packet contains a variable number of the following structures: + ++-------------+---------------------+----------------------------------------+ +| size | name | description | ++=============+=====================+========================================+ +| int8_t[20] | info_hash | The info hash of this info. | ++-------------+---------------------+----------------------------------------+ +| int32_t | complete | The total number of completed | +| | | downloads. | ++-------------+---------------------+----------------------------------------+ +| int32_t | downloaded | The current number of connected seeds. | ++-------------+---------------------+----------------------------------------+ +| int32_t | incomplete | The current number of connected | +| | | leechers. | ++-------------+---------------------+----------------------------------------+ + +errors +------ + +In case of a tracker error, the server replies with this packet: + ++-------------+---------------------+----------------------------------------+ +| size | name | description | ++=============+=====================+========================================+ +| int32_t | action | The action, in this case 3, for error. | ++-------------+---------------------+----------------------------------------+ +| int32_t | transaction_id | Must match the transaction_id sent | +| | | from the client. | ++-------------+---------------------+----------------------------------------+ +| int8[] | error_string | The rest of the packet is a string | +| | | describing the error. | ++-------------+---------------------+----------------------------------------+ + + +actions +------- + +The action fields has the followinf encoding: + + * connect = 0 + * announce = 1 + * scrape = 2 + * error = 3 (only in server replies) + + +credits +------- + +Protocol designed by Olaf van der Spek + diff --git a/include/libtorrent/peer_connection.hpp b/include/libtorrent/peer_connection.hpp index 018b5bb58..b82e6c73c 100755 --- a/include/libtorrent/peer_connection.hpp +++ b/include/libtorrent/peer_connection.hpp @@ -68,96 +68,101 @@ namespace libtorrent { struct session_impl; + template struct type {}; + // reads an integer from a byte stream // in big endian byte order and converts // it to native endianess - template - unsigned int read_uint(InIt& start) + template + inline T read_impl(InIt& start, type) { - unsigned int val = 0; - val |= static_cast(*start) << 24; ++start; - val |= static_cast(*start) << 16; ++start; - val |= static_cast(*start) << 8; ++start; - val |= static_cast(*start); ++start; - return val; - } - - template - inline int read_int(InIt& start) - { - return static_cast(read_uint(start)); - } - - template - inline unsigned char read_uchar(InIt& start) - { - unsigned char ret = static_cast(*start); - ++start; - return ret; - } - - template - inline unsigned short read_ushort(InIt& start) - { - unsigned short val = 0; - val |= static_cast(*start) << 8; ++start; - val |= static_cast(*start); ++start; - return val; - } - - // reads an integer to a byte stream - // and converts it from native endianess - template - void write_uint(unsigned int val, OutIt& start) - { - *start = static_cast((val >> 24) & 0xff); ++start; - *start = static_cast((val >> 16) & 0xff); ++start; - *start = static_cast((val >> 8) & 0xff); ++start; - *start = static_cast((val) & 0xff); ++start; - } - - template - inline void write_int(int val, OutIt& start) - { - write_uint(static_cast(val), start); - } - - template - void write_ushort(unsigned short val, OutIt& start) - { - *start = static_cast((val >> 8) & 0xff); ++start; - *start = static_cast((val) & 0xff); ++start; - } - - template - inline void write_uchar(unsigned char val, OutIt& start) - { - *start = static_cast(val); - ++start; - } - - template - inline void write_int64(boost::int64_t val, OutIt& start) - { - for (int i = 7; i <= 0; --i) + T ret = 0; + for (int i = 0; i < sizeof(T); ++i) { - *start = static_cast((val >> (i*8)) & 0xff); - ++start; - } - } - - template - inline boost::int64_t read_int64(InIt& start) - { - boost::int64_t ret = 0; - for (int i = 7; i <= 0; --i) - { - ret |= static_cast(*start) << (i*8); + ret <<= 8; + ret |= static_cast(*start); ++start; } return ret; } + template + inline void write_impl(T val, OutIt& start) + { + for (int i = sizeof(T)-1; i >= 0; --i) + { + *start = static_cast((val >> (i * 8)) & 0xff); + ++start; + } + } + + // -- adaptors + + template + boost::int64_t read_int64(InIt& start) + { return read_impl(start, type()); } + + template + boost::uint64_t read_uint64(InIt& start) + { return read_impl(start, type()); } + + template + boost::uint32_t read_uint32(InIt& start) + { return read_impl(start, type()); } + + template + boost::int32_t read_int32(InIt& start) + { return read_impl(start, type()); } + + template + boost::int16_t read_int16(InIt& start) + { return read_impl(start, type()); } + + template + boost::uint16_t read_uint16(InIt& start) + { return read_impl(start, type()); } + + template + boost::int8_t read_int8(InIt& start) + { return read_impl(start, type()); } + + template + boost::uint8_t read_uint8(InIt& start) + { return read_impl(start, type()); } + + + template + void write_uint64(boost::uint64_t val, OutIt& start) + { write_impl(val, start); } + + template + void write_int64(boost::int64_t val, OutIt& start) + { write_impl(val, start); } + + template + void write_uint32(boost::uint32_t val, OutIt& start) + { write_impl(val, start); } + + template + void write_int32(boost::int32_t val, OutIt& start) + { write_impl(val, start); } + + template + void write_uint16(boost::uint16_t val, OutIt& start) + { write_impl(val, start); } + + template + void write_int16(boost::int16_t val, OutIt& start) + { write_impl(val, start); } + + template + void write_uint8(boost::uint8_t val, OutIt& start) + { write_impl(val, start); } + + template + void write_int8(boost::int8_t val, OutIt& start) + { write_impl(val, start); } + } struct protocol_error: std::runtime_error diff --git a/include/libtorrent/torrent.hpp b/include/libtorrent/torrent.hpp index 5aaa41f37..3ed83c0e4 100755 --- a/include/libtorrent/torrent.hpp +++ b/include/libtorrent/torrent.hpp @@ -174,7 +174,7 @@ namespace libtorrent // when this torrent got a response from its tracker request virtual void tracker_response(std::vector& e, int interval); virtual void tracker_request_timed_out(); - virtual void tracker_request_error(int response_code, const char* str); + virtual void tracker_request_error(int response_code, const std::string& str); // generates a request string for sending // to the tracker diff --git a/src/alert.cpp b/src/alert.cpp index fdae1a2e6..a0e68708c 100755 --- a/src/alert.cpp +++ b/src/alert.cpp @@ -49,11 +49,17 @@ namespace libtorrent { void alert_manager::post_alert(const alert& alert_) { - // TODO: have an internal buffer limit boost::mutex::scoped_lock lock(m_mutex); - - if (m_severity <= alert_.severity()) - m_alerts.push(alert_.clone().release()); + if (m_severity > alert_.severity()) return; + + // the internal limit is 100 alerts + if (m_alerts.size() == 100) + { + alert* result = m_alerts.front(); + m_alerts.pop(); + delete result; + } + m_alerts.push(alert_.clone().release()); } std::auto_ptr alert_manager::get() diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp index 7f4491544..0bdbfbfdb 100755 --- a/src/peer_connection.cpp +++ b/src/peer_connection.cpp @@ -285,8 +285,8 @@ namespace libtorrent const char* ptr = &m_recv_buffer[1]; peer_request r; - r.piece = detail::read_int(ptr); - r.start = detail::read_int(ptr); + r.piece = detail::read_int32(ptr); + r.start = detail::read_int32(ptr); r.length = m_packet_size - 9; // is any of the piece message header data invalid? @@ -406,7 +406,7 @@ namespace libtorrent if (m_recv_pos < m_packet_size) return; const char* ptr = &m_recv_buffer[1]; - int index = detail::read_int(ptr); + int index = detail::read_int32(ptr); // if we got an invalid message, abort if (index >= m_have_piece.size() || index < 0) throw protocol_error("have message with higher index than the number of pieces"); @@ -514,9 +514,9 @@ namespace libtorrent peer_request r; const char* ptr = &m_recv_buffer[1]; - r.piece = detail::read_int(ptr); - r.start = detail::read_int(ptr); - r.length = detail::read_int(ptr); + r.piece = detail::read_int32(ptr); + r.start = detail::read_int32(ptr); + r.length = detail::read_int32(ptr); // make sure this request // is legal and taht the peer @@ -602,8 +602,8 @@ namespace libtorrent const char* ptr = &m_recv_buffer[1]; peer_request p; - p.piece = detail::read_int(ptr); - p.start = detail::read_int(ptr); + p.piece = detail::read_int32(ptr); + p.start = detail::read_int32(ptr); p.length = m_packet_size - 9; if (!verify_piece(p)) @@ -724,9 +724,9 @@ namespace libtorrent peer_request r; const char* ptr = &m_recv_buffer[1]; - r.piece = detail::read_int(ptr); - r.start = detail::read_int(ptr); - r.length = detail::read_int(ptr); + r.piece = detail::read_int32(ptr); + r.start = detail::read_int32(ptr); + r.length = detail::read_int32(ptr); std::deque::iterator i = std::find(m_requests.begin(), m_requests.end(), r); @@ -812,7 +812,7 @@ namespace libtorrent const char* ptr = &m_recv_buffer[1]; - int extended_id = detail::read_int(ptr); + int extended_id = detail::read_int32(ptr); switch (extended_id) { @@ -929,11 +929,11 @@ namespace libtorrent char* ptr = &m_send_buffer[start_offset]; // index - detail::write_int(block.piece_index, ptr); + detail::write_int32(block.piece_index, ptr); // begin - detail::write_int(block_offset, ptr); + detail::write_int32(block_offset, ptr); // length - detail::write_int(block_size, ptr); + detail::write_int32(block_size, ptr); #ifndef NDEBUG (*m_logger) << " ==> CANCEL [ piece: " << block.piece_index << " | s: " << block_offset << " | l: " << block_size << " | " << block.block_index << " ]\n"; @@ -968,13 +968,13 @@ namespace libtorrent char* ptr = &m_send_buffer[start_offset+5]; // index - detail::write_int(block.piece_index, ptr); + detail::write_int32(block.piece_index, ptr); // begin - detail::write_int(block_offset, ptr); + detail::write_int32(block_offset, ptr); // length - detail::write_int(block_size, ptr); + detail::write_int32(block_size, ptr); #ifndef NDEBUG (*m_logger) << " ==> REQUEST [ " @@ -1005,9 +1005,9 @@ namespace libtorrent bencode(std::back_inserter(message), e); std::back_insert_iterator > ptr(m_send_buffer); - detail::write_uint(1 + 4 + message.size(), ptr); - detail::write_uchar(msg_extended, ptr); - detail::write_int(m_extension_messages[extended_chat_message], ptr); + detail::write_uint32(1 + 4 + message.size(), ptr); + detail::write_uint8(msg_extended, ptr); + detail::write_int32(m_extension_messages[extended_chat_message], ptr); std::copy(message.begin(), message.end(), ptr); send_buffer_updated(); } @@ -1021,7 +1021,7 @@ namespace libtorrent const int old_size = m_send_buffer.size(); m_send_buffer.resize(old_size + packet_size); char* ptr = &m_send_buffer[old_size]; - detail::write_int(packet_size - 4, ptr); + detail::write_int32(packet_size - 4, ptr); m_send_buffer[old_size+4] = msg_bitfield; std::fill(m_send_buffer.begin()+old_size+5, m_send_buffer.end(), 0); for (std::size_t i = 0; i < m_have_piece.size(); ++i) @@ -1056,7 +1056,7 @@ namespace libtorrent // write the length of the message char* ptr = &m_send_buffer[msg_size_pos]; - detail::write_int(m_send_buffer.size() - msg_size_pos - 4, ptr); + detail::write_int32(m_send_buffer.size() - msg_size_pos - 4, ptr); send_buffer_updated(); } @@ -1120,7 +1120,7 @@ namespace libtorrent const int packet_size = 9; char msg[packet_size] = {0,0,0,5,msg_have}; char* ptr = msg+5; - detail::write_int(index, ptr); + detail::write_int32(index, ptr); m_send_buffer.insert(m_send_buffer.end(), msg, msg + packet_size); #ifndef NDEBUG (*m_logger) << " ==> HAVE [ piece: " << index << " ]\n"; @@ -1406,7 +1406,7 @@ namespace libtorrent // convert from big endian to native byte order const char* ptr = &m_recv_buffer[0]; - m_packet_size = detail::read_int(ptr); + m_packet_size = detail::read_int32(ptr); // don't accept packets larger than 1 MB if (m_packet_size > 1024*1024 || m_packet_size < 0) { @@ -1492,10 +1492,10 @@ namespace libtorrent const int packet_size = 4 + 5 + 4 + r.length; m_send_buffer.resize(send_buffer_offset + packet_size); char* ptr = &m_send_buffer[send_buffer_offset]; - detail::write_int(packet_size-4, ptr); + detail::write_int32(packet_size-4, ptr); *ptr = msg_piece; ++ptr; - detail::write_int(r.piece, ptr); - detail::write_int(r.start, ptr); + detail::write_int32(r.piece, ptr); + detail::write_int32(r.start, ptr); m_torrent->filesystem().read( &m_send_buffer[send_buffer_offset+13] diff --git a/src/torrent.cpp b/src/torrent.cpp index c79cf35d5..27a088715 100755 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -253,15 +253,17 @@ namespace libtorrent #ifndef NDEBUG std::stringstream s; - s << "interval: " << m_duration << "\n"; - s << "peers:\n"; + s << "TRACKER RESPONSE:\n" + "interval: " << m_duration << "\n" + "peers:\n"; for (std::vector::const_iterator i = peer_list.begin(); i != peer_list.end(); ++i) { s << " " << std::setfill(' ') << std::setw(16) << i->ip - << " " << std::setw(5) << std::dec << i->port << " " - << i->id << " " << identify_client(i->id) << "\n"; + << " " << std::setw(5) << std::dec << i->port << " "; + if (!i->id.is_all_zeros()) s << " " << i->id << " " << identify_client(i->id); + s << "\n"; } debug_log(s.str()); #endif @@ -746,7 +748,7 @@ namespace libtorrent // with some codes, we should just consider // the tracker as a failure and not retry // it anymore - void torrent::tracker_request_error(int response_code, const char* str) + void torrent::tracker_request_error(int response_code, const std::string& str) { #ifndef NDEBUG debug_log(std::string("*** tracker error: ") + str); diff --git a/src/torrent_handle.cpp b/src/torrent_handle.cpp index 8b5903adb..0aa668397 100755 --- a/src/torrent_handle.cpp +++ b/src/torrent_handle.cpp @@ -94,6 +94,7 @@ namespace libtorrent void torrent_handle::set_max_connections(int max_connections) { + assert(max_connections >= 2); if (m_ses == 0) throw invalid_handle(); {