jlibtorrent 2.0.12.9 is out — 86 upstream fixes, v2 torrent precision, and sharper NAT traversal

By the FrostWire team — github.com/frostwire/frostwire-jlibtorrent

We’re happy to ship jlibtorrent 2.0.12.9, the latest Java/JNI bindings for the libtorrent RC_2_0 branch. This release advances the underlying C++ engine by 86 commits (from 46cc651d to cb6fe6b9c), pulls in OpenSSL 3.6.0, and exposes four new Java APIs that give you finer control over NAT-PMP traversal, peer connection policies, and BitTorrent v2 metadata.

If you build BitTorrent clients, media streaming tools, or decentralized data pipelines in Java, this is the build you want.

What’s inside

1. TorrentInfo.pieceSizeForReq() — v2-aware piece sizing

BitTorrent v2 (hybrid and v2-only torrents) introduced Merkle trees and pad blocks to align pieces with 16 KiB blocks. That means the nominal piece size you read from a .torrent file and the actual number of bytes you must hash or request can differ.

pieceSizeForReq(int piece) returns the effective piece size for hash requests — the real byte count you pass to a hasher or a piece picker. For v1 and hybrid torrents it equals pieceSize(); for v2-only torrents it strips out padding so your progress bars and verification loops stay exact.

TorrentInfo ti = new TorrentInfo(torrentBytes);
long totalDataBytes = 0;

for (int i = 0; i < ti.numPieces(); i++) {
int reqSize = ti.pieceSizeForReq(i);
totalDataBytes += reqSize;
// allocate exactly reqSize bytes for the piece buffer
}

// totalDataBytes == ti.totalSize() for v1/hybrid
// totalDataBytes <= ti.totalSize() for v2 (pad blocks excluded)

Use it when:

  • Computing precise download progress on v2 torrents
  • Allocating per-piece hash buffers in a cross-version client
  • Building telemetry that must reconcile “bytes on disk” vs “bytes of content”

2. SettingsPack.natpmpGateway() — override the NAT-PMP gateway

NAT-PMP auto-discovery fails on VPNs, container networks, and multi-homed hosts. natpmpGateway(String) lets you point libtorrent at the exact gateway address to punch through.

SettingsPack pack = new SettingsPack();
pack.natpmpGateway("10.200.1.1"); // WireGuard exit node
session.applySettings(pack);

Leave it empty ("") and libtorrent falls back to automatic detection — the old behavior.

3. SettingsPack.allowMultipleConnectionsPerPid() — relax the duplicate-peer guard

By default libtorrent drops connections that share the same peer ID, a simple loop-prevention rule. In carrier-grade NAT (CGNAT) environments, dozens of legitimate peers can share one public IP and one peer ID. Enabling this setting lets you keep talking to all of them.

SettingsPack pack = new SettingsPack();

// Only enable on private trackers or known-CGNAT swarms
if (trackerIsCGNATHeavy(announceUrl)) {
pack.allowMultipleConnectionsPerPid(true)
.connectionsLimit(500); // raise ceiling to match
}

Security note: don’t flip this on open public swarms — it opens a trivial amplification vector.

4. SettingsPack.natpmpLeaseDuration() — control mapping lifetime

NAT-PMP mappings expire. The default lease is 3600 seconds (1 hour). For short mobile sessions you may want 300 s; for seed boxes, 7200 s reduces background chatter.

SettingsPack pack = new SettingsPack();

switch (deviceProfile) {
case MOBILE_TEMPORARY -> pack.natpmpLeaseDuration(300);
case DESKTOP_STANDARD -> pack.natpmpLeaseDuration(3600); // default
case SEED_BOX -> pack.natpmpLeaseDuration(7200);
}

Libtorrent auto-renews at roughly 50 % elapsed time, so a 300 s lease triggers a refresh every ~150 s.


Build & dependency updates

DependencyBeforeAfter
libtorrent46cc651dcb6fe6b9c (86 commits)
OpenSSL3.5.23.6.0
Boost1.88.01.88.0 (1.91.0 tested, ABI issue on macOS arm64)
SWIG4.3.14.4.1

The upstream 86-commit delta includes hardening around tracker URL validation, SOCKS5 parsing, resume-data sanitization, peer encryption, and symbolic link support (BEP 47). Your users get those fixes for free the moment they load the new native library.

Build note: -frtti is now required

One upstream commit (d0e59960a) introduced dynamic_cast inside the smart-ban plugin. That collides with our traditional -fno-rtti builds. We added -frtti to all platform configs (macosx-arm64linux-arm64, and by extension the Docker-based Linux/Windows/Android builds on our EC2 farm). Binary size impact is negligible; correctness is non-negotiable.


Get it

Maven (GitHub Packages)

repositories {
maven { url "https://maven.pkg.github.com/frostwire/frostwire-jlibtorrent" }
}

dependencies {
def v = '2.0.12.9'
implementation "com.frostwire:jlibtorrent:$v"
implementation "com.frostwire:jlibtorrent-macosx-arm64:$v" // or your platform
}

Direct download

JARs are attached to the GitHub Release. Grab the platform-independent jlibtorrent-2.0.12.9.jar plus your native artifact:


Full upstream changelog (libtorrent 46cc651d → cb6fe6b9c)

Notable upstream commits consumers should care about:

  • Sanitize resume data — reject mismatching info-hashes in resume data (read_resume_data now logs a warning)
  • Strengthen peer encryption — obfuscation layer tightened
  • SOCKS5 hardening — edge cases in UDP unwrap, CONNECT Host header parsing, and redirect handling patched
  • Tracker URL validation — stricter parsing to prevent malformed announce URLs from crashing the tracker manager
  • BEP 47 symlink support — create_torrent now stores symbolic links correctly in v1/v2 metadata
  • NATPMP gateway override — the libtorrent feature that became our natpmpGateway setting
  • Multiple connections per peer ID — the libtorrent feature that became our allowMultipleConnectionsPerPid setting
  • NAT-PMP lease duration control — the libtorrent feature that became our natpmpLeaseDuration setting
  • Add high_priority reannounce flag — carried forward from 2.0.12.8
  • Add disk_disable_copy_on_write — carried forward from 2.0.12.8
  • Add file pool performance counters — carried forward from 2.0.12.8

Compatibility

  • Java source/target: 17
  • BitTorrent protocols: v1, v2, hybrid (v1+v2)
  • Platforms: macOS (arm64, x86_64), Linux (x86_64, arm64), Windows (x86_64), Android (arm, arm64, x86, x86_64)

Leave a comment