BDecoder applies no recursion limit to untrusted bencode,
so a large nested list or map produces a StackOverflowError
that passes through every catch(Exception) guard on the receive path
and terminates the shared I2P session dispatcher thread.
Fix by declaring and catching Throwable everywhere.
Reported by: haoxucu
- consolidate length rectification code
- fix rectification for file length > 2 GB
- make InputStream method public again, with the requirement
to call rectify() first for files
- clarify plen param requirement for files vs. pieces
- add plen param for byte[] method
- add debug output for empty hashes
The request throttler had several problems:
- Throttling was very laggy, but when it reacted it throttled too quickly.
- PartialPieces got returned back to PeerCoordinator,
and then back to PeerState, every few seconds, rather
than continuing steady-state in PeerState
- Holding the PartialPiece in the PeerCoordinator for
several seconds while staying interested is poor and risks snubbing
- Max request queue size was reduced far too quickly,
doing so exponentially when the reduction occurred linearly
- shouldRequest() called the request limiter second in the conditional,
so the estimator was not decayed properly when over down bw limit
- shouldRequest() used overDownBandwidthLimit() rather than _down.offer(),
ensuring a very slow and laggy feedback loop.
- Requests were added too quickly on unthrottle
Fix these by:
- Fixing and slowing max request queue size reduction to simulate
an exponential reduction over time when throttled
- Fixing shouldRequest() to always call offer() for both limiters
- Slow addition of requests after unthrottle to simulate
a linear increase over time
Log tweaks also
The request queue now mostly maintains a steady size,
and properly meters the requests.
The PartialPiece returns to the PeerCoordinator much less often,
and comes back to PeerState much quicker if it does.
Further tuning TODO
- For fast peers:
Do not rerequest, peer is expected to meet its BEP 6 obligation,
and rerequesting needlessly inflates the request bandwidth estimate
- Drop dup requests for pieces peers already have
- Remove old comment about future enhancements we already did
- Fix repeated PartialPiece log about hole filled in
- Log tweaks
Should improve d/l from qbittorrent that aggressively reorders
for large piece sizes, use a buffer instead,
in two spots: creating and rechecking.
Pass the hash instead of the piece to MetaInfo.checkPiece()
Remove now-unused methods.