Naut/include/naut/tracker.h
ookami125 2178d6a70c 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>
2026-06-15 12:12:00 -04:00

68 lines
2.9 KiB
C

/* tracker.h — HTTP and UDP tracker clients (BEP-3/BEP-23, BEP-15).
*
* Split into pure codec (URL building, bencode response parsing, UDP packet
* encode/decode — all unit-testable without a socket) and thin blocking fetch
* helpers used by the swarm app. HTTPS/TLS is deferred to a later transport
* backend; the built-ins in this phase are plaintext HTTP and UDP.
*/
#ifndef NAUT_TRACKER_H
#define NAUT_TRACKER_H
#include "naut/common.h"
/* IPv4 compact peer (BEP-23). IPv6 (BEP-7) is a later addition. */
typedef struct { uint8_t ip[4]; uint16_t port; } naut_peer_addr;
typedef enum {
NAUT_TEV_NONE = 0, NAUT_TEV_COMPLETED = 1, NAUT_TEV_STARTED = 2, NAUT_TEV_STOPPED = 3
} naut_tracker_event; /* values match BEP-15 UDP event codes */
typedef struct {
uint8_t info_hash[20];
uint8_t peer_id[20];
uint16_t port;
uint64_t uploaded, downloaded, left;
naut_tracker_event event;
int32_t numwant; /* -1 for default */
uint32_t key;
} naut_announce_req;
typedef struct {
int32_t interval;
int32_t seeders, leechers; /* -1 if absent */
naut_peer_addr *peers;
size_t num_peers;
char *failure; /* tracker "failure reason", or NULL */
} naut_tracker_response;
void naut_tracker_response_free(naut_tracker_response *r);
/* --- HTTP --- */
/* Build the full announce GET URL (base?...params) with percent-encoded binary
* info_hash/peer_id. Returns bytes written (excl NUL) or 0 on overflow. */
size_t naut_tracker_http_url(const char *base, const naut_announce_req *req,
char *out, size_t outsz);
/* Parse a bencoded HTTP tracker response body (compact or dict peer list). */
naut_err naut_tracker_parse_http(const uint8_t *body, size_t len,
naut_tracker_response *out);
/* --- UDP (BEP-15): pure packet codec --- */
#define NAUT_UDP_CONNECT_REQ_LEN 16
#define NAUT_UDP_ANNOUNCE_REQ_LEN 98
void naut_udp_build_connect(uint8_t out[16], uint32_t txid);
naut_err naut_udp_parse_connect(const uint8_t *in, size_t len, uint32_t txid,
uint64_t *connection_id);
void naut_udp_build_announce(uint8_t out[98], uint64_t connection_id,
uint32_t txid, const naut_announce_req *req);
naut_err naut_udp_parse_announce(const uint8_t *in, size_t len, uint32_t txid,
naut_tracker_response *out);
/* --- live fetch helpers (blocking) --- */
/* HTTP GET the announce URL; fills out. Only http:// (no TLS yet). */
naut_err naut_tracker_announce_http(const char *url, naut_tracker_response *out);
/* Full UDP connect+announce handshake against host:port. */
naut_err naut_tracker_announce_udp(const char *host, uint16_t port,
const naut_announce_req *req,
naut_tracker_response *out);
#endif /* NAUT_TRACKER_H */