A maintainable, extensible BitTorrent client (C11, Linux/io_uring) targeting 10 GbE saturation. All torrent functionality is built from scratch; liburing is the only linked third-party dependency on the data path. Implements Phases 1-7 of the roadmap: - core: page-aligned buffer pool, MPMC/Treiber queues, bitfields, worker pool - crypto: SHA-1/256 (SHA-NI + scalar), Merkle (BEP-52), RC4 (MSE) - bencode/metainfo: zero-copy parser, v1/v2/hybrid .torrent + magnet - peer: sans-IO wire codec, MSE/PE handshake state machine, BEP-10, ut_metadata, PEX - piece/storage: block-level multi-peer engine, rarest-first + endgame, per-file completion events + single-file relocate (move-as-you-finish) - tracker/dht: HTTP + UDP (BEP-15) trackers, BEP-5 KRPC iterative lookup - platform: io_uring reactor (SQPOLL, registered buffers, SEND_ZC) - surface: versioned RPC, native plugin ABI, sandboxed Lua scripting, nautd/nautctl Verified against libtorrent (single/multi/hybrid, MSE, magnet-via-DHT, swarm); unit + interop tests green; ASan/UBSan/TSan clean. Scripting reference in docs/scripting.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
49 lines
1.9 KiB
C
49 lines
1.9 KiB
C
/* bitfield.h — fixed-size bitset over uint64 words with hardware popcount.
|
|
*
|
|
* Backs every "set of pieces/blocks" in the engine: a peer's have-set, our own
|
|
* completed pieces, the in-flight request map, interested/choked flags. The
|
|
* count()/find operations use __builtin_popcountll and __builtin_ctzll so a
|
|
* rarest-first picker can scan availability cheaply even for huge torrents.
|
|
*/
|
|
#ifndef NAUT_BITFIELD_H
|
|
#define NAUT_BITFIELD_H
|
|
|
|
#include "naut/common.h"
|
|
|
|
typedef struct naut_bitfield {
|
|
uint64_t *words;
|
|
size_t nbits;
|
|
size_t nwords;
|
|
} naut_bitfield;
|
|
|
|
naut_err naut_bitfield_init(naut_bitfield *bf, size_t nbits);
|
|
void naut_bitfield_free(naut_bitfield *bf);
|
|
|
|
NAUT_INLINE bool naut_bitfield_test(const naut_bitfield *bf, size_t i) {
|
|
return (bf->words[i >> 6] >> (i & 63)) & 1u;
|
|
}
|
|
NAUT_INLINE void naut_bitfield_set(naut_bitfield *bf, size_t i) {
|
|
bf->words[i >> 6] |= (uint64_t)1 << (i & 63);
|
|
}
|
|
NAUT_INLINE void naut_bitfield_clear(naut_bitfield *bf, size_t i) {
|
|
bf->words[i >> 6] &= ~((uint64_t)1 << (i & 63));
|
|
}
|
|
|
|
void naut_bitfield_set_all(naut_bitfield *bf);
|
|
void naut_bitfield_clear_all(naut_bitfield *bf);
|
|
|
|
/* number of set bits */
|
|
size_t naut_bitfield_count(const naut_bitfield *bf);
|
|
/* true when all nbits bits are set (torrent complete) */
|
|
bool naut_bitfield_all_set(const naut_bitfield *bf);
|
|
|
|
/* index of first 0 / first 1 bit at or after `from`, or SIZE_MAX if none */
|
|
size_t naut_bitfield_find_zero(const naut_bitfield *bf, size_t from);
|
|
size_t naut_bitfield_find_set(const naut_bitfield *bf, size_t from);
|
|
|
|
/* Load/serialize the BEP-3 wire format: MSB-first within each byte. The wire
|
|
* order differs from our little-endian word order, so these are not memcpy. */
|
|
void naut_bitfield_from_wire(naut_bitfield *bf, const uint8_t *bytes, size_t nbytes);
|
|
void naut_bitfield_to_wire(const naut_bitfield *bf, uint8_t *bytes, size_t nbytes);
|
|
|
|
#endif /* NAUT_BITFIELD_H */
|