This patch rolls together a number of patches
previously posted here (by others), and I've also added
a number of other fixes and enhancements. A list of
the incorporated patches and summary of the other
changes follows. There is nothing "official" about
this patch/release; I'm just offering it as a
contribution, with thanks to those who contributed before.
I've tested pretty extensively on FreeBSD (4.11), but
please let me know if you find any problems.
Assistance with fixing any such problems on other
platforms (and remaining portable) will be especially
appreciated.
A patched source distribution is also available at
http://www.rahul.net/dholmes/ctorrent/
Patches
* Incorporates the following patches. The number
is the Request ID
from the SourceForge patches page, which you can
reference for
the details of each patch. The name in brackets
is the name of the
patch file or a name I chose to refer to the
patch. Some of these
names are used below (in brackets) to describe a
fix or change to
a particular patch.
1042808 [getcwd] (incorporated in get1file patch)
1084776 [passkey] (incorporated in udlimit patch)
1109266 [align]
1109287 [tracker/tracker2]
1114197 [fmt] (incorporated in get1file patch)
1114364 [resetdl]
1116448 [get1file]
1118597 [crash]
1119467 [stall]
1119492 [rate]
1119497 [flush]
1119519 [opt]
1119689 [status]
1124342 [udlimit]
Download performance
* If a peer socket is ready for reading and
writing, perform both.
Previously the cases were exclusive, with
preference given to
reading.
* Download requests are now made to peers when
they are ready for
writing (in addition to the existing
event-driven cases). This
fixes peer stalls when a request couldn't be
sent in an
event-triggered case due to bandwidth limiting
or other
circumstances.
* Additional tests added so that the above request
checking doesn't
create hard loops.
Bandwidth measurement/management
* [rate] Bandwidth reporting is now not capped.
Also, only the time
used for the samples taken is used in the
calculation rather than
the maximum interval (this affects rate
calculation for individual
peers).
* Additional upload and download bandwidth limit
checks added so
that bw management is more accurate.
* Corrected condition inversion bug in
Rate::StopTimer(), which
affects peer rate calculations.
Peer count
* Request our max number of peers from the tracker
each time rather
than just taking the tracker's default, so we
can try to fill up.
* The tracker will be contacted early if all peers
disconnect so
that we can actively try to establish some more
peer connections.
To avoid hammering the tracker, we must have at
least one peer for
15 seconds in order for this to be invoked.
* Some clients use nonzero bytes in the "reserved"
part of the
handshake. Added code to ignore the reserved
bytes if the rest of
the handshake is as expected. This includes
Azureus 2300 thru 2304
(latest) which gives 0x80 as the first reserved
byte and BitComet
which gives 0x6578 ("ex") as the first two bytes.
* Update peer's timestamp on any message, not just
keepalives. Any
receipt of data from a peer now resets its
timeout, preventing
early disconnect.
Parallel requests
* Initial-piece and endgame cases have been
improved so that pieces
will be requested from multiple peers. Cancels
are sent as slices
(subpieces) are received. This endgame strategy
is described in
the BitTorrent online spec. The startup strategy
is also described
in posts and facilitates obtaining a single
piece more rapidly in
order to obtain some trade value. In initial
mode, the piece of
which we need the least parts is targeted. In
endgame mode, the
piece of which we need the most parts is
targeted. Slices that are
cancelled are also removed from the "pending"
queue, as are pieces
that are completed.
* When duplicating a piece request, the slice
request order is also
shuffled in order to minimize duplication of effort.
Tracker info
* [status] Seems to be missing tracker.cpp diff.
Added code to get
tracker's total peers, but not all trackers
report these fields in
the normal response. Also added code to count
successful updates
from the tracker.
* Added tracker connection state to status line (when
connecting/connected).
Tracker contact
* When interrupting (ctrl-C), connect to the
tracker immediately
rather than waiting 15 seconds.
* Contact tracker "soon" after transitioning to
seeder state.
Peer interaction
* Manage our interested state for each peer
dynamically as content
changes.
* Unchoking
+ Use the peer's interested state (confirming
via the bitfield
that it needs our data) to consider
unchoking. Using only the
bitfield could cause us to waste an upload
slot on a peer
that doesn't have all content but isn't
interested (like a
single-file downloader).
+ Choke peers that become uninterested or
don't need our data.
+ Try unchoking new peers only as slots open
or the optimistic
unchoke rotates. Unchoking too many peers
can temporarily
reduce per-peer upload rates, which would
make uploading to
us unappealing for good peers.
+ In a tie for download speed, prefer to
unchoke the peer to
whom we've uploaded the least data relative
to what we've
downloaded from him.
* Optimistic unchoking
+ Fixed condition inversion bug causing opt
unchoking to occur
too often.
+ A peer who has no pieces is now preferred
75% vs. a peer who
already has at least one piece, in order to
help the new peer
become productive. This is documented in
the online spec.
+ Set peer's last-unchoke-time when choking
the peer to get
better rotation of the optimistic unchoke.
The value is now
the last time that a peer was in the
unchoked state rather
than the time of the last unchoke event.
Miscellaneous items
* [tracker] Fixed normal program end (stop)
process, which was
crashing.
* [get1file] Restore compact tracker response support.
* [get1file] Made display of the status line info
dependent on
whether the option is in use.
* [get1file] Apply the filter when checking for
what we need from a
peer instead of when recording what the peer
has; this prevents
stalls when we move on to the next file. Update
interested state
for each peer when we begin a new file. Also
move the file-done
check into the piece completion code and check
whether the next
file(s) has also been completed.
* Reduced the slice size from 32K to 16K (same as
BT & Azureus).
This provides more precise DL rate measurement,
and helps insure
that we receive a productive amount of data
(i.e. a complete
slice) even if we are unchoked by a peer for
only one cycle. See
http://groups.yahoo.com/group/BitTorrent/message/1260
for more
discussion/analysis on this.
* Added -v (verbose) option for additional
debugging output.
Logged In: YES
user_id=1313842
Sorry about the formatting of the detailed description; I'll
know how to do it right "next time". For a more readable
version see the URL in the 3rd paragraph.
Logged In: YES
user_id=1313842
Revised the diff file format to make it relative to the
working directory and include a readme file (README-DNH.TXT)
with the above details.
"dnh1 release" patch for 1.3.4