Net::BitTorrent::Protocol::BEP15 - Packet Utilities for BEP15, the UDP Tracker Protocol


    use Net::BitTorrent::Protocol::BEP15 qw[:all];

    # Tell them we want to connect...
    my $handshake = build_connect_request(255);

    # ...send to tracker and get reply...
    my ($transaction_id, $connection_id) = parse_connect_reply( $reply );


What would BitTorrent be without packets? TCP noise, mostly.

For similar work and the specifications behind these packets, move on down to the See Also section.

Importing from Net::BitTorrent::Protocol::BEP15

There are two tags available for import. To get them both in one go, use the :all tag.


These create packets ready-to-send to trackers. See Building Functions.


These are used to parse unknown data into sensible packets. The same packet types we can build, we can also parse. You may want to use this to write your own UDP tracker. See Parsing Functions.

Building Functions

build_connect_request ( ... )

Creates a request for a connection id. The provided transaction_id should be a random 32-bit integer.

build_connect_reply( ... )

Creates a reply for a connection request. The transaction_id should match the value sent from the client. The connection_id is sent with every packet to identify the client.

build_announce_request( ... )

Creates a packet suited to announce with the tracker. The following keys are required:


This is the same connection_id returned by the tracker when you sent a connection request.


This is defined by you. It's a random integer which will be returned by the tracker in response to this packet.


This is the packed info hash of the torrent.


This is your client's peer id.


The amount of data you have downloaded so far this session.


The amount of data you have left to download before complete.


The amount of data you have uploaded to other peers in this session.


This value is either $NONE, $COMPLETED, $STARTED, or $STOPPED. $NONE is sent when you're simply reannouncing after a certain interval.

All of these are imported with the :types or :all tags.


A unique key that is randomized by the client. Unlike the transaction_id which is generated for every packet, this value should be kept per-session.


The port you're listening on.

...and the following are optional. Some have default values:


The request string extension is meant to allow torrent creators pass along cookies back to the tracker. This can be useful for authenticating that a torrent is allowed to be tracked by a tracker for instance. It could also be used to authenticate users by generating torrents with unique tokens in the tracker URL for each user.

Typically this starts with "/announce" The bittorrent client is not expected to append query string arguments for stats reporting, like "uploaded" and "downloaded" since this is already reported in the udp tracker protocol. However, the client is free to add arguments as extensions.


This is a list which contains a username and password. This function then correctly hashes the password to sent over the wire.


Your ip address. By default, this is 0 which tells the tracker to use the sender of this udp packet.


The maximum number of peers you want in the reply. The default is -1 which lets the tracker decide.

build_announce_reply( ... )

Creates a packet a UDP tracker would sent in reply to an announce packet from a client. The following are required: transaction_id, the interval at which the client should reannounce, the number of seeders and leechers, as well as a list of peers for the given infohash.

build_scrape_request( ... )

Creates a packet for a client to request basic data about a number of torrents. Up to about 74 torrents can be scraped at once. A full scrape can't be done with this protocol.

You must provide: the tracker provided connection_id, a transaction_id, and a list in info_hash.

build_scrape_request( ... )

Creates a packet for a tracker to sent in reply to a scrape request. You must provide the client defined transaction_id and a list of hashes as scrape data. The hashes contain integers for the following: downloaded, incomplete, and complete.

build_error_reply( ... )

Creates a packet to be sent to the client in case of an error. You must provide a transaction_id and failure reason.

Parsing Functions

These are the parsing counterparts for the build_ functions.

When the packet is invalid, a hash reference is returned with error and fatal keys. The value in error is a string describing what went wrong.

Return values for valid packets are explained below.

parse_reply( $data )

This will automatically call the correct parsing function for you. When you aren't exactly sure what the data is.

parse_request( $data )

This will automatically call the correct parsing function for you. When you aren't exactly sure what the data is. This would be use in you're writing a UDP tracker yourself.

parse_connect_request( $data )

Returns the parsed transaction id.

parse_connect_reply( $data )

Parses the reply for a connect request. Returns the original transaction id and the new connection id.

parse_announce_request( $data )

Returns connection_id, transaction_id, info_hash, peer_id, downloaded, left, uploaded, event, ip, key, num_want, port, ip.

Optionally, this packet might also contian authentication and request_string values.

parse_announce_reply( $data )

Returns the transaction_id, the interval at which you should re-announce, the current number of leechers and seeders, and an inflated list of peers.

parse_scrape_request( $data )

Returns the connection_id, transaction_id, and an info_hash which may contain multiple infohashes depending on the request.

parse_scrape_reply( $data )

Returns transaction_id and list of hashes in scrape. The scrape hashes contain downloaded, complete and incomplete keys.

parse_error_reply( $data )

Returns transaction_id and failure reason.

See Also - UDP Tracker Protocol for BitTorrent


Sanko Robinson <> -


License and Legal

Copyright (C) 2016 by Sanko Robinson <>

This program is free software; you can redistribute it and/or modify it under the terms of The Artistic License 2.0. See the LICENSE file included with this distribution or notes on the Artistic License 2.0 for clarification.

When separated from the distribution, all original POD documentation is covered by the Creative Commons Attribution-Share Alike 3.0 License. See the clarification of the CCA-SA3.0.

Neither this module nor the Author is affiliated with BitTorrent, Inc.