1 #ifndef _IPXE_PEERBLK_H
2 #define _IPXE_PEERBLK_H
3 
4 /** @file
5  *
6  * Peer Content Caching and Retrieval (PeerDist) protocol block downloads
7  *
8  */
9 
10 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
11 
12 #include <stdint.h>
13 #include <ipxe/refcnt.h>
14 #include <ipxe/interface.h>
15 #include <ipxe/crypto.h>
16 #include <ipxe/aes.h>
17 #include <ipxe/xferbuf.h>
18 #include <ipxe/retry.h>
19 #include <ipxe/process.h>
20 #include <ipxe/pccrc.h>
21 #include <ipxe/peerdisc.h>
22 
23 /** A PeerDist retrieval protocol decryption buffer descriptor */
24 struct peerdist_block_decrypt {
25 	/** Data transfer buffer */
26 	struct xfer_buffer *xferbuf;
27 	/** Offset within data transfer buffer */
28 	size_t offset;
29 	/** Length to use from data transfer buffer */
30 	size_t len;
31 };
32 
33 /** PeerDist retrieval protocol decryption data transfer buffer indices */
34 enum peerdist_block_decrypt_index {
35 	/** Data before the trimmed content */
36 	PEERBLK_BEFORE = 0,
37 	/** Data within the trimmed content */
38 	PEERBLK_DURING,
39 	/** Data after the trimmed content */
40 	PEERBLK_AFTER,
41 	/** Number of decryption buffers */
42 	PEERBLK_NUM_BUFFERS
43 };
44 
45 /** A PeerDist block download */
46 struct peerdist_block {
47 	/** Reference count */
48 	struct refcnt refcnt;
49 	/** Data transfer interface */
50 	struct interface xfer;
51 	/** Raw data interface */
52 	struct interface raw;
53 	/** Retrieval protocol interface */
54 	struct interface retrieval;
55 
56 	/** Original URI */
57 	struct uri *uri;
58 	/** Content range of this block */
59 	struct peerdist_range range;
60 	/** Trimmed range of this block */
61 	struct peerdist_range trim;
62 	/** Offset of first byte in trimmed range within overall download */
63 	size_t offset;
64 
65 	/** Digest algorithm */
66 	struct digest_algorithm *digest;
67 	/** Digest size
68 	 *
69 	 * Note that this may be shorter than the digest size of the
70 	 * digest algorithm.
71 	 */
72 	size_t digestsize;
73 	/** Digest context (statically allocated at instantiation time) */
74 	void *digestctx;
75 
76 	/** Cipher algorithm */
77 	struct cipher_algorithm *cipher;
78 	/** Cipher context (dynamically allocated as needed) */
79 	void *cipherctx;
80 
81 	/** Segment index */
82 	unsigned int segment;
83 	/** Segment identifier */
84 	uint8_t id[PEERDIST_DIGEST_MAX_SIZE];
85 	/** Segment secret */
86 	uint8_t secret[PEERDIST_DIGEST_MAX_SIZE];
87 	/** Block index */
88 	unsigned int block;
89 	/** Block hash */
90 	uint8_t hash[PEERDIST_DIGEST_MAX_SIZE];
91 
92 	/** Current position (relative to incoming data stream) */
93 	size_t pos;
94 	/** Start of trimmed content (relative to incoming data stream) */
95 	size_t start;
96 	/** End of trimmed content (relative to incoming data stream) */
97 	size_t end;
98 	/** Data buffer */
99 	struct xfer_buffer buffer;
100 
101 	/** Decryption process */
102 	struct process process;
103 	/** Decryption data buffer descriptors */
104 	struct peerdist_block_decrypt decrypt[PEERBLK_NUM_BUFFERS];
105 	/** Remaining decryption length */
106 	size_t cipher_remaining;
107 	/** Remaining digest length (excluding AES padding bytes) */
108 	size_t digest_remaining;
109 
110 	/** Discovery client */
111 	struct peerdisc_client discovery;
112 	/** Current position in discovered peer list */
113 	struct peerdisc_peer *peer;
114 	/** Block download queue */
115 	struct peerdist_block_queue *queue;
116 	/** List of queued block downloads */
117 	struct list_head queued;
118 	/** Retry timer */
119 	struct retry_timer timer;
120 	/** Number of full attempt cycles completed */
121 	unsigned int cycles;
122 	/** Most recent attempt failure */
123 	int rc;
124 
125 	/** Time at which block download was started */
126 	unsigned long started;
127 	/** Time at which most recent attempt was started */
128 	unsigned long attempted;
129 };
130 
131 /** PeerDist block download queue */
132 struct peerdist_block_queue {
133 	/** Download opening process */
134 	struct process process;
135 	/** List of queued downloads */
136 	struct list_head list;
137 
138 	/** Number of open downloads */
139 	unsigned int count;
140 	/** Maximum number of open downloads */
141 	unsigned int max;
142 
143 	/** Open block download
144 	 *
145 	 * @v peerblk		PeerDist block download
146 	 * @ret rc		Return status code
147 	 */
148 	int ( * open ) ( struct peerdist_block *peerblk );
149 };
150 
151 /** Retrieval protocol block fetch response (including transport header)
152  *
153  * @v digestsize	Digest size
154  * @v len		Data block length
155  * @v vrf_len		Length of uselessness
156  * @v blksize		Cipher block size
157  */
158 #define peerblk_msg_blk_t( digestsize, len, vrf_len, blksize )		\
159 	struct {							\
160 		struct peerdist_msg_transport_header hdr;		\
161 		peerdist_msg_blk_t ( digestsize, len, vrf_len,		\
162 				     blksize ) msg;			\
163 	} __attribute__ (( packed ))
164 
165 extern int peerblk_open ( struct interface *xfer, struct uri *uri,
166 			  struct peerdist_info_block *block );
167 
168 #endif /* _IPXE_PEERBLK_H */
169