iconv: Bail out of the loop when an illegal sequence of bytes occurs.
[elinks/elinks-j605.git] / src / protocol / bittorrent / common.h
blobf39d8bc4b3d92833b00b1c26d0aa4a9b85662021
2 #ifndef EL__PROTOCOL_BITTORRENT_COMMON_H
3 #define EL__PROTOCOL_BITTORRENT_COMMON_H
5 #include "main/timer.h"
6 #include "network/progress.h"
7 #include "network/socket.h"
8 #include "network/state.h"
9 #include "protocol/protocol.h"
10 #include "protocol/uri.h"
11 #include "util/error.h"
12 #include "util/lists.h"
13 #include "util/md5.h"
14 #include "util/sha1.h"
15 #include "util/time.h"
17 struct bitfield;
18 struct bittorrent_fetcher;
19 struct connection;
20 struct terminal;
22 /** The least acceptable default sharing rate. */
23 #define BITTORRENT_DEFAULT_SHARING_RATE 0.250
25 /** The number of seconds between updating the connection state and most
26 * importantly choke and unchoke peer connections. */
27 #define BITTORRENT_DEFAULT_CHOKE_INTERVAL 10
29 /** The length regarded as ``typical'' by the community wiki specification.
30 * Looks like Bram uses 2^14 here.
31 * Used for the protocol.bittorrent.request_length option */
32 #define BITTORRENT_REQUEST_LENGTH (1 << 14)
34 /** The length of requested blocks of pieces should not exceed 2^17 bytes.
35 * Used for the protocol.bittorrent.max_request_length option.
36 * Bram uses 2^23 here. */
37 #define BITTORRENT_REQUEST_ACCEPT_LENGTH (1 << 23)
39 /** The maximum size to allow a peer message to have. */
40 /* Bram uses 2^23 here. */
41 #define BITTORRENT_MESSAGE_MAX_SIZE (1 << 23)
44 /** 20-byte string ID used for both peer IDs and info-hashes. */
45 typedef sha1_digest_bin_T bittorrent_id_T;
47 /** Special peer ID used for determining whether an ID has been set. */
48 extern const bittorrent_id_T BITTORRENT_NULL_ID;
50 /** Check if the ID has been set. */
51 #define bittorrent_id_is_empty(id) \
52 (!memcmp(id, BITTORRENT_NULL_ID, sizeof(bittorrent_id_T)))
55 /** BitTorrent error states. */
56 enum bittorrent_state {
57 BITTORRENT_STATE_OK, /**< All is well. */
58 BITTORRENT_STATE_ERROR, /**< Some error happened. */
59 BITTORRENT_STATE_REQUEST_FAILURE, /**< Failure from tracker. */
60 BITTORRENT_STATE_OUT_OF_MEM, /**< Allocation failure. */
61 BITTORRENT_STATE_CACHE_FAILURE, /**< Cache data access failed. */
62 BITTORRENT_STATE_CACHE_RESUME, /**< Resume state from disk. */
63 BITTORRENT_STATE_FILE_MISSING, /**< File does not exist. */
66 /** For showing tracker failure responses to the user. */
67 struct bittorrent_message {
68 LIST_HEAD(struct bittorrent_message);
70 struct uri *uri;
71 struct connection_state state;
72 unsigned char string[1];
76 /* ************************************************************************** */
77 /* Peer-wire types: */
78 /* ************************************************************************** */
80 /** BitTorrent peer-wire state and message IDs. */
81 enum bittorrent_message_id {
82 /* Special internal state and message type. */
83 BITTORRENT_MESSAGE_ERROR = -3,
84 BITTORRENT_MESSAGE_INCOMPLETE = -2,
85 BITTORRENT_MESSAGE_KEEP_ALIVE = -1,
87 /* Valid message types. */
88 BITTORRENT_MESSAGE_CHOKE = 0,
89 BITTORRENT_MESSAGE_UNCHOKE = 1,
90 BITTORRENT_MESSAGE_INTERESTED = 2,
91 BITTORRENT_MESSAGE_NOT_INTERESTED = 3,
92 BITTORRENT_MESSAGE_HAVE = 4,
93 BITTORRENT_MESSAGE_BITFIELD = 5,
94 BITTORRENT_MESSAGE_REQUEST = 6,
95 BITTORRENT_MESSAGE_PIECE = 7,
96 BITTORRENT_MESSAGE_CANCEL = 8,
99 /** The peer request matches information sent in the request and cancel messages
100 * in the peer-wire protocol. See the piece cache header file (cache.h) for more
101 * information about the cloned flag. */
102 struct bittorrent_peer_request {
103 LIST_HEAD(struct bittorrent_peer_request);
105 uint32_t piece; /**< Zero-based piece index. */
106 uint32_t offset; /**< Zero-based piece byte offset. */
107 uint32_t length; /**< The wanted number of bytes. */
109 uint16_t block; /**< The block index in the piece. */
111 enum bittorrent_message_id id; /**< ID of queued pending message. */
113 unsigned int cloned:1; /**< The request was cloned. */
114 unsigned int requested:1; /**< Whether it has been requested. */
117 struct bittorrent_peer_status {
118 /** FIFO-like recording of requests. */
119 LIST_OF(struct bittorrent_peer_request) requests;
121 /* Flags for scheduling updating of the peer state. */
122 unsigned int choked:1; /**< The peer was choked. */
123 unsigned int interested:1; /**< The peer is interested. */
124 unsigned int snubbed:1; /**< The peer was snubbed. */
126 /* State flags used for determining what to accept. */
127 unsigned int handshake:1; /**< The handshake was sent. */
128 unsigned int bitfield:1; /**< The bitfield was sent. */
129 unsigned int initiater:1; /**< Initiater of the connection. */
130 unsigned int seeder:1; /**< The peer has the complete torrent. */
133 struct bittorrent_peer_stats {
134 time_t last_time;
135 time_t age;
137 double download_rate;
138 double have_rate;
140 off_t downloaded;
141 off_t uploaded;
144 /** Peer connection information. */
145 struct bittorrent_peer_connection {
146 LIST_HEAD(struct bittorrent_peer_connection);
148 /** Unique peer ID string which can be used to look-up the peer hash. */
149 bittorrent_id_T id;
151 /** Timer handle for scheduling timeouts. */
152 timer_id_T timer;
154 /** Socket information. */
155 struct socket *socket;
157 /** Progress information and counter for the number of uploaded or
158 * downloaded bytes depending on the mode. */
159 struct bittorrent_peer_stats stats;
161 /** The BitTorrent connection the peer connection is associated with.
162 * For recently accepted peer connections it might be NULL indicating
163 * that the info_hash has not yet been read from the handshake. */
164 struct bittorrent_connection *bittorrent;
166 /** Local client and remote peer status info. */
167 struct bittorrent_peer_status local;
168 struct bittorrent_peer_status remote;
170 /** Outgoing message queue. Note piece messages are maintained entirely
171 * in the request list in the bittorrent_peer_status struct. */
172 LIST_OF(struct bittorrent_peer_request) queue;
174 /** A bitfield of the available pieces from the peer.
175 * The size depends on the number of pieces. */
176 struct bitfield *bitfield;
180 /* ************************************************************************** */
181 /* Tracker types: */
182 /* ************************************************************************** */
184 /** Event state information needed by the tracker. */
185 enum bittorrent_tracker_event {
186 BITTORRENT_EVENT_STARTED = 0, /**< XXX: Zero, to always send first */
187 BITTORRENT_EVENT_STOPPED, /**< Graceful shut down */
188 BITTORRENT_EVENT_COMPLETED, /**< Download was completed */
189 BITTORRENT_EVENT_REGULAR, /**< Regular (periodical) tracker request */
192 /** This stores info about tracker requests.
193 * It is not a real connection because it consists of a series of HTTP requests
194 * but both the tracker and client is supposed to keep state information across
195 * all requests. */
196 struct bittorrent_tracker_connection {
197 /** Used for keeping track of when to send event info to the tracker. */
198 enum bittorrent_tracker_event event;
200 /** Time in seconds between contacting the tracker and a timer handle. */
201 timer_id_T timer;
202 int interval;
204 /** Requesting the tracker failed or was never started so no
205 * event=stopped should be sent. */
206 unsigned int failed:1;
207 unsigned int started:1;
211 /* ************************************************************************** */
212 /* Metafile types: */
213 /* ************************************************************************** */
215 /** Information about peers returned by the tracker. */
216 struct bittorrent_peer {
217 LIST_HEAD(struct bittorrent_peer);
219 bittorrent_id_T id; /**< Unique peer ID string. */
220 uint16_t port; /**< The port number to connect to. */
221 unsigned char ip[1]; /**< String with a IPv4 or IPv6 address. */
224 /** Information about a file in the torrent. */
225 struct bittorrent_file {
226 LIST_HEAD(struct bittorrent_file);
228 off_t length; /**< Length of the file in bytes. */
229 md5_digest_hex_T md5sum; /**< Hexadecimal MD5 sum of the file. */
230 int selected;
231 unsigned char name[1]; /**< Filename converted from path list. */
234 /** Static information from the .torrent metafile. */
235 struct bittorrent_meta {
236 /** The SHA1 info hash of the value of the info key from the metainfo
237 * .torrent file is used regularly when connecting to both the tracker
238 * and peers. */
239 bittorrent_id_T info_hash;
241 /** Optional information about the creation time of the torrent.
242 * Used if the document.download.set_original_time is true. */
243 time_t creation_date;
245 /** Optional comment in free-form text. */
246 unsigned char *comment;
248 /** The announced URI of each available tracker. */
249 struct uri_list tracker_uris;
251 /** The number of pieces. */
252 uint32_t pieces;
254 /** The number of bytes in each piece. */
255 uint32_t piece_length;
256 /** The last piece can be shorter than the others. */
257 uint32_t last_piece_length;
259 /** List of concatenated SHA1 hash values for each piece. */
260 unsigned char *piece_hash;
262 /** The type of the torrent. */
263 enum { BITTORRENT_SINGLE_FILE, BITTORRENT_MULTI_FILE } type;
265 /** Potential bad file path detected. */
266 unsigned int malicious_paths:1;
268 /** The name of either the single file or the top-most directory. */
269 unsigned char *name;
271 /** A list with information about files in the torrent.
272 * The list is a singleton for single-file torrents. */
273 LIST_OF(struct bittorrent_file) files;
276 enum bittorrent_connection_mode {
277 BITTORRENT_MODE_PIECELESS, /**< The client has no piece to share. */
278 BITTORRENT_MODE_NORMAL, /**< The client is up- and downloading. */
279 BITTORRENT_MODE_END_GAME, /**< All remaining pieces are requested. */
280 BITTORRENT_MODE_SEEDER, /**< The client is only uploading. */
283 /** This stores info about an active BitTorrent connection. Note, the list head
284 * is used by the handling of the peer-wire listening socket and should only be
285 * managed by that. */
286 struct bittorrent_connection {
287 LIST_HEAD(struct bittorrent_connection);
289 enum bittorrent_connection_mode mode;
291 /** Static information from the .torrent metafile. */
292 struct bittorrent_meta meta;
294 /** Dynamic tracker information. */
295 struct bittorrent_tracker_connection tracker;
297 /** Dynamic tracker information. */
298 struct bittorrent_piece_cache *cache;
300 /** Back-reference to the connection the bittorrent connection belongs
301 * to. */
302 struct connection *conn;
304 /** Active peer list
305 * The size is controlled by the protocol.bittorrent.max_active_peers
306 * option. */
307 LIST_OF(struct bittorrent_peer_connection) peers;
309 /** List of information about potential peers.
310 * @todo TODO: Use hash. */
311 LIST_OF(struct bittorrent_peer) peer_pool;
313 /** The peer ID of the client. */
314 bittorrent_id_T peer_id;
316 /** The port of the listening socket */
317 uint16_t port;
319 /** Timer handle for scheduling periodic updating and rating of peer
320 * connections. */
321 timer_id_T timer;
323 /** Statistics for the tracker and total progress information for the
324 * user interface. */
325 struct progress upload_progress;
326 off_t uploaded;
327 off_t downloaded;
328 off_t left;
330 /** Number of seeders. */
331 uint32_t complete;
332 /** Number of leechers. */
333 uint32_t incomplete;
335 double sharing_rate;
337 /** Information about any running metainfo file or tracker request. */
338 struct bittorrent_fetcher *fetch;
340 /** For notifying on completion.
341 * May be NULL. */
342 struct terminal *term;
345 /** Like struct string, except the data is const and not freed via
346 * this structure. So it is okay to make @c source point to data that
347 * is part of a larger buffer. Also, there is no @c magic member here. */
348 struct bittorrent_const_string {
349 const unsigned char *source;
350 int length;
353 static inline uint32_t
354 get_bittorrent_piece_length(struct bittorrent_meta *meta, uint32_t piece)
356 return piece == meta->pieces - 1
357 ? meta->last_piece_length : meta->piece_length;
360 unsigned char *get_hexed_bittorrent_id(bittorrent_id_T id);
364 bittorrent_piece_is_valid(struct bittorrent_meta *meta,
365 uint32_t piece, unsigned char *data, uint32_t datalen);
367 void init_bittorrent_peer_id(bittorrent_id_T peer_id);
370 bittorrent_id_is_known(struct bittorrent_connection *bittorrent,
371 bittorrent_id_T id);
373 enum bittorrent_state
374 add_peer_to_bittorrent_pool(struct bittorrent_connection *bittorrent,
375 bittorrent_id_T id, int port,
376 const unsigned char *ip, int iplen);
378 struct bittorrent_peer *
379 get_peer_from_bittorrent_pool(struct bittorrent_connection *bittorrent,
380 bittorrent_id_T id);
382 void done_bittorrent_meta(struct bittorrent_meta *meta);
383 void done_bittorrent_message(struct bittorrent_message *message);
386 /* ************************************************************************** */
387 /* Debug 'pretty printing' functions: */
388 /* ************************************************************************** */
390 unsigned char *get_peer_id(bittorrent_id_T peer);
391 unsigned char *get_peer_message(enum bittorrent_message_id message_id);
393 /* ************************************************************************** */
394 /* Peer request management: */
395 /* ************************************************************************** */
397 struct bittorrent_peer_request *
398 get_bittorrent_peer_request(struct bittorrent_peer_status *status,
399 uint32_t piece, uint32_t offset, uint32_t length);
401 void
402 add_bittorrent_peer_request(struct bittorrent_peer_status *status,
403 uint32_t piece, uint32_t offset, uint32_t length);
405 void
406 del_bittorrent_peer_request(struct bittorrent_peer_status *status,
407 uint32_t piece, uint32_t offset, uint32_t length);
410 /* ************************************************************************** */
411 /* URI fetching: */
412 /* ************************************************************************** */
414 typedef void (*bittorrent_fetch_callback_T)(void *, struct connection_state,
415 struct bittorrent_const_string *);
417 struct bittorrent_fetcher *
418 init_bittorrent_fetch(struct bittorrent_fetcher **fetcher_ref,
419 struct uri *uri, bittorrent_fetch_callback_T callback,
420 void *data, int delete);
421 void done_bittorrent_fetch(struct bittorrent_fetcher **fetcher_ref);
424 /* ************************************************************************** */
425 /* Blacklisting: */
426 /* ************************************************************************** */
428 enum bittorrent_blacklist_flags {
429 BITTORRENT_BLACKLIST_NONE, /**< No blacklisting is in effect */
430 BITTORRENT_BLACKLIST_PEER_POOL, /**< Blacklist from peer pool. */
431 BITTORRENT_BLACKLIST_MALICIOUS, /**< Malicious peer, refuse connection */
432 BITTORRENT_BLACKLIST_BEHAVIOUR, /**< Unfair behaviour, refuse connection */
435 void
436 add_bittorrent_blacklist_flags(bittorrent_id_T peer_id,
437 enum bittorrent_blacklist_flags flags);
439 void
440 del_bittorrent_blacklist_flags(bittorrent_id_T peer_id,
441 enum bittorrent_blacklist_flags flags);
443 enum bittorrent_blacklist_flags
444 get_bittorrent_blacklist_flags(bittorrent_id_T peer_id);
446 void done_bittorrent_blacklist(void);
448 #endif