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>
68 lines
2.9 KiB
C
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 */
|