iPXE
peerblk.h
Go to the documentation of this file.
00001 #ifndef _IPXE_PEERBLK_H
00002 #define _IPXE_PEERBLK_H
00003 
00004 /** @file
00005  *
00006  * Peer Content Caching and Retrieval (PeerDist) protocol block downloads
00007  *
00008  */
00009 
00010 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
00011 
00012 #include <stdint.h>
00013 #include <ipxe/refcnt.h>
00014 #include <ipxe/interface.h>
00015 #include <ipxe/crypto.h>
00016 #include <ipxe/aes.h>
00017 #include <ipxe/xferbuf.h>
00018 #include <ipxe/retry.h>
00019 #include <ipxe/process.h>
00020 #include <ipxe/pccrc.h>
00021 #include <ipxe/peerdisc.h>
00022 
00023 /** A PeerDist retrieval protocol decryption buffer descriptor */
00024 struct peerdist_block_decrypt {
00025         /** Data transfer buffer */
00026         struct xfer_buffer *xferbuf;
00027         /** Offset within data transfer buffer */
00028         size_t offset;
00029         /** Length to use from data transfer buffer */
00030         size_t len;
00031 };
00032 
00033 /** PeerDist retrieval protocol decryption data transfer buffer indices */
00034 enum peerdist_block_decrypt_index {
00035         /** Data before the trimmed content */
00036         PEERBLK_BEFORE = 0,
00037         /** Data within the trimmed content */
00038         PEERBLK_DURING,
00039         /** Data after the trimmed content */
00040         PEERBLK_AFTER,
00041         /** Number of decryption buffers */
00042         PEERBLK_NUM_BUFFERS
00043 };
00044 
00045 /** A PeerDist block download */
00046 struct peerdist_block {
00047         /** Reference count */
00048         struct refcnt refcnt;
00049         /** Data transfer interface */
00050         struct interface xfer;
00051         /** Raw data interface */
00052         struct interface raw;
00053         /** Retrieval protocol interface */
00054         struct interface retrieval;
00055 
00056         /** Original URI */
00057         struct uri *uri;
00058         /** Content range of this block */
00059         struct peerdist_range range;
00060         /** Trimmed range of this block */
00061         struct peerdist_range trim;
00062         /** Offset of first byte in trimmed range within overall download */
00063         size_t offset;
00064 
00065         /** Digest algorithm */
00066         struct digest_algorithm *digest;
00067         /** Digest size
00068          *
00069          * Note that this may be shorter than the digest size of the
00070          * digest algorithm.
00071          */
00072         size_t digestsize;
00073         /** Digest context (statically allocated at instantiation time) */
00074         void *digestctx;
00075 
00076         /** Cipher algorithm */
00077         struct cipher_algorithm *cipher;
00078         /** Cipher context (dynamically allocated as needed) */
00079         void *cipherctx;
00080 
00081         /** Segment index */
00082         unsigned int segment;
00083         /** Segment identifier */
00084         uint8_t id[PEERDIST_DIGEST_MAX_SIZE];
00085         /** Segment secret */
00086         uint8_t secret[PEERDIST_DIGEST_MAX_SIZE];
00087         /** Block index */
00088         unsigned int block;
00089         /** Block hash */
00090         uint8_t hash[PEERDIST_DIGEST_MAX_SIZE];
00091 
00092         /** Current position (relative to incoming data stream) */
00093         size_t pos;
00094         /** Start of trimmed content (relative to incoming data stream) */
00095         size_t start;
00096         /** End of trimmed content (relative to incoming data stream) */
00097         size_t end;
00098         /** Data buffer */
00099         struct xfer_buffer buffer;
00100 
00101         /** Decryption process */
00102         struct process process;
00103         /** Decryption data buffer descriptors */
00104         struct peerdist_block_decrypt decrypt[PEERBLK_NUM_BUFFERS];
00105         /** Remaining decryption length */
00106         size_t cipher_remaining;
00107         /** Remaining digest length (excluding AES padding bytes) */
00108         size_t digest_remaining;
00109 
00110         /** Discovery client */
00111         struct peerdisc_client discovery;
00112         /** Current position in discovered peer list */
00113         struct peerdisc_peer *peer;
00114         /** Block download queue */
00115         struct peerdist_block_queue *queue;
00116         /** List of queued block downloads */
00117         struct list_head queued;
00118         /** Retry timer */
00119         struct retry_timer timer;
00120         /** Number of full attempt cycles completed */
00121         unsigned int cycles;
00122         /** Most recent attempt failure */
00123         int rc;
00124 
00125         /** Time at which block download was started */
00126         unsigned long started;
00127         /** Time at which most recent attempt was started */
00128         unsigned long attempted;
00129 };
00130 
00131 /** PeerDist block download queue */
00132 struct peerdist_block_queue {
00133         /** Download opening process */
00134         struct process process;
00135         /** List of queued downloads */
00136         struct list_head list;
00137 
00138         /** Number of open downloads */
00139         unsigned int count;
00140         /** Maximum number of open downloads */
00141         unsigned int max;
00142 
00143         /** Open block download
00144          *
00145          * @v peerblk           PeerDist block download
00146          * @ret rc              Return status code
00147          */
00148         int ( * open ) ( struct peerdist_block *peerblk );
00149 };
00150 
00151 /** Retrieval protocol block fetch response (including transport header)
00152  *
00153  * @v digestsize        Digest size
00154  * @v len               Data block length
00155  * @v vrf_len           Length of uselessness
00156  * @v blksize           Cipher block size
00157  */
00158 #define peerblk_msg_blk_t( digestsize, len, vrf_len, blksize )          \
00159         struct {                                                        \
00160                 struct peerdist_msg_transport_header hdr;               \
00161                 peerdist_msg_blk_t ( digestsize, len, vrf_len,          \
00162                                      blksize ) msg;                     \
00163         } __attribute__ (( packed ))
00164 
00165 extern int peerblk_open ( struct interface *xfer, struct uri *uri,
00166                           struct peerdist_info_block *block );
00167 
00168 #endif /* _IPXE_PEERBLK_H */