#ifndef _IPXE_PEERBLK_H #define _IPXE_PEERBLK_H /** @file * * Peer Content Caching and Retrieval (PeerDist) protocol block downloads * */ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include #include #include #include #include #include #include #include #include #include /** A PeerDist retrieval protocol decryption buffer descriptor */ struct peerdist_block_decrypt { /** Data transfer buffer */ struct xfer_buffer *xferbuf; /** Offset within data transfer buffer */ size_t offset; /** Length to use from data transfer buffer */ size_t len; }; /** PeerDist retrieval protocol decryption data transfer buffer indices */ enum peerdist_block_decrypt_index { /** Data before the trimmed content */ PEERBLK_BEFORE = 0, /** Data within the trimmed content */ PEERBLK_DURING, /** Data after the trimmed content */ PEERBLK_AFTER, /** Number of decryption buffers */ PEERBLK_NUM_BUFFERS }; /** A PeerDist block download */ struct peerdist_block { /** Reference count */ struct refcnt refcnt; /** Data transfer interface */ struct interface xfer; /** Raw data interface */ struct interface raw; /** Retrieval protocol interface */ struct interface retrieval; /** Original URI */ struct uri *uri; /** Content range of this block */ struct peerdist_range range; /** Trimmed range of this block */ struct peerdist_range trim; /** Offset of first byte in trimmed range within overall download */ size_t offset; /** Digest algorithm */ struct digest_algorithm *digest; /** Digest size * * Note that this may be shorter than the digest size of the * digest algorithm. */ size_t digestsize; /** Digest context (statically allocated at instantiation time) */ void *digestctx; /** Cipher algorithm */ struct cipher_algorithm *cipher; /** Cipher context (dynamically allocated as needed) */ void *cipherctx; /** Segment index */ unsigned int segment; /** Segment identifier */ uint8_t id[PEERDIST_DIGEST_MAX_SIZE]; /** Segment secret */ uint8_t secret[PEERDIST_DIGEST_MAX_SIZE]; /** Block index */ unsigned int block; /** Block hash */ uint8_t hash[PEERDIST_DIGEST_MAX_SIZE]; /** Current position (relative to incoming data stream) */ size_t pos; /** Start of trimmed content (relative to incoming data stream) */ size_t start; /** End of trimmed content (relative to incoming data stream) */ size_t end; /** Data buffer */ struct xfer_buffer buffer; /** Decryption process */ struct process process; /** Decryption data buffer descriptors */ struct peerdist_block_decrypt decrypt[PEERBLK_NUM_BUFFERS]; /** Remaining decryption length */ size_t cipher_remaining; /** Remaining digest length (excluding AES padding bytes) */ size_t digest_remaining; /** Discovery client */ struct peerdisc_client discovery; /** Current position in discovered peer list */ struct peerdisc_peer *peer; /** Block download queue */ struct peerdist_block_queue *queue; /** List of queued block downloads */ struct list_head queued; /** Retry timer */ struct retry_timer timer; /** Number of full attempt cycles completed */ unsigned int cycles; /** Most recent attempt failure */ int rc; /** Time at which block download was started */ unsigned long started; /** Time at which most recent attempt was started */ unsigned long attempted; }; /** PeerDist block download queue */ struct peerdist_block_queue { /** Download opening process */ struct process process; /** List of queued downloads */ struct list_head list; /** Number of open downloads */ unsigned int count; /** Maximum number of open downloads */ unsigned int max; /** Open block download * * @v peerblk PeerDist block download * @ret rc Return status code */ int ( * open ) ( struct peerdist_block *peerblk ); }; /** Retrieval protocol block fetch response (including transport header) * * @v digestsize Digest size * @v len Data block length * @v vrf_len Length of uselessness * @v blksize Cipher block size */ #define peerblk_msg_blk_t( digestsize, len, vrf_len, blksize ) \ struct { \ struct peerdist_msg_transport_header hdr; \ peerdist_msg_blk_t ( digestsize, len, vrf_len, \ blksize ) msg; \ } __attribute__ (( packed )) extern int peerblk_open ( struct interface *xfer, struct uri *uri, struct peerdist_info_block *block ); #endif /* _IPXE_PEERBLK_H */