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
88
include/naut/mse.h
Normal file
88
include/naut/mse.h
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
/* mse.h - BitTorrent Message Stream Encryption (MSE/PE) transport. */
|
||||
#ifndef NAUT_MSE_H
|
||||
#define NAUT_MSE_H
|
||||
|
||||
#include "naut/common.h"
|
||||
#include "naut/peer.h"
|
||||
#include "naut/rc4.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#define NAUT_MSE_DH_LEN 96
|
||||
|
||||
typedef struct {
|
||||
naut_rc4 send;
|
||||
naut_rc4 recv;
|
||||
bool active;
|
||||
} naut_mse_stream;
|
||||
|
||||
/* ---- sans-IO handshake state machine ------------------------------------- *
|
||||
* The outgoing MSE/PE handshake as a pure state machine over byte buffers — no
|
||||
* sockets — so the same logic drives the blocking apps and the io_uring reactor
|
||||
* (where blocking in a handshake would stall a whole core's worth of peers).
|
||||
*
|
||||
* Drive it like a codec: pump NEED_WRITE bytes out, feed NEED_READ bytes in,
|
||||
* repeat until DONE or ERROR, then call _finish().
|
||||
*
|
||||
* h = naut_mse_handshake_begin(info_hash, peer_id, reserved);
|
||||
* for (;;) switch (naut_mse_handshake_status(h)) {
|
||||
* case NAUT_MSE_HS_NEED_WRITE: pull bytes, write them to the peer; break;
|
||||
* case NAUT_MSE_HS_NEED_READ: read bytes from the peer, feed them; break;
|
||||
* case NAUT_MSE_HS_DONE: naut_mse_handshake_finish(h, ...); goto ok;
|
||||
* case NAUT_MSE_HS_ERROR: ... ; goto err;
|
||||
* }
|
||||
*/
|
||||
typedef enum {
|
||||
NAUT_MSE_HS_NEED_READ,
|
||||
NAUT_MSE_HS_NEED_WRITE,
|
||||
NAUT_MSE_HS_DONE,
|
||||
NAUT_MSE_HS_ERROR,
|
||||
} naut_mse_hs_status;
|
||||
|
||||
typedef struct naut_mse_handshake naut_mse_handshake;
|
||||
|
||||
naut_mse_handshake *naut_mse_handshake_begin(
|
||||
const uint8_t info_hash[20],
|
||||
const uint8_t peer_id[NAUT_PEERID_LEN],
|
||||
uint64_t reserved);
|
||||
void naut_mse_handshake_free(naut_mse_handshake *h);
|
||||
|
||||
naut_mse_hs_status naut_mse_handshake_status(const naut_mse_handshake *h);
|
||||
|
||||
/* Copy pending outgoing bytes into buf (up to cap); returns the count, 0 when
|
||||
* nothing is queued. Call repeatedly until it returns 0. */
|
||||
size_t naut_mse_handshake_pull(naut_mse_handshake *h, uint8_t *buf, size_t cap);
|
||||
|
||||
/* Feed received bytes; *consumed reports how many were absorbed (the rest, if
|
||||
* any, must be re-fed — after DONE that remainder is the start of the encrypted
|
||||
* payload stream). Returns the new status. */
|
||||
naut_mse_hs_status naut_mse_handshake_feed(naut_mse_handshake *h,
|
||||
const uint8_t *data, size_t len,
|
||||
size_t *consumed);
|
||||
|
||||
/* Valid once status is DONE: hand out the negotiated stream and the peer's
|
||||
* decrypted BitTorrent handshake. */
|
||||
naut_err naut_mse_handshake_finish(naut_mse_handshake *h,
|
||||
naut_mse_stream *stream,
|
||||
uint8_t remote_handshake[NAUT_HANDSHAKE_LEN]);
|
||||
|
||||
/* Blocking convenience wrapper over the state machine: perform the whole
|
||||
* outgoing handshake on a blocking socket, offering RC4 only. The BitTorrent
|
||||
* handshake is carried as IA; the peer's decrypted handshake is returned in
|
||||
* remote_handshake. */
|
||||
naut_err naut_mse_client_handshake(
|
||||
int fd,
|
||||
const uint8_t info_hash[20],
|
||||
const uint8_t peer_id[NAUT_PEERID_LEN],
|
||||
uint64_t reserved,
|
||||
naut_mse_stream *stream,
|
||||
uint8_t remote_handshake[NAUT_HANDSHAKE_LEN]);
|
||||
|
||||
/* Stream I/O after a successful handshake. Encryption/decryption is in-place
|
||||
* with connection-owned RC4 state. send_all preserves the caller's buffer. */
|
||||
bool naut_mse_send_all(int fd, naut_mse_stream *stream,
|
||||
const void *data, size_t len);
|
||||
ssize_t naut_mse_recv(int fd, naut_mse_stream *stream,
|
||||
void *data, size_t len);
|
||||
|
||||
#endif /* NAUT_MSE_H */
|
||||
Loading…
Add table
Add a link
Reference in a new issue