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

NAME

Net::BitTorrent::Notes - Annotated Guide to the Ins and Outs of Net::BitTorrent

Description

Net::BitTorrent is a mess.

But it doesn't have to be! This document is a first draft attempt at defining a roadmap for future Net::BitTorrent development and a behavioral reference for third-party client developers. There are bits in here that may be of some use to regular users too.

Note: Net::BitTorrent::Notes and the ideas behind it are a work in progress.

Net::BitTorrent's Way-too-Obvious Class Hierarchy

                                            .---- N::B::T::T::UDP
                                           /
                      .-------- N::B::T::Tracker
                     /                     \
                    /   .-- N::B::T::File   `--- N::B::T::T::HTTP
                   /   /
            .---- Net::BitTorrent::Torrent
           /
          /   .--- Net::BitTorrent::DHT
         /   /           \
  Net::BitTorrent         `---- N::B::D::Node
         \
          `---- Net::BitTorrent::Peer

See Also: Class Pseudo-structures

Installation

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

  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/)

Prerequisites

Net::BitTorrent requires version and Digest::SHA. On Win32, we require Win32API::File and Encode when handling .torrents holding files with extended charset filenames.* As of perl 5.10, all of these modules are are CORE; they come bundled with the distribution.

I have listed these modules as prerequisites in Build.PL so, unless you answer 'no' when prompted, the CPAN shell should automagically install them for you.

* We also use the internal utf8() functions which didn't appear until perl 5.8.1. See Portability Hacks.

How Do I...

Parts that aren't handled internally are described here with sample code to get you started. In the future, this will probably be in a separate pod.

Get basic info from a .torrent without adding it to a client

Net::BitTorrent::Torrent objects can be created diretly without a parent client. While functionally limited (obvious things like an inability to serve data, etc.) basic information is available and some 'advanced' functions still work (hashchecking, for example). See Net::BitTorrent::Torrent for more.

Pause and Resume a .torrent Session

See Net::BitTorrent::Torrent::pause( ) and Net::BitTorrent::Torrent::start( )

Stop and Resume a .torrent Session

See See Net::BitTorrent::Torrent::stop( ) and Net::BitTorrent::Torrent::start( )

Quick Resume a .torrent Session Between Client Sessions

Early versions of N::B had resume built in but it was removed for various reasons. Adding this yourself is trivial, fortunately. For each torrent, store the bitfield, nodes (compact list of peers), piece priorities, and the modified times for each file just to be safe. Oh, and a list of the current 'working' pieces and their progress. Saving the DHT ID and routing table would be a good idea too. Add to that some sort of verification scheme to be sure you're loading information that hasn't been tampered with or corrupted. Then, when you load the torrent, reload the torrent with your stored data.

[TODO]

Set File Priorities

See "priority( [NEWVAL] )" in Net::BitTorrent::Torrent::File.

Implement My Own Event Loop

[TODO]

Net::BitTorrent Internals

This section describes all the behind the scenes stuff that makes Net::BitTorrent work. Or not work. It depends.

Class Pseudo-structures

Net::BitTorrent

 Net::BitTorrent = {
   TODO
 }

Net::BitTorrent::Session

 Net::BitTorrent::Session = {
   TODO
 }

Net::BitTorrent::Session::Tracker

 Net::BitTorrent::Session::Tracker = {
   TODO
 }

Net::BitTorrent::Session::Peer

 Net::BitTorrent::Session::Peer = {
   TODO
 }

Net::BitTorrent::Session::Peer::Request

 Net::BitTorrent::Session::Peer::Request = {
  TODO
 }

Net::BitTorrent::Session::File

 Net::BitTorrent::Session::File = {
   TODO
 }

Net::BitTorrent::Session::Piece

 Net::BitTorrent::Session::Piece = {
   TODO
 }

Peer ID Specification

Please see Net::BitTorrent::Version.

Handling of Errors and Bad Data

[TODO]

.torrent Metadata

[TODO]

Incoming Protocol Data

[TODO]

Disk Access Errors

[TODO]

Piece Selection

To have any symbolance of basic functionality, a BitTorrent client must have a good piece selection strategy. The 'strict priority' based algorhythm used by Net::BitTorrent seems to strike a balance between efficiency and speed while keeping the pipes full of incoming data. Here's the pseudocode:

  • Count the number of unrequested $free_blocks in all working pieces.

  • Count how many $free_slots we have open to us. To calculate this, we iterate through all peers who aren't choking us adding the difference between the total number of outgoing requests and the peer-defined maximum or our own internal 'safe' max of 20.

  • $max_working is set to the current number of working pieces plus the bool value of $free_blocks < $free_slots.

  • Calculating the priority @weights relys on [TODO]

    If @weights is empty, we return without making a new request.

  • Take the sum of all the relative (priority) weights and call it $total

  • Take a random number between 0 and 1, and multiply it by $total. Call the new number $rand_val

  • While $rand_val is positive, iterate through each element of @weights and do the following:

    • Subtract the (priority) weight of the element from $rand_val and increment a temporary index $i

    • If $rand_val went negative or we run out of values for @weights, we exit the loop.

  • If $weights[$i] is defined, we set the working value to true and request a free block. Blocks are requested in order from the beginning of the piece to the end. Finally, we re-request any rejected or canceled blocks.

  • ...otherwise, we return an undefined value.

The language used in this section probably only makes sense to me and will require a rewrite. For the actual code, see Net::BitTorrent::Torrent::_pick_piece().

Outgoing Requests

[TODO]

Queuing

[TODO]

Slow Blocks

[TODO]

Endgame

[TODO]

Incoming Requests

[TODO]

Queuing

[TODO]

Rejections (Fast Ext)

[TODO]

Trackers

[TODO]

Multi-tracker .torrents

[TODO]

UDP Trackers

[TODO]

Fast Set Advertising

[TODO]

Socket6 does not seem to work with Win32 so... no plans for IPv6 right now.

Implemented Extensions

[TODO]

Portability Hacks

Net::BitTorrent aims to be portable between the big three OS When possible, this should be achieved without a glut of code using easily obtained third-party modules. Core modules are considered first followed by well tested CPAN modules. Modules that prevent broad use (ie. fails to install on a majority of systems) will not be considered.

There will be times, though, that $^O-based clutter is needed. Here is a list of both stable and experimental workarounds by OS:

MSWin32
Extended charset filename support

[TODO]

Do Your Part

Automated Testing

[TODO]

Bug Reporting

Right now, the best way to contribute would be through bug reports and patch submissions.

Before creating a new report through Net::BitTorrent's Issue Tracker, 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. All patches should be made against the most recent revision and well tested. For a list of svn clients, some of which make patch creation a little easier, see http://subversion.tigris.org/links.html#clients.

  • Make sure the bug is reproducible.

  • Please write in clear English.

  • Include as much detail as possible when describing the bug. Provide "baby steps" to describe exactly how to replicate the bug. Sample code is welcome. Net::BitTorrent's issue tracker also allows attachments so, if relevant, also include the .torrent file regardless of its content.

  • Search the list of open and resolved issues to make sure the flaw hasn't already been reported. If it has, you can star the issue to stay up to date. You'll know what I mean by 'star' it when you get there... I can see how many people have stars on a particular issue and popular bugs get priority.

  • Issues are open to the public, so don't include passwords or other confidential information. Beyond that, you can never provide too much information in a bug report.

  • One bug is one bug report. Please do not include multiple, separate issues in one report unless they are explicitly related to each other.

  • If the bug is related to one .torrent in particular, please attach it to your report.

  • It never hurts to do a little homework. If you run into a problem, find the place that's causing trouble and manage to fix it, please attach a patch (diff against the latest svn revision) or at least a very good description (with code) of what you did.

  • Star the issue so you can stay up to date with my progress.

  • Look over your report before submission to be sure you've included as much detail as possible. Seriously. Get up, have a drink of water, come back, read over it again to make sure you've included everything you intended, and then submit.

Co-Development and Patch Submission

Net::BitTorrent is too large for just one person to hack on. If you're Perl proficient and would like to help, you can start by fixing problems reported in the Issue Tracker and bugs you find on your own. When I decide to start looking for permanant co-devs, you'll already have your foot in the door.

Please submit patches for review by attaching it through the Net::BitTorrent Issue Tracker. If it's a patch to fix an existing Issue, use that thread. Otherwise, create a new Issue. Minor patches get your name in the changelog. Major (security, especially) patches get your name in the Acknowledgments section. Oooo. Ahhh.

See Also

The Project's Website

For updates and links to the wiki and subversion repository access, please visit http://sankorobinson.com/net-bittorrent/.

Receive SVN Commit and Issue Tracker Updates

The preferred way is to subscribe to one of the feeds of the announce group. Both ATOM 1.0 and RSS 2.0 feeds are provided; see http://groups.google.com/group/net-bittorrent-announce/feeds for a list.

To have each message delivered to your mailbox, subscribe to the read only announce group by visiting http://groups.google.com/group/net-bittorrent-announce.

Public Mailinglist

Rather than contacting me directly (which you're welcome to do, it's just nice having a searchable, public archive), general questions and comments should be posted to the Net::BitTorrent mailing list. To subscribe to the list or view the archive, visit http://groups.google.com/group/net-bittorrent-discuss.

Issue Tracker

Use http://code.google.com/p/net-bittorrent/issues/list for bug tracking. Please include as much information as possible.

Stalk Me While I Tinker

Follow Net::BitTorrent's development on Twitter: http://twitter.com/Net_BitTorrent.

Ohloh

It's open source social networking. ...I think. Regardless of it's use, Net::BitTorrent has an Ohloh page: http://www.ohloh.net/projects/net-bittorrent/

Wait, project cost: $65,430? Yeah, okay!

Other Recommend Open Source BitTorrent Clients
RFC 3986 (URI: Generic Syntax)

Section 2.3. "Unreserved Characters" (http://tools.ietf.org/html/rfc3986#section-2.3)

PAUSE FAQ sub-section entitled "Developer Releases"

(http://www.cpan.org/modules/04pause.html)

Author

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

CPAN ID: SANKO

Disclaimer and Legal

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

This document and the specifications behind it are subject to change.

This original documentation is covered by the Creative Commons Attribution-Noncommercial-Share Alike 3.0 License (United States jurisdiction).

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

1 POD Error

The following errors were encountered while parsing the POD:

Around line 187:

=back without =over