1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-06-24 00:56:14 +00:00
elinks/src/protocol/bittorrent/piececache.h
Witold Filipczyk a67188413c [lists] LIST_HEAD -> LIST_HEAD_EL to not clash with libevent's LIST_HEAD. Also added curl implementation of ftpes and sftp
Implementation of ftpes and sftp is based on curl's hiperfifo example. It requires libevent.
ftpes only encrypts control channel. There were problems when both control and data were encrypted. It stucked on SIZE.
Only successful connections work, errors are not handled properly.
2023-06-19 18:43:53 +02:00

137 lines
5.4 KiB
C

#ifndef EL__PROTOCOL_BITTORRENT_PIECECACHE_H
#define EL__PROTOCOL_BITTORRENT_PIECECACHE_H
#include "protocol/bittorrent/common.h"
#include "util/lists.h"
#ifdef __cplusplus
extern "C" {
#endif
struct bitfield;
struct bittorrent_piece_cache_entry {
LIST_HEAD_EL(struct bittorrent_piece_cache_entry);
/** Piece rarity index
* To keep track of the client's view of the swarm in regards to pieces a
* piece rarity index for neighboring peers is maintained for each piece
* in the torrent. It keeps track of how many neighboring peers have the
* piece. The smaller the value the more rare the piece is. The table is
* updated when the client receives bitfield or have messages. Zero
* indicates that no neightboring peer has the piece. */
uint16_t rarity;
unsigned int completed:1; /**< All blocks was downloaded. */
unsigned int remaining:1; /**< Nothing has been even requested. */
unsigned int locked:1; /**< Edge piece from partial downloads. */
unsigned int selected:1; /**< Piece is part of partial download. */
/** A bitfield of the blocks which remains to be downloaded for this
* piece. May be NULL if downloading is not in progress. */
struct bitfield *blocks;
/** The data of the piece.
* May be NULL if data has not been downloaded
* or the piece has been written to disk.
* XXX: This memory is mmaped using the mem_mmap_*() functions. */
char *data;
};
struct bittorrent_piece_cache {
/* The following is mostly maintained for making it easy to display in
* dialogs. */
unsigned int remaining_pieces; /**< Number of untouched pieces */
unsigned int completed_pieces; /**< Number of downloaded pieces */
unsigned int loading_pieces; /**< Number of pieces in progress */
unsigned int rejected_pieces; /**< Number of hash check rejects */
unsigned int unavailable_pieces;/**< Number of unavailable pieces */
unsigned int partial_pieces; /**< Number of selected file pieces */
unsigned int locked_pieces; /**< Pieces locked due to partial download */
/* Flags set from the download dialog. */
unsigned int delete_files:1; /**< Unlink files on shutdown? */
unsigned int notify_complete:1; /**< Notify upon completion? */
unsigned int partial:1; /**< Dealing with a partial download? */
/** The pipe descripter used for communicating with the resume thread. */
int resume_fd;
uint32_t resume_pos;
/** A bitfield of the available pieces. */
struct bitfield *bitfield;
/** A list of completed and saved entries which has been loaded into
* memory. The allocated memory for all these entries is disposable. The
* entries are sorted in a LRU-manner. */
LIST_OF(struct bittorrent_piece_cache_entry) queue;
/** Remaining pieces are tracked using the remaining_blocks member of the
* piece cache entry and a free list of piece blocks to be requested.
* Requests are taken from the free list every time a peer queries which
* piece block to request next. If the piece list is empty (or if the
* remote peer does not have any of the pieces currently in the free
* list) the cache is searched for a remaining piece and any found piece
* is then broken into a number of requests. Typically, the querying
* peer will only add a few of the requests to its queue so the rest of
* the requests will end up in the free list. This way more than one
* peer can request blocks from the same piece and the overall strategy
* will try to finish already started pieces before it begins
* downloading of new ones.
*
* When the free list is empty _and_ the number of remaining pieces is
* zero the client enters the end game mode. That is, _all_ remaining
* requests are _pending_. To speed up the end game mode, more than one
* peer is allowed to request the same piece, however, it is important
* to cancel these requests when they are completed to not waste
* bandwitdth. To ease canceling in end game mode peer requests has a
* cloned flag. The flag is set when piece block requests are cloned. If
* the cloned flag is set when receiving a block then the peer-list is
* searched and requests for the same piece is canceled. */
LIST_OF(struct bittorrent_piece_request) free_list;
struct bittorrent_piece_cache_entry entries[1];
};
enum bittorrent_state
init_bittorrent_piece_cache(struct bittorrent_connection *bittorrent,
struct bittorrent_const_string *metafile);
void done_bittorrent_piece_cache(struct bittorrent_connection *bittorrent);
void update_bittorrent_piece_cache_state(struct bittorrent_connection *bittorrent);
/* Depending on the current download mode, try to find a block to request. */
struct bittorrent_peer_request *
find_bittorrent_peer_request(struct bittorrent_peer_connection *peer);
void
add_requests_to_bittorrent_piece_cache(struct bittorrent_peer_connection *peer,
struct bittorrent_peer_status *status);
void
update_bittorrent_piece_cache(struct bittorrent_peer_connection *peer,
uint32_t piece);
void
update_bittorrent_piece_cache_from_bitfield(struct bittorrent_peer_connection *peer);
void
remove_bittorrent_peer_from_piece_cache(struct bittorrent_peer_connection *peer);
enum bittorrent_state
add_to_bittorrent_piece_cache(struct bittorrent_peer_connection *peer,
uint32_t piece, uint32_t offset,
char *data, uint32_t datalen,
int *write_errno);
char *
get_bittorrent_piece_cache_data(struct bittorrent_connection *bittorrent,
uint32_t piece);
#ifdef __cplusplus
}
#endif
#endif