=pod

=head1 NAME

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

=head1 Description

This is a first draft attempt at defining a road map for future
C<Net::BitTorrent> development and a behavioral reference for third-party
client developers.  A few bits for users might slip in too.

=head1 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

=head1 Installation

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

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

See also: L<Automated Test Reports|/"Automated Test Reports">

=head2 Prerequisites

C<Net::BitTorrent> requires L<version|version> and
L<Digest::SHA|Digest::SHA>.  On Win32, we try to use
L<Win32API::File|Win32API::File> and L<Encode|Encode> to handle extended
charset filenamesL<[1]|/"[1]">.  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.

X<[1]> We also use the internal C<utf8()> functions which didn't appear
until perl 5.8.1.  See L<Portability Hacks|/"Portability Hacks">.

=head1 How Do I...

Parts that aren't handled internally are described here (eventually) with
sample code to get you started.

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

L<Net::BitTorrent::Torrent|Net::BitTorrent::Torrent> objects can be
created directly 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 L<Net::BitTorrent::Torrent|Net::BitTorrent::Torrent> for
more.

=head2 Pause and Resume a .torrent Session

See
L<Net::BitTorrent::Torrent::pause( )|Net::BitTorrent::Torrent/"pause( )">
and
L<Net::BitTorrent::Torrent::start( )|Net::BitTorrent::Torrent/"start( )">

=head2 Stop and Resume a .torrent Session

See
See
L<Net::BitTorrent::Torrent::stop( )|Net::BitTorrent::Torrent/"stop( )">
and
L<Net::BitTorrent::Torrent::start( )|Net::BitTorrent::Torrent/"start( )">


=head2 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 node ID and routing table would be a good idea too.  Add to that
some sort of verification scheme to be sure you're not loading corrupt
data.  Then, when you reload the torrent, shove your data through all the
related back alley private methods until I come up with a less insane way
to do this safely.

=head2 Set File Priorities

See
L<Net::BitTorrent::Torrent::File|Net::BitTorrent::Torrent::File/"priority( [NEWVAL] )">.

=head2 Implement My Own Event Loop

[TODO]

=head1 Net::BitTorrent Internals

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

=head2 Peer ID Specification

Please see L<Net::BitTorrent::Version|Net::BitTorrent::Version>.

=head2 Handling of Errors and Bad Data

[TODO]

=head3 .torrent Metadata

[TODO]

=head3 Incoming Protocol Data

[TODO]

=head3 Disk Access Errors

[TODO]

=head2 Piece Selection

To have any semblance of basic functionality, a BitTorrent client must
have a good piece selection strategy.  The 'strict priority' based
algorithm used by L<Net::BitTorrent|Net::BitTorrent> seems to strike a
balance between efficiency and speed while keeping the pipes full of
incoming data.  I'll walk you through it...

=over 4

=item 1.

Count the number of unrequited C<$free_blocks> in all working pieces.

=item 2.

Count how many C<$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.

=item 3.

C<$max_working> is set to the current number of working pieces plus the
bool value of C<$free_blocks E<lt> $free_slots>.

=item 4.

Calculate C<%weights> based on file priorities and our bitfield.

=over

=item 4b.

If C<%weights> is empty, we return without making a new request.

=back

=item 5.

Take the sum of all the relative (priority) weights and call it C<$total>

=item 6.

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

=item 7.

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

=over

=item 7b.

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

=item 7c.

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

=back

=item 8.

If C<%weights{$i}> is defined...

=over

=item 8b.

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.

=item 8c.

...otherwise, we return an undefined value.

=back

=back

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

=head2 Outgoing Requests

[TODO]

=head3 Queuing

[TODO]

=head3 Slow Blocks

[TODO]

=head3 Endgame

[TODO]

=head2 Incoming Requests

[TODO]

=head3 Queuing

[TODO]

=head3 Rejections (Fast Ext)

[TODO]

=head2 Trackers

[TODO]

=head3 Multi-tracker .torrents

[TODO]

=head3 UDP Trackers

[TODO]

=head2 Fast Set Advertising

[TODO]

=head2 IPv6-Related Information

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

=head2 Implemented Extensions

The BitTorrent Community Forum coordinates the development of the
BitTorrent protocol suite, its reference implementation, and BitTorrent
Enhancement Proposals (BEPs).  For more information, see BEP 0: Index of
BitTorrent Enhancement Proposals
http://bittorrent.org/beps/bep_0000.html

This is the list of extensions used by this release of
L<Net::BitTorrent|Net::BitTorrent> sorted by their progress toward
standardization.

=head3 Accepted BEPs

These BEPs describe mechanisms that have been deployed in one or more
BitTorrent implementations and have proven useful.  They may require
minor revisions.  They await the blessing of the BDFL before they can be
considered Final.

=over

=item *

BEP 32: Tracker Returns Compact Peer Lists -
http://bittorrent.org/beps/bep_0023.html

=back

=head3 Draft BEPs

The following BEPs are under consideration for standardization.

=over

=item *

BEP 5: DHT Protocol - http://bittorrent.org/beps/bep_0005.html

=item *

BEP 6: Fast Extension - http://bittorrent.org/beps/bep_0006.html

Note: the Fast Extension is only partially implemented in
L<Net::BitTorrent|Net::BitTorrent>.

=item *

BEP 10: Extension Protocol - http://bittorrent.org/beps/bep_0010.html

=item *

BEP 12: Multitracker Metadata Extension -
http://bittorrent.org/beps/bep_0012.html

=item *

BEP 15: UDP Tracker Protocol - http://bittorrent.org/beps/bep_0015.html

=item *

BEP 27: Private Torrents - http://bittorrent.org/beps/bep_0027.html

=back

=head2 Portability Hacks

L<Net::BitTorrent|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 C<$^O>-based clutter is needed.  Here
is a list of both stable and experimental workarounds by OS:

=over

=item MSWin32

=over

=item Extended charset filename support

[TODO]

=back

=back

=head1 Giving back

If you're interested in assisting with
L<Net::BitTorent|Net::BitTorrent>'s development but don't know where to
begin, here are a few ideas.

=head2 Automated Test Reports

Becoming a CPAN Tester is an easy, automatic way to contribute to the
quality of your favorite module and CPAN in general.  If you would like
to contribute automated test reports for C<Net::BitTorrent>, install
C<CPAN::Reporter> from the CPAN shell first:

 $ 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, see the
L<CPAN::Reporter|CPAN::Reporter/"DESCRIPTION"> documentation and
http://cpantesters.org/.

=head2 Bug Reporting

Found bugs should be reported through C<Net::BitTorrent>'s
L<Issue Tracker|/"Issue Tracker">.  Please include as much information as
possible.  Before creating a new report through C<Net::BitTorrent>'s
L<Issue Tracker|/"Issue Tracker">, please review the following list:

=over

=item 1.

Make sure you are using the most recent release of C<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
L<http://subversion.tigris.org/links.html#clients>.

=item 2.

Make sure the bug is reproducible.

=item 3.

Please write in clear English.

=item 4.

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.

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

=item 5.

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.

=item 6.

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.

=item 7.

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

=item 8.

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.

=item 9.

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

=item 10.

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.

=back

=head2 Co-Development and Patch Submission

C<Net::BitTorrent> is too large for just one person to hack on.  If
you're Perl adept and would like to help, you can start by fixing
problems reported in the L<Issue Tracker|/"Issue Tracker"> and bugs you
find on your own.  I am currently seeking co-devs and patches are a great
way to get your foot in the door.

Please submit patches for review by attaching it through the
C<Net::BitTorrent> L<Issue Tracker|/"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
L<Acknowledgments|Net::BitTorrent/Acknowledgments> section.  Oooo.
Ahhh.

=head1 See Also

=over

=item Support and Information Links for C<Net::BitTorrent>

=over 4

=item The Project's Website

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

=item 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
L<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
L<http://groups.google.com/group/net-bittorrent-announce>.

=item 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 C<Net::BitTorrent> mailing list.  To
subscribe to the list or view the archive, visit
L<http://groups.google.com/group/net-bittorrent-discuss>.

=item Issue Tracker

Use L<http://code.google.com/p/net-bittorrent/issues/list> for bug
tracking.  Please include as much information as possible and review the
list L<above|/"Bug Reporting">.

=item Stalk Me While I Tinker

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

=item 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!

=back

=item Other Recommend Open Source BitTorrent Clients

=over 4

=item *

libtorrent (L<http://www.rasterbar.com/products/libtorrent/>) is covered
by the The BSD License.

=item *

Bitflu (L<http://bitflu.workaround.ch/>) is a full client written in
(*nix oriented) Perl and available under the Perl/Artistic License.

=item *

btpeer (L<http://www.alhem.net/project/btpeer/>) is "a collection of
classes implementing the core client functionality of the BitTorrent
protocol" and has been released under the GPL.

=item *

Arctic (L<http://dev.int64.org/arctic.html>) is a minimal client based on
libtorrent, written in C++ and released under the MIT License.

=back

=item RFC 3986 (URI: Generic Syntax)

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

=item PAUSE FAQ sub-section entitled "Developer Releases"

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

=back

=head1 Author

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

CPAN ID: SANKO

=head1 License and Legal

Copyright (C) 2008 by Sanko Robinson E<lt>sanko@cpan.orgE<gt>

This program is free software; you can redistribute it and/or modify
it under the terms of The Artistic License 2.0.  See the F<LICENSE>
file included with this distribution or
http://www.perlfoundation.org/artistic_license_2_0.  For
clarification, see http://www.perlfoundation.org/artistic_2_0_notes.

When separated from the distribution, all POD documentation is covered
by the Creative Commons Attribution-Share Alike 3.0 License.  See
http://creativecommons.org/licenses/by-sa/3.0/us/legalcode.  For
clarification, see http://creativecommons.org/licenses/by-sa/3.0/us/.

Neither this module nor the L<Author|/Author> is affiliated with
BitTorrent, Inc.

=for svn $Id: Notes.pod 34 2008-11-20 03:38:52Z sanko@cpan.org $

=cut
