Initial commit: Naut-Torrent — from-scratch 10 GbE BitTorrent client
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>
This commit is contained in:
commit
2178d6a70c
121 changed files with 12644 additions and 0 deletions
86
include/naut/piece.h
Normal file
86
include/naut/piece.h
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
/* piece.h — download state: block requests, piece assembly, verify, persist.
|
||||
*
|
||||
* A piece is assembled in memory as its blocks arrive, verified against the
|
||||
* metainfo hash (SHA-1 for v1/hybrid), then written to storage in one shot —
|
||||
* so a corrupt piece never reaches disk.
|
||||
*/
|
||||
#ifndef NAUT_PIECE_H
|
||||
#define NAUT_PIECE_H
|
||||
|
||||
#include "naut/common.h"
|
||||
#include "naut/metainfo.h"
|
||||
#include "naut/storage.h"
|
||||
#include "naut/bitfield.h"
|
||||
#include "naut/worker.h"
|
||||
|
||||
typedef struct naut_download naut_download;
|
||||
|
||||
naut_download *naut_download_create(const naut_metainfo *mi, naut_storage *st);
|
||||
void naut_download_destroy(naut_download *d);
|
||||
|
||||
/* Optional hash offload. Completed-piece SHA-1 jobs run on the worker pool;
|
||||
* naut_download_poll() finalizes verified pieces on the owning engine thread.
|
||||
* The pool must outlive the download. */
|
||||
void naut_download_set_worker_pool(naut_download *d, naut_worker_pool *pool);
|
||||
naut_err naut_download_poll(naut_download *d, uint32_t *pieces_completed);
|
||||
|
||||
/* ---- multi-peer swarm interface (Phase 4) ------------------------------- *
|
||||
* Availability: report what each peer has so rarest-first can rank pieces. A
|
||||
* peer's bitfield is added on connect (BITFIELD) and removed on disconnect; a
|
||||
* single HAVE bumps one piece. */
|
||||
void naut_download_add_bitfield(naut_download *d, const naut_bitfield *peer_have);
|
||||
void naut_download_remove_bitfield(naut_download *d, const naut_bitfield *peer_have);
|
||||
void naut_download_inc_avail(naut_download *d, uint32_t piece);
|
||||
|
||||
/* Pick the next block to request for a peer with `peer_have`. Uses rarest-first,
|
||||
* prefers finishing in-progress pieces, and switches to endgame (allowing a
|
||||
* block to be requested from multiple peers) when few blocks remain. Returns
|
||||
* false if this peer has nothing useful to request right now. */
|
||||
bool naut_download_pick(naut_download *d, const naut_bitfield *peer_have,
|
||||
uint32_t *index, uint32_t *begin, uint32_t *length);
|
||||
|
||||
/* Endgame may duplicate a block across peers, but never back to the same peer.
|
||||
* `peer_has_request` lets the caller expose that peer's current request set.
|
||||
* Outside endgame this behaves exactly like naut_download_pick(). */
|
||||
typedef bool (*naut_request_active_cb)(void *ctx, uint32_t index, uint32_t begin);
|
||||
bool naut_download_pick_for_peer(naut_download *d, const naut_bitfield *peer_have,
|
||||
naut_request_active_cb peer_has_request, void *ctx,
|
||||
uint32_t *index, uint32_t *begin, uint32_t *length);
|
||||
|
||||
/* Release a request (peer disconnected, or cancel) so the block can be re-picked. */
|
||||
void naut_download_unrequest(naut_download *d, uint32_t index, uint32_t begin);
|
||||
|
||||
bool naut_download_have(const naut_download *d, uint32_t piece);
|
||||
bool naut_download_in_endgame(const naut_download *d);
|
||||
|
||||
/* Per-file completion: fired the moment the last piece overlapping a file's byte
|
||||
* range verifies (so the file's bytes on disk are final and it is safe to move).
|
||||
* This is the engine seam for the user's "move files as they finish" feature —
|
||||
* the scripting layer (Phase 7) forwards this to an on_file_complete hook and may
|
||||
* then call naut_storage_relocate(). The callback runs on the engine thread; a
|
||||
* script must marshal any action back through the command queue.
|
||||
*
|
||||
* NOTE: fires during naut_download_on_block(); a single block may complete
|
||||
* several files (small files packed into one piece). Empty files are reported as
|
||||
* complete via naut_download_file_complete() but do not fire the callback. */
|
||||
typedef void (*naut_file_complete_cb)(void *ctx, uint32_t file_index, const char *path);
|
||||
void naut_download_set_file_cb(naut_download *d, naut_file_complete_cb cb, void *ctx);
|
||||
bool naut_download_file_complete(const naut_download *d, uint32_t file_index);
|
||||
|
||||
/* Hand out the next block to request. false => nothing left to hand out right
|
||||
* now (all blocks have been requested). */
|
||||
bool naut_download_next_request(naut_download *d,
|
||||
uint32_t *index, uint32_t *begin, uint32_t *length);
|
||||
|
||||
/* Feed a received PIECE block. *piece_done is set true iff this block completed
|
||||
* a piece that then verified and was written to storage. With a worker pool,
|
||||
* completion is reported later through naut_download_poll(). */
|
||||
naut_err naut_download_on_block(naut_download *d, uint32_t index, uint32_t begin,
|
||||
const uint8_t *data, uint32_t len, bool *piece_done);
|
||||
|
||||
bool naut_download_complete(const naut_download *d);
|
||||
uint32_t naut_download_num_pieces(const naut_download *d);
|
||||
uint32_t naut_download_pieces_done(const naut_download *d);
|
||||
uint64_t naut_download_bytes_done(const naut_download *d);
|
||||
|
||||
#endif /* NAUT_PIECE_H */
|
||||
Loading…
Add table
Add a link
Reference in a new issue