iPXE
Macros | Functions | Variables
peerblk.c File Reference

Peer Content Caching and Retrieval (PeerDist) protocol block downloads. More...

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <ipxe/http.h>
#include <ipxe/iobuf.h>
#include <ipxe/xfer.h>
#include <ipxe/uri.h>
#include <ipxe/timer.h>
#include <ipxe/profile.h>
#include <ipxe/fault.h>
#include <ipxe/pccrr.h>
#include <ipxe/peerblk.h>

Go to the source code of this file.

Macros

#define PEERBLK_DECRYPT_CHUNKSIZE   2048
 PeerDist decryption chunksize. More...
 
#define PEERBLK_RAW_MAX   2
 PeerDist maximum number of concurrent raw block downloads. More...
 
#define PEERBLK_RAW_OPEN_TIMEOUT   ( 10 * TICKS_PER_SEC )
 PeerDist raw block download attempt initial progress timeout. More...
 
#define PEERBLK_RAW_RX_TIMEOUT   ( 15 * TICKS_PER_SEC )
 PeerDist raw block download attempt ongoing progress timeout. More...
 
#define PEERBLK_RETRIEVAL_OPEN_TIMEOUT   ( 3 * TICKS_PER_SEC )
 PeerDist retrieval protocol block download attempt initial progress timeout. More...
 
#define PEERBLK_RETRIEVAL_RX_TIMEOUT   ( 5 * TICKS_PER_SEC )
 PeerDist retrieval protocol block download attempt ongoing progress timeout. More...
 
#define PEERBLK_MAX_ATTEMPT_CYCLES   4
 PeerDist maximum number of full download attempt cycles. More...
 

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
 FILE_SECBOOT (PERMITTED)
 
static void peerblk_dequeue (struct peerdist_block *peerblk)
 Remove block from download queue. More...
 
static unsigned long peerblk_timestamp (void)
 Get profiling timestamp. More...
 
static void peerblk_free (struct refcnt *refcnt)
 Free PeerDist block download. More...
 
static void peerblk_reset (struct peerdist_block *peerblk, int rc)
 Reset PeerDist block download attempt. More...
 
static void peerblk_close (struct peerdist_block *peerblk, int rc)
 Close PeerDist block download. More...
 
static size_t peerblk_offset (struct peerdist_block *peerblk, size_t pos)
 Calculate offset within overall download. More...
 
static int peerblk_deliver (struct peerdist_block *peerblk, struct io_buffer *iobuf, struct xfer_metadata *meta, size_t pos)
 Deliver download attempt data block. More...
 
static void peerblk_done (struct peerdist_block *peerblk, int rc)
 Finish PeerDist block download attempt. More...
 
static int peerblk_raw_open (struct peerdist_block *peerblk)
 Open PeerDist raw block download attempt. More...
 
static int peerblk_raw_rx (struct peerdist_block *peerblk, struct io_buffer *iobuf, struct xfer_metadata *meta)
 Receive PeerDist raw data. More...
 
static void peerblk_raw_close (struct peerdist_block *peerblk, int rc)
 Close PeerDist raw block download attempt. More...
 
static void peerblk_step (struct peerdist_block_queue *queue)
 PeerDist block download queue process. More...
 
static void peerblk_enqueue (struct peerdist_block *peerblk, struct peerdist_block_queue *queue)
 Add block to download queue. More...
 
static struct uripeerblk_retrieval_uri (const char *location)
 Construct PeerDist retrieval protocol URI. More...
 
static int peerblk_retrieval_open (struct peerdist_block *peerblk, const char *location)
 Open PeerDist retrieval protocol block download attempt. More...
 
static int peerblk_retrieval_rx (struct peerdist_block *peerblk, struct io_buffer *iobuf, struct xfer_metadata *meta)
 Receive PeerDist retrieval protocol data. More...
 
static int peerblk_parse_header (struct peerdist_block *peerblk)
 Parse retrieval protocol message header. More...
 
static int peerblk_parse_block (struct peerdist_block *peerblk, size_t *buf_len)
 Parse retrieval protocol message segment and block details. More...
 
static int peerblk_parse_useless (struct peerdist_block *peerblk, size_t buf_len, size_t *vrf_len)
 Parse retrieval protocol message useless details. More...
 
static int peerblk_parse_iv (struct peerdist_block *peerblk, size_t buf_len, size_t vrf_len)
 Parse retrieval protocol message initialisation vector details. More...
 
static int peerblk_decrypt_read (struct peerdist_block *peerblk, void *data, size_t len)
 Read from decryption buffers. More...
 
static int peerblk_decrypt_write (struct peerdist_block *peerblk, const void *data, size_t len)
 Write to decryption buffers and update offsets and lengths. More...
 
static void peerblk_decrypt (struct peerdist_block *peerblk)
 Decrypt one chunk of PeerDist retrieval protocol data. More...
 
static void peerblk_retrieval_close (struct peerdist_block *peerblk, int rc)
 Close PeerDist retrieval protocol block download attempt. More...
 
static void peerblk_expired (struct retry_timer *timer, int over __unused)
 Handle PeerDist retry timer expiry. More...
 
static void peerblk_discovered (struct peerdisc_client *discovery)
 Handle PeerDist peer discovery. More...
 
int peerblk_open (struct interface *xfer, struct uri *uri, struct peerdist_info_block *block)
 Open PeerDist block download. More...
 

Variables

static struct profiler peerblk_download_profiler __profiler
 PeerDist block download profiler. More...
 
static struct process_descriptor peerblk_queue_desc
 PeerDist block download queue process descriptor. More...
 
static struct peerdist_block_queue peerblk_raw_queue
 Raw block download queue. More...
 
static struct interface_operation peerblk_xfer_operations []
 PeerDist block download data transfer interface operations. More...
 
static struct interface_descriptor peerblk_xfer_desc
 PeerDist block download data transfer interface descriptor. More...
 
static struct interface_operation peerblk_raw_operations []
 PeerDist block download raw data interface operations. More...
 
static struct interface_descriptor peerblk_raw_desc
 PeerDist block download raw data interface descriptor. More...
 
static struct interface_operation peerblk_retrieval_operations []
 PeerDist block download retrieval protocol interface operations. More...
 
static struct interface_descriptor peerblk_retrieval_desc
 PeerDist block download retrieval protocol interface descriptor. More...
 
static struct process_descriptor peerblk_process_desc
 PeerDist block download decryption process descriptor. More...
 
static struct peerdisc_client_operations peerblk_discovery_operations
 PeerDist block download discovery operations. More...
 

Detailed Description

Peer Content Caching and Retrieval (PeerDist) protocol block downloads.

Definition in file peerblk.c.

Macro Definition Documentation

◆ PEERBLK_DECRYPT_CHUNKSIZE

#define PEERBLK_DECRYPT_CHUNKSIZE   2048

PeerDist decryption chunksize.

This is a policy decision.

Definition at line 51 of file peerblk.c.

◆ PEERBLK_RAW_MAX

#define PEERBLK_RAW_MAX   2

PeerDist maximum number of concurrent raw block downloads.

Raw block downloads are expensive if the origin server uses HTTPS, since each concurrent download will require local TLS resources (including potentially large received encrypted data buffers).

Raw block downloads may also be prohibitively slow to initiate when the origin server is using HTTPS and client certificates. Origin servers for PeerDist downloads are likely to be running IIS, which has a bug that breaks session resumption and requires each connection to go through the full client certificate verification.

Limit the total number of concurrent raw block downloads to ameliorate these problems.

This is a policy decision.

Definition at line 70 of file peerblk.c.

◆ PEERBLK_RAW_OPEN_TIMEOUT

#define PEERBLK_RAW_OPEN_TIMEOUT   ( 10 * TICKS_PER_SEC )

PeerDist raw block download attempt initial progress timeout.

This is a policy decision.

Definition at line 76 of file peerblk.c.

◆ PEERBLK_RAW_RX_TIMEOUT

#define PEERBLK_RAW_RX_TIMEOUT   ( 15 * TICKS_PER_SEC )

PeerDist raw block download attempt ongoing progress timeout.

This is a policy decision.

Definition at line 82 of file peerblk.c.

◆ PEERBLK_RETRIEVAL_OPEN_TIMEOUT

#define PEERBLK_RETRIEVAL_OPEN_TIMEOUT   ( 3 * TICKS_PER_SEC )

PeerDist retrieval protocol block download attempt initial progress timeout.

This is a policy decision.

Definition at line 88 of file peerblk.c.

◆ PEERBLK_RETRIEVAL_RX_TIMEOUT

#define PEERBLK_RETRIEVAL_RX_TIMEOUT   ( 5 * TICKS_PER_SEC )

PeerDist retrieval protocol block download attempt ongoing progress timeout.

This is a policy decision.

Definition at line 94 of file peerblk.c.

◆ PEERBLK_MAX_ATTEMPT_CYCLES

#define PEERBLK_MAX_ATTEMPT_CYCLES   4

PeerDist maximum number of full download attempt cycles.

This is the maximum number of times that we will try a full cycle of download attempts (i.e. a retrieval protocol download attempt from each discovered peer plus a raw download attempt from the origin server).

This is a policy decision.

Definition at line 105 of file peerblk.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED  )

◆ peerblk_dequeue()

static void peerblk_dequeue ( struct peerdist_block peerblk)
static

Remove block from download queue.

Parameters
peerblkPeerDist block download

Definition at line 538 of file peerblk.c.

538  {
539  struct peerdist_block_queue *queue = peerblk->queue;
540 
541  /* Sanity checks */
542  assert ( queue != NULL );
543 
544  /* Remove block from queue */
545  peerblk->queue = NULL;
546  if ( list_empty ( &peerblk->queued ) ) {
547 
548  /* Open download: decrement count and reschedule queue */
549  queue->count--;
550  process_add ( &queue->process );
551 
552  } else {
553 
554  /* Queued download: remove from queue */
555  list_del ( &peerblk->queued );
556  INIT_LIST_HEAD ( &peerblk->queued );
557  }
558 }
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:137
#define list_del(list)
Delete an entry from a list.
Definition: list.h:120
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
struct peerdist_block_queue * queue
Block download queue.
Definition: peerblk.h:116
void process_add(struct process *process)
Add process to process list.
Definition: process.c:60
PeerDist block download queue.
Definition: peerblk.h:133
struct list_head queued
List of queued block downloads.
Definition: peerblk.h:118
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:46
uint16_t queue
Queue ID.
Definition: ena.h:22
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322

References assert(), INIT_LIST_HEAD, list_del, list_empty, NULL, process_add(), queue, peerdist_block::queue, and peerdist_block::queued.

Referenced by peerblk_reset().

◆ peerblk_timestamp()

static unsigned long peerblk_timestamp ( void  )
inlinestatic

Get profiling timestamp.

Return values
timestampTimestamp

Definition at line 139 of file peerblk.c.

139  {
140 
141  if ( PROFILING ) {
142  return currticks();
143  } else {
144  return 0;
145  }
146 }
#define PROFILING
Definition: profile.h:20
unsigned long currticks(void)
Get current system time in ticks.
Definition: timer.c:43

References currticks(), and PROFILING.

Referenced by peerblk_close(), peerblk_discovered(), peerblk_done(), peerblk_expired(), and peerblk_open().

◆ peerblk_free()

static void peerblk_free ( struct refcnt refcnt)
static

Free PeerDist block download.

Parameters
refcntReference count

Definition at line 153 of file peerblk.c.

153  {
154  struct peerdist_block *peerblk =
156 
157  uri_put ( peerblk->uri );
158  free ( peerblk->cipherctx );
159  free ( peerblk );
160 }
static void uri_put(struct uri *uri)
Decrement URI reference count.
Definition: uri.h:206
A reference counter.
Definition: refcnt.h:27
struct uri * uri
Original URI.
Definition: peerblk.h:58
A PeerDist block download.
Definition: peerblk.h:47
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:36
void * cipherctx
Cipher context (dynamically allocated as needed)
Definition: peerblk.h:80
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:55

References peerdist_block::cipherctx, container_of, free, peerdist_block::uri, and uri_put().

Referenced by peerblk_open().

◆ peerblk_reset()

static void peerblk_reset ( struct peerdist_block peerblk,
int  rc 
)
static

Reset PeerDist block download attempt.

Parameters
peerblkPeerDist block download
rcReason for reset

Definition at line 168 of file peerblk.c.

168  {
169 
170  /* Stop decryption process */
171  process_del ( &peerblk->process );
172 
173  /* Stop timer */
174  stop_timer ( &peerblk->timer );
175 
176  /* Abort any current download attempt */
177  intf_restart ( &peerblk->raw, rc );
178  intf_restart ( &peerblk->retrieval, rc );
179 
180  /* Remove from download queue, if applicable */
181  if ( peerblk->queue )
182  peerblk_dequeue ( peerblk );
183 
184  /* Empty received data buffer */
185  xferbuf_free ( &peerblk->buffer );
186  peerblk->pos = 0;
187 
188  /* Reset digest and free cipher context */
189  digest_init ( peerblk->digest, peerblk->digestctx );
190  free ( peerblk->cipherctx );
191  peerblk->cipherctx = NULL;
192  peerblk->cipher = NULL;
193 
194  /* Reset trim thresholds */
195  peerblk->start = ( peerblk->trim.start - peerblk->range.start );
196  peerblk->end = ( peerblk->trim.end - peerblk->range.start );
197  assert ( peerblk->start <= peerblk->end );
198 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition: interface.c:344
struct xfer_buffer buffer
Data buffer.
Definition: peerblk.h:100
size_t start
Start offset.
Definition: pccrc.h:311
struct interface retrieval
Retrieval protocol interface.
Definition: peerblk.h:55
void * digestctx
Digest context (statically allocated at instantiation time)
Definition: peerblk.h:75
void xferbuf_free(struct xfer_buffer *xferbuf)
Free data transfer buffer.
Definition: xferbuf.c:74
struct process process
Decryption process.
Definition: peerblk.h:103
void process_del(struct process *process)
Remove process from process list.
Definition: process.c:80
struct cipher_algorithm * cipher
Cipher algorithm.
Definition: peerblk.h:78
static void peerblk_dequeue(struct peerdist_block *peerblk)
Remove block from download queue.
Definition: peerblk.c:538
size_t end
End of trimmed content (relative to incoming data stream)
Definition: peerblk.h:98
struct digest_algorithm * digest
Digest algorithm.
Definition: peerblk.h:67
struct peerdist_range range
Content range of this block.
Definition: peerblk.h:60
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
struct peerdist_block_queue * queue
Block download queue.
Definition: peerblk.h:116
struct interface raw
Raw data interface.
Definition: peerblk.h:53
static void digest_init(struct digest_algorithm *digest, void *ctx)
Definition: crypto.h:219
void * cipherctx
Cipher context (dynamically allocated as needed)
Definition: peerblk.h:80
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:55
size_t start
Start of trimmed content (relative to incoming data stream)
Definition: peerblk.h:96
struct retry_timer timer
Retry timer.
Definition: peerblk.h:120
void stop_timer(struct retry_timer *timer)
Stop timer.
Definition: retry.c:118
struct peerdist_range trim
Trimmed range of this block.
Definition: peerblk.h:62
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
size_t pos
Current position (relative to incoming data stream)
Definition: peerblk.h:94
size_t end
End offset.
Definition: pccrc.h:313

References assert(), peerdist_block::buffer, peerdist_block::cipher, peerdist_block::cipherctx, peerdist_block::digest, digest_init(), peerdist_block::digestctx, peerdist_block::end, peerdist_range::end, free, intf_restart(), NULL, peerblk_dequeue(), peerdist_block::pos, peerdist_block::process, process_del(), peerdist_block::queue, peerdist_block::range, peerdist_block::raw, rc, peerdist_block::retrieval, peerdist_block::start, peerdist_range::start, stop_timer(), peerdist_block::timer, peerdist_block::trim, and xferbuf_free().

Referenced by peerblk_close(), peerblk_done(), and peerblk_expired().

◆ peerblk_close()

static void peerblk_close ( struct peerdist_block peerblk,
int  rc 
)
static

Close PeerDist block download.

Parameters
peerblkPeerDist block download
rcReason for close

Definition at line 206 of file peerblk.c.

206  {
207  unsigned long now = peerblk_timestamp();
208 
209  /* Profile overall block download */
210  profile_custom ( &peerblk_download_profiler,
211  ( now - peerblk->started ) );
212 
213  /* Reset download attempt */
214  peerblk_reset ( peerblk, rc );
215 
216  /* Close discovery */
217  peerdisc_close ( &peerblk->discovery );
218 
219  /* Shut down all interfaces */
220  intf_shutdown ( &peerblk->retrieval, rc );
221  intf_shutdown ( &peerblk->raw, rc );
222  intf_shutdown ( &peerblk->xfer, rc );
223 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
Definition: interface.c:279
struct interface retrieval
Retrieval protocol interface.
Definition: peerblk.h:55
static void profile_custom(struct profiler *profiler, unsigned long sample)
Record profiling sample in custom units.
Definition: profile.h:201
struct peerdisc_client discovery
Discovery client.
Definition: peerblk.h:112
static unsigned long peerblk_timestamp(void)
Get profiling timestamp.
Definition: peerblk.c:139
static void peerblk_reset(struct peerdist_block *peerblk, int rc)
Reset PeerDist block download attempt.
Definition: peerblk.c:168
struct interface raw
Raw data interface.
Definition: peerblk.h:53
struct interface xfer
Data transfer interface.
Definition: peerblk.h:51
unsigned long started
Time at which block download was started.
Definition: peerblk.h:127
void peerdisc_close(struct peerdisc_client *peerdisc)
Close PeerDist discovery client.
Definition: peerdisc.c:598

References peerdist_block::discovery, intf_shutdown(), peerblk_reset(), peerblk_timestamp(), peerdisc_close(), profile_custom(), peerdist_block::raw, rc, peerdist_block::retrieval, peerdist_block::started, and peerdist_block::xfer.

Referenced by peerblk_done(), peerblk_expired(), peerblk_open(), and peerblk_step().

◆ peerblk_offset()

static size_t peerblk_offset ( struct peerdist_block peerblk,
size_t  pos 
)
inlinestatic

Calculate offset within overall download.

Parameters
peerblkPeerDist block download
posPosition within incoming data stream
Return values
offsetOffset within overall download

Definition at line 233 of file peerblk.c.

233  {
234 
235  return ( ( pos - peerblk->start ) + peerblk->offset );
236 }
size_t offset
Offset of first byte in trimmed range within overall download.
Definition: peerblk.h:64
size_t start
Start of trimmed content (relative to incoming data stream)
Definition: peerblk.h:96
size_t pos
Current position (relative to incoming data stream)
Definition: peerblk.h:94

References peerdist_block::offset, peerdist_block::pos, and peerdist_block::start.

Referenced by peerblk_deliver(), and peerblk_parse_block().

◆ peerblk_deliver()

static int peerblk_deliver ( struct peerdist_block peerblk,
struct io_buffer iobuf,
struct xfer_metadata meta,
size_t  pos 
)
static

Deliver download attempt data block.

Parameters
peerblkPeerDist block download
iobufI/O buffer
metaOriginal data transfer metadata
posPosition within incoming data stream
Return values
rcReturn status code

Definition at line 247 of file peerblk.c.

249  {
250  struct xfer_metadata xfer_meta;
251  size_t len = iob_len ( iobuf );
252  size_t start = pos;
253  size_t end = ( pos + len );
254  int rc;
255 
256  /* Discard zero-length packets and packets which lie entirely
257  * outside the trimmed range.
258  */
259  if ( ( start >= peerblk->end ) || ( end <= peerblk->start ) ||
260  ( len == 0 ) ) {
261  free_iob ( iobuf );
262  return 0;
263  }
264 
265  /* Truncate data to within trimmed range */
266  if ( start < peerblk->start ) {
267  iob_pull ( iobuf, ( peerblk->start - start ) );
268  start = peerblk->start;
269  }
270  if ( end > peerblk->end ) {
271  iob_unput ( iobuf, ( end - peerblk->end ) );
272  end = peerblk->end;
273  }
274 
275  /* Construct metadata */
276  memcpy ( &xfer_meta, meta, sizeof ( xfer_meta ) );
277  xfer_meta.flags |= XFER_FL_ABS_OFFSET;
278  xfer_meta.offset = peerblk_offset ( peerblk, start );
279 
280  /* Deliver data */
281  if ( ( rc = xfer_deliver ( &peerblk->xfer, iob_disown ( iobuf ),
282  &xfer_meta ) ) != 0 ) {
283  DBGC ( peerblk, "PEERBLK %p %d.%d could not deliver data: %s\n",
284  peerblk, peerblk->segment, peerblk->block,
285  strerror ( rc ) );
286  return rc;
287  }
288 
289  return 0;
290 }
#define iob_pull(iobuf, len)
Definition: iobuf.h:107
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
Data transfer metadata.
Definition: xfer.h:23
static size_t peerblk_offset(struct peerdist_block *peerblk, size_t pos)
Calculate offset within overall download.
Definition: peerblk.c:233
#define XFER_FL_ABS_OFFSET
Offset is absolute.
Definition: xfer.h:48
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:153
#define DBGC(...)
Definition: compiler.h:505
size_t end
End of trimmed content (relative to incoming data stream)
Definition: peerblk.h:98
uint32_t start
Starting offset.
Definition: netvsc.h:12
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:217
void * memcpy(void *dest, const void *src, size_t len) __nonnull
ring len
Length.
Definition: dwmac.h:231
unsigned int segment
Segment index.
Definition: peerblk.h:83
unsigned int block
Block index.
Definition: peerblk.h:89
struct interface xfer
Data transfer interface.
Definition: peerblk.h:51
#define iob_unput(iobuf, len)
Definition: iobuf.h:140
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:160
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition: xfer.c:195
size_t start
Start of trimmed content (relative to incoming data stream)
Definition: peerblk.h:96
uint32_t end
Ending offset.
Definition: netvsc.h:18
uint8_t meta
Metadata flags.
Definition: ena.h:14

References peerdist_block::block, DBGC, end, peerdist_block::end, xfer_metadata::flags, free_iob(), iob_disown, iob_len(), iob_pull, iob_unput, len, memcpy(), meta, xfer_metadata::offset, peerblk_offset(), rc, peerdist_block::segment, start, peerdist_block::start, strerror(), peerdist_block::xfer, xfer_deliver(), and XFER_FL_ABS_OFFSET.

Referenced by peerblk_raw_rx(), and peerblk_retrieval_rx().

◆ peerblk_done()

static void peerblk_done ( struct peerdist_block peerblk,
int  rc 
)
static

Finish PeerDist block download attempt.

Parameters
peerblkPeerDist block download
rcReason for close

Definition at line 298 of file peerblk.c.

298  {
299  struct digest_algorithm *digest = peerblk->digest;
300  struct peerdisc_segment *segment = peerblk->discovery.segment;
301  struct peerdisc_peer *head;
302  struct peerdisc_peer *peer;
303  uint8_t hash[digest->digestsize];
304  unsigned long now = peerblk_timestamp();
305 
306  /* Check for errors on completion */
307  if ( rc != 0 ) {
308  DBGC ( peerblk, "PEERBLK %p %d.%d attempt failed: %s\n",
309  peerblk, peerblk->segment, peerblk->block,
310  strerror ( rc ) );
311  goto err;
312  }
313 
314  /* Check digest */
315  digest_final ( digest, peerblk->digestctx, hash );
316  if ( memcmp ( hash, peerblk->hash, peerblk->digestsize ) != 0 ) {
317  DBGC ( peerblk, "PEERBLK %p %d.%d digest mismatch:\n",
318  peerblk, peerblk->segment, peerblk->block );
319  DBGC_HDA ( peerblk, 0, hash, peerblk->digestsize );
320  DBGC_HDA ( peerblk, 0, peerblk->hash, peerblk->digestsize );
321  rc = -EIO;
322  goto err;
323  }
324 
325  /* Profile successful attempt */
326  profile_custom ( &peerblk_attempt_success_profiler,
327  ( now - peerblk->attempted ) );
328 
329  /* Report peer statistics */
330  head = list_entry ( &segment->peers, struct peerdisc_peer, list );
331  peer = ( ( peerblk->peer == head ) ? NULL : peerblk->peer );
332  peerdisc_stat ( &peerblk->xfer, peer, &segment->peers );
333 
334  /* Close download */
335  peerblk_close ( peerblk, 0 );
336  return;
337 
338  err:
339  /* Record failure reason and schedule a retry attempt */
340  profile_custom ( &peerblk_attempt_failure_profiler,
341  ( now - peerblk->attempted ) );
342  peerblk_reset ( peerblk, rc );
343  peerblk->rc = rc;
344  start_timer_nodelay ( &peerblk->timer );
345 }
uint16_t segment
Code segment.
Definition: librm.h:138
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
pseudo_bit_t hash[0x00010]
Definition: arbel.h:13
static void start_timer_nodelay(struct retry_timer *timer)
Start timer with no delay.
Definition: retry.h:100
static void digest_final(struct digest_algorithm *digest, void *ctx, void *out)
Definition: crypto.h:230
A PeerDist discovery segment.
Definition: peerdisc.h:43
void * digestctx
Digest context (statically allocated at instantiation time)
Definition: peerblk.h:75
#define DBGC(...)
Definition: compiler.h:505
static void profile_custom(struct profiler *profiler, unsigned long sample)
Record profiling sample in custom units.
Definition: profile.h:201
uint8_t head
Head number.
Definition: int13.h:34
struct peerdisc_client discovery
Discovery client.
Definition: peerblk.h:112
static unsigned long peerblk_timestamp(void)
Get profiling timestamp.
Definition: peerblk.c:139
static void peerblk_reset(struct peerdist_block *peerblk, int rc)
Reset PeerDist block download attempt.
Definition: peerblk.c:168
struct digest_algorithm * digest
Digest algorithm.
Definition: peerblk.h:67
void peerdisc_stat(struct interface *intf, struct peerdisc_peer *peer, struct list_head *peers)
Report peer discovery statistics.
Definition: peerdisc.c:101
int rc
Most recent attempt failure.
Definition: peerblk.h:124
#define DBGC_HDA(...)
Definition: compiler.h:506
unsigned int segment
Segment index.
Definition: peerblk.h:83
unsigned int block
Block index.
Definition: peerblk.h:89
struct peerdisc_peer * peer
Current position in discovered peer list.
Definition: peerblk.h:114
struct interface xfer
Data transfer interface.
Definition: peerblk.h:51
uint8_t hash[PEERDIST_DIGEST_MAX_SIZE]
Block hash.
Definition: peerblk.h:91
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
unsigned char uint8_t
Definition: stdint.h:10
size_t digestsize
Digest size.
Definition: peerblk.h:73
struct peerdisc_segment * segment
Discovery segment.
Definition: peerdisc.h:82
unsigned long attempted
Time at which most recent attempt was started.
Definition: peerblk.h:129
struct retry_timer timer
Retry timer.
Definition: peerblk.h:120
static void peerblk_close(struct peerdist_block *peerblk, int rc)
Close PeerDist block download.
Definition: peerblk.c:206
size_t digestsize
Digest size.
Definition: crypto.h:27
#define EIO
Input/output error.
Definition: errno.h:434
A message digest algorithm.
Definition: crypto.h:19
struct mschapv2_challenge peer
Peer challenge.
Definition: mschapv2.h:12
struct list_head list
List of peers.
Definition: peerdisc.h:74
#define list_entry(list, type, member)
Get the container of a list entry.
Definition: list.h:322
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:115
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
A PeerDist discovery peer.
Definition: peerdisc.h:72

References peerdist_block::attempted, peerdist_block::block, DBGC, DBGC_HDA, peerdist_block::digest, digest_final(), peerdist_block::digestctx, digest_algorithm::digestsize, peerdist_block::digestsize, peerdist_block::discovery, EIO, hash, peerdist_block::hash, head, peerdisc_peer::list, list_entry, memcmp(), NULL, peer, peerdist_block::peer, peerblk_close(), peerblk_reset(), peerblk_timestamp(), peerdisc_stat(), profile_custom(), peerdist_block::rc, rc, peerdisc_client::segment, peerdist_block::segment, segment, start_timer_nodelay(), strerror(), peerdist_block::timer, and peerdist_block::xfer.

Referenced by peerblk_decrypt(), peerblk_raw_close(), peerblk_raw_rx(), peerblk_retrieval_close(), and peerblk_retrieval_rx().

◆ peerblk_raw_open()

static int peerblk_raw_open ( struct peerdist_block peerblk)
static

Open PeerDist raw block download attempt.

Parameters
peerblkPeerDist block download
Return values
rcReturn status code

Definition at line 360 of file peerblk.c.

360  {
361  struct http_request_range range;
362  int rc;
363 
364  DBGC2 ( peerblk, "PEERBLK %p %d.%d attempting raw range request\n",
365  peerblk, peerblk->segment, peerblk->block );
366 
367  /* Construct HTTP range */
368  memset ( &range, 0, sizeof ( range ) );
369  range.start = peerblk->range.start;
370  range.len = ( peerblk->range.end - peerblk->range.start );
371 
372  /* Initiate range request to retrieve block */
373  if ( ( rc = http_open ( &peerblk->raw, &http_get, peerblk->uri,
374  &range, NULL ) ) != 0 ) {
375  DBGC ( peerblk, "PEERBLK %p %d.%d could not create range "
376  "request: %s\n", peerblk, peerblk->segment,
377  peerblk->block, strerror ( rc ) );
378  return rc;
379  }
380 
381  /* Annul HTTP connection (for testing) if applicable. Do not
382  * report as an immediate error, in order to test our ability
383  * to recover from a totally unresponsive HTTP server.
384  */
385  if ( inject_fault ( PEERBLK_ANNUL_RATE ) )
386  intf_restart ( &peerblk->raw, 0 );
387 
388  /* Start download attempt timer */
389  peerblk->rc = -ETIMEDOUT;
391 
392  return 0;
393 }
uint32_t start
Starting bus:dev.fn address.
Definition: pci_io.h:25
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition: interface.c:344
struct pci_range range
PCI bus:dev.fn address range.
Definition: pcicloud.c:40
#define PEERBLK_RAW_OPEN_TIMEOUT
PeerDist raw block download attempt initial progress timeout.
Definition: peerblk.c:76
HTTP request range descriptor.
Definition: http.h:136
size_t start
Start offset.
Definition: pccrc.h:311
#define DBGC(...)
Definition: compiler.h:505
struct uri * uri
Original URI.
Definition: peerblk.h:58
int rc
Most recent attempt failure.
Definition: peerblk.h:124
struct peerdist_range range
Content range of this block.
Definition: peerblk.h:60
unsigned int segment
Segment index.
Definition: peerblk.h:83
struct interface raw
Raw data interface.
Definition: peerblk.h:53
unsigned int block
Block index.
Definition: peerblk.h:89
struct http_method http_get
HTTP GET method.
Definition: httpcore.c:144
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
void start_timer_fixed(struct retry_timer *timer, unsigned long timeout)
Start timer with a specified timeout.
Definition: retry.c:65
#define PEERBLK_ANNUL_RATE
Definition: fault.h:25
struct retry_timer timer
Retry timer.
Definition: peerblk.h:120
#define DBGC2(...)
Definition: compiler.h:522
int http_open(struct interface *xfer, struct http_method *method, struct uri *uri, struct http_request_range *range, struct http_request_content *content)
Open HTTP transaction.
Definition: httpcore.c:642
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
#define ETIMEDOUT
Connection timed out.
Definition: errno.h:670
size_t end
End offset.
Definition: pccrc.h:313
void * memset(void *dest, int character, size_t len) __nonnull

References peerdist_block::block, DBGC, DBGC2, peerdist_range::end, ETIMEDOUT, http_get, http_open(), intf_restart(), memset(), NULL, PEERBLK_ANNUL_RATE, PEERBLK_RAW_OPEN_TIMEOUT, peerdist_block::range, range, peerdist_block::raw, peerdist_block::rc, rc, peerdist_block::segment, pci_range::start, peerdist_range::start, start_timer_fixed(), strerror(), peerdist_block::timer, and peerdist_block::uri.

◆ peerblk_raw_rx()

static int peerblk_raw_rx ( struct peerdist_block peerblk,
struct io_buffer iobuf,
struct xfer_metadata meta 
)
static

Receive PeerDist raw data.

Parameters
peerblkPeerDist block download
iobufI/O buffer
metaData transfer metadata
Return values
rcReturn status code

Definition at line 403 of file peerblk.c.

405  {
406  size_t len = iob_len ( iobuf );
407  size_t pos = peerblk->pos;
408  size_t mid = ( ( peerblk->range.end - peerblk->range.start ) / 2 );
409  int rc;
410 
411  /* Corrupt received data (for testing) if applicable */
412  inject_corruption ( PEERBLK_CORRUPT_RATE, iobuf->data, len );
413 
414  /* Fail if data is delivered out of order, since the streaming
415  * digest requires strict ordering.
416  */
417  if ( ( rc = xfer_check_order ( meta, &peerblk->pos, len ) ) != 0 )
418  goto err;
419 
420  /* Add data to digest */
421  digest_update ( peerblk->digest, peerblk->digestctx, iobuf->data, len );
422 
423  /* Deliver data */
424  if ( ( rc = peerblk_deliver ( peerblk, iob_disown ( iobuf ), meta,
425  pos ) ) != 0 )
426  goto err;
427 
428  /* Extend download attempt timer */
430 
431  /* Stall download attempt (for testing) if applicable */
432  if ( ( pos < mid ) && ( ( pos + len ) >= mid ) &&
433  ( ( rc = inject_fault ( PEERBLK_STALL_RATE ) ) != 0 ) ) {
434  intf_restart ( &peerblk->raw, rc );
435  }
436 
437  return 0;
438 
439  err:
440  free_iob ( iobuf );
441  peerblk_done ( peerblk, rc );
442  return rc;
443 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static void digest_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Definition: crypto.h:224
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition: interface.c:344
uint16_t mid
Middle 16 bits of address.
Definition: librm.h:144
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:153
size_t start
Start offset.
Definition: pccrc.h:311
void * digestctx
Digest context (statically allocated at instantiation time)
Definition: peerblk.h:75
static int peerblk_deliver(struct peerdist_block *peerblk, struct io_buffer *iobuf, struct xfer_metadata *meta, size_t pos)
Deliver download attempt data block.
Definition: peerblk.c:247
int xfer_check_order(struct xfer_metadata *meta, size_t *pos, size_t len)
Check that data is delivered strictly in order.
Definition: xfer.c:378
#define PEERBLK_STALL_RATE
Definition: fault.h:28
struct digest_algorithm * digest
Digest algorithm.
Definition: peerblk.h:67
struct peerdist_range range
Content range of this block.
Definition: peerblk.h:60
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:217
#define PEERBLK_RAW_RX_TIMEOUT
PeerDist raw block download attempt ongoing progress timeout.
Definition: peerblk.c:82
ring len
Length.
Definition: dwmac.h:231
struct interface raw
Raw data interface.
Definition: peerblk.h:53
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:160
void start_timer_fixed(struct retry_timer *timer, unsigned long timeout)
Start timer with a specified timeout.
Definition: retry.c:65
struct retry_timer timer
Retry timer.
Definition: peerblk.h:120
static void peerblk_done(struct peerdist_block *peerblk, int rc)
Finish PeerDist block download attempt.
Definition: peerblk.c:298
void * data
Start of data.
Definition: iobuf.h:53
#define PEERBLK_CORRUPT_RATE
Definition: fault.h:34
uint8_t meta
Metadata flags.
Definition: ena.h:14
size_t pos
Current position (relative to incoming data stream)
Definition: peerblk.h:94
size_t end
End offset.
Definition: pccrc.h:313

References io_buffer::data, peerdist_block::digest, digest_update(), peerdist_block::digestctx, peerdist_range::end, free_iob(), intf_restart(), iob_disown, iob_len(), len, meta, mid, PEERBLK_CORRUPT_RATE, peerblk_deliver(), peerblk_done(), PEERBLK_RAW_RX_TIMEOUT, PEERBLK_STALL_RATE, peerdist_block::pos, peerdist_block::range, peerdist_block::raw, rc, peerdist_range::start, start_timer_fixed(), peerdist_block::timer, and xfer_check_order().

◆ peerblk_raw_close()

static void peerblk_raw_close ( struct peerdist_block peerblk,
int  rc 
)
static

Close PeerDist raw block download attempt.

Parameters
peerblkPeerDist block download
rcReason for close

Definition at line 451 of file peerblk.c.

451  {
452 
453  /* Restart interface */
454  intf_restart ( &peerblk->raw, rc );
455 
456  /* Fail immediately if we have an error */
457  if ( rc != 0 )
458  goto done;
459 
460  /* Abort download attempt (for testing) if applicable */
461  if ( ( rc = inject_fault ( PEERBLK_ABORT_RATE ) ) != 0 )
462  goto done;
463 
464  done:
465  /* Complete download attempt */
466  peerblk_done ( peerblk, rc );
467 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition: interface.c:344
#define PEERBLK_ABORT_RATE
Definition: fault.h:31
struct interface raw
Raw data interface.
Definition: peerblk.h:53
static void peerblk_done(struct peerdist_block *peerblk, int rc)
Finish PeerDist block download attempt.
Definition: peerblk.c:298
struct bofm_section_header done
Definition: bofm_test.c:46

References done, intf_restart(), PEERBLK_ABORT_RATE, peerblk_done(), peerdist_block::raw, and rc.

◆ peerblk_step()

static void peerblk_step ( struct peerdist_block_queue queue)
static

PeerDist block download queue process.

Parameters
queueBlock download queue

Definition at line 481 of file peerblk.c.

481  {
482  struct peerdist_block *peerblk;
483  int rc;
484 
485  /* Do nothing yet if we have too many open block downloads */
486  if ( queue->count >= queue->max )
487  return;
488 
489  /* Do nothing unless there are queued block downloads */
490  peerblk = list_first_entry ( &queue->list, struct peerdist_block,
491  queued );
492  if ( ! peerblk )
493  return;
494 
495  /* Reschedule queue process */
496  process_add ( &queue->process );
497 
498  /* Remove block from queue */
499  list_del ( &peerblk->queued );
500  INIT_LIST_HEAD ( &peerblk->queued );
501 
502  /* Attempt download */
503  if ( ( rc = queue->open ( peerblk ) ) != 0 ) {
504  peerblk_close ( peerblk, rc );
505  return;
506  }
507 
508  /* Increment open block download count */
509  queue->count++;
510 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition: list.h:334
#define list_del(list)
Delete an entry from a list.
Definition: list.h:120
A PeerDist block download.
Definition: peerblk.h:47
void process_add(struct process *process)
Add process to process list.
Definition: process.c:60
struct list_head queued
List of queued block downloads.
Definition: peerblk.h:118
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:46
static void peerblk_close(struct peerdist_block *peerblk, int rc)
Close PeerDist block download.
Definition: peerblk.c:206
uint16_t queue
Queue ID.
Definition: ena.h:22

References INIT_LIST_HEAD, list_del, list_first_entry, peerblk_close(), process_add(), queue, peerdist_block::queued, and rc.

◆ peerblk_enqueue()

static void peerblk_enqueue ( struct peerdist_block peerblk,
struct peerdist_block_queue queue 
)
static

Add block to download queue.

Parameters
peerblkPeerDist block download
queueBlock download queue

Definition at line 518 of file peerblk.c.

519  {
520 
521  /* Sanity checks */
522  assert ( peerblk->queue == NULL );
523  assert ( list_empty ( &peerblk->queued ) );
524 
525  /* Add block to queue */
526  peerblk->queue = queue;
527  list_add_tail ( &peerblk->queued, &queue->list );
528 
529  /* Schedule queue process */
530  process_add ( &queue->process );
531 }
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:137
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
struct peerdist_block_queue * queue
Block download queue.
Definition: peerblk.h:116
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:94
void process_add(struct process *process)
Add process to process list.
Definition: process.c:60
struct list_head queued
List of queued block downloads.
Definition: peerblk.h:118
uint16_t queue
Queue ID.
Definition: ena.h:22
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322

References assert(), list_add_tail, list_empty, NULL, process_add(), queue, peerdist_block::queue, and peerdist_block::queued.

Referenced by peerblk_expired().

◆ peerblk_retrieval_uri()

static struct uri* peerblk_retrieval_uri ( const char *  location)
static

Construct PeerDist retrieval protocol URI.

Parameters
locationPeer location
Return values
uriRetrieval URI, or NULL on error

Definition at line 585 of file peerblk.c.

585  {
586  char uri_string[ 7 /* "http://" */ + strlen ( location ) +
587  sizeof ( PEERDIST_MAGIC_PATH /* includes NUL */ ) ];
588 
589  /* Construct URI string */
590  snprintf ( uri_string, sizeof ( uri_string ),
591  ( "http://%s" PEERDIST_MAGIC_PATH ), location );
592 
593  /* Parse URI string */
594  return parse_uri ( uri_string );
595 }
#define PEERDIST_MAGIC_PATH
Magic retrieval URI path.
Definition: pccrr.h:18
size_t strlen(const char *src)
Get length of string.
Definition: string.c:244
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:383
struct uri * parse_uri(const char *uri_string)
Parse URI.
Definition: uri.c:297

References parse_uri(), PEERDIST_MAGIC_PATH, snprintf(), and strlen().

Referenced by peerblk_retrieval_open().

◆ peerblk_retrieval_open()

static int peerblk_retrieval_open ( struct peerdist_block peerblk,
const char *  location 
)
static

Open PeerDist retrieval protocol block download attempt.

Parameters
peerblkPeerDist block download
locationPeer location
Return values
rcReturn status code

Definition at line 604 of file peerblk.c.

605  {
606  size_t digestsize = peerblk->digestsize;
607  peerdist_msg_getblks_t ( digestsize, 1, 0 ) req;
608  peerblk_msg_blk_t ( digestsize, 0, 0, 0 ) *rsp;
609  struct http_request_content content;
610  struct uri *uri;
611  int rc;
612 
613  DBGC2 ( peerblk, "PEERBLK %p %d.%d attempting retrieval from %s\n",
614  peerblk, peerblk->segment, peerblk->block, location );
615 
616  /* Construct block fetch request */
617  memset ( &req, 0, sizeof ( req ) );
619  req.getblks.hdr.type = htonl ( PEERDIST_MSG_GETBLKS_TYPE );
620  req.getblks.hdr.len = htonl ( sizeof ( req ) );
621  req.getblks.hdr.algorithm = htonl ( PEERDIST_MSG_AES_128_CBC );
623  memcpy ( req.segment.id, peerblk->id, digestsize );
624  req.ranges.ranges.count = htonl ( 1 );
625  req.ranges.range[0].first = htonl ( peerblk->block );
626  req.ranges.range[0].count = htonl ( 1 );
627 
628  /* Construct POST request content */
629  memset ( &content, 0, sizeof ( content ) );
630  content.data = &req;
631  content.len = sizeof ( req );
632 
633  /* Construct URI */
634  if ( ( uri = peerblk_retrieval_uri ( location ) ) == NULL ) {
635  rc = -ENOMEM;
636  goto err_uri;
637  }
638 
639  /* Update trim thresholds */
640  peerblk->start += offsetof ( typeof ( *rsp ), msg.vrf );
641  peerblk->end += offsetof ( typeof ( *rsp ), msg.vrf );
642 
643  /* Initiate HTTP POST to retrieve block */
644  if ( ( rc = http_open ( &peerblk->retrieval, &http_post, uri,
645  NULL, &content ) ) != 0 ) {
646  DBGC ( peerblk, "PEERBLK %p %d.%d could not create retrieval "
647  "request: %s\n", peerblk, peerblk->segment,
648  peerblk->block, strerror ( rc ) );
649  goto err_open;
650  }
651 
652  /* Annul HTTP connection (for testing) if applicable. Do not
653  * report as an immediate error, in order to test our ability
654  * to recover from a totally unresponsive HTTP server.
655  */
656  if ( inject_fault ( PEERBLK_ANNUL_RATE ) )
657  intf_restart ( &peerblk->retrieval, 0 );
658 
659  /* Start download attempt timer */
660  peerblk->rc = -ETIMEDOUT;
662 
663  err_open:
664  uri_put ( uri );
665  err_uri:
666  return rc;
667 }
AES-128 in CBC mode.
Definition: pccrr.h:172
static struct uri * peerblk_retrieval_uri(const char *location)
Construct PeerDist retrieval protocol URI.
Definition: peerblk.c:585
uint16_t segment
Code segment.
Definition: librm.h:138
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition: interface.c:344
struct pci_range range
PCI bus:dev.fn address range.
Definition: pcicloud.c:40
static void uri_put(struct uri *uri)
Decrement URI reference count.
Definition: uri.h:206
void msg(unsigned int row, const char *fmt,...)
Print message centred on specified row.
Definition: message.c:62
uint32_t first
First block in range.
Definition: pccrr.h:15
struct golan_inbox_hdr hdr
Message header.
Definition: CIB_PRM.h:28
#define PEERBLK_RETRIEVAL_OPEN_TIMEOUT
PeerDist retrieval protocol block download attempt initial progress timeout.
Definition: peerblk.c:88
uint32_t type
Operating system type.
Definition: ena.h:12
struct interface retrieval
Retrieval protocol interface.
Definition: peerblk.h:55
#define DBGC(...)
Definition: compiler.h:505
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h:25
#define htonl(value)
Definition: byteswap.h:134
size_t end
End of trimmed content (relative to incoming data stream)
Definition: peerblk.h:98
int rc
Most recent attempt failure.
Definition: peerblk.h:124
#define ENOMEM
Not enough space.
Definition: errno.h:535
void * memcpy(void *dest, const void *src, size_t len) __nonnull
u32 version
Driver version.
Definition: ath9k_hw.c:1985
#define PEERDIST_MSG_GETBLKS_TYPE
Retrieval protocol block fetch request type.
Definition: pccrr.h:278
ring len
Length.
Definition: dwmac.h:231
unsigned int segment
Segment index.
Definition: peerblk.h:83
static unsigned int count
Number of entries.
Definition: dwmac.h:225
unsigned int block
Block index.
Definition: peerblk.h:89
HTTP request content descriptor.
Definition: http.h:144
uint64_t rsp
Definition: librm.h:153
#define PEERDIST_MSG_GETBLKS_VERSION
Retrieval protocol block fetch request version.
Definition: pccrr.h:275
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
size_t digestsize
Digest size.
Definition: peerblk.h:73
size_t start
Start of trimmed content (relative to incoming data stream)
Definition: peerblk.h:96
void start_timer_fixed(struct retry_timer *timer, unsigned long timeout)
Start timer with a specified timeout.
Definition: retry.c:65
#define PEERBLK_ANNUL_RATE
Definition: fault.h:25
u16 algorithm
Authentication algorithm (Open System or Shared Key)
Definition: ieee80211.h:1030
struct retry_timer timer
Retry timer.
Definition: peerblk.h:120
#define peerblk_msg_blk_t(digestsize, len, vrf_len, blksize)
Retrieval protocol block fetch response (including transport header)
Definition: peerblk.h:159
#define DBGC2(...)
Definition: compiler.h:522
uint8_t block[3][8]
DES-encrypted blocks.
Definition: mschapv2.h:12
int http_open(struct interface *xfer, struct http_method *method, struct uri *uri, struct http_request_range *range, struct http_request_content *content)
Open HTTP transaction.
Definition: httpcore.c:642
uint8_t data[48]
Additional event data.
Definition: ena.h:22
__be32 raw[7]
Definition: CIB_PRM.h:28
A Uniform Resource Identifier.
Definition: uri.h:65
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:48
uint32_t digestsize
Digest size (i.e.
Definition: pccrr.h:15
#define peerdist_msg_getblks_t(digestsize, count, vrf_len)
Retrieval protocol block fetch request.
Definition: pccrr.h:266
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
#define ETIMEDOUT
Connection timed out.
Definition: errno.h:670
struct http_method http_post
HTTP POST method.
Definition: httpcore.c:149
if(natsemi->flags &NATSEMI_64BIT) return 1
void * memset(void *dest, int character, size_t len) __nonnull

References peerdist_block::block, http_request_content::data, DBGC, DBGC2, digestsize, peerdist_block::digestsize, peerdist_block::end, ENOMEM, ETIMEDOUT, htonl, http_open(), http_post, peerdist_block::id, intf_restart(), http_request_content::len, memcpy(), memset(), msg(), NULL, offsetof, PEERBLK_ANNUL_RATE, peerblk_msg_blk_t, PEERBLK_RETRIEVAL_OPEN_TIMEOUT, peerblk_retrieval_uri(), PEERDIST_MSG_AES_128_CBC, peerdist_msg_getblks_t, PEERDIST_MSG_GETBLKS_TYPE, PEERDIST_MSG_GETBLKS_VERSION, peerdist_block::rc, rc, peerdist_block::retrieval, rsp, peerdist_block::segment, peerdist_block::start, start_timer_fixed(), strerror(), peerdist_block::timer, typeof(), and uri_put().

Referenced by peerblk_expired().

◆ peerblk_retrieval_rx()

static int peerblk_retrieval_rx ( struct peerdist_block peerblk,
struct io_buffer iobuf,
struct xfer_metadata meta 
)
static

Receive PeerDist retrieval protocol data.

Parameters
peerblkPeerDist block download
iobufI/O buffer
metaData transfer metadata
Return values
rcReturn status code

Definition at line 677 of file peerblk.c.

679  {
680  size_t len = iob_len ( iobuf );
681  size_t start;
682  size_t end;
683  size_t before;
684  size_t after;
685  size_t cut;
686  int rc;
687 
688  /* Some genius at Microsoft thought it would be a great idea
689  * to place the AES-CBC initialisation vector *after* the
690  * encrypted data, thereby making it logically impossible to
691  * decrypt each packet as it arrives.
692  *
693  * To work around this mindless stupidity, we deliver the
694  * ciphertext as-is and later use xfer_buffer() to obtain
695  * access to the underlying data transfer buffer in order to
696  * perform the decryption.
697  *
698  * There will be some data both before and after the bytes
699  * corresponding to the trimmed plaintext: a MSG_BLK
700  * header/footer, some block padding for the AES-CBC cipher,
701  * and a possibly large quantity of unwanted ciphertext which
702  * is excluded from the trimmed content range. We store this
703  * data in a local data transfer buffer. If the amount of
704  * data to be stored is too large, we will fail allocation and
705  * so eventually fall back to using a range request (which
706  * does not require this kind of temporary storage
707  * allocation).
708  */
709 
710  /* Corrupt received data (for testing) if applicable */
711  inject_corruption ( PEERBLK_CORRUPT_RATE, iobuf->data, len );
712 
713  /* Calculate start and end positions of this buffer */
714  start = peerblk->pos;
715  if ( meta->flags & XFER_FL_ABS_OFFSET )
716  start = 0;
717  start += meta->offset;
718  end = ( start + len );
719 
720  /* Buffer any data before the trimmed content */
721  if ( ( start < peerblk->start ) && ( len > 0 ) ) {
722 
723  /* Calculate length of data before the trimmed content */
724  before = ( peerblk->start - start );
725  if ( before > len )
726  before = len;
727 
728  /* Buffer data before the trimmed content */
729  if ( ( rc = xferbuf_write ( &peerblk->buffer, start,
730  iobuf->data, before ) ) != 0 ) {
731  DBGC ( peerblk, "PEERBLK %p %d.%d could not buffer "
732  "data: %s\n", peerblk, peerblk->segment,
733  peerblk->block, strerror ( rc ) );
734  goto err;
735  }
736  }
737 
738  /* Buffer any data after the trimmed content */
739  if ( ( end > peerblk->end ) && ( len > 0 ) ) {
740 
741  /* Calculate length of data after the trimmed content */
742  after = ( end - peerblk->end );
743  if ( after > len )
744  after = len;
745 
746  /* Buffer data after the trimmed content */
747  cut = ( peerblk->end - peerblk->start );
748  if ( ( rc = xferbuf_write ( &peerblk->buffer,
749  ( end - after - cut ),
750  ( iobuf->data + len - after ),
751  after ) ) != 0 ) {
752  DBGC ( peerblk, "PEERBLK %p %d.%d could not buffer "
753  "data: %s\n", peerblk, peerblk->segment,
754  peerblk->block, strerror ( rc ) );
755  goto err;
756  }
757  }
758 
759  /* Deliver any remaining data */
760  if ( ( rc = peerblk_deliver ( peerblk, iob_disown ( iobuf ), meta,
761  start ) ) != 0 )
762  goto err;
763 
764  /* Update position */
765  peerblk->pos = end;
766 
767  /* Extend download attempt timer */
769 
770  /* Stall download attempt (for testing) if applicable */
771  if ( ( start < peerblk->end ) && ( end >= peerblk->end ) &&
772  ( ( rc = inject_fault ( PEERBLK_STALL_RATE ) ) != 0 ) ) {
773  intf_restart ( &peerblk->retrieval, rc );
774  }
775 
776  return 0;
777 
778  err:
779  free_iob ( iobuf );
780  peerblk_done ( peerblk, rc );
781  return rc;
782 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition: interface.c:344
struct xfer_buffer buffer
Data buffer.
Definition: peerblk.h:100
#define PEERBLK_RETRIEVAL_RX_TIMEOUT
PeerDist retrieval protocol block download attempt ongoing progress timeout.
Definition: peerblk.c:94
#define XFER_FL_ABS_OFFSET
Offset is absolute.
Definition: xfer.h:48
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:153
struct interface retrieval
Retrieval protocol interface.
Definition: peerblk.h:55
#define DBGC(...)
Definition: compiler.h:505
int32_t before
Initial microcode version.
Definition: ucode.h:16
static int peerblk_deliver(struct peerdist_block *peerblk, struct io_buffer *iobuf, struct xfer_metadata *meta, size_t pos)
Deliver download attempt data block.
Definition: peerblk.c:247
#define PEERBLK_STALL_RATE
Definition: fault.h:28
int xferbuf_write(struct xfer_buffer *xferbuf, size_t offset, const void *data, size_t len)
Write to data transfer buffer.
Definition: xferbuf.c:113
size_t end
End of trimmed content (relative to incoming data stream)
Definition: peerblk.h:98
uint32_t start
Starting offset.
Definition: netvsc.h:12
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:217
ring len
Length.
Definition: dwmac.h:231
unsigned int segment
Segment index.
Definition: peerblk.h:83
unsigned int block
Block index.
Definition: peerblk.h:89
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:160
size_t start
Start of trimmed content (relative to incoming data stream)
Definition: peerblk.h:96
void start_timer_fixed(struct retry_timer *timer, unsigned long timeout)
Start timer with a specified timeout.
Definition: retry.c:65
struct retry_timer timer
Retry timer.
Definition: peerblk.h:120
static void peerblk_done(struct peerdist_block *peerblk, int rc)
Finish PeerDist block download attempt.
Definition: peerblk.c:298
int32_t after
Final microcode version.
Definition: ucode.h:18
void * data
Start of data.
Definition: iobuf.h:53
#define PEERBLK_CORRUPT_RATE
Definition: fault.h:34
uint32_t end
Ending offset.
Definition: netvsc.h:18
uint8_t meta
Metadata flags.
Definition: ena.h:14
size_t pos
Current position (relative to incoming data stream)
Definition: peerblk.h:94

References after, before, peerdist_block::block, peerdist_block::buffer, io_buffer::data, DBGC, end, peerdist_block::end, free_iob(), intf_restart(), iob_disown, iob_len(), len, meta, PEERBLK_CORRUPT_RATE, peerblk_deliver(), peerblk_done(), PEERBLK_RETRIEVAL_RX_TIMEOUT, PEERBLK_STALL_RATE, peerdist_block::pos, rc, peerdist_block::retrieval, peerdist_block::segment, start, peerdist_block::start, start_timer_fixed(), strerror(), peerdist_block::timer, XFER_FL_ABS_OFFSET, and xferbuf_write().

◆ peerblk_parse_header()

static int peerblk_parse_header ( struct peerdist_block peerblk)
static

Parse retrieval protocol message header.

Parameters
peerblkPeerDist block download
Return values
rcReturn status code

Definition at line 790 of file peerblk.c.

790  {
791  struct {
793  struct peerdist_msg_header msg;
794  } __attribute__ (( packed )) *msg = peerblk->buffer.data;
795  struct cipher_algorithm *cipher;
796  size_t len = peerblk->buffer.len;
797  size_t keylen = 0;
798  int rc;
799 
800  /* Check message length */
801  if ( len < sizeof ( *msg ) ) {
802  DBGC ( peerblk, "PEERBLK %p %d.%d message too short for header "
803  "(%zd bytes)\n", peerblk, peerblk->segment,
804  peerblk->block, len );
805  return -ERANGE;
806  }
807 
808  /* Check message type */
809  if ( msg->msg.type != htonl ( PEERDIST_MSG_BLK_TYPE ) ) {
810  DBGC ( peerblk, "PEERBLK %p %d.%d unexpected message type "
811  "%#08x\n", peerblk, peerblk->segment, peerblk->block,
812  ntohl ( msg->msg.type ) );
813  return -EPROTO;
814  }
815 
816  /* Determine cipher algorithm and key length */
817  cipher = &aes_cbc_algorithm;
818  switch ( msg->msg.algorithm ) {
819  case htonl ( PEERDIST_MSG_PLAINTEXT ) :
820  cipher = NULL;
821  break;
823  keylen = ( 128 / 8 );
824  break;
826  keylen = ( 192 / 8 );
827  break;
829  keylen = ( 256 / 8 );
830  break;
831  default:
832  DBGC ( peerblk, "PEERBLK %p %d.%d unrecognised algorithm "
833  "%#08x\n", peerblk, peerblk->segment, peerblk->block,
834  ntohl ( msg->msg.algorithm ) );
835  return -ENOTSUP;
836  }
837  DBGC2 ( peerblk, "PEERBLK %p %d.%d using %s with %zd-bit key\n",
838  peerblk, peerblk->segment, peerblk->block,
839  ( cipher ? cipher->name : "plaintext" ), ( 8 * keylen ) );
840 
841  /* Sanity check key length against maximum secret length */
842  if ( keylen > peerblk->digestsize ) {
843  DBGC ( peerblk, "PEERBLK %p %d.%d %zd-byte secret too short "
844  "for %zd-bit key\n", peerblk, peerblk->segment,
845  peerblk->block, peerblk->digestsize, ( 8 * keylen ) );
846  return -EPROTO;
847  }
848 
849  /* Allocate cipher context, if applicable. Freeing the cipher
850  * context (on error or otherwise) is handled by peerblk_reset().
851  */
852  peerblk->cipher = cipher;
853  assert ( peerblk->cipherctx == NULL );
854  if ( cipher ) {
855  peerblk->cipherctx = malloc ( cipher->ctxsize );
856  if ( ! peerblk->cipherctx )
857  return -ENOMEM;
858  }
859 
860  /* Initialise cipher, if applicable */
861  if ( cipher &&
862  ( rc = cipher_setkey ( cipher, peerblk->cipherctx, peerblk->secret,
863  keylen ) ) != 0 ) {
864  DBGC ( peerblk, "PEERBLK %p %d.%d could not set key: %s\n",
865  peerblk, peerblk->segment, peerblk->block,
866  strerror ( rc ) );
867  return rc;
868  }
869 
870  return 0;
871 }
void * data
Data.
Definition: xferbuf.h:21
#define __attribute__(x)
Definition: compiler.h:10
AES-128 in CBC mode.
Definition: pccrr.h:172
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct xfer_buffer buffer
Data buffer.
Definition: peerblk.h:100
void msg(unsigned int row, const char *fmt,...)
Print message centred on specified row.
Definition: message.c:62
struct golan_inbox_hdr hdr
Message header.
Definition: CIB_PRM.h:28
#define PEERDIST_MSG_BLK_TYPE
Retrieval protocol block fetch response type.
Definition: pccrr.h:351
#define DBGC(...)
Definition: compiler.h:505
#define ntohl(value)
Definition: byteswap.h:135
#define htonl(value)
Definition: byteswap.h:134
struct cipher_algorithm * cipher
Cipher algorithm.
Definition: peerblk.h:78
#define ENOTSUP
Operation not supported.
Definition: errno.h:590
size_t len
Size of data.
Definition: xferbuf.h:23
#define ENOMEM
Not enough space.
Definition: errno.h:535
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
ring len
Length.
Definition: dwmac.h:231
unsigned int segment
Segment index.
Definition: peerblk.h:83
unsigned int block
Block index.
Definition: peerblk.h:89
Retrieval protocol transport response header.
Definition: pccrr.h:180
No encryption.
Definition: pccrr.h:170
#define EPROTO
Protocol error.
Definition: errno.h:625
#define ERANGE
Result too large.
Definition: errno.h:640
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
void * cipherctx
Cipher context (dynamically allocated as needed)
Definition: peerblk.h:80
AES-192 in CBC mode.
Definition: pccrr.h:174
size_t digestsize
Digest size.
Definition: peerblk.h:73
size_t ctxsize
Context size.
Definition: crypto.h:55
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:621
Retrieval protocol message header.
Definition: pccrr.h:152
struct cipher_algorithm aes_cbc_algorithm
#define DBGC2(...)
Definition: compiler.h:522
uint8_t secret[PEERDIST_DIGEST_MAX_SIZE]
Segment secret.
Definition: peerblk.h:87
A cipher algorithm.
Definition: crypto.h:51
AES-256 in CBC mode.
Definition: pccrr.h:176
const char * name
Algorithm name.
Definition: crypto.h:53
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
static int cipher_setkey(struct cipher_algorithm *cipher, void *ctx, const void *key, size_t keylen)
Definition: crypto.h:235

References __attribute__, aes_cbc_algorithm, assert(), peerdist_block::block, peerdist_block::buffer, peerdist_block::cipher, cipher_setkey(), peerdist_block::cipherctx, cipher_algorithm::ctxsize, xfer_buffer::data, DBGC, DBGC2, peerdist_block::digestsize, ENOMEM, ENOTSUP, EPROTO, ERANGE, hdr, htonl, xfer_buffer::len, len, malloc(), msg(), cipher_algorithm::name, ntohl, NULL, PEERDIST_MSG_AES_128_CBC, PEERDIST_MSG_AES_192_CBC, PEERDIST_MSG_AES_256_CBC, PEERDIST_MSG_BLK_TYPE, PEERDIST_MSG_PLAINTEXT, rc, peerdist_block::secret, peerdist_block::segment, and strerror().

Referenced by peerblk_retrieval_close().

◆ peerblk_parse_block()

static int peerblk_parse_block ( struct peerdist_block peerblk,
size_t buf_len 
)
static

Parse retrieval protocol message segment and block details.

Parameters
peerblkPeerDist block download
buf_lenLength of buffered data to fill in
Return values
rcReturn status code

Definition at line 880 of file peerblk.c.

881  {
882  size_t digestsize = peerblk->digestsize;
883  peerblk_msg_blk_t ( digestsize, 0, 0, 0 ) *msg = peerblk->buffer.data;
884  size_t len = peerblk->buffer.len;
885  size_t data_len;
886  size_t total;
887 
888  /* Check message length */
889  if ( len < offsetof ( typeof ( *msg ), msg.block.data ) ) {
890  DBGC ( peerblk, "PEERBLK %p %d.%d message too short for "
891  "zero-length data (%zd bytes)\n", peerblk,
892  peerblk->segment, peerblk->block, len );
893  return -ERANGE;
894  }
895 
896  /* Check digest size */
897  if ( ntohl ( msg->msg.segment.segment.digestsize ) != digestsize ) {
898  DBGC ( peerblk, "PEERBLK %p %d.%d incorrect digest size %d\n",
899  peerblk, peerblk->segment, peerblk->block,
900  ntohl ( msg->msg.segment.segment.digestsize ) );
901  return -EPROTO;
902  }
903 
904  /* Check segment ID */
905  if ( memcmp ( msg->msg.segment.id, peerblk->id, digestsize ) != 0 ) {
906  DBGC ( peerblk, "PEERBLK %p %d.%d segment ID mismatch\n",
907  peerblk, peerblk->segment, peerblk->block );
908  return -EPROTO;
909  }
910 
911  /* Check block ID */
912  if ( ntohl ( msg->msg.index ) != peerblk->block ) {
913  DBGC ( peerblk, "PEERBLK %p %d.%d block ID mismatch (got %d)\n",
914  peerblk, peerblk->segment, peerblk->block,
915  ntohl ( msg->msg.index ) );
916  return -EPROTO;
917  }
918 
919  /* Check for missing blocks */
920  data_len = be32_to_cpu ( msg->msg.block.block.len );
921  if ( ! data_len ) {
922  DBGC ( peerblk, "PEERBLK %p %d.%d block not found\n",
923  peerblk, peerblk->segment, peerblk->block );
924  return -ENOENT;
925  }
926 
927  /* Check for underlength blocks */
928  if ( data_len < ( peerblk->range.end - peerblk->range.start ) ) {
929  DBGC ( peerblk, "PEERBLK %p %d.%d underlength block (%zd "
930  "bytes)\n", peerblk, peerblk->segment, peerblk->block,
931  data_len );
932  return -ERANGE;
933  }
934 
935  /* Calculate buffered data length (i.e. excluding data which
936  * was delivered to the final data transfer buffer).
937  */
938  *buf_len = ( data_len - ( peerblk->end - peerblk->start ) );
939 
940  /* Describe data before the trimmed content */
941  peerblk->decrypt[PEERBLK_BEFORE].xferbuf = &peerblk->buffer;
942  peerblk->decrypt[PEERBLK_BEFORE].offset =
943  offsetof ( typeof ( *msg ), msg.block.data );
944  peerblk->decrypt[PEERBLK_BEFORE].len =
945  ( peerblk->start -
946  offsetof ( typeof ( *msg ), msg.block.data ) );
947  total = peerblk->decrypt[PEERBLK_BEFORE].len;
948 
949  /* Describe data within the trimmed content */
950  peerblk->decrypt[PEERBLK_DURING].offset =
951  peerblk_offset ( peerblk, peerblk->start );
952  peerblk->decrypt[PEERBLK_DURING].len =
953  ( peerblk->end - peerblk->start );
954  total += peerblk->decrypt[PEERBLK_DURING].len;
955 
956  /* Describe data after the trimmed content */
957  peerblk->decrypt[PEERBLK_AFTER].xferbuf = &peerblk->buffer;
958  peerblk->decrypt[PEERBLK_AFTER].offset = peerblk->start;
959  peerblk->decrypt[PEERBLK_AFTER].len =
960  ( offsetof ( typeof ( *msg ), msg.block.data )
961  + *buf_len - peerblk->start );
962  total += peerblk->decrypt[PEERBLK_AFTER].len;
963 
964  /* Sanity check */
965  assert ( total == be32_to_cpu ( msg->msg.block.block.len ) );
966 
967  /* Initialise cipher and digest lengths */
968  peerblk->cipher_remaining = total;
969  peerblk->digest_remaining =
970  ( peerblk->range.end - peerblk->range.start );
971  assert ( peerblk->cipher_remaining >= peerblk->digest_remaining );
972 
973  return 0;
974 }
void * data
Data.
Definition: xferbuf.h:21
struct xfer_buffer buffer
Data buffer.
Definition: peerblk.h:100
void msg(unsigned int row, const char *fmt,...)
Print message centred on specified row.
Definition: message.c:62
Data after the trimmed content.
Definition: peerblk.h:41
static size_t peerblk_offset(struct peerdist_block *peerblk, size_t pos)
Calculate offset within overall download.
Definition: peerblk.c:233
size_t digest_remaining
Remaining digest length (excluding AES padding bytes)
Definition: peerblk.h:109
size_t start
Start offset.
Definition: pccrc.h:311
#define DBGC(...)
Definition: compiler.h:505
#define ENOENT
No such file or directory.
Definition: errno.h:515
#define ntohl(value)
Definition: byteswap.h:135
uint32_t data_len
Microcode data size (or 0 to indicate 2000 bytes)
Definition: ucode.h:26
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h:25
size_t end
End of trimmed content (relative to incoming data stream)
Definition: peerblk.h:98
Data before the trimmed content.
Definition: peerblk.h:37
size_t len
Size of data.
Definition: xferbuf.h:23
Data within the trimmed content.
Definition: peerblk.h:39
struct peerdist_range range
Content range of this block.
Definition: peerblk.h:60
#define be32_to_cpu(value)
Definition: byteswap.h:117
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
ring len
Length.
Definition: dwmac.h:231
unsigned int segment
Segment index.
Definition: peerblk.h:83
size_t offset
Offset within data transfer buffer.
Definition: peerblk.h:29
unsigned int block
Block index.
Definition: peerblk.h:89
uint8_t id[PEERDIST_DIGEST_MAX_SIZE]
Segment identifier.
Definition: peerblk.h:85
#define EPROTO
Protocol error.
Definition: errno.h:625
#define ERANGE
Result too large.
Definition: errno.h:640
struct xfer_buffer * xferbuf
Data transfer buffer.
Definition: peerblk.h:27
size_t digestsize
Digest size.
Definition: peerblk.h:73
size_t start
Start of trimmed content (relative to incoming data stream)
Definition: peerblk.h:96
#define peerblk_msg_blk_t(digestsize, len, vrf_len, blksize)
Retrieval protocol block fetch response (including transport header)
Definition: peerblk.h:159
struct peerdist_block_decrypt decrypt[PEERBLK_NUM_BUFFERS]
Decryption data buffer descriptors.
Definition: peerblk.h:105
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:48
uint32_t digestsize
Digest size (i.e.
Definition: pccrr.h:15
size_t cipher_remaining
Remaining decryption length.
Definition: peerblk.h:107
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:115
size_t len
Length to use from data transfer buffer.
Definition: peerblk.h:31
size_t end
End offset.
Definition: pccrc.h:313

References assert(), be32_to_cpu, peerdist_block::block, peerdist_block::buffer, peerdist_block::cipher_remaining, xfer_buffer::data, data_len, DBGC, peerdist_block::decrypt, peerdist_block::digest_remaining, digestsize, peerdist_block::digestsize, peerdist_block::end, peerdist_range::end, ENOENT, EPROTO, ERANGE, peerdist_block::id, xfer_buffer::len, peerdist_block_decrypt::len, len, memcmp(), msg(), ntohl, peerdist_block_decrypt::offset, offsetof, PEERBLK_AFTER, PEERBLK_BEFORE, PEERBLK_DURING, peerblk_msg_blk_t, peerblk_offset(), peerdist_block::range, peerdist_block::segment, peerdist_block::start, peerdist_range::start, typeof(), and peerdist_block_decrypt::xferbuf.

Referenced by peerblk_retrieval_close().

◆ peerblk_parse_useless()

static int peerblk_parse_useless ( struct peerdist_block peerblk,
size_t  buf_len,
size_t vrf_len 
)
static

Parse retrieval protocol message useless details.

Parameters
peerblkPeerDist block download
buf_lenLength of buffered data
vrf_lenLength of uselessness to fill in
Return values
rcReturn status code

Definition at line 984 of file peerblk.c.

985  {
986  size_t digestsize = peerblk->digestsize;
987  peerblk_msg_blk_t ( digestsize, buf_len, 0, 0 ) *msg =
988  peerblk->buffer.data;
989  size_t len = peerblk->buffer.len;
990 
991  /* Check message length */
992  if ( len < offsetof ( typeof ( *msg ), msg.vrf.data ) ) {
993  DBGC ( peerblk, "PEERBLK %p %d.%d message too short for "
994  "zero-length uselessness (%zd bytes)\n", peerblk,
995  peerblk->segment, peerblk->block, len );
996  return -ERANGE;
997  }
998 
999  /* Extract length of uselessness */
1000  *vrf_len = be32_to_cpu ( msg->msg.vrf.vrf.len );
1001 
1002  return 0;
1003 }
void * data
Data.
Definition: xferbuf.h:21
struct xfer_buffer buffer
Data buffer.
Definition: peerblk.h:100
void msg(unsigned int row, const char *fmt,...)
Print message centred on specified row.
Definition: message.c:62
#define DBGC(...)
Definition: compiler.h:505
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h:25
size_t len
Size of data.
Definition: xferbuf.h:23
#define be32_to_cpu(value)
Definition: byteswap.h:117
ring len
Length.
Definition: dwmac.h:231
unsigned int segment
Segment index.
Definition: peerblk.h:83
unsigned int block
Block index.
Definition: peerblk.h:89
#define ERANGE
Result too large.
Definition: errno.h:640
size_t digestsize
Digest size.
Definition: peerblk.h:73
#define peerblk_msg_blk_t(digestsize, len, vrf_len, blksize)
Retrieval protocol block fetch response (including transport header)
Definition: peerblk.h:159
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:48
uint32_t digestsize
Digest size (i.e.
Definition: pccrr.h:15

References be32_to_cpu, peerdist_block::block, peerdist_block::buffer, xfer_buffer::data, DBGC, digestsize, peerdist_block::digestsize, ERANGE, xfer_buffer::len, len, msg(), offsetof, peerblk_msg_blk_t, peerdist_block::segment, and typeof().

Referenced by peerblk_retrieval_close().

◆ peerblk_parse_iv()

static int peerblk_parse_iv ( struct peerdist_block peerblk,
size_t  buf_len,
size_t  vrf_len 
)
static

Parse retrieval protocol message initialisation vector details.

Parameters
peerblkPeerDist block download
buf_lenLength of buffered data
vrf_lenLength of uselessness
Return values
rcReturn status code

Definition at line 1013 of file peerblk.c.

1014  {
1015  size_t digestsize = peerblk->digestsize;
1016  size_t blksize = peerblk->cipher->blocksize;
1017  peerblk_msg_blk_t ( digestsize, buf_len, vrf_len, blksize ) *msg =
1018  peerblk->buffer.data;
1019  size_t len = peerblk->buffer.len;
1020 
1021  /* Check message length */
1022  if ( len < sizeof ( *msg ) ) {
1023  DBGC ( peerblk, "PEERBLK %p %d.%d message too short for "
1024  "initialisation vector (%zd bytes)\n", peerblk,
1025  peerblk->segment, peerblk->block, len );
1026  return -ERANGE;
1027  }
1028 
1029  /* Check initialisation vector size */
1030  if ( ntohl ( msg->msg.iv.iv.blksize ) != blksize ) {
1031  DBGC ( peerblk, "PEERBLK %p %d.%d incorrect IV size %d\n",
1032  peerblk, peerblk->segment, peerblk->block,
1033  ntohl ( msg->msg.iv.iv.blksize ) );
1034  return -EPROTO;
1035  }
1036 
1037  /* Set initialisation vector */
1038  cipher_setiv ( peerblk->cipher, peerblk->cipherctx, msg->msg.iv.data,
1039  blksize );
1040 
1041  return 0;
1042 }
void * data
Data.
Definition: xferbuf.h:21
size_t blocksize
Block size.
Definition: crypto.h:61
struct xfer_buffer buffer
Data buffer.
Definition: peerblk.h:100
void msg(unsigned int row, const char *fmt,...)
Print message centred on specified row.
Definition: message.c:62
#define DBGC(...)
Definition: compiler.h:505
#define ntohl(value)
Definition: byteswap.h:135
struct cipher_algorithm * cipher
Cipher algorithm.
Definition: peerblk.h:78
size_t len
Size of data.
Definition: xferbuf.h:23
ring len
Length.
Definition: dwmac.h:231
unsigned int segment
Segment index.
Definition: peerblk.h:83
unsigned int block
Block index.
Definition: peerblk.h:89
#define EPROTO
Protocol error.
Definition: errno.h:625
#define ERANGE
Result too large.
Definition: errno.h:640
void * cipherctx
Cipher context (dynamically allocated as needed)
Definition: peerblk.h:80
static void cipher_setiv(struct cipher_algorithm *cipher, void *ctx, const void *iv, size_t ivlen)
Definition: crypto.h:241
size_t digestsize
Digest size.
Definition: peerblk.h:73
#define peerblk_msg_blk_t(digestsize, len, vrf_len, blksize)
Retrieval protocol block fetch response (including transport header)
Definition: peerblk.h:159
uint32_t blksize
Cipher block size.
Definition: pccrr.h:15
uint32_t digestsize
Digest size (i.e.
Definition: pccrr.h:15

References blksize, peerdist_block::block, cipher_algorithm::blocksize, peerdist_block::buffer, peerdist_block::cipher, cipher_setiv(), peerdist_block::cipherctx, xfer_buffer::data, DBGC, digestsize, peerdist_block::digestsize, EPROTO, ERANGE, xfer_buffer::len, len, msg(), ntohl, peerblk_msg_blk_t, and peerdist_block::segment.

Referenced by peerblk_retrieval_close().

◆ peerblk_decrypt_read()

static int peerblk_decrypt_read ( struct peerdist_block peerblk,
void *  data,
size_t  len 
)
static

Read from decryption buffers.

Parameters
peerblkPeerDist block download
dataData buffer
lenLength to read
Return values
rcReturn status code

Definition at line 1052 of file peerblk.c.

1053  {
1054  struct peerdist_block_decrypt *decrypt = peerblk->decrypt;
1055  size_t frag_len;
1056  int rc;
1057 
1058  /* Read from each decryption buffer in turn */
1059  for ( ; len ; decrypt++, data += frag_len, len -= frag_len ) {
1060 
1061  /* Calculate length to use from this buffer */
1062  frag_len = decrypt->len;
1063  if ( frag_len > len )
1064  frag_len = len;
1065  if ( ! frag_len )
1066  continue;
1067 
1068  /* Read from this buffer */
1069  if ( ( rc = xferbuf_read ( decrypt->xferbuf, decrypt->offset,
1070  data, frag_len ) ) != 0 )
1071  return rc;
1072  }
1073 
1074  return 0;
1075 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
A PeerDist retrieval protocol decryption buffer descriptor.
Definition: peerblk.h:25
ring len
Length.
Definition: dwmac.h:231
size_t offset
Offset within data transfer buffer.
Definition: peerblk.h:29
struct xfer_buffer * xferbuf
Data transfer buffer.
Definition: peerblk.h:27
int xferbuf_read(struct xfer_buffer *xferbuf, size_t offset, void *data, size_t len)
Read from data transfer buffer.
Definition: xferbuf.c:147
struct peerdist_block_decrypt decrypt[PEERBLK_NUM_BUFFERS]
Decryption data buffer descriptors.
Definition: peerblk.h:105
uint8_t data[48]
Additional event data.
Definition: ena.h:22
size_t len
Length to use from data transfer buffer.
Definition: peerblk.h:31

References data, peerdist_block::decrypt, peerdist_block_decrypt::len, len, peerdist_block_decrypt::offset, rc, peerdist_block_decrypt::xferbuf, and xferbuf_read().

Referenced by peerblk_decrypt().

◆ peerblk_decrypt_write()

static int peerblk_decrypt_write ( struct peerdist_block peerblk,
const void *  data,
size_t  len 
)
static

Write to decryption buffers and update offsets and lengths.

Parameters
peerblkPeerDist block download
dataData buffer
lenLength to read
Return values
rcReturn status code

Definition at line 1085 of file peerblk.c.

1086  {
1087  struct peerdist_block_decrypt *decrypt = peerblk->decrypt;
1088  size_t frag_len;
1089  int rc;
1090 
1091  /* Write to each decryption buffer in turn */
1092  for ( ; len ; decrypt++, data += frag_len, len -= frag_len ) {
1093 
1094  /* Calculate length to use from this buffer */
1095  frag_len = decrypt->len;
1096  if ( frag_len > len )
1097  frag_len = len;
1098  if ( ! frag_len )
1099  continue;
1100 
1101  /* Write to this buffer */
1102  if ( ( rc = xferbuf_write ( decrypt->xferbuf, decrypt->offset,
1103  data, frag_len ) ) != 0 )
1104  return rc;
1105 
1106  /* Update offset and length */
1107  decrypt->offset += frag_len;
1108  decrypt->len -= frag_len;
1109  }
1110 
1111  return 0;
1112 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
A PeerDist retrieval protocol decryption buffer descriptor.
Definition: peerblk.h:25
int xferbuf_write(struct xfer_buffer *xferbuf, size_t offset, const void *data, size_t len)
Write to data transfer buffer.
Definition: xferbuf.c:113
ring len
Length.
Definition: dwmac.h:231
size_t offset
Offset within data transfer buffer.
Definition: peerblk.h:29
struct xfer_buffer * xferbuf
Data transfer buffer.
Definition: peerblk.h:27
struct peerdist_block_decrypt decrypt[PEERBLK_NUM_BUFFERS]
Decryption data buffer descriptors.
Definition: peerblk.h:105
uint8_t data[48]
Additional event data.
Definition: ena.h:22
size_t len
Length to use from data transfer buffer.
Definition: peerblk.h:31

References data, peerdist_block::decrypt, peerdist_block_decrypt::len, len, peerdist_block_decrypt::offset, rc, peerdist_block_decrypt::xferbuf, and xferbuf_write().

Referenced by peerblk_decrypt().

◆ peerblk_decrypt()

static void peerblk_decrypt ( struct peerdist_block peerblk)
static

Decrypt one chunk of PeerDist retrieval protocol data.

Parameters
peerblkPeerDist block download

Definition at line 1119 of file peerblk.c.

1119  {
1120  struct cipher_algorithm *cipher = peerblk->cipher;
1121  struct digest_algorithm *digest = peerblk->digest;
1122  struct xfer_buffer *xferbuf;
1123  size_t cipher_len;
1124  size_t digest_len;
1125  void *data;
1126  int rc;
1127 
1128  /* Sanity check */
1129  assert ( ( PEERBLK_DECRYPT_CHUNKSIZE % cipher->blocksize ) == 0 );
1130 
1131  /* Get the underlying data transfer buffer */
1132  xferbuf = xfer_buffer ( &peerblk->xfer );
1133  if ( ! xferbuf ) {
1134  DBGC ( peerblk, "PEERBLK %p %d.%d has no underlying data "
1135  "transfer buffer\n", peerblk, peerblk->segment,
1136  peerblk->block );
1137  rc = -ENOTSUP;
1138  goto err_xfer_buffer;
1139  }
1140  peerblk->decrypt[PEERBLK_DURING].xferbuf = xferbuf;
1141 
1142  /* Calculate cipher and digest lengths */
1143  cipher_len = PEERBLK_DECRYPT_CHUNKSIZE;
1144  if ( cipher_len > peerblk->cipher_remaining )
1145  cipher_len = peerblk->cipher_remaining;
1146  digest_len = cipher_len;
1147  if ( digest_len > peerblk->digest_remaining )
1148  digest_len = peerblk->digest_remaining;
1149  assert ( ( cipher_len & ( cipher->blocksize - 1 ) ) == 0 );
1150 
1151  /* Allocate temporary data buffer */
1152  data = malloc ( cipher_len );
1153  if ( ! data ) {
1154  rc = -ENOMEM;
1155  goto err_alloc_data;
1156  }
1157 
1158  /* Read ciphertext */
1159  if ( ( rc = peerblk_decrypt_read ( peerblk, data, cipher_len ) ) != 0 ){
1160  DBGC ( peerblk, "PEERBLK %p %d.%d could not read ciphertext: "
1161  "%s\n", peerblk, peerblk->segment, peerblk->block,
1162  strerror ( rc ) );
1163  goto err_read;
1164  }
1165 
1166  /* Decrypt data */
1167  cipher_decrypt ( cipher, peerblk->cipherctx, data, data, cipher_len );
1168 
1169  /* Add data to digest */
1170  digest_update ( digest, peerblk->digestctx, data, digest_len );
1171 
1172  /* Write plaintext */
1173  if ( ( rc = peerblk_decrypt_write ( peerblk, data, cipher_len ) ) != 0){
1174  DBGC ( peerblk, "PEERBLK %p %d.%d could not write plaintext: "
1175  "%s\n", peerblk, peerblk->segment, peerblk->block,
1176  strerror ( rc ) );
1177  goto err_write;
1178  }
1179 
1180  /* Consume input */
1181  peerblk->cipher_remaining -= cipher_len;
1182  peerblk->digest_remaining -= digest_len;
1183 
1184  /* Free temporary data buffer */
1185  free ( data );
1186 
1187  /* Continue processing until all input is consumed */
1188  if ( peerblk->cipher_remaining )
1189  return;
1190 
1191  /* Complete download attempt */
1192  peerblk_done ( peerblk, 0 );
1193  return;
1194 
1195  err_write:
1196  err_read:
1197  free ( data );
1198  err_alloc_data:
1199  err_xfer_buffer:
1200  peerblk_done ( peerblk, rc );
1201 }
size_t blocksize
Block size.
Definition: crypto.h:61
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static void digest_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Definition: crypto.h:224
size_t digest_remaining
Remaining digest length (excluding AES padding bytes)
Definition: peerblk.h:109
A data transfer buffer.
Definition: xferbuf.h:19
void * digestctx
Digest context (statically allocated at instantiation time)
Definition: peerblk.h:75
#define DBGC(...)
Definition: compiler.h:505
struct cipher_algorithm * cipher
Cipher algorithm.
Definition: peerblk.h:78
#define ENOTSUP
Operation not supported.
Definition: errno.h:590
struct digest_algorithm * digest
Digest algorithm.
Definition: peerblk.h:67
Data within the trimmed content.
Definition: peerblk.h:39
#define ENOMEM
Not enough space.
Definition: errno.h:535
static int peerblk_decrypt_write(struct peerdist_block *peerblk, const void *data, size_t len)
Write to decryption buffers and update offsets and lengths.
Definition: peerblk.c:1085
#define PEERBLK_DECRYPT_CHUNKSIZE
PeerDist decryption chunksize.
Definition: peerblk.c:51
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
unsigned int segment
Segment index.
Definition: peerblk.h:83
unsigned int block
Block index.
Definition: peerblk.h:89
struct interface xfer
Data transfer interface.
Definition: peerblk.h:51
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
void * cipherctx
Cipher context (dynamically allocated as needed)
Definition: peerblk.h:80
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:55
struct xfer_buffer * xferbuf
Data transfer buffer.
Definition: peerblk.h:27
struct xfer_buffer * xfer_buffer(struct interface *intf)
Get underlying data transfer buffer.
Definition: xferbuf.c:306
#define cipher_decrypt(cipher, ctx, src, dst, len)
Definition: crypto.h:261
static int peerblk_decrypt_read(struct peerdist_block *peerblk, void *data, size_t len)
Read from decryption buffers.
Definition: peerblk.c:1052
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:621
static void peerblk_done(struct peerdist_block *peerblk, int rc)
Finish PeerDist block download attempt.
Definition: peerblk.c:298
struct peerdist_block_decrypt decrypt[PEERBLK_NUM_BUFFERS]
Decryption data buffer descriptors.
Definition: peerblk.h:105
A message digest algorithm.
Definition: crypto.h:19
uint8_t data[48]
Additional event data.
Definition: ena.h:22
A cipher algorithm.
Definition: crypto.h:51
size_t cipher_remaining
Remaining decryption length.
Definition: peerblk.h:107

References assert(), peerdist_block::block, cipher_algorithm::blocksize, peerdist_block::cipher, cipher_decrypt, peerdist_block::cipher_remaining, peerdist_block::cipherctx, data, DBGC, peerdist_block::decrypt, peerdist_block::digest, peerdist_block::digest_remaining, digest_update(), peerdist_block::digestctx, ENOMEM, ENOTSUP, free, malloc(), PEERBLK_DECRYPT_CHUNKSIZE, peerblk_decrypt_read(), peerblk_decrypt_write(), peerblk_done(), PEERBLK_DURING, rc, peerdist_block::segment, strerror(), peerdist_block::xfer, xfer_buffer(), and peerdist_block_decrypt::xferbuf.

◆ peerblk_retrieval_close()

static void peerblk_retrieval_close ( struct peerdist_block peerblk,
int  rc 
)
static

Close PeerDist retrieval protocol block download attempt.

Parameters
peerblkPeerDist block download
rcReason for close

Definition at line 1209 of file peerblk.c.

1209  {
1210  size_t buf_len;
1211  size_t vrf_len;
1212 
1213  /* Restart interface */
1214  intf_restart ( &peerblk->retrieval, rc );
1215 
1216  /* Fail immediately if we have an error */
1217  if ( rc != 0 )
1218  goto done;
1219 
1220  /* Abort download attempt (for testing) if applicable */
1221  if ( ( rc = inject_fault ( PEERBLK_ABORT_RATE ) ) != 0 )
1222  goto done;
1223 
1224  /* Parse message header */
1225  if ( ( rc = peerblk_parse_header ( peerblk ) ) != 0 )
1226  goto done;
1227 
1228  /* Parse message segment and block details */
1229  if ( ( rc = peerblk_parse_block ( peerblk, &buf_len ) ) != 0 )
1230  goto done;
1231 
1232  /* If the block was plaintext, then there is nothing more to do */
1233  if ( ! peerblk->cipher )
1234  goto done;
1235 
1236  /* Parse message useless details */
1237  if ( ( rc = peerblk_parse_useless ( peerblk, buf_len, &vrf_len ) ) != 0)
1238  goto done;
1239 
1240  /* Parse message initialisation vector details */
1241  if ( ( rc = peerblk_parse_iv ( peerblk, buf_len, vrf_len ) ) != 0 )
1242  goto done;
1243 
1244  /* Fail if decryption length is not aligned to the cipher block size */
1245  if ( peerblk->cipher_remaining & ( peerblk->cipher->blocksize - 1 ) ) {
1246  DBGC ( peerblk, "PEERBLK %p %d.%d unaligned data length %zd\n",
1247  peerblk, peerblk->segment, peerblk->block,
1248  peerblk->cipher_remaining );
1249  rc = -EPROTO;
1250  goto done;
1251  }
1252 
1253  /* Stop the download attempt timer: there is no point in
1254  * timing out while decrypting.
1255  */
1256  stop_timer ( &peerblk->timer );
1257 
1258  /* Start decryption process */
1259  process_add ( &peerblk->process );
1260  return;
1261 
1262  done:
1263  /* Complete download attempt */
1264  peerblk_done ( peerblk, rc );
1265 }
size_t blocksize
Block size.
Definition: crypto.h:61
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition: interface.c:344
static int peerblk_parse_useless(struct peerdist_block *peerblk, size_t buf_len, size_t *vrf_len)
Parse retrieval protocol message useless details.
Definition: peerblk.c:984
struct interface retrieval
Retrieval protocol interface.
Definition: peerblk.h:55
#define DBGC(...)
Definition: compiler.h:505
struct process process
Decryption process.
Definition: peerblk.h:103
struct cipher_algorithm * cipher
Cipher algorithm.
Definition: peerblk.h:78
#define PEERBLK_ABORT_RATE
Definition: fault.h:31
unsigned int segment
Segment index.
Definition: peerblk.h:83
unsigned int block
Block index.
Definition: peerblk.h:89
#define EPROTO
Protocol error.
Definition: errno.h:625
void process_add(struct process *process)
Add process to process list.
Definition: process.c:60
static int peerblk_parse_header(struct peerdist_block *peerblk)
Parse retrieval protocol message header.
Definition: peerblk.c:790
struct retry_timer timer
Retry timer.
Definition: peerblk.h:120
void stop_timer(struct retry_timer *timer)
Stop timer.
Definition: retry.c:118
static void peerblk_done(struct peerdist_block *peerblk, int rc)
Finish PeerDist block download attempt.
Definition: peerblk.c:298
static int peerblk_parse_block(struct peerdist_block *peerblk, size_t *buf_len)
Parse retrieval protocol message segment and block details.
Definition: peerblk.c:880
static int peerblk_parse_iv(struct peerdist_block *peerblk, size_t buf_len, size_t vrf_len)
Parse retrieval protocol message initialisation vector details.
Definition: peerblk.c:1013
size_t cipher_remaining
Remaining decryption length.
Definition: peerblk.h:107
struct bofm_section_header done
Definition: bofm_test.c:46

References peerdist_block::block, cipher_algorithm::blocksize, peerdist_block::cipher, peerdist_block::cipher_remaining, DBGC, done, EPROTO, intf_restart(), PEERBLK_ABORT_RATE, peerblk_done(), peerblk_parse_block(), peerblk_parse_header(), peerblk_parse_iv(), peerblk_parse_useless(), peerdist_block::process, process_add(), rc, peerdist_block::retrieval, peerdist_block::segment, stop_timer(), and peerdist_block::timer.

◆ peerblk_expired()

static void peerblk_expired ( struct retry_timer timer,
int over  __unused 
)
static

Handle PeerDist retry timer expiry.

Parameters
timerRetry timer
overFailure indicator

Definition at line 1280 of file peerblk.c.

1280  {
1281  struct peerdist_block *peerblk =
1282  container_of ( timer, struct peerdist_block, timer );
1283  struct peerdisc_segment *segment = peerblk->discovery.segment;
1284  struct peerdisc_peer *head;
1285  unsigned long now = peerblk_timestamp();
1286  const char *location;
1287  int rc;
1288 
1289  /* Profile discovery timeout, if applicable */
1290  if ( ( peerblk->peer == NULL ) && ( timer->timeout != 0 ) ) {
1291  profile_custom ( &peerblk_discovery_timeout_profiler,
1292  ( now - peerblk->started ) );
1293  DBGC ( peerblk, "PEERBLK %p %d.%d discovery timed out after "
1294  "%ld ticks\n", peerblk, peerblk->segment,
1295  peerblk->block, timer->timeout );
1296  }
1297 
1298  /* Profile download timeout, if applicable */
1299  if ( ( peerblk->peer != NULL ) && ( timer->timeout != 0 ) ) {
1300  profile_custom ( &peerblk_attempt_timeout_profiler,
1301  ( now - peerblk->attempted ) );
1302  DBGC ( peerblk, "PEERBLK %p %d.%d timed out after %ld ticks\n",
1303  peerblk, peerblk->segment, peerblk->block,
1304  timer->timeout );
1305  }
1306 
1307  /* Abort any current download attempt */
1308  peerblk_reset ( peerblk, -ETIMEDOUT );
1309 
1310  /* Record attempt start time */
1311  peerblk->attempted = now;
1312 
1313  /* If we have exceeded our maximum number of attempt cycles
1314  * (each cycle comprising a retrieval protocol download from
1315  * each peer in the list followed by a raw download from the
1316  * origin server), then abort the overall download.
1317  */
1318  head = list_entry ( &segment->peers, struct peerdisc_peer, list );
1319  if ( ( peerblk->peer == head ) &&
1320  ( ++peerblk->cycles >= PEERBLK_MAX_ATTEMPT_CYCLES ) ) {
1321  rc = peerblk->rc;
1322  assert ( rc != 0 );
1323  goto err;
1324  }
1325 
1326  /* If we have not yet made any download attempts, then move to
1327  * the start of the peer list.
1328  */
1329  if ( peerblk->peer == NULL )
1330  peerblk->peer = head;
1331 
1332  /* Attempt retrieval protocol download from next usable peer */
1333  list_for_each_entry_continue ( peerblk->peer, &segment->peers, list ) {
1334 
1335  /* Attempt retrieval protocol download from this peer */
1336  location = peerblk->peer->location;
1337  if ( ( rc = peerblk_retrieval_open ( peerblk,
1338  location ) ) != 0 ) {
1339  /* Non-fatal: continue to try next peer */
1340  continue;
1341  }
1342 
1343  /* Peer download started */
1344  return;
1345  }
1346 
1347  /* Add to raw download queue */
1348  peerblk_enqueue ( peerblk, &peerblk_raw_queue );
1349 
1350  return;
1351 
1352  err:
1353  peerblk_close ( peerblk, rc );
1354 }
uint16_t segment
Code segment.
Definition: librm.h:138
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define PEERBLK_MAX_ATTEMPT_CYCLES
PeerDist maximum number of full download attempt cycles.
Definition: peerblk.c:105
#define list_for_each_entry_continue(pos, head, member)
Iterate over entries in a list, starting after current position.
Definition: list.h:474
A PeerDist discovery segment.
Definition: peerdisc.h:43
#define DBGC(...)
Definition: compiler.h:505
unsigned int cycles
Number of full attempt cycles completed.
Definition: peerblk.h:122
static void profile_custom(struct profiler *profiler, unsigned long sample)
Record profiling sample in custom units.
Definition: profile.h:201
uint8_t head
Head number.
Definition: int13.h:34
struct peerdisc_client discovery
Discovery client.
Definition: peerblk.h:112
static unsigned long peerblk_timestamp(void)
Get profiling timestamp.
Definition: peerblk.c:139
static void peerblk_reset(struct peerdist_block *peerblk, int rc)
Reset PeerDist block download attempt.
Definition: peerblk.c:168
A timer.
Definition: timer.h:29
int rc
Most recent attempt failure.
Definition: peerblk.h:124
A PeerDist block download.
Definition: peerblk.h:47
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:36
unsigned int segment
Segment index.
Definition: peerblk.h:83
unsigned int block
Block index.
Definition: peerblk.h:89
struct peerdisc_peer * peer
Current position in discovered peer list.
Definition: peerblk.h:114
static struct peerdist_block_queue peerblk_raw_queue
Raw block download queue.
Definition: peerblk.c:565
char location[0]
Peer location.
Definition: peerdisc.h:76
static void peerblk_enqueue(struct peerdist_block *peerblk, struct peerdist_block_queue *queue)
Add block to download queue.
Definition: peerblk.c:518
unsigned long started
Time at which block download was started.
Definition: peerblk.h:127
struct peerdisc_segment * segment
Discovery segment.
Definition: peerdisc.h:82
unsigned long attempted
Time at which most recent attempt was started.
Definition: peerblk.h:129
static void peerblk_close(struct peerdist_block *peerblk, int rc)
Close PeerDist block download.
Definition: peerblk.c:206
static int peerblk_retrieval_open(struct peerdist_block *peerblk, const char *location)
Open PeerDist retrieval protocol block download attempt.
Definition: peerblk.c:604
struct list_head list
List of peers.
Definition: peerdisc.h:74
#define list_entry(list, type, member)
Get the container of a list entry.
Definition: list.h:322
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
#define ETIMEDOUT
Connection timed out.
Definition: errno.h:670
A PeerDist discovery peer.
Definition: peerdisc.h:72

References assert(), peerdist_block::attempted, peerdist_block::block, container_of, peerdist_block::cycles, DBGC, peerdist_block::discovery, ETIMEDOUT, head, peerdisc_peer::list, list_entry, list_for_each_entry_continue, peerdisc_peer::location, NULL, peerdist_block::peer, peerblk_close(), peerblk_enqueue(), PEERBLK_MAX_ATTEMPT_CYCLES, peerblk_raw_queue, peerblk_reset(), peerblk_retrieval_open(), peerblk_timestamp(), profile_custom(), peerdist_block::rc, rc, peerdisc_client::segment, peerdist_block::segment, segment, and peerdist_block::started.

Referenced by peerblk_open().

◆ peerblk_discovered()

static void peerblk_discovered ( struct peerdisc_client discovery)
static

Handle PeerDist peer discovery.

Parameters
discoveryPeerDist discovery client

Definition at line 1361 of file peerblk.c.

1361  {
1362  struct peerdist_block *peerblk =
1364  unsigned long now = peerblk_timestamp();
1365 
1366  /* Do nothing unless we are still waiting for the initial
1367  * discovery timeout.
1368  */
1369  if ( ( peerblk->peer != NULL ) || ( peerblk->timer.timeout == 0 ) )
1370  return;
1371 
1372  /* Schedule an immediate retry */
1373  start_timer_nodelay ( &peerblk->timer );
1374 
1375  /* Profile discovery success */
1376  profile_custom ( &peerblk_discovery_success_profiler,
1377  ( now - peerblk->started ) );
1378 }
static void start_timer_nodelay(struct retry_timer *timer)
Start timer with no delay.
Definition: retry.h:100
static void profile_custom(struct profiler *profiler, unsigned long sample)
Record profiling sample in custom units.
Definition: profile.h:201
struct peerdisc_client discovery
Discovery client.
Definition: peerblk.h:112
static unsigned long peerblk_timestamp(void)
Get profiling timestamp.
Definition: peerblk.c:139
A PeerDist block download.
Definition: peerblk.h:47
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:36
struct peerdisc_peer * peer
Current position in discovered peer list.
Definition: peerblk.h:114
unsigned long started
Time at which block download was started.
Definition: peerblk.h:127
struct retry_timer timer
Retry timer.
Definition: peerblk.h:120
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
unsigned long timeout
Timeout value (in ticks)
Definition: retry.h:28

References container_of, peerdist_block::discovery, NULL, peerdist_block::peer, peerblk_timestamp(), profile_custom(), start_timer_nodelay(), peerdist_block::started, retry_timer::timeout, and peerdist_block::timer.

◆ peerblk_open()

int peerblk_open ( struct interface xfer,
struct uri uri,
struct peerdist_info_block block 
)

Open PeerDist block download.

Parameters
xferData transfer interface
uriOriginal URI
infoContent information block
Return values
rcReturn status code

Definition at line 1434 of file peerblk.c.

1435  {
1436  const struct peerdist_info_segment *segment = block->segment;
1437  const struct peerdist_info *info = segment->info;
1438  struct digest_algorithm *digest = info->digest;
1439  struct peerdist_block *peerblk;
1440  unsigned long timeout;
1441  size_t digestsize;
1442  int rc;
1443 
1444  /* Allocate and initialise structure */
1445  peerblk = zalloc ( sizeof ( *peerblk ) + digest->ctxsize );
1446  if ( ! peerblk ) {
1447  rc = -ENOMEM;
1448  goto err_alloc;
1449  }
1450  ref_init ( &peerblk->refcnt, peerblk_free );
1451  intf_init ( &peerblk->xfer, &peerblk_xfer_desc, &peerblk->refcnt );
1452  intf_init ( &peerblk->raw, &peerblk_raw_desc, &peerblk->refcnt );
1454  &peerblk->refcnt );
1455  peerblk->uri = uri_get ( uri );
1456  memcpy ( &peerblk->range, &block->range, sizeof ( peerblk->range ) );
1457  memcpy ( &peerblk->trim, &block->trim, sizeof ( peerblk->trim ) );
1458  peerblk->offset = ( block->trim.start - info->trim.start );
1459  peerblk->digest = info->digest;
1460  peerblk->digestsize = digestsize = info->digestsize;
1461  peerblk->digestctx = ( ( ( void * ) peerblk ) + sizeof ( *peerblk ) );
1462  peerblk->segment = segment->index;
1463  memcpy ( peerblk->id, segment->id, sizeof ( peerblk->id ) );
1464  memcpy ( peerblk->secret, segment->secret, sizeof ( peerblk->secret ) );
1465  peerblk->block = block->index;
1466  memcpy ( peerblk->hash, block->hash, sizeof ( peerblk->hash ) );
1467  xferbuf_malloc_init ( &peerblk->buffer );
1469  &peerblk->refcnt );
1471  INIT_LIST_HEAD ( &peerblk->queued );
1472  timer_init ( &peerblk->timer, peerblk_expired, &peerblk->refcnt );
1473  DBGC2 ( peerblk, "PEERBLK %p %d.%d id %02x%02x%02x%02x%02x..."
1474  "%02x%02x%02x [%08zx,%08zx)", peerblk, peerblk->segment,
1475  peerblk->block, peerblk->id[0], peerblk->id[1], peerblk->id[2],
1476  peerblk->id[3], peerblk->id[4], peerblk->id[ digestsize - 3 ],
1477  peerblk->id[ digestsize - 2 ], peerblk->id[ digestsize - 1 ],
1478  peerblk->range.start, peerblk->range.end );
1479  if ( ( peerblk->trim.start != peerblk->range.start ) ||
1480  ( peerblk->trim.end != peerblk->range.end ) ) {
1481  DBGC2 ( peerblk, " covers [%08zx,%08zx)",
1482  peerblk->trim.start, peerblk->trim.end );
1483  }
1484  DBGC2 ( peerblk, "\n" );
1485 
1486  /* Open discovery */
1487  if ( ( rc = peerdisc_open ( &peerblk->discovery, peerblk->id,
1488  peerblk->digestsize ) ) != 0 )
1489  goto err_open_discovery;
1490 
1491  /* Schedule a retry attempt either immediately (if we already
1492  * have some peers) or after the discovery timeout.
1493  */
1494  timeout = ( list_empty ( &peerblk->discovery.segment->peers ) ?
1496  start_timer_fixed ( &peerblk->timer, timeout );
1497 
1498  /* Record start time */
1499  peerblk->started = peerblk_timestamp();
1500 
1501  /* Attach to parent interface, mortalise self, and return */
1502  intf_plug_plug ( xfer, &peerblk->xfer );
1503  ref_put ( &peerblk->refcnt );
1504  return 0;
1505 
1506  err_open_discovery:
1507  peerblk_close ( peerblk, rc );
1508  err_alloc:
1509  return rc;
1510 }
struct list_head peers
List of discovered peers.
Definition: peerdisc.h:64
uint16_t segment
Code segment.
Definition: librm.h:138
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define TICKS_PER_SEC
Number of ticks per second.
Definition: timer.h:16
u32 info
Definition: ar9003_mac.h:24
A content information segment.
Definition: pccrc.h:347
struct xfer_buffer buffer
Data buffer.
Definition: peerblk.h:100
static struct uri * uri_get(struct uri *uri)
Increment URI reference count.
Definition: uri.h:195
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:65
size_t start
Start offset.
Definition: pccrc.h:311
struct interface retrieval
Retrieval protocol interface.
Definition: peerblk.h:55
void * digestctx
Digest context (statically allocated at instantiation time)
Definition: peerblk.h:75
size_t offset
Offset of first byte in trimmed range within overall download.
Definition: peerblk.h:64
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition: interface.c:108
static void peerdisc_init(struct peerdisc_client *peerdisc, struct peerdisc_client_operations *op)
Initialise PeerDist discovery.
Definition: peerdisc.h:105
static struct process_descriptor peerblk_process_desc
PeerDist block download decryption process descriptor.
Definition: peerblk.c:1418
struct peerdisc_client discovery
Discovery client.
Definition: peerblk.h:112
struct process process
Decryption process.
Definition: peerblk.h:103
static unsigned long peerblk_timestamp(void)
Get profiling timestamp.
Definition: peerblk.c:139
struct digest_algorithm * digest
Digest algorithm.
Definition: peerblk.h:67
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:137
struct uri * uri
Original URI.
Definition: peerblk.h:58
struct peerdist_range range
Content range of this block.
Definition: peerblk.h:60
#define ENOMEM
Not enough space.
Definition: errno.h:535
void * memcpy(void *dest, const void *src, size_t len) __nonnull
A PeerDist block download.
Definition: peerblk.h:47
int peerdisc_open(struct peerdisc_client *peerdisc, const void *id, size_t len)
Open PeerDist discovery client.
Definition: peerdisc.c:560
static void peerblk_expired(struct retry_timer *timer, int over __unused)
Handle PeerDist retry timer expiry.
Definition: peerblk.c:1280
unsigned int segment
Segment index.
Definition: peerblk.h:83
struct interface raw
Raw data interface.
Definition: peerblk.h:53
static void xferbuf_malloc_init(struct xfer_buffer *xferbuf)
Initialise malloc()-based data transfer buffer.
Definition: xferbuf.h:54
unsigned int block
Block index.
Definition: peerblk.h:89
uint8_t id[PEERDIST_DIGEST_MAX_SIZE]
Segment identifier.
Definition: peerblk.h:85
struct interface xfer
Data transfer interface.
Definition: peerblk.h:51
uint8_t hash[PEERDIST_DIGEST_MAX_SIZE]
Block hash.
Definition: peerblk.h:91
Content information.
Definition: pccrc.h:317
static struct peerdisc_client_operations peerblk_discovery_operations
PeerDist block download discovery operations.
Definition: peerblk.c:1422
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:662
static void peerblk_free(struct refcnt *refcnt)
Free PeerDist block download.
Definition: peerblk.c:153
size_t digestsize
Digest size.
Definition: peerblk.h:73
unsigned long started
Time at which block download was started.
Definition: peerblk.h:127
static void process_init_stopped(struct process *process, struct process_descriptor *desc, struct refcnt *refcnt)
Initialise process without adding to process list.
Definition: process.h:146
struct list_head queued
List of queued block downloads.
Definition: peerblk.h:118
static struct interface_descriptor peerblk_retrieval_desc
PeerDist block download retrieval protocol interface descriptor.
Definition: peerblk.c:1413
struct peerdisc_segment * segment
Discovery segment.
Definition: peerdisc.h:82
struct refcnt refcnt
Reference count.
Definition: peerblk.h:49
void start_timer_fixed(struct retry_timer *timer, unsigned long timeout)
Start timer with a specified timeout.
Definition: retry.c:65
struct retry_timer timer
Retry timer.
Definition: peerblk.h:120
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:46
static void peerblk_close(struct peerdist_block *peerblk, int rc)
Close PeerDist block download.
Definition: peerblk.c:206
size_t ctxsize
Context size.
Definition: crypto.h:23
#define DBGC2(...)
Definition: compiler.h:522
uint8_t block[3][8]
DES-encrypted blocks.
Definition: mschapv2.h:12
uint8_t secret[PEERDIST_DIGEST_MAX_SIZE]
Segment secret.
Definition: peerblk.h:87
A message digest algorithm.
Definition: crypto.h:19
struct peerdist_range trim
Trimmed range of this block.
Definition: peerblk.h:62
static struct interface_descriptor peerblk_raw_desc
PeerDist block download raw data interface descriptor.
Definition: peerblk.c:1403
A Uniform Resource Identifier.
Definition: uri.h:65
void timeout(int)
static struct interface_descriptor peerblk_xfer_desc
PeerDist block download data transfer interface descriptor.
Definition: peerblk.c:1393
uint32_t digestsize
Digest size (i.e.
Definition: pccrr.h:15
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition: interface.h:204
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:107
size_t end
End offset.
Definition: pccrc.h:313
unsigned int peerdisc_timeout_secs
Recommended discovery timeout (in seconds)
Definition: peerdisc.c:75

References block, peerdist_block::block, peerdist_block::buffer, digest_algorithm::ctxsize, DBGC2, peerdist_block::digest, peerdist_block::digestctx, digestsize, peerdist_block::digestsize, peerdist_block::discovery, peerdist_range::end, ENOMEM, peerdist_block::hash, peerdist_block::id, info, INIT_LIST_HEAD, intf_init(), intf_plug_plug(), list_empty, memcpy(), peerdist_block::offset, peerblk_close(), peerblk_discovery_operations, peerblk_expired(), peerblk_free(), peerblk_process_desc, peerblk_raw_desc, peerblk_retrieval_desc, peerblk_timestamp(), peerblk_xfer_desc, peerdisc_init(), peerdisc_open(), peerdisc_timeout_secs, peerdisc_segment::peers, peerdist_block::process, process_init_stopped(), peerdist_block::queued, peerdist_block::range, peerdist_block::raw, rc, ref_init, ref_put, peerdist_block::refcnt, peerdist_block::retrieval, peerdist_block::secret, peerdisc_client::segment, peerdist_block::segment, segment, peerdist_range::start, start_timer_fixed(), peerdist_block::started, TICKS_PER_SEC, timeout(), peerdist_block::timer, peerdist_block::trim, peerdist_block::uri, uri_get(), peerdist_block::xfer, xferbuf_malloc_init(), and zalloc().

Referenced by peermux_step().

Variable Documentation

◆ __profiler

struct profiler peerblk_discovery_timeout_profiler __profiler
static
Initial value:
=
{ .name = "peerblk.download" }

PeerDist block download profiler.

PeerDist block download discovery timeout profiler.

PeerDist block download discovery success profiler.

PeerDist block download attempt timeout profiler.

PeerDist block download attempt failure profiler.

PeerDist block download attempt success profiler.

Definition at line 108 of file peerblk.c.

◆ peerblk_queue_desc

struct process_descriptor peerblk_queue_desc
static
Initial value:
=
A process.
Definition: process.h:18
static void peerblk_step(struct peerdist_block_queue *queue)
PeerDist block download queue process.
Definition: peerblk.c:481
#define PROC_DESC_ONCE(object_type, process, _step)
Define a process descriptor for a process that runs only once.
Definition: process.h:98
PeerDist block download queue.
Definition: peerblk.h:133

PeerDist block download queue process descriptor.

Definition at line 561 of file peerblk.c.

◆ peerblk_raw_queue

struct peerdist_block_queue peerblk_raw_queue
static
Initial value:
= {
}
static struct process_descriptor peerblk_queue_desc
PeerDist block download queue process descriptor.
Definition: peerblk.c:561
struct list_head list
List of queued downloads.
Definition: peerblk.h:137
#define PROC_INIT(_process, _desc)
Initialise a static process.
Definition: process.h:132
struct process process
Download opening process.
Definition: peerblk.h:135
static struct peerdist_block_queue peerblk_raw_queue
Raw block download queue.
Definition: peerblk.c:565
static int peerblk_raw_open(struct peerdist_block *peerblk)
Open PeerDist raw block download attempt.
Definition: peerblk.c:360
#define PEERBLK_RAW_MAX
PeerDist maximum number of concurrent raw block downloads.
Definition: peerblk.c:70
#define LIST_HEAD_INIT(list)
Initialise a static list head.
Definition: list.h:31

Raw block download queue.

Definition at line 565 of file peerblk.c.

Referenced by peerblk_expired().

◆ peerblk_xfer_operations

struct interface_operation peerblk_xfer_operations[]
static
Initial value:
= {
}
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:250
A PeerDist block download.
Definition: peerblk.h:47
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:33
static void peerblk_close(struct peerdist_block *peerblk, int rc)
Close PeerDist block download.
Definition: peerblk.c:206

PeerDist block download data transfer interface operations.

Definition at line 1388 of file peerblk.c.

◆ peerblk_xfer_desc

struct interface_descriptor peerblk_xfer_desc
static
Initial value:
=
A PeerDist block download.
Definition: peerblk.h:47
struct interface xfer
Data transfer interface.
Definition: peerblk.h:51
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:81
static struct interface_operation peerblk_xfer_operations[]
PeerDist block download data transfer interface operations.
Definition: peerblk.c:1388

PeerDist block download data transfer interface descriptor.

Definition at line 1393 of file peerblk.c.

Referenced by peerblk_open().

◆ peerblk_raw_operations

struct interface_operation peerblk_raw_operations[]
static
Initial value:
= {
}
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:250
A PeerDist block download.
Definition: peerblk.h:47
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:33
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition: xfer.c:195
static int peerblk_raw_rx(struct peerdist_block *peerblk, struct io_buffer *iobuf, struct xfer_metadata *meta)
Receive PeerDist raw data.
Definition: peerblk.c:403
static void peerblk_raw_close(struct peerdist_block *peerblk, int rc)
Close PeerDist raw block download attempt.
Definition: peerblk.c:451

PeerDist block download raw data interface operations.

Definition at line 1397 of file peerblk.c.

◆ peerblk_raw_desc

struct interface_descriptor peerblk_raw_desc
static
Initial value:
=
A PeerDist block download.
Definition: peerblk.h:47
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:81
static struct interface_operation peerblk_raw_operations[]
PeerDist block download raw data interface operations.
Definition: peerblk.c:1397
__be32 raw[7]
Definition: CIB_PRM.h:28

PeerDist block download raw data interface descriptor.

Definition at line 1403 of file peerblk.c.

Referenced by peerblk_open().

◆ peerblk_retrieval_operations

struct interface_operation peerblk_retrieval_operations[]
static
Initial value:
= {
}
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:250
static int peerblk_retrieval_rx(struct peerdist_block *peerblk, struct io_buffer *iobuf, struct xfer_metadata *meta)
Receive PeerDist retrieval protocol data.
Definition: peerblk.c:677
A PeerDist block download.
Definition: peerblk.h:47
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:33
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition: xfer.c:195
static void peerblk_retrieval_close(struct peerdist_block *peerblk, int rc)
Close PeerDist retrieval protocol block download attempt.
Definition: peerblk.c:1209

PeerDist block download retrieval protocol interface operations.

Definition at line 1407 of file peerblk.c.

◆ peerblk_retrieval_desc

struct interface_descriptor peerblk_retrieval_desc
static
Initial value:
=
struct interface retrieval
Retrieval protocol interface.
Definition: peerblk.h:55
A PeerDist block download.
Definition: peerblk.h:47
static struct interface_operation peerblk_retrieval_operations[]
PeerDist block download retrieval protocol interface operations.
Definition: peerblk.c:1407
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:81

PeerDist block download retrieval protocol interface descriptor.

Definition at line 1413 of file peerblk.c.

Referenced by peerblk_open().

◆ peerblk_process_desc

struct process_descriptor peerblk_process_desc
static
Initial value:
=
A process.
Definition: process.h:18
static void peerblk_decrypt(struct peerdist_block *peerblk)
Decrypt one chunk of PeerDist retrieval protocol data.
Definition: peerblk.c:1119
A PeerDist block download.
Definition: peerblk.h:47
#define PROC_DESC(object_type, process, _step)
Define a process descriptor.
Definition: process.h:83

PeerDist block download decryption process descriptor.

Definition at line 1418 of file peerblk.c.

Referenced by peerblk_open().

◆ peerblk_discovery_operations

struct peerdisc_client_operations peerblk_discovery_operations
static
Initial value:
= {
.discovered = peerblk_discovered,
}
static void peerblk_discovered(struct peerdisc_client *discovery)
Handle PeerDist peer discovery.
Definition: peerblk.c:1361

PeerDist block download discovery operations.

Definition at line 1422 of file peerblk.c.

Referenced by peerblk_open().