summaryrefslogtreecommitdiffstats
path: root/qemu/roms/ipxe/src/include/ipxe/peerblk.h
blob: 6fc9172f6a6582970f05d8c205469eb92e6169b4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#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 <stdint.h>
#include <ipxe/refcnt.h>
#include <ipxe/interface.h>
#include <ipxe/crypto.h>
#include <ipxe/aes.h>
#include <ipxe/xferbuf.h>
#include <ipxe/retry.h>
#include <ipxe/process.h>
#include <ipxe/pccrc.h>
#include <ipxe/peerdisc.h>

/** 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;
	/** 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;
};

/** 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 */