The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Net::BitTorrent - BitTorrent peer-to-peer protocol class

Synopsis

    use Net::BitTorrent;

    sub hash_pass {
        my ($self, $piece) = @_;
        printf(qq[hash_pass: piece number %04d of %s\n],
               $piece->index, $piece->session);
    }

    my $client = Net::BitTorrent->new();
    $client->set_callback(q[piece_hash_pass], \&hash_pass);

    # ...
    # set various callbacks if you so desire
    # ...

    my $torrent = $client->add_session({path => q[a.legal.torrent]})
        or die q[Cannot load .torrent];

    while (1) {
        $client->do_one_loop();

        # Etc.
    }

Description

Net::BitTorrent is a class based implementation of the current BitTorrent Protocol Specification. Each Net::BitTorrent object is capable of handling several concurrent .torrent sessions.

Constructor

new ( { [ARGS] } )

Creates a Net::BitTorrent object. new ( ) accepts arguments as a hash, using key-value pairs, all of which are optional. The most common are:

LocalAddr

Local host bind address. The value must be an IPv4 ("dotted quad") IP- address of the xx.xx.xx.xx form. Unlike the LocalAddr key used by IO::Socket::INET, it does not (currently) support an embedded port number. LocalHost is a synonym for LocalAddr.

Default: 0.0.0.0 (any address)

LocalPort

TCP port opened to remote peers for incoming connections. If handed a list of ports, Net::BitTorrent will traverse the list, attempting to open on each of the ports until we succeed. If this value is undef or 0, we allow the OS to choose an open port at random.

Though the default in most clients is a random port in the 6881-6889 range, BitTorrent has not been assigned a port number or range by the IANA. Nor is such a standard needed.

Default: 0 (any available)

Timeout

The maximum amount of time, in seconds, possibly fractional, select() is allowed to wait before returning in "do_one_loop".

Default: 1.0

Besides these, there are a number of advanced options that can be set via the constructor. Use these with caution as they can greatly affect the basic functionality and usefulness of the module.

maximum_buffer_size

Amount of data, in bytes, we store from a peer before dropping their connection. Setting this too high leaves you open to DDoS-like attacks. Malicious or not.

Default: 131072 (2**17) (This default may change as the module matures)

maximum_peers_per_client

Maximum number of peers per client object.

Default: 300 (This default may change as the module matures)

maximum_peers_per_session

Maximum number of peers per session.

Default: 100 (This default may change as the module matures)

maximum_peers_half_open

Maximum number of sockets we have yet to receive a handshake from.

NOTE: On some OSes (WinXP, et al.), setting this too high can cause problems with the TCP stack.

Default: 8

maximum_requests_per_peer

Maximum number of requested blocks we keep in queue with each peer.

Default: 10

kBps_up

Maximum amount of data transfered per second to remote hosts.

Default: 0 (unlimited)

kBps_down

Maximum amount of data transfered per second from remote hosts.

Default: 0 (unlimited)

Methods

Unless otherwise stated, all methods return either a true or false value, with true meaning that the operation was a success. When a method states that it returns a value, failure will result in undef or an empty list.

Besides these listed here, there are several set_callback[...] methods described in the "Callbacks" section.

add_session ( { ... } )

Loads a .torrent file and adds the new Net::BitTorrent::Session object to the client.

Most arguments passed to this method are handed directly to Net::BitTorrent::Session::new( ). The only mandatory parameter is path. path's value is the filename of the .torrent file to load. Please see Net::BitTorrent::Session::new( ) for a list of possible parameters.

In addition to Net::BitTorrent::Session::new( )'s supported arguments, add_session accepts a skip_hashcheck key. If this bool value is set to a true value, the files will not be checked for integrity and we assume that we have none of the data of this torrent.

This method returns the new Net::BitTorrent::Session object on success.

See also: sessions, remove_session, Net::BitTorrent::Session

as_string ( [ VERBOSE ] )

Returns a 'ready to print' dump of the Net::BitTorrent object's data structure. If called in void context, the structure is printed to STDERR.

Note: The serialized version returned by this method is not a full, accurate representation of the object and cannot be evaled into a new Net::BitTorrent object or used as resume data. The layout of and the data included in this dump is subject to change in future versions. This is a debugging method, not to be used under normal circumstances.

See also: [id://317520]

debug_level ( [NEW VALUE] )

Mutator to get/set the minimum level of messages passed to the log callback handler. See LOG LEVELS for more.

do_one_loop ( )

Processes the various socket-containing objects (peers, trackers) held by this Net::BitTorrent object. This method should be called frequently.

process_connections ( READERSREF, WRITERSREF, ERRORSREF )

Use this method when you want to implement your own select statement for event processing instead of using Net::BitTorrent's do_one_loop method. The parameters are references to the readers, writers, and errors parameters used by the select statement.

Use the internal _fileno ( ) method to set up the necessary bit vectors for your select ( ) call.

Note: This is a work in progress.

See Also: Alternative Event Processing

process_timers ( )

Net::BitTorrent relies heavily on internal timing of various events (socket timeouts, tracker requests, etc.) and simply cannot function without processing these timers from time to time.

Use this method only when you implement your own select statement for event processing and do not use Net::BitTorrent's do_one_loop method.

Note: This is a work in progress.

maximum_buffer_size ( [NEW VALUE] )

Mutator to get/set the amount of unparsed data, in bytes, we store from a peer before dropping their connection. Be sure to keep this value high enough to allow incoming blocks (2**16 by default) to be held in memory without trouble but low enough to keep DDoS-like attacks at bay.

Default: 131072 (2**17) (This default may change as the module matures)

maximum_peers_half_open ( [NEW VALUE] )

Mutator to get/set the maximum number of peers we have yet to receive a handshake from. These include sockets that have not connected yet.

NOTE: On some OSes (WinXP, et al.), setting this too high can cause problems with the TCP stack.

Default: 8

maximum_peers_per_client ( [NEW VALUE] )

Mutator to get/set the maximum number of peers per client object.

Default: 300

See also: theory.org (http://tinyurl.com/4jgdnl)

maximum_peers_per_session ( [NEW VALUE] )

Mutator to get/set the maximum number of peers per session.

Default: 100

maximum_requests_size ( [NEW VALUE] )

Mutator to get/set the maximum size, in bytes, a peer is allowed to request from us as a single block of data.

Default: 32768

See also: theory.org (http://tinyurl.com/32k7wu)

maximum_requests_per_peer ( [NEW VALUE] )

Mutator to get/set the maximum number of blocks we have in queue from each peer.

Default: 10

kBps_down ( [NEW VALUE] )

Mutator to get/set the maximum amount of data transfered per second from remote hosts in kilobytes. This rate limits both peers and trackers. To remove transfer limits, set this value to 0.

Default: 0 (unlimited)

kBps_down ( [NEW VALUE] )

Mutator to get/set the maximum amount of data transfered per second from remote hosts in kilobytes. This rate limits both peers and trackers. To remove transfer limits, set this value to 0.

Default: 0 (unlimited)

peer_id ( )

Returns the Peer ID generated to identify this Net::BitTorrent object internally, with trackers, and with remote peers.

See also: theory.org (http://tinyurl.com/4a9cuv)

remove_session ( SESSION )

Removes a Net::BitTorrent::Session object from the client.

See also: sessions, add_session, Net::BitTorrent::Session

sessions ( )

Returns a list of loaded Net::BitTorrent::Session objects.

See Also: add_session, remove_session, Net::BitTorrent::Session

sockaddr ( )

Return the address part of the sockaddr structure for the socket.

See also: "sockaddr" in IO::Socket::INET

sockport ( )

Return the port number that the socket is using on the local host.

See also: "sockport" in IO::Socket::INET

timeout ( [TIMEOUT] )

Mutator which gets or sets the maximum amount of time, in seconds, possibly fractional, select() is allowed to wait before returning in "do_one_loop".

See Also: do_one_loop, Timeout argument of the constructor

Callbacks

set_callback( TYPE, CODEREF )

Net::BitTorrent provides a convenient callback system. To set a callback, use the set_callback( ) method. For example, to catch all attempts to read from a file, use $client->set_callback( 'file_read', \&on_read ).

Here is the current list of events fired by Net::BitTorrent and related classes as well as a brief description (soon) of them:

Peer level

Peer level events are triggered by Net::BitTorrent::Peer objects.

peer_connect

Callback arguments: ( CLIENT, PEER )

peer_disconnect

Callback arguments: ( CLIENT, PEER, [REASON] )

peer_incoming_bitfield

Callback arguments: ( CLIENT, PEER )

peer_incoming_block

Callback arguments: ( CLIENT, PEER, BLOCK )

peer_incoming_cancel

Callback arguments: ( CLIENT, PEER, REQUEST )

peer_incoming_choke

Callback arguments: ( CLIENT, PEER )

peer_incoming_data

Callback arguments: ( CLIENT, PEER, LENGTH )

peer_incoming_disinterested

Callback arguments: ( CLIENT, PEER )

peer_incoming_handshake

Callback arguments: ( CLIENT, PEER )

peer_incoming_have

Callback arguments: ( CLIENT, PEER, INDEX )

peer_incoming_interested

Callback arguments: ( CLIENT, PEER )

peer_incoming_keepalive

Callback arguments: ( CLIENT, PEER )

peer_incoming_packet

Callback arguments: ( CLIENT, PEER, PACKET )

peer_incoming_request

Callback arguments: ( CLIENT, PEER, REQUEST )

peer_incoming_unchoke

Callback arguments: ( CLIENT, PEER )

peer_outgoing_bitfield

Callback arguments: ( CLIENT, PEER )

peer_outgoing_block

Callback arguments: ( CLIENT, PEER, REQUEST )

peer_outgoing_cancel

Callback arguments: ( CLIENT, PEER, BLOCK )

peer_outgoing_choke

Callback arguments: ( CLIENT, PEER )

peer_outgoing_data

Callback arguments: ( CLIENT, PEER, LENGTH )

peer_outgoing_disinterested

Callback arguments: ( CLIENT, PEER )

peer_outgoing_handshake

Callback arguments: ( CLIENT, PEER )

peer_outgoing_have

Callback arguments: ( CLIENT, PEER, INDEX )

peer_outgoing_interested

Callback arguments: ( CLIENT, PEER )

peer_outgoing_keepalive

Callback arguments: ( CLIENT, PEER )

peer_outgoing_request

Callback arguments: ( CLIENT, PEER, BLOCK )

peer_outgoing_unchoke

Callback arguments: ( CLIENT, PEER )

Tracker level

Peer level events are triggered by Net::BitTorrent::Tracker objects.

tracker_announce

Callback arguments: ( CLIENT, TRACKER )

tracker_announce_okay

Callback arguments: ( CLIENT, TRACKER )

tracker_connect

Callback arguments: ( CLIENT, TRACKER )

tracker_disconnect

Callback arguments: ( CLIENT, TRACKER )

tracker_error

Callback arguments: ( CLIENT, TRACKER, MESSAGE )

tracker_incoming_data

Callback arguments: ( CLIENT, TRACKER, LENGTH )

tracker_outgoing_data

Callback arguments: ( CLIENT, TRACKER, LENGTH )

tracker_scrape

Callback arguments: ( CLIENT, TRACKER )

tracker_scrape_okay

Callback arguments: ( CLIENT, TRACKER )

File level

File level events are triggered by Net::BitTorrent::Session::File objects.

file_close

Callback arguments: ( CLIENT, FILE )

file_error

Callback arguments: ( CLIENT, FILE, [REASON] )

file_open

Callback arguments: ( CLIENT, FILE )

file_read

Callback arguments: ( CLIENT, FILE, LENGTH )

file_write

Callback arguments: ( CLIENT, FILE, LENGTH )

Piece level

Peer level events are triggered by Net::BitTorrent::Session::Piece objects.

piece_hash_fail

Callback arguments: ( CLIENT, PIECE )

piece_hash_pass

Callback arguments: ( CLIENT, PIECE )

Block level

Block level events are triggered by Net::BitTorrent::Session::Piece::Block objects.

block_write

Callback arguments: ( CLIENT, BLOCK )

Debug level

Debug level callbacks can be from anywhere and are not object specific.

log

Callback arguments: ( CLIENT, LEVEL, STRING )

See also: LOG LEVELS

Implemented Extensions

Um, none yet.

Bugs

Numerous, I'm sure. If you find one not listed in the Todo file included with this distribution, please report it.

List of know bugs:

  • Test suite is incomplete.

  • This list of bugs is incomplete.

Found bugs should be reported through http://code.google.com/p/net-bittorrent/issues/list. Please include as much information as possible. For more, see "I've found a bug! Now what?" in Net::BitTorrent::FAQ.

Notes

Support and Availability

Visit the following for support and information related to Net::BitTorrent:

The project's website

For wiki and subversion repository access, please visit the project's home: http://net-bittorrent.googlecode.com/.

Bug and Issue Tracker

Use http://code.google.com/p/net-bittorrent/issues/list for bug tracking.

Before creating and sending a report, please review the following list:

  • Make sure you are using the most recent release of Net::BitTorrent. This may mean checking out the latest svn commit.

  • Make sure the bug is reproducible.

  • See the complete checklist in Net::BitTorrent::FAQ.

See Net::BitTorrent::FAQ for links to a mailing list, svn information, and more.

Dependencies

Net::BitTorrent requires version, and Digest::SHA. As of perl 5.10, these are CORE modules; they come bundled with the distribution.

Development Policy

  • All APIs are subject to change.

    Changes to documented or well established parts will be clearly listed and archived in the CHANGES file.

    Functions and parameters that are all_lower_case_and_contain_underscores are typically experimental and have a very good chance of being depreciated in a future version.

  • All undocumented functionality is subject to change without notice.

    Because it's still early in its development, Net::BitTorrent is filled with incomplete bits of stuff. I understand some of it seems stable, but I reserve the right to change or eliminate code at any time without warning unless functionality is defined in POD documentation.

    If you sift through the source and find something nifty that isn't described in full in POD, don't expect your code to work with future releases.

Examples

For a demonstration of Net::BitTorrent, see scripts/client.pl and scripts/web-gui.pl.

Installation

This distribution uses Module::Build for installation, so use the following procedure:

  perl Build.PL
  ./Build
  ./Build test
  ./Build install

Or, if you're on a platform (like DOS or Windows) that doesn't require the "./" notation, you can do this:

  perl Build.PL
  Build
  Build test
  Build install

If you would like to contribute automated test reports (and I hope you do), first install CPAN::Reporter from the CPAN shell and then install Net::BitTorrent:

 $ cpan
 cpan> install CPAN::Reporter
 cpan> reload cpan
 cpan> o conf init test_report
   [...follow the CPAN::Reporter setup prompts...]
 cpan> o conf commit
 cpan> install Net::BitTorrent

For more on becoming a CPAN tester and why this is useful, please see the CPAN::Reporter documentation, http://cpantesters.perl.org/, and the CPAN Testers Wiki (http://cpantest.grango.org/).

Alternative Event Processing

To making integrating Net::BitTorrent into an existing select-based event loop just a little easier, an alternative way of doing event processing (vs. do_one_loop ( )) has been designed... uh, I mean ganked. Simply call the "process_connections" method with references to the lists of readers, writers, and errors given to you by select. Connections that don't belong to the object will be ignored, and connections that do belong to the object will be removed from the select lists so that you can use the lists for your own purposes.

Here's a painfully simple example:

  while (1) {
      my ($rin, $win, $ein) = (q[], q[], q[]);
      vec($rin, fileno($server), 1) = 1;
      for my $object (values %{$bittorrent->_connections}) {
          vec($rin, $object->_fileno, 1) = 1;
          vec($win, $object->_fileno, 1) = 1
              if $object ne $bittorrent and $object->_queue_outgoing;
      }

      # Add your other sockets to the bit vectors

      $ein = $rin | $win;
      my ($nfound) = select($rin, $win, $ein, 1);
      $bittorrent->process_connections(\$rin, \$win, \$ein)
          if $nfound and $nfound != -1;
      $bittorrent->process_timers;    # Don't forget this!

      # Now $rin, $win, and $ein only have the file descriptors not
      # associated with Net::BitTorrent (related) objects in them -
      # we can process our events.
  }

For a full demonstration, see scripts/web-gui.pl.

This is experimental and may be removed or improved in the future.

See Also

http://bittorrent.org/beps/bep_0003.html - BitTorrent Protocol Specification

Net::BitTorrent::FAQ - Random questions. More jibba jabba.

Net::BitTorrent::PeerID - The standard used to identify Net::BitTorrent in the wild.

Acknowledgments

Bram Cohen, for designing the base protocol and letting the community decide what to do with it.

L Rotger

#bittorrent on Freenode for letting me idle.

Michel Valdrighi

Author

Sanko Robinson <sanko@cpan.org> - http://sankorobinson.com/

CPAN ID: SANKO

License and Legal

Copyright 2008 by Sanko Robinson <sanko@cpan.org>

This program is free software; you can redistribute it and/or modify it under the same terms as Perl 5.10 (or higher). See http://www.perl.com/perl/misc/Artistic.html or the LICENSE file included with this distribution.

All POD documentation is covered by the Creative Commons Attribution- Noncommercial-Share Alike 3.0 License (http://creativecommons.org/licenses/by-nc-sa/3.0/us/).

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