/* bee.c */ typedef struct Bee Bee; enum { TString, TInteger, TList, TDict, }; struct Bee { int type; union { struct { /* String */ char *s; int slen; }; vlong i; /* Integer */ struct { /* List */ Bee *l; uint nl; }; struct { /* Dict */ Bee *keys; Bee *values; uint dlen; }; }; }; /* bite.c */ typedef struct Bite Bite; struct Bite { int n; int piecen; int offset; int length; Bite *next; }; /* bits.c */ typedef struct Bits Bits; struct Bits { uchar *p; int n; int nhave; }; /* deluge.c */ extern int debug; enum { STACKSIZE = 512*1024, Peeridlen = 20, Infohashlen = 20, Piecehashlen = 20, Listenport = 6881, Listenattempts = 100, MinInterval = 30, Bitelength = 1<<14, DefaultInterval = 1800, WantUnchokedCount = 4, Stablesecs = 10, Minscheduled = 6, Maxdialedpeers = 40, Maxpeers = 80, }; /* file.c */ typedef struct File File; struct File { int fd; char *path; vlong length; vlong offset; /* offset in bittorrent "file" */ File *next; }; /* msg.c */ enum { MKeepalive = -1, MChoke = 0, MUnchoke, MInterested, MNotinterested, MHave, MBitfield, MRequest, MPiece, MCancel, MLast = MCancel, }; typedef struct Msg Msg; struct Msg { ulong msglength; int type; union { Bits *haves; ulong have; /* Have */ struct { /* Request, Cancel, Piece */ ulong index; ulong begin; ulong length; char *piece; }; }; int peern; Msg *next; }; /* piece.c */ typedef struct Piece Piece; struct Piece { int n; uchar hash[Piecehashlen]; int *ids; int nids; int length; Bits *bites; Bits *reqbites; }; /* rate.c */ enum { Upload, Download, }; typedef struct Rate Rate; struct Rate { int nticks; int i; vlong ulcur, dlcur; vlong first; ulong *ul, *dl; }; /* peer.c */ enum { Choked = 1<<0, /* status of remote peer */ Interested = 1<<1, /* 1<<2 and 1<<3 are reserved for Choked and Interested for ourselves */ Connecting = 1<<4, Valid = 1<<5, Bad = 1<<6, }; typedef struct Peer Peer; struct Peer { int havefirst; int n; char *ip; char *port; uchar peerid[Peeridlen]; int fd; Bits *pieces; Rate *rate; uint status; /* status of peer */ Bite *lreq; /* what we requested */ Bite *rreq; /* what remote requested */ int changed; ulong lastchange; Channel *write; Msg *meta; /* non-piece messages we need to send */ Msg *dataout; /* piece-only messages we need to send */ Peer *next; }; /* torrent.c */ enum { Random, Rarestfirst, Endgame, Seeding, }; typedef struct Torrent Torrent; struct Torrent { File *files; /* files on disk */ int filecreated; /* if the initialisation created at least one file */ ulong piecelen; /* length of a piece */ Piece *pieces; /* all pieces */ int npieces; /* number of pieces */ vlong length; /* total length of torrent file(s) */ char *announce; /* tracker url */ uchar infohash[Infohashlen]; /* hash of info bee from torrent file */ vlong dl; /* downloaded bytes */ vlong ul; /* uploaded bytes */ Rate *rate; /* transfer rates */ vlong stored; /* bytes we have stored to file */ int interval; /* how often to connect to tracker */ char *listenport; /* where we listen */ uchar peerid[Peeridlen]; /* our (random) peer id */ int strategy; /* our current strategy */ Bits *haves; /* which pieces we have */ Bits *reqpieces; /* which pieces have been requested */ Channel *inpeer; /* through which the listener proc sends incoming connections */ Channel *timer; /* signals when to recalculate transfer spee and rethink chokes */ Channel *inmsg; /* messages incoming from peer */ Channel *dialpeer; /* peers that need to be dialed */ Channel *dialedpeer; /* peers that have been dialed */ Channel *needshake; /* peers that need to handshake */ Channel *shakedpeer; /* connected and handshaked peers */ Channel *stalepeer; /* disconnect peers */ Channel *track; /* do request to tracker */ Channel *prospect; /* for new prospect peers (from tracker) */ Channel *newinterval; /* new interval */ Channel *written; /* when something written to peer */ Peer *peers; /* connected peers */ Peer *bad; /* bad peers we don't want to connect to */ ulong peern; /* peer counter */ Peer *todial; /* peers that still need to be dialed */ Peer *tohandshake; /* peers that still need to handshake */ };