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 <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)
 
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 49 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 68 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 74 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 80 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 86 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 92 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 103 of file peerblk.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ peerblk_dequeue()

static void peerblk_dequeue ( struct peerdist_block peerblk)
static

Remove block from download queue.

Parameters
peerblkPeerDist block download

Definition at line 536 of file peerblk.c.

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

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 137 of file peerblk.c.

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

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 151 of file peerblk.c.

151  {
152  struct peerdist_block *peerblk =
154 
155  uri_put ( peerblk->uri );
156  free ( peerblk->cipherctx );
157  free ( peerblk );
158 }
static void uri_put(struct uri *uri)
Decrement URI reference count.
Definition: uri.h:188
A reference counter.
Definition: refcnt.h:26
struct uri * uri
Original URI.
Definition: peerblk.h:57
A PeerDist block download.
Definition: peerblk.h:46
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
void * cipherctx
Cipher context (dynamically allocated as needed)
Definition: peerblk.h:79
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54

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 166 of file peerblk.c.

166  {
167 
168  /* Stop decryption process */
169  process_del ( &peerblk->process );
170 
171  /* Stop timer */
172  stop_timer ( &peerblk->timer );
173 
174  /* Abort any current download attempt */
175  intf_restart ( &peerblk->raw, rc );
176  intf_restart ( &peerblk->retrieval, rc );
177 
178  /* Remove from download queue, if applicable */
179  if ( peerblk->queue )
180  peerblk_dequeue ( peerblk );
181 
182  /* Empty received data buffer */
183  xferbuf_free ( &peerblk->buffer );
184  peerblk->pos = 0;
185 
186  /* Reset digest and free cipher context */
187  digest_init ( peerblk->digest, peerblk->digestctx );
188  free ( peerblk->cipherctx );
189  peerblk->cipherctx = NULL;
190  peerblk->cipher = NULL;
191 
192  /* Reset trim thresholds */
193  peerblk->start = ( peerblk->trim.start - peerblk->range.start );
194  peerblk->end = ( peerblk->trim.end - peerblk->range.start );
195  assert ( peerblk->start <= peerblk->end );
196 }
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:337
struct xfer_buffer buffer
Data buffer.
Definition: peerblk.h:99
size_t start
Start offset.
Definition: pccrc.h:311
struct interface retrieval
Retrieval protocol interface.
Definition: peerblk.h:54
void * digestctx
Digest context (statically allocated at instantiation time)
Definition: peerblk.h:74
void xferbuf_free(struct xfer_buffer *xferbuf)
Free data transfer buffer.
Definition: xferbuf.c:58
struct process process
Decryption process.
Definition: peerblk.h:102
void process_del(struct process *process)
Remove process from process list.
Definition: process.c:79
struct cipher_algorithm * cipher
Cipher algorithm.
Definition: peerblk.h:77
static void peerblk_dequeue(struct peerdist_block *peerblk)
Remove block from download queue.
Definition: peerblk.c:536
size_t end
End of trimmed content (relative to incoming data stream)
Definition: peerblk.h:97
struct digest_algorithm * digest
Digest algorithm.
Definition: peerblk.h:66
struct peerdist_range range
Content range of this block.
Definition: peerblk.h:59
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
struct peerdist_block_queue * queue
Block download queue.
Definition: peerblk.h:115
struct interface raw
Raw data interface.
Definition: peerblk.h:52
static void digest_init(struct digest_algorithm *digest, void *ctx)
Definition: crypto.h:172
void * cipherctx
Cipher context (dynamically allocated as needed)
Definition: peerblk.h:79
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
size_t start
Start of trimmed content (relative to incoming data stream)
Definition: peerblk.h:95
struct retry_timer timer
Retry timer.
Definition: peerblk.h:119
void stop_timer(struct retry_timer *timer)
Stop timer.
Definition: retry.c:117
struct peerdist_range trim
Trimmed range of this block.
Definition: peerblk.h:61
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
size_t pos
Current position (relative to incoming data stream)
Definition: peerblk.h:93
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 204 of file peerblk.c.

204  {
205  unsigned long now = peerblk_timestamp();
206 
207  /* Profile overall block download */
208  profile_custom ( &peerblk_download_profiler,
209  ( now - peerblk->started ) );
210 
211  /* Reset download attempt */
212  peerblk_reset ( peerblk, rc );
213 
214  /* Close discovery */
215  peerdisc_close ( &peerblk->discovery );
216 
217  /* Shut down all interfaces */
218  intf_shutdown ( &peerblk->retrieval, rc );
219  intf_shutdown ( &peerblk->raw, rc );
220  intf_shutdown ( &peerblk->xfer, rc );
221 }
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:273
struct interface retrieval
Retrieval protocol interface.
Definition: peerblk.h:54
static void profile_custom(struct profiler *profiler, unsigned long sample)
Record profiling sample in custom units.
Definition: profile.h:198
struct peerdisc_client discovery
Discovery client.
Definition: peerblk.h:111
static unsigned long peerblk_timestamp(void)
Get profiling timestamp.
Definition: peerblk.c:137
static void peerblk_reset(struct peerdist_block *peerblk, int rc)
Reset PeerDist block download attempt.
Definition: peerblk.c:166
struct interface raw
Raw data interface.
Definition: peerblk.h:52
struct interface xfer
Data transfer interface.
Definition: peerblk.h:50
unsigned long started
Time at which block download was started.
Definition: peerblk.h:126
void peerdisc_close(struct peerdisc_client *peerdisc)
Close PeerDist discovery client.
Definition: peerdisc.c:574

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 231 of file peerblk.c.

231  {
232 
233  return ( ( pos - peerblk->start ) + peerblk->offset );
234 }
size_t offset
Offset of first byte in trimmed range within overall download.
Definition: peerblk.h:63
size_t start
Start of trimmed content (relative to incoming data stream)
Definition: peerblk.h:95
size_t pos
Current position (relative to incoming data stream)
Definition: peerblk.h:93

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 245 of file peerblk.c.

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

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 296 of file peerblk.c.

296  {
297  struct digest_algorithm *digest = peerblk->digest;
298  struct peerdisc_segment *segment = peerblk->discovery.segment;
299  struct peerdisc_peer *head;
300  struct peerdisc_peer *peer;
301  uint8_t hash[digest->digestsize];
302  unsigned long now = peerblk_timestamp();
303 
304  /* Check for errors on completion */
305  if ( rc != 0 ) {
306  DBGC ( peerblk, "PEERBLK %p %d.%d attempt failed: %s\n",
307  peerblk, peerblk->segment, peerblk->block,
308  strerror ( rc ) );
309  goto err;
310  }
311 
312  /* Check digest */
313  digest_final ( digest, peerblk->digestctx, hash );
314  if ( memcmp ( hash, peerblk->hash, peerblk->digestsize ) != 0 ) {
315  DBGC ( peerblk, "PEERBLK %p %d.%d digest mismatch:\n",
316  peerblk, peerblk->segment, peerblk->block );
317  DBGC_HDA ( peerblk, 0, hash, peerblk->digestsize );
318  DBGC_HDA ( peerblk, 0, peerblk->hash, peerblk->digestsize );
319  rc = -EIO;
320  goto err;
321  }
322 
323  /* Profile successful attempt */
324  profile_custom ( &peerblk_attempt_success_profiler,
325  ( now - peerblk->attempted ) );
326 
327  /* Report peer statistics */
328  head = list_entry ( &segment->peers, struct peerdisc_peer, list );
329  peer = ( ( peerblk->peer == head ) ? NULL : peerblk->peer );
330  peerdisc_stat ( &peerblk->xfer, peer, &segment->peers );
331 
332  /* Close download */
333  peerblk_close ( peerblk, 0 );
334  return;
335 
336  err:
337  /* Record failure reason and schedule a retry attempt */
338  profile_custom ( &peerblk_attempt_failure_profiler,
339  ( now - peerblk->attempted ) );
340  peerblk_reset ( peerblk, rc );
341  peerblk->rc = rc;
342  start_timer_nodelay ( &peerblk->timer );
343 }
uint16_t segment
Code segment.
Definition: librm.h:252
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static void start_timer_nodelay(struct retry_timer *timer)
Start timer with no delay.
Definition: retry.h:99
static void digest_final(struct digest_algorithm *digest, void *ctx, void *out)
Definition: crypto.h:182
A PeerDist discovery segment.
Definition: peerdisc.h:42
void * digestctx
Digest context (statically allocated at instantiation time)
Definition: peerblk.h:74
#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:198
uint8_t head
Head number.
Definition: int13.h:34
struct peerdisc_client discovery
Discovery client.
Definition: peerblk.h:111
struct md4_digest digest
Digest of data already processed.
Definition: md4.h:12
static unsigned long peerblk_timestamp(void)
Get profiling timestamp.
Definition: peerblk.c:137
static void peerblk_reset(struct peerdist_block *peerblk, int rc)
Reset PeerDist block download attempt.
Definition: peerblk.c:166
struct digest_algorithm * digest
Digest algorithm.
Definition: peerblk.h:66
void peerdisc_stat(struct interface *intf, struct peerdisc_peer *peer, struct list_head *peers)
Report peer discovery statistics.
Definition: peerdisc.c:97
int rc
Most recent attempt failure.
Definition: peerblk.h:123
#define DBGC_HDA(...)
Definition: compiler.h:506
unsigned int segment
Segment index.
Definition: peerblk.h:82
unsigned int block
Block index.
Definition: peerblk.h:88
struct peerdisc_peer * peer
Current position in discovered peer list.
Definition: peerblk.h:113
struct interface xfer
Data transfer interface.
Definition: peerblk.h:50
uint8_t hash[PEERDIST_DIGEST_MAX_SIZE]
Block hash.
Definition: peerblk.h:90
pseudo_bit_t hash[0x00010]
Hash algorithm.
Definition: arbel.h:13
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
unsigned char uint8_t
Definition: stdint.h:10
size_t digestsize
Digest size.
Definition: peerblk.h:72
struct peerdisc_segment * segment
Discovery segment.
Definition: peerdisc.h:81
unsigned long attempted
Time at which most recent attempt was started.
Definition: peerblk.h:128
struct retry_timer timer
Retry timer.
Definition: peerblk.h:119
static void peerblk_close(struct peerdist_block *peerblk, int rc)
Close PeerDist block download.
Definition: peerblk.c:204
#define EIO
Input/output error.
Definition: errno.h:433
A message digest algorithm.
Definition: crypto.h:16
struct list_head list
List of peers.
Definition: peerdisc.h:73
#define list_entry(list, type, member)
Get the container of a list entry.
Definition: list.h:321
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:113
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
A PeerDist discovery peer.
Definition: peerdisc.h:71

References peerdist_block::attempted, peerdist_block::block, DBGC, DBGC_HDA, digest, peerdist_block::digest, digest_final(), peerdist_block::digestctx, peerdist_block::digestsize, peerdist_block::discovery, EIO, hash, peerdist_block::hash, head, peerdisc_peer::list, list_entry, memcmp(), NULL, 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 358 of file peerblk.c.

358  {
359  struct http_request_range range;
360  int rc;
361 
362  DBGC2 ( peerblk, "PEERBLK %p %d.%d attempting raw range request\n",
363  peerblk, peerblk->segment, peerblk->block );
364 
365  /* Construct HTTP range */
366  memset ( &range, 0, sizeof ( range ) );
367  range.start = peerblk->range.start;
368  range.len = ( peerblk->range.end - peerblk->range.start );
369 
370  /* Initiate range request to retrieve block */
371  if ( ( rc = http_open ( &peerblk->raw, &http_get, peerblk->uri,
372  &range, NULL ) ) != 0 ) {
373  DBGC ( peerblk, "PEERBLK %p %d.%d could not create range "
374  "request: %s\n", peerblk, peerblk->segment,
375  peerblk->block, strerror ( rc ) );
376  return rc;
377  }
378 
379  /* Annul HTTP connection (for testing) if applicable. Do not
380  * report as an immediate error, in order to test our ability
381  * to recover from a totally unresponsive HTTP server.
382  */
383  if ( inject_fault ( PEERBLK_ANNUL_RATE ) )
384  intf_restart ( &peerblk->raw, 0 );
385 
386  /* Start download attempt timer */
387  peerblk->rc = -ETIMEDOUT;
389 
390  return 0;
391 }
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:337
#define PEERBLK_RAW_OPEN_TIMEOUT
PeerDist raw block download attempt initial progress timeout.
Definition: peerblk.c:74
HTTP request range descriptor.
Definition: http.h:137
size_t start
Start offset.
Definition: pccrc.h:311
#define DBGC(...)
Definition: compiler.h:505
struct uri * uri
Original URI.
Definition: peerblk.h:57
int rc
Most recent attempt failure.
Definition: peerblk.h:123
struct peerdist_range range
Content range of this block.
Definition: peerblk.h:59
unsigned int segment
Segment index.
Definition: peerblk.h:82
struct interface raw
Raw data interface.
Definition: peerblk.h:52
unsigned int block
Block index.
Definition: peerblk.h:88
struct http_method http_get
HTTP GET method.
Definition: httpcore.c:138
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
void start_timer_fixed(struct retry_timer *timer, unsigned long timeout)
Start timer with a specified timeout.
Definition: retry.c:64
#define PEERBLK_ANNUL_RATE
Definition: fault.h:21
struct retry_timer timer
Retry timer.
Definition: peerblk.h:119
#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:586
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
#define ETIMEDOUT
Connection timed out.
Definition: errno.h:669
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(), http_request_range::len, memset(), NULL, PEERBLK_ANNUL_RATE, PEERBLK_RAW_OPEN_TIMEOUT, peerdist_block::range, peerdist_block::raw, peerdist_block::rc, rc, peerdist_block::segment, http_request_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 401 of file peerblk.c.

403  {
404  size_t len = iob_len ( iobuf );
405  size_t pos = peerblk->pos;
406  size_t mid = ( ( peerblk->range.end - peerblk->range.start ) / 2 );
407  int rc;
408 
409  /* Corrupt received data (for testing) if applicable */
410  inject_corruption ( PEERBLK_CORRUPT_RATE, iobuf->data, len );
411 
412  /* Fail if data is delivered out of order, since the streaming
413  * digest requires strict ordering.
414  */
415  if ( ( rc = xfer_check_order ( meta, &peerblk->pos, len ) ) != 0 )
416  goto err;
417 
418  /* Add data to digest */
419  digest_update ( peerblk->digest, peerblk->digestctx, iobuf->data, len );
420 
421  /* Deliver data */
422  if ( ( rc = peerblk_deliver ( peerblk, iob_disown ( iobuf ), meta,
423  pos ) ) != 0 )
424  goto err;
425 
426  /* Extend download attempt timer */
428 
429  /* Stall download attempt (for testing) if applicable */
430  if ( ( pos < mid ) && ( ( pos + len ) >= mid ) &&
431  ( ( rc = inject_fault ( PEERBLK_STALL_RATE ) ) != 0 ) ) {
432  intf_restart ( &peerblk->raw, rc );
433  }
434 
435  return 0;
436 
437  err:
438  free_iob ( iobuf );
439  peerblk_done ( peerblk, rc );
440  return rc;
441 }
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:177
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition: interface.c:337
uint16_t mid
Middle 16 bits of address.
Definition: librm.h:258
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:145
size_t start
Start offset.
Definition: pccrc.h:311
void * digestctx
Digest context (statically allocated at instantiation time)
Definition: peerblk.h:74
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:245
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:376
#define PEERBLK_STALL_RATE
Definition: fault.h:24
struct digest_algorithm * digest
Digest algorithm.
Definition: peerblk.h:66
struct peerdist_range range
Content range of this block.
Definition: peerblk.h:59
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:208
#define PEERBLK_RAW_RX_TIMEOUT
PeerDist raw block download attempt ongoing progress timeout.
Definition: peerblk.c:80
struct interface raw
Raw data interface.
Definition: peerblk.h:52
int meta(WINDOW *, bool)
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:151
void start_timer_fixed(struct retry_timer *timer, unsigned long timeout)
Start timer with a specified timeout.
Definition: retry.c:64
struct retry_timer timer
Retry timer.
Definition: peerblk.h:119
static void peerblk_done(struct peerdist_block *peerblk, int rc)
Finish PeerDist block download attempt.
Definition: peerblk.c:296
uint32_t len
Length.
Definition: ena.h:14
void * data
Start of data.
Definition: iobuf.h:44
#define PEERBLK_CORRUPT_RATE
Definition: fault.h:30
size_t pos
Current position (relative to incoming data stream)
Definition: peerblk.h:93
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 449 of file peerblk.c.

449  {
450 
451  /* Restart interface */
452  intf_restart ( &peerblk->raw, rc );
453 
454  /* Fail immediately if we have an error */
455  if ( rc != 0 )
456  goto done;
457 
458  /* Abort download attempt (for testing) if applicable */
459  if ( ( rc = inject_fault ( PEERBLK_ABORT_RATE ) ) != 0 )
460  goto done;
461 
462  done:
463  /* Complete download attempt */
464  peerblk_done ( peerblk, rc );
465 }
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:337
#define PEERBLK_ABORT_RATE
Definition: fault.h:27
struct interface raw
Raw data interface.
Definition: peerblk.h:52
static void peerblk_done(struct peerdist_block *peerblk, int rc)
Finish PeerDist block download attempt.
Definition: peerblk.c:296
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 479 of file peerblk.c.

479  {
480  struct peerdist_block *peerblk;
481  int rc;
482 
483  /* Do nothing yet if we have too many open block downloads */
484  if ( queue->count >= queue->max )
485  return;
486 
487  /* Do nothing unless there are queued block downloads */
488  peerblk = list_first_entry ( &queue->list, struct peerdist_block,
489  queued );
490  if ( ! peerblk )
491  return;
492 
493  /* Reschedule queue process */
494  process_add ( &queue->process );
495 
496  /* Remove block from queue */
497  list_del ( &peerblk->queued );
498  INIT_LIST_HEAD ( &peerblk->queued );
499 
500  /* Attempt download */
501  if ( ( rc = queue->open ( peerblk ) ) != 0 ) {
502  peerblk_close ( peerblk, rc );
503  return;
504  }
505 
506  /* Increment open block download count */
507  queue->count++;
508 }
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:333
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
A PeerDist block download.
Definition: peerblk.h:46
void process_add(struct process *process)
Add process to process list.
Definition: process.c:59
struct list_head queued
List of queued block downloads.
Definition: peerblk.h:117
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:45
static void peerblk_close(struct peerdist_block *peerblk, int rc)
Close PeerDist block download.
Definition: peerblk.c:204
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 516 of file peerblk.c.

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

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 583 of file peerblk.c.

583  {
584  char uri_string[ 7 /* "http://" */ + strlen ( location ) +
585  sizeof ( PEERDIST_MAGIC_PATH /* includes NUL */ ) ];
586 
587  /* Construct URI string */
588  snprintf ( uri_string, sizeof ( uri_string ),
589  ( "http://%s" PEERDIST_MAGIC_PATH ), location );
590 
591  /* Parse URI string */
592  return parse_uri ( uri_string );
593 }
#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:228
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:382
struct uri * parse_uri(const char *uri_string)
Parse URI.
Definition: uri.c:295

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 602 of file peerblk.c.

603  {
604  size_t digestsize = peerblk->digestsize;
605  peerdist_msg_getblks_t ( digestsize, 1, 0 ) req;
606  peerblk_msg_blk_t ( digestsize, 0, 0, 0 ) *rsp;
607  struct http_request_content content;
608  struct uri *uri;
609  int rc;
610 
611  DBGC2 ( peerblk, "PEERBLK %p %d.%d attempting retrieval from %s\n",
612  peerblk, peerblk->segment, peerblk->block, location );
613 
614  /* Construct block fetch request */
615  memset ( &req, 0, sizeof ( req ) );
617  req.getblks.hdr.type = htonl ( PEERDIST_MSG_GETBLKS_TYPE );
618  req.getblks.hdr.len = htonl ( sizeof ( req ) );
619  req.getblks.hdr.algorithm = htonl ( PEERDIST_MSG_AES_128_CBC );
621  memcpy ( req.segment.id, peerblk->id, digestsize );
622  req.ranges.ranges.count = htonl ( 1 );
623  req.ranges.range[0].first = htonl ( peerblk->block );
624  req.ranges.range[0].count = htonl ( 1 );
625 
626  /* Construct POST request content */
627  memset ( &content, 0, sizeof ( content ) );
628  content.data = &req;
629  content.len = sizeof ( req );
630 
631  /* Construct URI */
632  if ( ( uri = peerblk_retrieval_uri ( location ) ) == NULL ) {
633  rc = -ENOMEM;
634  goto err_uri;
635  }
636 
637  /* Update trim thresholds */
638  peerblk->start += offsetof ( typeof ( *rsp ), msg.vrf );
639  peerblk->end += offsetof ( typeof ( *rsp ), msg.vrf );
640 
641  /* Initiate HTTP POST to retrieve block */
642  if ( ( rc = http_open ( &peerblk->retrieval, &http_post, uri,
643  NULL, &content ) ) != 0 ) {
644  DBGC ( peerblk, "PEERBLK %p %d.%d could not create retrieval "
645  "request: %s\n", peerblk, peerblk->segment,
646  peerblk->block, strerror ( rc ) );
647  goto err_open;
648  }
649 
650  /* Annul HTTP connection (for testing) if applicable. Do not
651  * report as an immediate error, in order to test our ability
652  * to recover from a totally unresponsive HTTP server.
653  */
654  if ( inject_fault ( PEERBLK_ANNUL_RATE ) )
655  intf_restart ( &peerblk->retrieval, 0 );
656 
657  /* Start download attempt timer */
658  peerblk->rc = -ETIMEDOUT;
660 
661  err_open:
662  uri_put ( uri );
663  err_uri:
664  return rc;
665 }
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:583
uint16_t segment
Code segment.
Definition: librm.h:252
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:337
static void uri_put(struct uri *uri)
Decrement URI reference count.
Definition: uri.h:188
#define PEERBLK_RETRIEVAL_OPEN_TIMEOUT
PeerDist retrieval protocol block download attempt initial progress timeout.
Definition: peerblk.c:86
uint8_t type
Type.
Definition: ena.h:16
uint16_t block
Definition: tftp.h:12
struct interface retrieval
Retrieval protocol interface.
Definition: peerblk.h:54
#define DBGC(...)
Definition: compiler.h:505
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h:24
#define htonl(value)
Definition: byteswap.h:133
size_t end
End of trimmed content (relative to incoming data stream)
Definition: peerblk.h:97
int rc
Most recent attempt failure.
Definition: peerblk.h:123
#define ENOMEM
Not enough space.
Definition: errno.h:534
struct peerdist_range range
Content range of this block.
Definition: peerblk.h:59
void * memcpy(void *dest, const void *src, size_t len) __nonnull
u32 version
Version number.
Definition: ath9k_hw.c:1983
#define PEERDIST_MSG_GETBLKS_TYPE
Retrieval protocol block fetch request type.
Definition: pccrr.h:278
unsigned int segment
Segment index.
Definition: peerblk.h:82
unsigned int block
Block index.
Definition: peerblk.h:88
HTTP request content descriptor.
Definition: http.h:145
uint64_t rsp
Definition: librm.h:267
#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:78
size_t digestsize
Digest size.
Definition: peerblk.h:72
size_t start
Start of trimmed content (relative to incoming data stream)
Definition: peerblk.h:95
uint32_t hdr
Message header.
Definition: intelvf.h:12
void start_timer_fixed(struct retry_timer *timer, unsigned long timeout)
Start timer with a specified timeout.
Definition: retry.c:64
#define PEERBLK_ANNUL_RATE
Definition: fault.h:21
u16 algorithm
Authentication algorithm (Open System or Shared Key)
Definition: ieee80211.h:1030
struct retry_timer timer
Retry timer.
Definition: peerblk.h:119
#define peerblk_msg_blk_t(digestsize, len, vrf_len, blksize)
Retrieval protocol block fetch response (including transport header)
Definition: peerblk.h:158
uint32_t len
Length.
Definition: ena.h:14
#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:586
uint16_t count
Number of entries.
Definition: ena.h:22
uint32_t d
Definition: md4.c:31
__be32 raw[7]
Definition: CIB_PRM.h:28
A Uniform Resource Identifier.
Definition: uri.h:50
unsigned int n
Definition: entropy.h:159
uint32_t digestsize
Digest size (i.e.
Definition: pccrr.h:14
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
#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:362
#define ETIMEDOUT
Connection timed out.
Definition: errno.h:669
struct http_method http_post
HTTP POST method.
Definition: httpcore.c:143
uint32_t first
Length to skip in first segment.
Definition: pccrc.h:23
if(natsemi->flags &NATSEMI_64BIT) return 1
void * memset(void *dest, int character, size_t len) __nonnull
static void msg(unsigned int row, const char *fmt,...)
Print message centred on specified row.
Definition: settings_ui.c:285

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, 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 675 of file peerblk.c.

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

References 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 788 of file peerblk.c.

788  {
789  struct {
791  struct peerdist_msg_header msg;
792  } __attribute__ (( packed )) *msg = peerblk->buffer.data;
793  struct cipher_algorithm *cipher;
794  size_t len = peerblk->buffer.len;
795  size_t keylen = 0;
796  int rc;
797 
798  /* Check message length */
799  if ( len < sizeof ( *msg ) ) {
800  DBGC ( peerblk, "PEERBLK %p %d.%d message too short for header "
801  "(%zd bytes)\n", peerblk, peerblk->segment,
802  peerblk->block, len );
803  return -ERANGE;
804  }
805 
806  /* Check message type */
807  if ( msg->msg.type != htonl ( PEERDIST_MSG_BLK_TYPE ) ) {
808  DBGC ( peerblk, "PEERBLK %p %d.%d unexpected message type "
809  "%#08x\n", peerblk, peerblk->segment, peerblk->block,
810  ntohl ( msg->msg.type ) );
811  return -EPROTO;
812  }
813 
814  /* Determine cipher algorithm and key length */
815  cipher = &aes_cbc_algorithm;
816  switch ( msg->msg.algorithm ) {
817  case htonl ( PEERDIST_MSG_PLAINTEXT ) :
818  cipher = NULL;
819  break;
821  keylen = ( 128 / 8 );
822  break;
824  keylen = ( 192 / 8 );
825  break;
827  keylen = ( 256 / 8 );
828  break;
829  default:
830  DBGC ( peerblk, "PEERBLK %p %d.%d unrecognised algorithm "
831  "%#08x\n", peerblk, peerblk->segment, peerblk->block,
832  ntohl ( msg->msg.algorithm ) );
833  return -ENOTSUP;
834  }
835  DBGC2 ( peerblk, "PEERBLK %p %d.%d using %s with %zd-bit key\n",
836  peerblk, peerblk->segment, peerblk->block,
837  ( cipher ? cipher->name : "plaintext" ), ( 8 * keylen ) );
838 
839  /* Sanity check key length against maximum secret length */
840  if ( keylen > peerblk->digestsize ) {
841  DBGC ( peerblk, "PEERBLK %p %d.%d %zd-byte secret too short "
842  "for %zd-bit key\n", peerblk, peerblk->segment,
843  peerblk->block, peerblk->digestsize, ( 8 * keylen ) );
844  return -EPROTO;
845  }
846 
847  /* Allocate cipher context, if applicable. Freeing the cipher
848  * context (on error or otherwise) is handled by peerblk_reset().
849  */
850  peerblk->cipher = cipher;
851  assert ( peerblk->cipherctx == NULL );
852  if ( cipher ) {
853  peerblk->cipherctx = malloc ( cipher->ctxsize );
854  if ( ! peerblk->cipherctx )
855  return -ENOMEM;
856  }
857 
858  /* Initialise cipher, if applicable */
859  if ( cipher &&
860  ( rc = cipher_setkey ( cipher, peerblk->cipherctx, peerblk->secret,
861  keylen ) ) != 0 ) {
862  DBGC ( peerblk, "PEERBLK %p %d.%d could not set key: %s\n",
863  peerblk, peerblk->segment, peerblk->block,
864  strerror ( rc ) );
865  return rc;
866  }
867 
868  return 0;
869 }
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:99
#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:134
#define htonl(value)
Definition: byteswap.h:133
struct cipher_algorithm * cipher
Cipher algorithm.
Definition: peerblk.h:77
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
size_t len
Size of data.
Definition: xferbuf.h:23
#define ENOMEM
Not enough space.
Definition: errno.h:534
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
unsigned int segment
Segment index.
Definition: peerblk.h:82
unsigned int block
Block index.
Definition: peerblk.h:88
Retrieval protocol transport response header.
Definition: pccrr.h:180
No encryption.
Definition: pccrr.h:170
#define EPROTO
Protocol error.
Definition: errno.h:624
#define ERANGE
Result too large.
Definition: errno.h:639
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
void * cipherctx
Cipher context (dynamically allocated as needed)
Definition: peerblk.h:79
AES-192 in CBC mode.
Definition: pccrr.h:174
size_t digestsize
Digest size.
Definition: peerblk.h:72
size_t ctxsize
Context size.
Definition: crypto.h:52
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
Retrieval protocol message header.
Definition: pccrr.h:152
struct cipher_algorithm aes_cbc_algorithm
uint32_t hdr
Message header.
Definition: intelvf.h:12
uint32_t len
Length.
Definition: ena.h:14
#define DBGC2(...)
Definition: compiler.h:522
uint8_t secret[PEERDIST_DIGEST_MAX_SIZE]
Segment secret.
Definition: peerblk.h:86
A cipher algorithm.
Definition: crypto.h:48
AES-256 in CBC mode.
Definition: pccrr.h:176
const char * name
Algorithm name.
Definition: crypto.h:50
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
static int cipher_setkey(struct cipher_algorithm *cipher, void *ctx, const void *key, size_t keylen)
Definition: crypto.h:187
static void msg(unsigned int row, const char *fmt,...)
Print message centred on specified row.
Definition: settings_ui.c:285

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, len, xfer_buffer::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 878 of file peerblk.c.

879  {
880  size_t digestsize = peerblk->digestsize;
881  peerblk_msg_blk_t ( digestsize, 0, 0, 0 ) *msg = peerblk->buffer.data;
882  size_t len = peerblk->buffer.len;
883  size_t data_len;
884  size_t total;
885 
886  /* Check message length */
887  if ( len < offsetof ( typeof ( *msg ), msg.block.data ) ) {
888  DBGC ( peerblk, "PEERBLK %p %d.%d message too short for "
889  "zero-length data (%zd bytes)\n", peerblk,
890  peerblk->segment, peerblk->block, len );
891  return -ERANGE;
892  }
893 
894  /* Check digest size */
895  if ( ntohl ( msg->msg.segment.segment.digestsize ) != digestsize ) {
896  DBGC ( peerblk, "PEERBLK %p %d.%d incorrect digest size %d\n",
897  peerblk, peerblk->segment, peerblk->block,
898  ntohl ( msg->msg.segment.segment.digestsize ) );
899  return -EPROTO;
900  }
901 
902  /* Check segment ID */
903  if ( memcmp ( msg->msg.segment.id, peerblk->id, digestsize ) != 0 ) {
904  DBGC ( peerblk, "PEERBLK %p %d.%d segment ID mismatch\n",
905  peerblk, peerblk->segment, peerblk->block );
906  return -EPROTO;
907  }
908 
909  /* Check block ID */
910  if ( ntohl ( msg->msg.index ) != peerblk->block ) {
911  DBGC ( peerblk, "PEERBLK %p %d.%d block ID mismatch (got %d)\n",
912  peerblk, peerblk->segment, peerblk->block,
913  ntohl ( msg->msg.index ) );
914  return -EPROTO;
915  }
916 
917  /* Check for missing blocks */
918  data_len = be32_to_cpu ( msg->msg.block.block.len );
919  if ( ! data_len ) {
920  DBGC ( peerblk, "PEERBLK %p %d.%d block not found\n",
921  peerblk, peerblk->segment, peerblk->block );
922  return -ENOENT;
923  }
924 
925  /* Check for underlength blocks */
926  if ( data_len < ( peerblk->range.end - peerblk->range.start ) ) {
927  DBGC ( peerblk, "PEERBLK %p %d.%d underlength block (%zd "
928  "bytes)\n", peerblk, peerblk->segment, peerblk->block,
929  data_len );
930  return -ERANGE;
931  }
932 
933  /* Calculate buffered data length (i.e. excluding data which
934  * was delivered to the final data transfer buffer).
935  */
936  *buf_len = ( data_len - ( peerblk->end - peerblk->start ) );
937 
938  /* Describe data before the trimmed content */
939  peerblk->decrypt[PEERBLK_BEFORE].xferbuf = &peerblk->buffer;
940  peerblk->decrypt[PEERBLK_BEFORE].offset =
941  offsetof ( typeof ( *msg ), msg.block.data );
942  peerblk->decrypt[PEERBLK_BEFORE].len =
943  ( peerblk->start -
944  offsetof ( typeof ( *msg ), msg.block.data ) );
945  total = peerblk->decrypt[PEERBLK_BEFORE].len;
946 
947  /* Describe data within the trimmed content */
948  peerblk->decrypt[PEERBLK_DURING].offset =
949  peerblk_offset ( peerblk, peerblk->start );
950  peerblk->decrypt[PEERBLK_DURING].len =
951  ( peerblk->end - peerblk->start );
952  total += peerblk->decrypt[PEERBLK_DURING].len;
953 
954  /* Describe data after the trimmed content */
955  peerblk->decrypt[PEERBLK_AFTER].xferbuf = &peerblk->buffer;
956  peerblk->decrypt[PEERBLK_AFTER].offset = peerblk->start;
957  peerblk->decrypt[PEERBLK_AFTER].len =
958  ( offsetof ( typeof ( *msg ), msg.block.data )
959  + *buf_len - peerblk->start );
960  total += peerblk->decrypt[PEERBLK_AFTER].len;
961 
962  /* Sanity check */
963  assert ( total == be32_to_cpu ( msg->msg.block.block.len ) );
964 
965  /* Initialise cipher and digest lengths */
966  peerblk->cipher_remaining = total;
967  peerblk->digest_remaining =
968  ( peerblk->range.end - peerblk->range.start );
969  assert ( peerblk->cipher_remaining >= peerblk->digest_remaining );
970 
971  return 0;
972 }
void * data
Data.
Definition: xferbuf.h:21
struct xfer_buffer buffer
Data buffer.
Definition: peerblk.h:99
Data after the trimmed content.
Definition: peerblk.h:40
static size_t peerblk_offset(struct peerdist_block *peerblk, size_t pos)
Calculate offset within overall download.
Definition: peerblk.c:231
size_t digest_remaining
Remaining digest length (excluding AES padding bytes)
Definition: peerblk.h:108
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:514
#define ntohl(value)
Definition: byteswap.h:134
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h:24
size_t end
End of trimmed content (relative to incoming data stream)
Definition: peerblk.h:97
Data before the trimmed content.
Definition: peerblk.h:36
size_t len
Size of data.
Definition: xferbuf.h:23
Data within the trimmed content.
Definition: peerblk.h:38
struct peerdist_range range
Content range of this block.
Definition: peerblk.h:59
#define be32_to_cpu(value)
Definition: byteswap.h:116
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
unsigned int segment
Segment index.
Definition: peerblk.h:82
size_t offset
Offset within data transfer buffer.
Definition: peerblk.h:28
unsigned int block
Block index.
Definition: peerblk.h:88
uint8_t id[PEERDIST_DIGEST_MAX_SIZE]
Segment identifier.
Definition: peerblk.h:84
#define EPROTO
Protocol error.
Definition: errno.h:624
#define ERANGE
Result too large.
Definition: errno.h:639
struct xfer_buffer * xferbuf
Data transfer buffer.
Definition: peerblk.h:26
size_t digestsize
Digest size.
Definition: peerblk.h:72
size_t start
Start of trimmed content (relative to incoming data stream)
Definition: peerblk.h:95
#define peerblk_msg_blk_t(digestsize, len, vrf_len, blksize)
Retrieval protocol block fetch response (including transport header)
Definition: peerblk.h:158
uint32_t len
Length.
Definition: ena.h:14
struct peerdist_block_decrypt decrypt[PEERBLK_NUM_BUFFERS]
Decryption data buffer descriptors.
Definition: peerblk.h:104
uint32_t digestsize
Digest size (i.e.
Definition: pccrr.h:14
size_t cipher_remaining
Remaining decryption length.
Definition: peerblk.h:106
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:113
size_t len
Length to use from data transfer buffer.
Definition: peerblk.h:30
size_t end
End offset.
Definition: pccrc.h:313
static void msg(unsigned int row, const char *fmt,...)
Print message centred on specified row.
Definition: settings_ui.c:285

References assert(), be32_to_cpu, peerdist_block::block, peerdist_block::buffer, peerdist_block::cipher_remaining, xfer_buffer::data, DBGC, peerdist_block::decrypt, peerdist_block::digest_remaining, digestsize, peerdist_block::digestsize, peerdist_block::end, peerdist_range::end, ENOENT, EPROTO, ERANGE, peerdist_block::id, len, xfer_buffer::len, peerdist_block_decrypt::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, 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 982 of file peerblk.c.

983  {
984  size_t digestsize = peerblk->digestsize;
985  peerblk_msg_blk_t ( digestsize, buf_len, 0, 0 ) *msg =
986  peerblk->buffer.data;
987  size_t len = peerblk->buffer.len;
988 
989  /* Check message length */
990  if ( len < offsetof ( typeof ( *msg ), msg.vrf.data ) ) {
991  DBGC ( peerblk, "PEERBLK %p %d.%d message too short for "
992  "zero-length uselessness (%zd bytes)\n", peerblk,
993  peerblk->segment, peerblk->block, len );
994  return -ERANGE;
995  }
996 
997  /* Extract length of uselessness */
998  *vrf_len = be32_to_cpu ( msg->msg.vrf.vrf.len );
999 
1000  return 0;
1001 }
void * data
Data.
Definition: xferbuf.h:21
struct xfer_buffer buffer
Data buffer.
Definition: peerblk.h:99
#define DBGC(...)
Definition: compiler.h:505
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h:24
size_t len
Size of data.
Definition: xferbuf.h:23
#define be32_to_cpu(value)
Definition: byteswap.h:116
unsigned int segment
Segment index.
Definition: peerblk.h:82
unsigned int block
Block index.
Definition: peerblk.h:88
#define ERANGE
Result too large.
Definition: errno.h:639
size_t digestsize
Digest size.
Definition: peerblk.h:72
#define peerblk_msg_blk_t(digestsize, len, vrf_len, blksize)
Retrieval protocol block fetch response (including transport header)
Definition: peerblk.h:158
uint32_t len
Length.
Definition: ena.h:14
uint32_t digestsize
Digest size (i.e.
Definition: pccrr.h:14
static void msg(unsigned int row, const char *fmt,...)
Print message centred on specified row.
Definition: settings_ui.c:285

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

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 1011 of file peerblk.c.

1012  {
1013  size_t digestsize = peerblk->digestsize;
1014  size_t blksize = peerblk->cipher->blocksize;
1015  peerblk_msg_blk_t ( digestsize, buf_len, vrf_len, blksize ) *msg =
1016  peerblk->buffer.data;
1017  size_t len = peerblk->buffer.len;
1018 
1019  /* Check message length */
1020  if ( len < sizeof ( *msg ) ) {
1021  DBGC ( peerblk, "PEERBLK %p %d.%d message too short for "
1022  "initialisation vector (%zd bytes)\n", peerblk,
1023  peerblk->segment, peerblk->block, len );
1024  return -ERANGE;
1025  }
1026 
1027  /* Check initialisation vector size */
1028  if ( ntohl ( msg->msg.iv.iv.blksize ) != blksize ) {
1029  DBGC ( peerblk, "PEERBLK %p %d.%d incorrect IV size %d\n",
1030  peerblk, peerblk->segment, peerblk->block,
1031  ntohl ( msg->msg.iv.iv.blksize ) );
1032  return -EPROTO;
1033  }
1034 
1035  /* Set initialisation vector */
1036  cipher_setiv ( peerblk->cipher, peerblk->cipherctx, msg->msg.iv.data );
1037 
1038  return 0;
1039 }
void * data
Data.
Definition: xferbuf.h:21
size_t blocksize
Block size.
Definition: crypto.h:54
struct xfer_buffer buffer
Data buffer.
Definition: peerblk.h:99
#define DBGC(...)
Definition: compiler.h:505
uint32_t blksize
Block size for this segment.
Definition: pccrc.h:24
#define ntohl(value)
Definition: byteswap.h:134
struct cipher_algorithm * cipher
Cipher algorithm.
Definition: peerblk.h:77
size_t len
Size of data.
Definition: xferbuf.h:23
unsigned int segment
Segment index.
Definition: peerblk.h:82
unsigned int block
Block index.
Definition: peerblk.h:88
#define EPROTO
Protocol error.
Definition: errno.h:624
#define ERANGE
Result too large.
Definition: errno.h:639
void * cipherctx
Cipher context (dynamically allocated as needed)
Definition: peerblk.h:79
size_t digestsize
Digest size.
Definition: peerblk.h:72
#define peerblk_msg_blk_t(digestsize, len, vrf_len, blksize)
Retrieval protocol block fetch response (including transport header)
Definition: peerblk.h:158
uint32_t len
Length.
Definition: ena.h:14
uint32_t digestsize
Digest size (i.e.
Definition: pccrr.h:14
static void cipher_setiv(struct cipher_algorithm *cipher, void *ctx, const void *iv)
Definition: crypto.h:192
static void msg(unsigned int row, const char *fmt,...)
Print message centred on specified row.
Definition: settings_ui.c:285

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, len, xfer_buffer::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 1049 of file peerblk.c.

1050  {
1051  struct peerdist_block_decrypt *decrypt = peerblk->decrypt;
1052  size_t frag_len;
1053  int rc;
1054 
1055  /* Read from each decryption buffer in turn */
1056  for ( ; len ; decrypt++, data += frag_len, len -= frag_len ) {
1057 
1058  /* Calculate length to use from this buffer */
1059  frag_len = decrypt->len;
1060  if ( frag_len > len )
1061  frag_len = len;
1062  if ( ! frag_len )
1063  continue;
1064 
1065  /* Read from this buffer */
1066  if ( ( rc = xferbuf_read ( decrypt->xferbuf, decrypt->offset,
1067  data, frag_len ) ) != 0 )
1068  return rc;
1069  }
1070 
1071  return 0;
1072 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
A PeerDist retrieval protocol decryption buffer descriptor.
Definition: peerblk.h:24
size_t offset
Offset within data transfer buffer.
Definition: peerblk.h:28
struct xfer_buffer * xferbuf
Data transfer buffer.
Definition: peerblk.h:26
int xferbuf_read(struct xfer_buffer *xferbuf, size_t offset, void *data, size_t len)
Read from data transfer buffer.
Definition: xferbuf.c:128
uint32_t len
Length.
Definition: ena.h:14
struct peerdist_block_decrypt decrypt[PEERBLK_NUM_BUFFERS]
Decryption data buffer descriptors.
Definition: peerblk.h:104
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
size_t len
Length to use from data transfer buffer.
Definition: peerblk.h:30

References data, peerdist_block::decrypt, len, peerdist_block_decrypt::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 1082 of file peerblk.c.

1083  {
1084  struct peerdist_block_decrypt *decrypt = peerblk->decrypt;
1085  size_t frag_len;
1086  int rc;
1087 
1088  /* Write to each decryption buffer in turn */
1089  for ( ; len ; decrypt++, data += frag_len, len -= frag_len ) {
1090 
1091  /* Calculate length to use from this buffer */
1092  frag_len = decrypt->len;
1093  if ( frag_len > len )
1094  frag_len = len;
1095  if ( ! frag_len )
1096  continue;
1097 
1098  /* Write to this buffer */
1099  if ( ( rc = xferbuf_write ( decrypt->xferbuf, decrypt->offset,
1100  data, frag_len ) ) != 0 )
1101  return rc;
1102 
1103  /* Update offset and length */
1104  decrypt->offset += frag_len;
1105  decrypt->len -= frag_len;
1106  }
1107 
1108  return 0;
1109 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
A PeerDist retrieval protocol decryption buffer descriptor.
Definition: peerblk.h:24
int xferbuf_write(struct xfer_buffer *xferbuf, size_t offset, const void *data, size_t len)
Write to data transfer buffer.
Definition: xferbuf.c:98
size_t offset
Offset within data transfer buffer.
Definition: peerblk.h:28
struct xfer_buffer * xferbuf
Data transfer buffer.
Definition: peerblk.h:26
uint32_t len
Length.
Definition: ena.h:14
struct peerdist_block_decrypt decrypt[PEERBLK_NUM_BUFFERS]
Decryption data buffer descriptors.
Definition: peerblk.h:104
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
size_t len
Length to use from data transfer buffer.
Definition: peerblk.h:30

References data, peerdist_block::decrypt, len, peerdist_block_decrypt::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 1116 of file peerblk.c.

1116  {
1117  struct cipher_algorithm *cipher = peerblk->cipher;
1118  struct digest_algorithm *digest = peerblk->digest;
1119  struct xfer_buffer *xferbuf;
1120  size_t cipher_len;
1121  size_t digest_len;
1122  void *data;
1123  int rc;
1124 
1125  /* Sanity check */
1126  assert ( ( PEERBLK_DECRYPT_CHUNKSIZE % cipher->blocksize ) == 0 );
1127 
1128  /* Get the underlying data transfer buffer */
1129  xferbuf = xfer_buffer ( &peerblk->xfer );
1130  if ( ! xferbuf ) {
1131  DBGC ( peerblk, "PEERBLK %p %d.%d has no underlying data "
1132  "transfer buffer\n", peerblk, peerblk->segment,
1133  peerblk->block );
1134  rc = -ENOTSUP;
1135  goto err_xfer_buffer;
1136  }
1137  peerblk->decrypt[PEERBLK_DURING].xferbuf = xferbuf;
1138 
1139  /* Calculate cipher and digest lengths */
1140  cipher_len = PEERBLK_DECRYPT_CHUNKSIZE;
1141  if ( cipher_len > peerblk->cipher_remaining )
1142  cipher_len = peerblk->cipher_remaining;
1143  digest_len = cipher_len;
1144  if ( digest_len > peerblk->digest_remaining )
1145  digest_len = peerblk->digest_remaining;
1146  assert ( ( cipher_len & ( cipher->blocksize - 1 ) ) == 0 );
1147 
1148  /* Allocate temporary data buffer */
1149  data = malloc ( cipher_len );
1150  if ( ! data ) {
1151  rc = -ENOMEM;
1152  goto err_alloc_data;
1153  }
1154 
1155  /* Read ciphertext */
1156  if ( ( rc = peerblk_decrypt_read ( peerblk, data, cipher_len ) ) != 0 ){
1157  DBGC ( peerblk, "PEERBLK %p %d.%d could not read ciphertext: "
1158  "%s\n", peerblk, peerblk->segment, peerblk->block,
1159  strerror ( rc ) );
1160  goto err_read;
1161  }
1162 
1163  /* Decrypt data */
1164  cipher_decrypt ( cipher, peerblk->cipherctx, data, data, cipher_len );
1165 
1166  /* Add data to digest */
1167  digest_update ( digest, peerblk->digestctx, data, digest_len );
1168 
1169  /* Write plaintext */
1170  if ( ( rc = peerblk_decrypt_write ( peerblk, data, cipher_len ) ) != 0){
1171  DBGC ( peerblk, "PEERBLK %p %d.%d could not write plaintext: "
1172  "%s\n", peerblk, peerblk->segment, peerblk->block,
1173  strerror ( rc ) );
1174  goto err_write;
1175  }
1176 
1177  /* Consume input */
1178  peerblk->cipher_remaining -= cipher_len;
1179  peerblk->digest_remaining -= digest_len;
1180 
1181  /* Free temporary data buffer */
1182  free ( data );
1183 
1184  /* Continue processing until all input is consumed */
1185  if ( peerblk->cipher_remaining )
1186  return;
1187 
1188  /* Complete download attempt */
1189  peerblk_done ( peerblk, 0 );
1190  return;
1191 
1192  err_write:
1193  err_read:
1194  free ( data );
1195  err_alloc_data:
1196  err_xfer_buffer:
1197  peerblk_done ( peerblk, rc );
1198 }
size_t blocksize
Block size.
Definition: crypto.h:54
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:177
size_t digest_remaining
Remaining digest length (excluding AES padding bytes)
Definition: peerblk.h:108
A data transfer buffer.
Definition: xferbuf.h:19
void * digestctx
Digest context (statically allocated at instantiation time)
Definition: peerblk.h:74
#define DBGC(...)
Definition: compiler.h:505
struct md4_digest digest
Digest of data already processed.
Definition: md4.h:12
struct cipher_algorithm * cipher
Cipher algorithm.
Definition: peerblk.h:77
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
struct digest_algorithm * digest
Digest algorithm.
Definition: peerblk.h:66
Data within the trimmed content.
Definition: peerblk.h:38
#define ENOMEM
Not enough space.
Definition: errno.h:534
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:1082
#define PEERBLK_DECRYPT_CHUNKSIZE
PeerDist decryption chunksize.
Definition: peerblk.c:49
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
unsigned int segment
Segment index.
Definition: peerblk.h:82
unsigned int block
Block index.
Definition: peerblk.h:88
struct interface xfer
Data transfer interface.
Definition: peerblk.h:50
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
void * cipherctx
Cipher context (dynamically allocated as needed)
Definition: peerblk.h:79
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
struct xfer_buffer * xferbuf
Data transfer buffer.
Definition: peerblk.h:26
struct xfer_buffer * xfer_buffer(struct interface *intf)
Get underlying data transfer buffer.
Definition: xferbuf.c:301
#define cipher_decrypt(cipher, ctx, src, dst, len)
Definition: crypto.h:212
static int peerblk_decrypt_read(struct peerdist_block *peerblk, void *data, size_t len)
Read from decryption buffers.
Definition: peerblk.c:1049
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
static void peerblk_done(struct peerdist_block *peerblk, int rc)
Finish PeerDist block download attempt.
Definition: peerblk.c:296
struct peerdist_block_decrypt decrypt[PEERBLK_NUM_BUFFERS]
Decryption data buffer descriptors.
Definition: peerblk.h:104
A message digest algorithm.
Definition: crypto.h:16
A cipher algorithm.
Definition: crypto.h:48
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
size_t cipher_remaining
Remaining decryption length.
Definition: peerblk.h:106

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, digest, 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 1206 of file peerblk.c.

1206  {
1207  size_t buf_len;
1208  size_t vrf_len;
1209 
1210  /* Restart interface */
1211  intf_restart ( &peerblk->retrieval, rc );
1212 
1213  /* Fail immediately if we have an error */
1214  if ( rc != 0 )
1215  goto done;
1216 
1217  /* Abort download attempt (for testing) if applicable */
1218  if ( ( rc = inject_fault ( PEERBLK_ABORT_RATE ) ) != 0 )
1219  goto done;
1220 
1221  /* Parse message header */
1222  if ( ( rc = peerblk_parse_header ( peerblk ) ) != 0 )
1223  goto done;
1224 
1225  /* Parse message segment and block details */
1226  if ( ( rc = peerblk_parse_block ( peerblk, &buf_len ) ) != 0 )
1227  goto done;
1228 
1229  /* If the block was plaintext, then there is nothing more to do */
1230  if ( ! peerblk->cipher )
1231  goto done;
1232 
1233  /* Parse message useless details */
1234  if ( ( rc = peerblk_parse_useless ( peerblk, buf_len, &vrf_len ) ) != 0)
1235  goto done;
1236 
1237  /* Parse message initialisation vector details */
1238  if ( ( rc = peerblk_parse_iv ( peerblk, buf_len, vrf_len ) ) != 0 )
1239  goto done;
1240 
1241  /* Fail if decryption length is not aligned to the cipher block size */
1242  if ( peerblk->cipher_remaining & ( peerblk->cipher->blocksize - 1 ) ) {
1243  DBGC ( peerblk, "PEERBLK %p %d.%d unaligned data length %zd\n",
1244  peerblk, peerblk->segment, peerblk->block,
1245  peerblk->cipher_remaining );
1246  rc = -EPROTO;
1247  goto done;
1248  }
1249 
1250  /* Stop the download attempt timer: there is no point in
1251  * timing out while decrypting.
1252  */
1253  stop_timer ( &peerblk->timer );
1254 
1255  /* Start decryption process */
1256  process_add ( &peerblk->process );
1257  return;
1258 
1259  done:
1260  /* Complete download attempt */
1261  peerblk_done ( peerblk, rc );
1262 }
size_t blocksize
Block size.
Definition: crypto.h:54
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:337
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:982
struct interface retrieval
Retrieval protocol interface.
Definition: peerblk.h:54
#define DBGC(...)
Definition: compiler.h:505
struct process process
Decryption process.
Definition: peerblk.h:102
struct cipher_algorithm * cipher
Cipher algorithm.
Definition: peerblk.h:77
#define PEERBLK_ABORT_RATE
Definition: fault.h:27
unsigned int segment
Segment index.
Definition: peerblk.h:82
unsigned int block
Block index.
Definition: peerblk.h:88
#define EPROTO
Protocol error.
Definition: errno.h:624
void process_add(struct process *process)
Add process to process list.
Definition: process.c:59
static int peerblk_parse_header(struct peerdist_block *peerblk)
Parse retrieval protocol message header.
Definition: peerblk.c:788
struct retry_timer timer
Retry timer.
Definition: peerblk.h:119
void stop_timer(struct retry_timer *timer)
Stop timer.
Definition: retry.c:117
static void peerblk_done(struct peerdist_block *peerblk, int rc)
Finish PeerDist block download attempt.
Definition: peerblk.c:296
static int peerblk_parse_block(struct peerdist_block *peerblk, size_t *buf_len)
Parse retrieval protocol message segment and block details.
Definition: peerblk.c:878
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:1011
size_t cipher_remaining
Remaining decryption length.
Definition: peerblk.h:106
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 1277 of file peerblk.c.

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

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 1358 of file peerblk.c.

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

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 1431 of file peerblk.c.

1432  {
1433  const struct peerdist_info_segment *segment = block->segment;
1434  const struct peerdist_info *info = segment->info;
1435  struct digest_algorithm *digest = info->digest;
1436  struct peerdist_block *peerblk;
1437  unsigned long timeout;
1438  size_t digestsize;
1439  int rc;
1440 
1441  /* Allocate and initialise structure */
1442  peerblk = zalloc ( sizeof ( *peerblk ) + digest->ctxsize );
1443  if ( ! peerblk ) {
1444  rc = -ENOMEM;
1445  goto err_alloc;
1446  }
1447  ref_init ( &peerblk->refcnt, peerblk_free );
1448  intf_init ( &peerblk->xfer, &peerblk_xfer_desc, &peerblk->refcnt );
1449  intf_init ( &peerblk->raw, &peerblk_raw_desc, &peerblk->refcnt );
1451  &peerblk->refcnt );
1452  peerblk->uri = uri_get ( uri );
1453  memcpy ( &peerblk->range, &block->range, sizeof ( peerblk->range ) );
1454  memcpy ( &peerblk->trim, &block->trim, sizeof ( peerblk->trim ) );
1455  peerblk->offset = ( block->trim.start - info->trim.start );
1456  peerblk->digest = info->digest;
1457  peerblk->digestsize = digestsize = info->digestsize;
1458  peerblk->digestctx = ( ( ( void * ) peerblk ) + sizeof ( *peerblk ) );
1459  peerblk->segment = segment->index;
1460  memcpy ( peerblk->id, segment->id, sizeof ( peerblk->id ) );
1461  memcpy ( peerblk->secret, segment->secret, sizeof ( peerblk->secret ) );
1462  peerblk->block = block->index;
1463  memcpy ( peerblk->hash, block->hash, sizeof ( peerblk->hash ) );
1464  xferbuf_malloc_init ( &peerblk->buffer );
1466  &peerblk->refcnt );
1468  INIT_LIST_HEAD ( &peerblk->queued );
1469  timer_init ( &peerblk->timer, peerblk_expired, &peerblk->refcnt );
1470  DBGC2 ( peerblk, "PEERBLK %p %d.%d id %02x%02x%02x%02x%02x..."
1471  "%02x%02x%02x [%08zx,%08zx)", peerblk, peerblk->segment,
1472  peerblk->block, peerblk->id[0], peerblk->id[1], peerblk->id[2],
1473  peerblk->id[3], peerblk->id[4], peerblk->id[ digestsize - 3 ],
1474  peerblk->id[ digestsize - 2 ], peerblk->id[ digestsize - 1 ],
1475  peerblk->range.start, peerblk->range.end );
1476  if ( ( peerblk->trim.start != peerblk->range.start ) ||
1477  ( peerblk->trim.end != peerblk->range.end ) ) {
1478  DBGC2 ( peerblk, " covers [%08zx,%08zx)",
1479  peerblk->trim.start, peerblk->trim.end );
1480  }
1481  DBGC2 ( peerblk, "\n" );
1482 
1483  /* Open discovery */
1484  if ( ( rc = peerdisc_open ( &peerblk->discovery, peerblk->id,
1485  peerblk->digestsize ) ) != 0 )
1486  goto err_open_discovery;
1487 
1488  /* Schedule a retry attempt either immediately (if we already
1489  * have some peers) or after the discovery timeout.
1490  */
1491  timeout = ( list_empty ( &peerblk->discovery.segment->peers ) ?
1493  start_timer_fixed ( &peerblk->timer, timeout );
1494 
1495  /* Record start time */
1496  peerblk->started = peerblk_timestamp();
1497 
1498  /* Attach to parent interface, mortalise self, and return */
1499  intf_plug_plug ( xfer, &peerblk->xfer );
1500  ref_put ( &peerblk->refcnt );
1501  return 0;
1502 
1503  err_open_discovery:
1504  peerblk_close ( peerblk, rc );
1505  err_alloc:
1506  return rc;
1507 }
struct list_head peers
List of discovered peers.
Definition: peerdisc.h:63
uint16_t segment
Code segment.
Definition: librm.h:252
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define TICKS_PER_SEC
Number of ticks per second.
Definition: timer.h:15
u32 info
Definition: ar9003_mac.h:67
A content information segment.
Definition: pccrc.h:347
struct xfer_buffer buffer
Data buffer.
Definition: peerblk.h:99
static struct uri * uri_get(struct uri *uri)
Increment URI reference count.
Definition: uri.h:177
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
size_t start
Start offset.
Definition: pccrc.h:311
uint16_t block
Definition: tftp.h:12
struct interface retrieval
Retrieval protocol interface.
Definition: peerblk.h:54
void * digestctx
Digest context (statically allocated at instantiation time)
Definition: peerblk.h:74
size_t offset
Offset of first byte in trimmed range within overall download.
Definition: peerblk.h:63
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition: interface.c:102
static void peerdisc_init(struct peerdisc_client *peerdisc, struct peerdisc_client_operations *op)
Initialise PeerDist discovery.
Definition: peerdisc.h:104
static struct process_descriptor peerblk_process_desc
PeerDist block download decryption process descriptor.
Definition: peerblk.c:1415
struct peerdisc_client discovery
Discovery client.
Definition: peerblk.h:111
struct process process
Decryption process.
Definition: peerblk.h:102
struct md4_digest digest
Digest of data already processed.
Definition: md4.h:12
static unsigned long peerblk_timestamp(void)
Get profiling timestamp.
Definition: peerblk.c:137
struct digest_algorithm * digest
Digest algorithm.
Definition: peerblk.h:66
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:136
struct uri * uri
Original URI.
Definition: peerblk.h:57
struct peerdist_range range
Content range of this block.
Definition: peerblk.h:59
#define ENOMEM
Not enough space.
Definition: errno.h:534
void * memcpy(void *dest, const void *src, size_t len) __nonnull
A PeerDist block download.
Definition: peerblk.h:46
int peerdisc_open(struct peerdisc_client *peerdisc, const void *id, size_t len)
Open PeerDist discovery client.
Definition: peerdisc.c:536
static void peerblk_expired(struct retry_timer *timer, int over __unused)
Handle PeerDist retry timer expiry.
Definition: peerblk.c:1277
unsigned int segment
Segment index.
Definition: peerblk.h:82
struct interface raw
Raw data interface.
Definition: peerblk.h:52
unsigned int block
Block index.
Definition: peerblk.h:88
uint8_t id[PEERDIST_DIGEST_MAX_SIZE]
Segment identifier.
Definition: peerblk.h:84
struct interface xfer
Data transfer interface.
Definition: peerblk.h:50
uint8_t hash[PEERDIST_DIGEST_MAX_SIZE]
Block hash.
Definition: peerblk.h:90
Content information.
Definition: pccrc.h:317
static struct peerdisc_client_operations peerblk_discovery_operations
PeerDist block download discovery operations.
Definition: peerblk.c:1419
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
static void peerblk_free(struct refcnt *refcnt)
Free PeerDist block download.
Definition: peerblk.c:151
size_t digestsize
Digest size.
Definition: peerblk.h:72
unsigned long started
Time at which block download was started.
Definition: peerblk.h:126
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:145
struct list_head queued
List of queued block downloads.
Definition: peerblk.h:117
static struct interface_descriptor peerblk_retrieval_desc
PeerDist block download retrieval protocol interface descriptor.
Definition: peerblk.c:1410
struct peerdisc_segment * segment
Discovery segment.
Definition: peerdisc.h:81
struct refcnt refcnt
Reference count.
Definition: peerblk.h:48
void start_timer_fixed(struct retry_timer *timer, unsigned long timeout)
Start timer with a specified timeout.
Definition: retry.c:64
struct retry_timer timer
Retry timer.
Definition: peerblk.h:119
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:45
static void peerblk_close(struct peerdist_block *peerblk, int rc)
Close PeerDist block download.
Definition: peerblk.c:204
#define DBGC2(...)
Definition: compiler.h:522
uint8_t secret[PEERDIST_DIGEST_MAX_SIZE]
Segment secret.
Definition: peerblk.h:86
A message digest algorithm.
Definition: crypto.h:16
struct peerdist_range trim
Trimmed range of this block.
Definition: peerblk.h:61
static struct interface_descriptor peerblk_raw_desc
PeerDist block download raw data interface descriptor.
Definition: peerblk.c:1400
A Uniform Resource Identifier.
Definition: uri.h:50
void timeout(int)
static struct interface_descriptor peerblk_xfer_desc
PeerDist block download data transfer interface descriptor.
Definition: peerblk.c:1390
uint32_t digestsize
Digest size (i.e.
Definition: pccrr.h:14
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition: interface.h:173
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106
size_t end
End offset.
Definition: pccrc.h:313
unsigned int peerdisc_timeout_secs
Recommended discovery timeout (in seconds)
Definition: peerdisc.c:74

References block, peerdist_block::block, peerdist_block::buffer, DBGC2, digest, 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, 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 106 of file peerblk.c.

◆ peerblk_queue_desc

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

PeerDist block download queue process descriptor.

Definition at line 559 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:559
struct list_head list
List of queued downloads.
Definition: peerblk.h:136
#define PROC_INIT(_process, _desc)
Initialise a static process.
Definition: process.h:131
struct process process
Download opening process.
Definition: peerblk.h:134
static struct peerdist_block_queue peerblk_raw_queue
Raw block download queue.
Definition: peerblk.c:563
static int peerblk_raw_open(struct peerdist_block *peerblk)
Open PeerDist raw block download attempt.
Definition: peerblk.c:358
#define PEERBLK_RAW_MAX
PeerDist maximum number of concurrent raw block downloads.
Definition: peerblk.c:68
#define LIST_HEAD_INIT(list)
Initialise a static list head.
Definition: list.h:30

Raw block download queue.

Definition at line 563 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:244
A PeerDist block download.
Definition: peerblk.h:46
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:32
static void peerblk_close(struct peerdist_block *peerblk, int rc)
Close PeerDist block download.
Definition: peerblk.c:204

PeerDist block download data transfer interface operations.

Definition at line 1385 of file peerblk.c.

◆ peerblk_xfer_desc

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

PeerDist block download data transfer interface descriptor.

Definition at line 1390 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:244
A PeerDist block download.
Definition: peerblk.h:46
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:32
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition: xfer.c:193
static int peerblk_raw_rx(struct peerdist_block *peerblk, struct io_buffer *iobuf, struct xfer_metadata *meta)
Receive PeerDist raw data.
Definition: peerblk.c:401
static void peerblk_raw_close(struct peerdist_block *peerblk, int rc)
Close PeerDist raw block download attempt.
Definition: peerblk.c:449

PeerDist block download raw data interface operations.

Definition at line 1394 of file peerblk.c.

◆ peerblk_raw_desc

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

PeerDist block download raw data interface descriptor.

Definition at line 1400 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:244
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:675
A PeerDist block download.
Definition: peerblk.h:46
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:32
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition: xfer.c:193
static void peerblk_retrieval_close(struct peerdist_block *peerblk, int rc)
Close PeerDist retrieval protocol block download attempt.
Definition: peerblk.c:1206

PeerDist block download retrieval protocol interface operations.

Definition at line 1404 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:54
A PeerDist block download.
Definition: peerblk.h:46
static struct interface_operation peerblk_retrieval_operations[]
PeerDist block download retrieval protocol interface operations.
Definition: peerblk.c:1404
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:65

PeerDist block download retrieval protocol interface descriptor.

Definition at line 1410 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:17
static void peerblk_decrypt(struct peerdist_block *peerblk)
Decrypt one chunk of PeerDist retrieval protocol data.
Definition: peerblk.c:1116
A PeerDist block download.
Definition: peerblk.h:46
#define PROC_DESC(object_type, process, _step)
Define a process descriptor.
Definition: process.h:82

PeerDist block download decryption process descriptor.

Definition at line 1415 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:1358

PeerDist block download discovery operations.

Definition at line 1419 of file peerblk.c.

Referenced by peerblk_open().