#define HASHSIZE 20
#define PEERIDLEN 20
enum {
BThas = (1<<0), /* least sig bit: "has that piece" */
BTshar = (1<<1), /* 2nd least sig bit: "piece is shared" */
BThashar = BThas|BTshar,
BTnone = 0,
};
typedef struct Piece Piece;
struct Piece{
int index;
char status;
Piece *next;
};
struct Peerinfo {
char *address;
char *id;
int port;
};
typedef struct Peerinfo Peerinfo;
struct Peer {
Peerinfo *peerinfo;
int fd;
char seeder;
char busy;
char *bitfield;
Piece *pieceslist;
int piecesnb;
char am_choking;
char am_interested;
char peer_choking;
char peer_interested;
char sid;
};
typedef struct Peer Peer;
/*
* Torrent.fileborder[i]: index of piece where file i starts. fileborder[0] = 0.
* Torrent.firstoffset[i]: offset (in bytes) where file i starts, relatively to the beginning of fileborder[i]. firstoffset[0] = 0.
* Torrent.lastpiece: length (in bytes) of actual data within the last piece.
* Typical piece length: 262144; max(piecesnb) = 2^31 - 1
=> max torrent size = 262144 * max(piecesnb) ~= 5e14 bytes
=> int should be enough for piecesnb for a long time.
*/
struct Torrent {
char *announce;
char **announcelist;
int annlistsize;
Rune *comment;
Rune *createdby;
uvlong creationdate;
Rune *encoding;
int multifile;
uint piecelength;
Rune *name;
int piecesnb;
uchar **sha1list;
uint private;
uvlong *filelength;
Rune **filepath;
Rune **filemd5sum;
int filesnb;
uchar *infohash;
int infosize;
Piece *pieceslist;
char **datafiles;
int *fileborder;
int *firstoffset;
int lastpiece;
Peer **peers;
char peersnb;
char *bitfield;
int bitfieldsize;
Peerinfo **peersinfo;
char peersinfonb;
};
typedef struct Torrent Torrent;
char *forgerequest(Torrent *tor, char *req);
int checkpiece(char *data, Torrent *tor, int index);
void preppieceslist(Torrent *tor);
void writedata(ulong index, char *data, Torrent *tor, Peer *peer);
void scanpieces(Torrent *tor, char *datadir);
void preppeerspieces(Torrent *tor, Peer *peer);
void readdata(ulong index, char *data, Torrent *tor, Peer *peer);
int updatepeerspieces(Torrent *tor, Peer *peer, int index, char op);
void freepeer(Peer *peer);
|