|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +libtorrent-rasterbar is a C++17 BitTorrent library (version 2.1.0). It supports v1 and v2 torrents, DHT, WebTorrent (WebRTC), and optional I2P/SSL. |
| 8 | + |
| 9 | +## Build Systems |
| 10 | + |
| 11 | +The project has **two build systems**: boost-build (b2/bjam) and CMake. **Boost-build is the preferred build system** per the contributing guidelines. |
| 12 | + |
| 13 | +### Boost-build (b2) — preferred |
| 14 | + |
| 15 | +**Never add `-j` (parallel jobs) flags to b2 commands.** b2 manages parallelism on its own. |
| 16 | + |
| 17 | +Build the library (from repo root): |
| 18 | +```sh |
| 19 | +b2 |
| 20 | +``` |
| 21 | + |
| 22 | +Run unit tests: |
| 23 | +```sh |
| 24 | +cd test && b2 |
| 25 | +``` |
| 26 | + |
| 27 | +Run a single test: |
| 28 | +```sh |
| 29 | +cd test && b2 test_session |
| 30 | +``` |
| 31 | + |
| 32 | +Run deterministic tests (no flaky networking): |
| 33 | +```sh |
| 34 | +cd test && b2 deterministic-tests |
| 35 | +``` |
| 36 | + |
| 37 | +Run simulations: |
| 38 | +```sh |
| 39 | +cd simulation && b2 |
| 40 | +``` |
| 41 | + |
| 42 | +Build with developer options (typical for development): |
| 43 | +```sh |
| 44 | +cd test && b2 asserts=on invariant-checks=full debug-iterators=on picker-debugging=on |
| 45 | +``` |
| 46 | + |
| 47 | +Build with sanitizers: |
| 48 | +```sh |
| 49 | +cd test && b2 address-sanitizer=norecover undefined-sanitizer=norecover asserts=on |
| 50 | +``` |
| 51 | + |
| 52 | +Build examples, tools, fuzzers, python bindings: |
| 53 | +```sh |
| 54 | +cd examples && b2 |
| 55 | +cd tools && b2 |
| 56 | +cd fuzzers && b2 clang |
| 57 | +cd bindings/python && b2 |
| 58 | +``` |
| 59 | + |
| 60 | +### CMake — alternative |
| 61 | + |
| 62 | +```sh |
| 63 | +cmake -B build -DCMAKE_BUILD_TYPE=Debug -Dbuild_tests=ON |
| 64 | +cmake --build build |
| 65 | +cd build && ctest |
| 66 | +``` |
| 67 | + |
| 68 | +Run a single test via CMake: |
| 69 | +```sh |
| 70 | +cd build && ./test/test_session |
| 71 | +``` |
| 72 | + |
| 73 | +## Pre-commit |
| 74 | + |
| 75 | +The repo uses [pre-commit](https://pre-commit.com). Before pushing: |
| 76 | +```sh |
| 77 | +pip install pre-commit |
| 78 | +pre-commit install |
| 79 | +pre-commit run --all-files |
| 80 | +``` |
| 81 | + |
| 82 | +Pre-commit hooks include trailing whitespace, YAML/TOML/XML checks, RST formatting, Python formatting (black, isort, flake8, mypy, autoflake), and auto-generation of: |
| 83 | +- `include/libtorrent/fwd.hpp` and `include/libtorrent/libtorrent.hpp` via `tools/gen_fwd.py` and `tools/gen_convenience_header.py` |
| 84 | +- C binding headers (`bindings/c/include/libtorrent_settings.h`, `libtorrent_alerts.h`) via `bindings/c/tools/gen_header.py` and `bindings/c/tools/gen_alert_header.py` |
| 85 | + |
| 86 | +## Key Architecture |
| 87 | + |
| 88 | +### Threading Model |
| 89 | + |
| 90 | +Three thread categories: |
| 91 | +1. **Main network thread** — all sockets, session/torrent/peer state, boost.asio event loop |
| 92 | +2. **Disk I/O thread(s)** — reads, writes, and SHA-1/SHA-256 piece verification (count controlled by `settings_pack::aio_threads`) |
| 93 | +3. **Resolver thread** — spawned by boost.asio for async DNS on platforms without native async getaddrinfo |
| 94 | + |
| 95 | +All interaction with session/torrent state from outside must go through the network thread (via `session_handle` and `torrent_handle`). |
| 96 | + |
| 97 | +### Core Classes |
| 98 | + |
| 99 | +- **`session`** (`include/libtorrent/session.hpp`) — public API, pimpl over `session_impl` |
| 100 | +- **`session_impl`** (`include/libtorrent/aux_/session_impl.hpp`) — all session state: torrent list, connection list, global rate limits, DHT state, port mapping |
| 101 | +- **`torrent`** (`include/libtorrent/aux_/torrent.hpp`, `src/torrent.cpp`) — all state for a single swarm: piece picker, peer connections, file storage |
| 102 | +- **`torrent_handle`** (`include/libtorrent/torrent_handle.hpp`) — public pimpl handle, weak reference to `torrent`; sends messages to network thread |
| 103 | +- **`peer_connection`** / **`bt_peer_connection`** — BitTorrent protocol implementation |
| 104 | +- **`piece_picker`** — download strategy (which blocks to request from which peers). See `.claude/rules/piece-picker.md` for a detailed description. |
| 105 | +- **`peer_list`** — list of known (not necessarily connected) peers for a swarm |
| 106 | + |
| 107 | +### Disk I/O |
| 108 | + |
| 109 | +Three disk backends: |
| 110 | +- `mmap_disk_io` — mmap-based (default on 64-bit when mmap is available) |
| 111 | +- `posix_disk_io` — fallback single-threaded POSIX I/O (used on 32-bit or without mmap) |
| 112 | +- `pread_disk_io` — multi-threaded backend using `pread()`/`pwrite()`. See `.claude/rules/disk-cache.md` for a detailed description. |
| 113 | + |
| 114 | +### DHT (Kademlia) |
| 115 | + |
| 116 | +Source in `src/kademlia/`, headers in `include/libtorrent/kademlia/`. Includes ed25519 signing (`src/ed25519/`). |
| 117 | + |
| 118 | +### Extensions |
| 119 | + |
| 120 | +Protocol extensions live in `src/` and `include/libtorrent/extensions/`: |
| 121 | +- `ut_metadata` — magnet link metadata exchange |
| 122 | +- `ut_pex` — peer exchange |
| 123 | +- `smart_ban` — ban peers that send corrupt data |
| 124 | +- `i2p_pex` — peer exchange for I2P peers |
| 125 | + |
| 126 | +### WebTorrent (WebRTC) |
| 127 | + |
| 128 | +Optional feature controlled by `webtorrent=on` / `-Dwebtorrent=ON`. Uses `deps/libdatachannel` and the `rtc_stream`/`rtc_signaling` subsystem. |
| 129 | + |
| 130 | +### Python Bindings |
| 131 | + |
| 132 | +Source in `bindings/python/src/*.cpp`, built as `libtorrent.so` using boost.python. See `.claude/rules/python-bindings.md` for detailed conventions. |
| 133 | + |
| 134 | +### Simulations |
| 135 | + |
| 136 | +`simulation/` contains network simulation tests that use `libsimulator` (a deterministic virtual network). These test high-level behaviors (swarms, DHT, session management) without real network access. All simulation tests run with `invariant-checks=full`, `asserts=on`, `debug-iterators=on`. |
| 137 | + |
| 138 | +### Terminology |
| 139 | + |
| 140 | +- **piece** — SHA-1/SHA-256 verified chunk of torrent data (typically power-of-two size) |
| 141 | +- **block** — 16 KiB sub-unit of a piece (the transfer unit in the protocol) |
| 142 | +- **torrent_peer** — a known-but-not-connected peer entry |
| 143 | +- **peer_connection** — an active connection to a peer |
| 144 | + |
| 145 | +## Key Build Options (b2 features) |
| 146 | + |
| 147 | +| Feature | Values | |
| 148 | +|---------|--------| |
| 149 | +| `crypto` | `built-in`, `openssl`, `openssl-shared`, `wolfssl`, `gcrypt`, `gnutls`, `libcrypto` | |
| 150 | +| `asserts` | `on`, `off`, `production`, `system` | |
| 151 | +| `invariant-checks` | `off`, `on`, `full` | |
| 152 | +| `logging` | `on`, `off` | |
| 153 | +| `deprecated-functions` | `on`, `off`, `1`, `2`, `3`, `4` | |
| 154 | +| `webtorrent` | `on`, `off` | |
| 155 | +| `address-sanitizer` | `norecover`, `recover`, `off` | |
| 156 | +| `undefined-sanitizer` | `norecover`, `recover`, `off` | |
| 157 | +| `thread-sanitizer` | `norecover`, `recover`, `off` | |
| 158 | +| `picker-debugging` | `on`, `off` | |
| 159 | +| `debug-iterators` | `default`, `off`, `on`, `harden` | |
| 160 | + |
| 161 | +`deprecated-functions` selects the ABI/API version via `TORRENT_ABI_VERSION`. Different values are **link-incompatible**. Higher numbers expose a more modern interface and remove older deprecated APIs: |
| 162 | + |
| 163 | +| Value | `TORRENT_ABI_VERSION` | Corresponds to | |
| 164 | +|-------|-----------------------|----------------| |
| 165 | +| `on` | (oldest supported) | libtorrent 1.x | |
| 166 | +| `1` | 1 | libtorrent 1.x | |
| 167 | +| `2` | 2 | libtorrent 2.0 | |
| 168 | +| `3` | 3 | libtorrent 2.x | |
| 169 | +| `4` | 4 | libtorrent 2.1 | |
| 170 | +| `off` | 100 (newest) | latest API | |
| 171 | + |
| 172 | +## Directory Layout |
| 173 | + |
| 174 | +``` |
| 175 | +src/ main library source |
| 176 | +src/kademlia/ DHT implementation |
| 177 | +src/ed25519/ ed25519 signing (vendored) |
| 178 | +include/libtorrent/ public API headers |
| 179 | +include/libtorrent/aux_/ internal headers (not public API) |
| 180 | +include/libtorrent/kademlia/ DHT headers |
| 181 | +include/libtorrent/extensions/ extension headers |
| 182 | +test/ unit tests (test_*.cpp) |
| 183 | +simulation/ network simulation tests (test_*.cpp) |
| 184 | +fuzzers/src/ fuzz targets |
| 185 | +examples/ example programs |
| 186 | +tools/ utility scripts and programs |
| 187 | +bindings/python/ Python bindings (boost.python) |
| 188 | +bindings/c/ C API bindings |
| 189 | +deps/ vendored dependencies |
| 190 | + deps/try_signal/ signal handling |
| 191 | + deps/asio-gnutls/ GnuTLS adapter for asio |
| 192 | + deps/json/ nlohmann/json (for WebTorrent) |
| 193 | + deps/libdatachannel/ WebRTC (for WebTorrent) |
| 194 | +``` |
| 195 | + |
| 196 | +## Adding New Source Files |
| 197 | + |
| 198 | +When adding a new `.cpp` or `.hpp` file, it must be added to **all three** build systems: |
| 199 | +1. `Jamfile` (boost-build) |
| 200 | +2. `CMakeLists.txt` |
| 201 | +3. `Makefile` (if applicable) |
| 202 | + |
| 203 | +## Code-Generation Tools |
| 204 | + |
| 205 | +After modifying public API headers, regenerate the derived headers by running these scripts from the repo root: |
| 206 | + |
| 207 | +- `tools/gen_fwd.py` — regenerates `include/libtorrent/fwd.hpp` (forward declarations for all public types) |
| 208 | +- `tools/gen_convenience_header.py` — regenerates `include/libtorrent/libtorrent.hpp` (the convenience header that includes all public headers) |
| 209 | + |
| 210 | +These are also run automatically by the pre-commit hooks. |
| 211 | + |
| 212 | +## Coding Conventions |
| 213 | + |
| 214 | +- Comments must use ASCII characters only (no Unicode, smart quotes, em-dashes, etc.) |
| 215 | +- Use a single space after a period in comments (not two spaces) |
| 216 | +- Declare variables `const` whenever they are not reassigned after initialization |
| 217 | +- C++17 throughout; no C++20 features yet |
| 218 | +- `namespace lt = libtorrent` alias is always available |
| 219 | +- Asserts: use `TORRENT_ASSERT(cond)` (active when `TORRENT_USE_ASSERTS` is defined, i.e. debug builds) |
| 220 | +- Invariant checks: expensive checks inside `#if TORRENT_USE_INVARIANT_CHECKS` |
| 221 | +- Public API headers use `TORRENT_EXPORT` macro; internal symbols use hidden visibility |
| 222 | +- Internal functions and classes use `TORRENT_EXPORT_EXTRA` macro; to grant access to tests |
| 223 | +- ABI versioning via `TORRENT_VERSION_NAMESPACE_2/3/4` inline namespace macros (defined in `include/libtorrent/aux_/export.hpp`); `_2` = v1.2, `_3` = v2, `_4` = v2.1 |
| 224 | +- Warnings are treated as errors in CI (both gcc and clang) |
| 225 | +- Changes to ABI (fields/ordering of public classes) must target `master`, not `RC_*` stable branches |
| 226 | +- `settings_pack` enum values must be appended at the end of each enum group (int, bool, string) — never inserted in the middle — to avoid changing the numeric values of existing settings and breaking ABI |
| 227 | +- prefer the C++ counterparts to C headers |
| 228 | +- do not use using-statements in header files |
| 229 | +- prefer to fully qualify standard types and functions |
| 230 | +- prefer the short lt namespace alias when fully qualifying libtorrent types |
| 231 | +- prefer using default member initializers over initializer list |
| 232 | + |
| 233 | +### Strong Types |
| 234 | + |
| 235 | +Avoid raw `int` for indices and flags; use `aux::strong_typedef` (`include/libtorrent/units.hpp`) and `flags::bitfield_flag` (`include/libtorrent/flags.hpp`). See `.claude/rules/strong-types.md` for details. |
0 commit comments