/* 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 */
};
|