iPXE
Macros | Functions | Variables
peerblk.c File Reference

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

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

Go to the source code of this file.

Macros

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

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
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 50 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 69 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 75 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 81 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 87 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 93 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 104 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 537 of file peerblk.c.

537  {
538  struct peerdist_block_queue *queue = peerblk->queue;
539 
540  /* Sanity checks */
541  assert ( queue != NULL );
542 
543  /* Remove block from queue */
544  peerblk->queue = NULL;
545  if ( list_empty ( &peerblk->queued ) ) {
546 
547  /* Open download: decrement count and reschedule queue */
548  queue->count--;
549  process_add ( &queue->process );
550 
551  } else {
552 
553  /* Queued download: remove from queue */
554  list_del ( &peerblk->queued );
555  INIT_LIST_HEAD ( &peerblk->queued );
556  }
557 }
#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:321

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

138  {
139 
140  if ( PROFILING ) {
141  return currticks();
142  } else {
143  return 0;
144  }
145 }
#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 152 of file peerblk.c.

152  {
153  struct peerdist_block *peerblk =
155 
156  uri_put ( peerblk->uri );
157  free ( peerblk->cipherctx );
158  free ( peerblk );
159 }
static void uri_put(struct uri *uri)
Decrement URI reference count.
Definition: uri.h:205
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 167 of file peerblk.c.

167  {
168 
169  /* Stop decryption process */
170  process_del ( &peerblk->process );
171 
172  /* Stop timer */
173  stop_timer ( &peerblk->timer );
174 
175  /* Abort any current download attempt */
176  intf_restart ( &peerblk->raw, rc );
177  intf_restart ( &peerblk->retrieval, rc );
178 
179  /* Remove from download queue, if applicable */
180  if ( peerblk->queue )
181  peerblk_dequeue ( peerblk );
182 
183  /* Empty received data buffer */
184  xferbuf_free ( &peerblk->buffer );
185  peerblk->pos = 0;
186 
187  /* Reset digest and free cipher context */
188  digest_init ( peerblk->digest, peerblk->digestctx );
189  free ( peerblk->cipherctx );
190  peerblk->cipherctx = NULL;
191  peerblk->cipher = NULL;
192 
193  /* Reset trim thresholds */
194  peerblk->start = ( peerblk->trim.start - peerblk->range.start );
195  peerblk->end = ( peerblk->trim.end - peerblk->range.start );
196  assert ( peerblk->start <= peerblk->end );
197 }
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:343
struct xfer_buffer buffer
Data buffer.
Definition: peerblk.h:99
size_t start
Start offset.
Definition: pccrc.h:310
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:73
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:537
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:196
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:321
size_t pos
Current position (relative to incoming data stream)
Definition: peerblk.h:93
size_t end
End offset.
Definition: pccrc.h:312

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

205  {
206  unsigned long now = peerblk_timestamp();
207 
208  /* Profile overall block download */
209  profile_custom ( &peerblk_download_profiler,
210  ( now - peerblk->started ) );
211 
212  /* Reset download attempt */
213  peerblk_reset ( peerblk, rc );
214 
215  /* Close discovery */
216  peerdisc_close ( &peerblk->discovery );
217 
218  /* Shut down all interfaces */
219  intf_shutdown ( &peerblk->retrieval, rc );
220  intf_shutdown ( &peerblk->raw, rc );
221  intf_shutdown ( &peerblk->xfer, rc );
222 }
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:278
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:200
struct peerdisc_client discovery
Discovery client.
Definition: peerblk.h:111
static unsigned long peerblk_timestamp(void)
Get profiling timestamp.
Definition: peerblk.c:138
static void peerblk_reset(struct peerdist_block *peerblk, int rc)
Reset PeerDist block download attempt.
Definition: peerblk.c:167
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:597

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

232  {
233 
234  return ( ( pos - peerblk->start ) + peerblk->offset );
235 }
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 246 of file peerblk.c.

248  {
249  struct xfer_metadata xfer_meta;
250  size_t len = iob_len ( iobuf );
251  size_t start = pos;
252  size_t end = ( pos + len );
253  int rc;
254 
255  /* Discard zero-length packets and packets which lie entirely
256  * outside the trimmed range.
257  */
258  if ( ( start >= peerblk->end ) || ( end <= peerblk->start ) ||
259  ( len == 0 ) ) {
260  free_iob ( iobuf );
261  return 0;
262  }
263 
264  /* Truncate data to within trimmed range */
265  if ( start < peerblk->start ) {
266  iob_pull ( iobuf, ( peerblk->start - start ) );
267  start = peerblk->start;
268  }
269  if ( end > peerblk->end ) {
270  iob_unput ( iobuf, ( end - peerblk->end ) );
271  end = peerblk->end;
272  }
273 
274  /* Construct metadata */
275  memcpy ( &xfer_meta, meta, sizeof ( xfer_meta ) );
276  xfer_meta.flags |= XFER_FL_ABS_OFFSET;
277  xfer_meta.offset = peerblk_offset ( peerblk, start );
278 
279  /* Deliver data */
280  if ( ( rc = xfer_deliver ( &peerblk->xfer, iob_disown ( iobuf ),
281  &xfer_meta ) ) != 0 ) {
282  DBGC ( peerblk, "PEERBLK %p %d.%d could not deliver data: %s\n",
283  peerblk, peerblk->segment, peerblk->block,
284  strerror ( rc ) );
285  return rc;
286  }
287 
288  return 0;
289 }
#define iob_pull(iobuf, len)
Definition: iobuf.h:106
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:232
#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:152
#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:216
void * memcpy(void *dest, const void *src, size_t len) __nonnull
ring len
Length.
Definition: dwmac.h:231
unsigned int segment
Segment index.
Definition: peerblk.h:82
unsigned int block
Block index.
Definition: peerblk.h:88
struct interface xfer
Data transfer interface.
Definition: peerblk.h:50
#define iob_unput(iobuf, len)
Definition: iobuf.h:139
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:159
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition: xfer.c:194
size_t start
Start of trimmed content (relative to incoming data stream)
Definition: peerblk.h:95
uint32_t end
Ending offset.
Definition: netvsc.h:18
uint8_t meta
Metadata flags.
Definition: ena.h:14

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

Referenced by peerblk_raw_rx(), and peerblk_retrieval_rx().

◆ peerblk_done()

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

Finish PeerDist block download attempt.

Parameters
peerblkPeerDist block download
rcReason for close

Definition at line 297 of file peerblk.c.

297  {
298  struct digest_algorithm *digest = peerblk->digest;
299  struct peerdisc_segment *segment = peerblk->discovery.segment;
300  struct peerdisc_peer *head;
301  struct peerdisc_peer *peer;
302  uint8_t hash[digest->digestsize];
303  unsigned long now = peerblk_timestamp();
304 
305  /* Check for errors on completion */
306  if ( rc != 0 ) {
307  DBGC ( peerblk, "PEERBLK %p %d.%d attempt failed: %s\n",
308  peerblk, peerblk->segment, peerblk->block,
309  strerror ( rc ) );
310  goto err;
311  }
312 
313  /* Check digest */
314  digest_final ( digest, peerblk->digestctx, hash );
315  if ( memcmp ( hash, peerblk->hash, peerblk->digestsize ) != 0 ) {
316  DBGC ( peerblk, "PEERBLK %p %d.%d digest mismatch:\n",
317  peerblk, peerblk->segment, peerblk->block );
318  DBGC_HDA ( peerblk, 0, hash, peerblk->digestsize );
319  DBGC_HDA ( peerblk, 0, peerblk->hash, peerblk->digestsize );
320  rc = -EIO;
321  goto err;
322  }
323 
324  /* Profile successful attempt */
325  profile_custom ( &peerblk_attempt_success_profiler,
326  ( now - peerblk->attempted ) );
327 
328  /* Report peer statistics */
329  head = list_entry ( &segment->peers, struct peerdisc_peer, list );
330  peer = ( ( peerblk->peer == head ) ? NULL : peerblk->peer );
331  peerdisc_stat ( &peerblk->xfer, peer, &segment->peers );
332 
333  /* Close download */
334  peerblk_close ( peerblk, 0 );
335  return;
336 
337  err:
338  /* Record failure reason and schedule a retry attempt */
339  profile_custom ( &peerblk_attempt_failure_profiler,
340  ( now - peerblk->attempted ) );
341  peerblk_reset ( peerblk, rc );
342  peerblk->rc = rc;
343  start_timer_nodelay ( &peerblk->timer );
344 }
uint16_t segment
Code segment.
Definition: librm.h:138
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
pseudo_bit_t hash[0x00010]
Definition: arbel.h:13
static void start_timer_nodelay(struct retry_timer *timer)
Start timer with no delay.
Definition: retry.h:99
static void digest_final(struct digest_algorithm *digest, void *ctx, void *out)
Definition: crypto.h:207
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:200
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:138
static void peerblk_reset(struct peerdist_block *peerblk, int rc)
Reset PeerDist block download attempt.
Definition: peerblk.c:167
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:100
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
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:205
size_t digestsize
Digest size.
Definition: crypto.h:26
#define EIO
Input/output error.
Definition: errno.h:433
A message digest algorithm.
Definition: crypto.h:18
struct mschapv2_challenge peer
Peer challenge.
Definition: mschapv2.h:12
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:114
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
A PeerDist discovery peer.
Definition: peerdisc.h:71

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

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

◆ peerblk_raw_open()

static int peerblk_raw_open ( struct peerdist_block peerblk)
static

Open PeerDist raw block download attempt.

Parameters
peerblkPeerDist block download
Return values
rcReturn status code

Definition at line 359 of file peerblk.c.

359  {
360  struct http_request_range range;
361  int rc;
362 
363  DBGC2 ( peerblk, "PEERBLK %p %d.%d attempting raw range request\n",
364  peerblk, peerblk->segment, peerblk->block );
365 
366  /* Construct HTTP range */
367  memset ( &range, 0, sizeof ( range ) );
368  range.start = peerblk->range.start;
369  range.len = ( peerblk->range.end - peerblk->range.start );
370 
371  /* Initiate range request to retrieve block */
372  if ( ( rc = http_open ( &peerblk->raw, &http_get, peerblk->uri,
373  &range, NULL ) ) != 0 ) {
374  DBGC ( peerblk, "PEERBLK %p %d.%d could not create range "
375  "request: %s\n", peerblk, peerblk->segment,
376  peerblk->block, strerror ( rc ) );
377  return rc;
378  }
379 
380  /* Annul HTTP connection (for testing) if applicable. Do not
381  * report as an immediate error, in order to test our ability
382  * to recover from a totally unresponsive HTTP server.
383  */
384  if ( inject_fault ( PEERBLK_ANNUL_RATE ) )
385  intf_restart ( &peerblk->raw, 0 );
386 
387  /* Start download attempt timer */
388  peerblk->rc = -ETIMEDOUT;
390 
391  return 0;
392 }
uint32_t start
Starting bus:dev.fn address.
Definition: pci_io.h:24
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:343
struct pci_range range
PCI bus:dev.fn address range.
Definition: pcicloud.c:40
#define PEERBLK_RAW_OPEN_TIMEOUT
PeerDist raw block download attempt initial progress timeout.
Definition: peerblk.c:75
HTTP request range descriptor.
Definition: http.h:135
size_t start
Start offset.
Definition: pccrc.h:310
#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:143
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:641
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
#define ETIMEDOUT
Connection timed out.
Definition: errno.h:669
size_t end
End offset.
Definition: pccrc.h:312
void * memset(void *dest, int character, size_t len) __nonnull

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

◆ peerblk_raw_rx()

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

Receive PeerDist raw data.

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

Definition at line 402 of file peerblk.c.

404  {
405  size_t len = iob_len ( iobuf );
406  size_t pos = peerblk->pos;
407  size_t mid = ( ( peerblk->range.end - peerblk->range.start ) / 2 );
408  int rc;
409 
410  /* Corrupt received data (for testing) if applicable */
411  inject_corruption ( PEERBLK_CORRUPT_RATE, iobuf->data, len );
412 
413  /* Fail if data is delivered out of order, since the streaming
414  * digest requires strict ordering.
415  */
416  if ( ( rc = xfer_check_order ( meta, &peerblk->pos, len ) ) != 0 )
417  goto err;
418 
419  /* Add data to digest */
420  digest_update ( peerblk->digest, peerblk->digestctx, iobuf->data, len );
421 
422  /* Deliver data */
423  if ( ( rc = peerblk_deliver ( peerblk, iob_disown ( iobuf ), meta,
424  pos ) ) != 0 )
425  goto err;
426 
427  /* Extend download attempt timer */
429 
430  /* Stall download attempt (for testing) if applicable */
431  if ( ( pos < mid ) && ( ( pos + len ) >= mid ) &&
432  ( ( rc = inject_fault ( PEERBLK_STALL_RATE ) ) != 0 ) ) {
433  intf_restart ( &peerblk->raw, rc );
434  }
435 
436  return 0;
437 
438  err:
439  free_iob ( iobuf );
440  peerblk_done ( peerblk, rc );
441  return rc;
442 }
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:201
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition: interface.c:343
uint16_t mid
Middle 16 bits of address.
Definition: librm.h:144
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:152
size_t start
Start offset.
Definition: pccrc.h:310
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:246
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:377
#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:216
#define PEERBLK_RAW_RX_TIMEOUT
PeerDist raw block download attempt ongoing progress timeout.
Definition: peerblk.c:81
ring len
Length.
Definition: dwmac.h:231
struct interface raw
Raw data interface.
Definition: peerblk.h:52
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:159
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:297
void * data
Start of data.
Definition: iobuf.h:52
#define PEERBLK_CORRUPT_RATE
Definition: fault.h:30
uint8_t meta
Metadata flags.
Definition: ena.h:14
size_t pos
Current position (relative to incoming data stream)
Definition: peerblk.h:93
size_t end
End offset.
Definition: pccrc.h:312

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

450  {
451 
452  /* Restart interface */
453  intf_restart ( &peerblk->raw, rc );
454 
455  /* Fail immediately if we have an error */
456  if ( rc != 0 )
457  goto done;
458 
459  /* Abort download attempt (for testing) if applicable */
460  if ( ( rc = inject_fault ( PEERBLK_ABORT_RATE ) ) != 0 )
461  goto done;
462 
463  done:
464  /* Complete download attempt */
465  peerblk_done ( peerblk, rc );
466 }
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:343
#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:297
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 480 of file peerblk.c.

480  {
481  struct peerdist_block *peerblk;
482  int rc;
483 
484  /* Do nothing yet if we have too many open block downloads */
485  if ( queue->count >= queue->max )
486  return;
487 
488  /* Do nothing unless there are queued block downloads */
489  peerblk = list_first_entry ( &queue->list, struct peerdist_block,
490  queued );
491  if ( ! peerblk )
492  return;
493 
494  /* Reschedule queue process */
495  process_add ( &queue->process );
496 
497  /* Remove block from queue */
498  list_del ( &peerblk->queued );
499  INIT_LIST_HEAD ( &peerblk->queued );
500 
501  /* Attempt download */
502  if ( ( rc = queue->open ( peerblk ) ) != 0 ) {
503  peerblk_close ( peerblk, rc );
504  return;
505  }
506 
507  /* Increment open block download count */
508  queue->count++;
509 }
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:205
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 517 of file peerblk.c.

518  {
519 
520  /* Sanity checks */
521  assert ( peerblk->queue == NULL );
522  assert ( list_empty ( &peerblk->queued ) );
523 
524  /* Add block to queue */
525  peerblk->queue = queue;
526  list_add_tail ( &peerblk->queued, &queue->list );
527 
528  /* Schedule queue process */
529  process_add ( &queue->process );
530 }
#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:321

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

584  {
585  char uri_string[ 7 /* "http://" */ + strlen ( location ) +
586  sizeof ( PEERDIST_MAGIC_PATH /* includes NUL */ ) ];
587 
588  /* Construct URI string */
589  snprintf ( uri_string, sizeof ( uri_string ),
590  ( "http://%s" PEERDIST_MAGIC_PATH ), location );
591 
592  /* Parse URI string */
593  return parse_uri ( uri_string );
594 }
#define PEERDIST_MAGIC_PATH
Magic retrieval URI path.
Definition: pccrr.h:17
size_t strlen(const char *src)
Get length of string.
Definition: string.c:243
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:296

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

604  {
605  size_t digestsize = peerblk->digestsize;
606  peerdist_msg_getblks_t ( digestsize, 1, 0 ) req;
607  peerblk_msg_blk_t ( digestsize, 0, 0, 0 ) *rsp;
608  struct http_request_content content;
609  struct uri *uri;
610  int rc;
611 
612  DBGC2 ( peerblk, "PEERBLK %p %d.%d attempting retrieval from %s\n",
613  peerblk, peerblk->segment, peerblk->block, location );
614 
615  /* Construct block fetch request */
616  memset ( &req, 0, sizeof ( req ) );
618  req.getblks.hdr.type = htonl ( PEERDIST_MSG_GETBLKS_TYPE );
619  req.getblks.hdr.len = htonl ( sizeof ( req ) );
620  req.getblks.hdr.algorithm = htonl ( PEERDIST_MSG_AES_128_CBC );
622  memcpy ( req.segment.id, peerblk->id, digestsize );
623  req.ranges.ranges.count = htonl ( 1 );
624  req.ranges.range[0].first = htonl ( peerblk->block );
625  req.ranges.range[0].count = htonl ( 1 );
626 
627  /* Construct POST request content */
628  memset ( &content, 0, sizeof ( content ) );
629  content.data = &req;
630  content.len = sizeof ( req );
631 
632  /* Construct URI */
633  if ( ( uri = peerblk_retrieval_uri ( location ) ) == NULL ) {
634  rc = -ENOMEM;
635  goto err_uri;
636  }
637 
638  /* Update trim thresholds */
639  peerblk->start += offsetof ( typeof ( *rsp ), msg.vrf );
640  peerblk->end += offsetof ( typeof ( *rsp ), msg.vrf );
641 
642  /* Initiate HTTP POST to retrieve block */
643  if ( ( rc = http_open ( &peerblk->retrieval, &http_post, uri,
644  NULL, &content ) ) != 0 ) {
645  DBGC ( peerblk, "PEERBLK %p %d.%d could not create retrieval "
646  "request: %s\n", peerblk, peerblk->segment,
647  peerblk->block, strerror ( rc ) );
648  goto err_open;
649  }
650 
651  /* Annul HTTP connection (for testing) if applicable. Do not
652  * report as an immediate error, in order to test our ability
653  * to recover from a totally unresponsive HTTP server.
654  */
655  if ( inject_fault ( PEERBLK_ANNUL_RATE ) )
656  intf_restart ( &peerblk->retrieval, 0 );
657 
658  /* Start download attempt timer */
659  peerblk->rc = -ETIMEDOUT;
661 
662  err_open:
663  uri_put ( uri );
664  err_uri:
665  return rc;
666 }
AES-128 in CBC mode.
Definition: pccrr.h:171
static struct uri * peerblk_retrieval_uri(const char *location)
Construct PeerDist retrieval protocol URI.
Definition: peerblk.c:584
uint16_t segment
Code segment.
Definition: librm.h:138
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition: interface.c:343
struct pci_range range
PCI bus:dev.fn address range.
Definition: pcicloud.c:40
static void uri_put(struct uri *uri)
Decrement URI reference count.
Definition: uri.h:205
void msg(unsigned int row, const char *fmt,...)
Print message centred on specified row.
Definition: message.c:61
uint32_t first
First block in range.
Definition: pccrr.h:14
struct golan_inbox_hdr hdr
Message header.
Definition: CIB_PRM.h:28
#define PEERBLK_RETRIEVAL_OPEN_TIMEOUT
PeerDist retrieval protocol block download attempt initial progress timeout.
Definition: peerblk.c:87
uint32_t type
Operating system type.
Definition: ena.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
void * memcpy(void *dest, const void *src, size_t len) __nonnull
u32 version
Driver version.
Definition: ath9k_hw.c:1983
#define PEERDIST_MSG_GETBLKS_TYPE
Retrieval protocol block fetch request type.
Definition: pccrr.h:277
ring len
Length.
Definition: dwmac.h:231
unsigned int segment
Segment index.
Definition: peerblk.h:82
static unsigned int count
Number of entries.
Definition: dwmac.h:225
unsigned int block
Block index.
Definition: peerblk.h:88
HTTP request content descriptor.
Definition: http.h:143
uint64_t rsp
Definition: librm.h:153
#define PEERDIST_MSG_GETBLKS_VERSION
Retrieval protocol block fetch request version.
Definition: pccrr.h:274
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
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
#define DBGC2(...)
Definition: compiler.h:522
uint8_t block[3][8]
DES-encrypted blocks.
Definition: mschapv2.h:12
int http_open(struct interface *xfer, struct http_method *method, struct uri *uri, struct http_request_range *range, struct http_request_content *content)
Open HTTP transaction.
Definition: httpcore.c:641
uint8_t data[48]
Additional event data.
Definition: ena.h:22
__be32 raw[7]
Definition: CIB_PRM.h:28
A Uniform Resource Identifier.
Definition: uri.h:64
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:47
uint32_t digestsize
Digest size (i.e.
Definition: pccrr.h:14
#define peerdist_msg_getblks_t(digestsize, count, vrf_len)
Retrieval protocol block fetch request.
Definition: pccrr.h:265
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
#define ETIMEDOUT
Connection timed out.
Definition: errno.h:669
struct http_method http_post
HTTP POST method.
Definition: httpcore.c:148
if(natsemi->flags &NATSEMI_64BIT) return 1
void * memset(void *dest, int character, size_t len) __nonnull

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

Referenced by peerblk_expired().

◆ peerblk_retrieval_rx()

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

Receive PeerDist retrieval protocol data.

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

Definition at line 676 of file peerblk.c.

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

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

◆ peerblk_parse_header()

static int peerblk_parse_header ( struct peerdist_block peerblk)
static

Parse retrieval protocol message header.

Parameters
peerblkPeerDist block download
Return values
rcReturn status code

Definition at line 789 of file peerblk.c.

789  {
790  struct {
792  struct peerdist_msg_header msg;
793  } __attribute__ (( packed )) *msg = peerblk->buffer.data;
794  struct cipher_algorithm *cipher;
795  size_t len = peerblk->buffer.len;
796  size_t keylen = 0;
797  int rc;
798 
799  /* Check message length */
800  if ( len < sizeof ( *msg ) ) {
801  DBGC ( peerblk, "PEERBLK %p %d.%d message too short for header "
802  "(%zd bytes)\n", peerblk, peerblk->segment,
803  peerblk->block, len );
804  return -ERANGE;
805  }
806 
807  /* Check message type */
808  if ( msg->msg.type != htonl ( PEERDIST_MSG_BLK_TYPE ) ) {
809  DBGC ( peerblk, "PEERBLK %p %d.%d unexpected message type "
810  "%#08x\n", peerblk, peerblk->segment, peerblk->block,
811  ntohl ( msg->msg.type ) );
812  return -EPROTO;
813  }
814 
815  /* Determine cipher algorithm and key length */
816  cipher = &aes_cbc_algorithm;
817  switch ( msg->msg.algorithm ) {
818  case htonl ( PEERDIST_MSG_PLAINTEXT ) :
819  cipher = NULL;
820  break;
822  keylen = ( 128 / 8 );
823  break;
825  keylen = ( 192 / 8 );
826  break;
828  keylen = ( 256 / 8 );
829  break;
830  default:
831  DBGC ( peerblk, "PEERBLK %p %d.%d unrecognised algorithm "
832  "%#08x\n", peerblk, peerblk->segment, peerblk->block,
833  ntohl ( msg->msg.algorithm ) );
834  return -ENOTSUP;
835  }
836  DBGC2 ( peerblk, "PEERBLK %p %d.%d using %s with %zd-bit key\n",
837  peerblk, peerblk->segment, peerblk->block,
838  ( cipher ? cipher->name : "plaintext" ), ( 8 * keylen ) );
839 
840  /* Sanity check key length against maximum secret length */
841  if ( keylen > peerblk->digestsize ) {
842  DBGC ( peerblk, "PEERBLK %p %d.%d %zd-byte secret too short "
843  "for %zd-bit key\n", peerblk, peerblk->segment,
844  peerblk->block, peerblk->digestsize, ( 8 * keylen ) );
845  return -EPROTO;
846  }
847 
848  /* Allocate cipher context, if applicable. Freeing the cipher
849  * context (on error or otherwise) is handled by peerblk_reset().
850  */
851  peerblk->cipher = cipher;
852  assert ( peerblk->cipherctx == NULL );
853  if ( cipher ) {
854  peerblk->cipherctx = malloc ( cipher->ctxsize );
855  if ( ! peerblk->cipherctx )
856  return -ENOMEM;
857  }
858 
859  /* Initialise cipher, if applicable */
860  if ( cipher &&
861  ( rc = cipher_setkey ( cipher, peerblk->cipherctx, peerblk->secret,
862  keylen ) ) != 0 ) {
863  DBGC ( peerblk, "PEERBLK %p %d.%d could not set key: %s\n",
864  peerblk, peerblk->segment, peerblk->block,
865  strerror ( rc ) );
866  return rc;
867  }
868 
869  return 0;
870 }
void * data
Data.
Definition: xferbuf.h:20
#define __attribute__(x)
Definition: compiler.h:10
AES-128 in CBC mode.
Definition: pccrr.h:171
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct xfer_buffer buffer
Data buffer.
Definition: peerblk.h:99
void msg(unsigned int row, const char *fmt,...)
Print message centred on specified row.
Definition: message.c:61
struct golan_inbox_hdr hdr
Message header.
Definition: CIB_PRM.h:28
#define PEERDIST_MSG_BLK_TYPE
Retrieval protocol block fetch response type.
Definition: pccrr.h:350
#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:22
#define ENOMEM
Not enough space.
Definition: errno.h:534
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
ring len
Length.
Definition: dwmac.h:231
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:179
No encryption.
Definition: pccrr.h:169
#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:173
size_t digestsize
Digest size.
Definition: peerblk.h:72
size_t ctxsize
Context size.
Definition: crypto.h:54
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:620
Retrieval protocol message header.
Definition: pccrr.h:151
struct cipher_algorithm aes_cbc_algorithm
#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:50
AES-256 in CBC mode.
Definition: pccrr.h:175
const char * name
Algorithm name.
Definition: crypto.h:52
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
static int cipher_setkey(struct cipher_algorithm *cipher, void *ctx, const void *key, size_t keylen)
Definition: crypto.h:212

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

Referenced by peerblk_retrieval_close().

◆ peerblk_parse_block()

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

Parse retrieval protocol message segment and block details.

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

Definition at line 879 of file peerblk.c.

880  {
881  size_t digestsize = peerblk->digestsize;
882  peerblk_msg_blk_t ( digestsize, 0, 0, 0 ) *msg = peerblk->buffer.data;
883  size_t len = peerblk->buffer.len;
884  size_t data_len;
885  size_t total;
886 
887  /* Check message length */
888  if ( len < offsetof ( typeof ( *msg ), msg.block.data ) ) {
889  DBGC ( peerblk, "PEERBLK %p %d.%d message too short for "
890  "zero-length data (%zd bytes)\n", peerblk,
891  peerblk->segment, peerblk->block, len );
892  return -ERANGE;
893  }
894 
895  /* Check digest size */
896  if ( ntohl ( msg->msg.segment.segment.digestsize ) != digestsize ) {
897  DBGC ( peerblk, "PEERBLK %p %d.%d incorrect digest size %d\n",
898  peerblk, peerblk->segment, peerblk->block,
899  ntohl ( msg->msg.segment.segment.digestsize ) );
900  return -EPROTO;
901  }
902 
903  /* Check segment ID */
904  if ( memcmp ( msg->msg.segment.id, peerblk->id, digestsize ) != 0 ) {
905  DBGC ( peerblk, "PEERBLK %p %d.%d segment ID mismatch\n",
906  peerblk, peerblk->segment, peerblk->block );
907  return -EPROTO;
908  }
909 
910  /* Check block ID */
911  if ( ntohl ( msg->msg.index ) != peerblk->block ) {
912  DBGC ( peerblk, "PEERBLK %p %d.%d block ID mismatch (got %d)\n",
913  peerblk, peerblk->segment, peerblk->block,
914  ntohl ( msg->msg.index ) );
915  return -EPROTO;
916  }
917 
918  /* Check for missing blocks */
919  data_len = be32_to_cpu ( msg->msg.block.block.len );
920  if ( ! data_len ) {
921  DBGC ( peerblk, "PEERBLK %p %d.%d block not found\n",
922  peerblk, peerblk->segment, peerblk->block );
923  return -ENOENT;
924  }
925 
926  /* Check for underlength blocks */
927  if ( data_len < ( peerblk->range.end - peerblk->range.start ) ) {
928  DBGC ( peerblk, "PEERBLK %p %d.%d underlength block (%zd "
929  "bytes)\n", peerblk, peerblk->segment, peerblk->block,
930  data_len );
931  return -ERANGE;
932  }
933 
934  /* Calculate buffered data length (i.e. excluding data which
935  * was delivered to the final data transfer buffer).
936  */
937  *buf_len = ( data_len - ( peerblk->end - peerblk->start ) );
938 
939  /* Describe data before the trimmed content */
940  peerblk->decrypt[PEERBLK_BEFORE].xferbuf = &peerblk->buffer;
941  peerblk->decrypt[PEERBLK_BEFORE].offset =
942  offsetof ( typeof ( *msg ), msg.block.data );
943  peerblk->decrypt[PEERBLK_BEFORE].len =
944  ( peerblk->start -
945  offsetof ( typeof ( *msg ), msg.block.data ) );
946  total = peerblk->decrypt[PEERBLK_BEFORE].len;
947 
948  /* Describe data within the trimmed content */
949  peerblk->decrypt[PEERBLK_DURING].offset =
950  peerblk_offset ( peerblk, peerblk->start );
951  peerblk->decrypt[PEERBLK_DURING].len =
952  ( peerblk->end - peerblk->start );
953  total += peerblk->decrypt[PEERBLK_DURING].len;
954 
955  /* Describe data after the trimmed content */
956  peerblk->decrypt[PEERBLK_AFTER].xferbuf = &peerblk->buffer;
957  peerblk->decrypt[PEERBLK_AFTER].offset = peerblk->start;
958  peerblk->decrypt[PEERBLK_AFTER].len =
959  ( offsetof ( typeof ( *msg ), msg.block.data )
960  + *buf_len - peerblk->start );
961  total += peerblk->decrypt[PEERBLK_AFTER].len;
962 
963  /* Sanity check */
964  assert ( total == be32_to_cpu ( msg->msg.block.block.len ) );
965 
966  /* Initialise cipher and digest lengths */
967  peerblk->cipher_remaining = total;
968  peerblk->digest_remaining =
969  ( peerblk->range.end - peerblk->range.start );
970  assert ( peerblk->cipher_remaining >= peerblk->digest_remaining );
971 
972  return 0;
973 }
void * data
Data.
Definition: xferbuf.h:20
struct xfer_buffer buffer
Data buffer.
Definition: peerblk.h:99
void msg(unsigned int row, const char *fmt,...)
Print message centred on specified row.
Definition: message.c:61
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:232
size_t digest_remaining
Remaining digest length (excluding AES padding bytes)
Definition: peerblk.h:108
size_t start
Start offset.
Definition: pccrc.h:310
#define DBGC(...)
Definition: compiler.h:505
#define ENOENT
No such file or directory.
Definition: errno.h:514
#define ntohl(value)
Definition: byteswap.h:134
uint32_t data_len
Microcode data size (or 0 to indicate 2000 bytes)
Definition: ucode.h:26
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h: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:22
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)
ring len
Length.
Definition: dwmac.h:231
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
struct peerdist_block_decrypt decrypt[PEERBLK_NUM_BUFFERS]
Decryption data buffer descriptors.
Definition: peerblk.h:104
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:47
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:114
size_t len
Length to use from data transfer buffer.
Definition: peerblk.h:30
size_t end
End offset.
Definition: pccrc.h:312

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

Referenced by peerblk_retrieval_close().

◆ peerblk_parse_useless()

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

Parse retrieval protocol message useless details.

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

Definition at line 983 of file peerblk.c.

984  {
985  size_t digestsize = peerblk->digestsize;
986  peerblk_msg_blk_t ( digestsize, buf_len, 0, 0 ) *msg =
987  peerblk->buffer.data;
988  size_t len = peerblk->buffer.len;
989 
990  /* Check message length */
991  if ( len < offsetof ( typeof ( *msg ), msg.vrf.data ) ) {
992  DBGC ( peerblk, "PEERBLK %p %d.%d message too short for "
993  "zero-length uselessness (%zd bytes)\n", peerblk,
994  peerblk->segment, peerblk->block, len );
995  return -ERANGE;
996  }
997 
998  /* Extract length of uselessness */
999  *vrf_len = be32_to_cpu ( msg->msg.vrf.vrf.len );
1000 
1001  return 0;
1002 }
void * data
Data.
Definition: xferbuf.h:20
struct xfer_buffer buffer
Data buffer.
Definition: peerblk.h:99
void msg(unsigned int row, const char *fmt,...)
Print message centred on specified row.
Definition: message.c:61
#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:22
#define be32_to_cpu(value)
Definition: byteswap.h:116
ring len
Length.
Definition: dwmac.h:231
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
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:47
uint32_t digestsize
Digest size (i.e.
Definition: pccrr.h:14

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

Referenced by peerblk_retrieval_close().

◆ peerblk_parse_iv()

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

Parse retrieval protocol message initialisation vector details.

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

Definition at line 1012 of file peerblk.c.

1013  {
1014  size_t digestsize = peerblk->digestsize;
1015  size_t blksize = peerblk->cipher->blocksize;
1016  peerblk_msg_blk_t ( digestsize, buf_len, vrf_len, blksize ) *msg =
1017  peerblk->buffer.data;
1018  size_t len = peerblk->buffer.len;
1019 
1020  /* Check message length */
1021  if ( len < sizeof ( *msg ) ) {
1022  DBGC ( peerblk, "PEERBLK %p %d.%d message too short for "
1023  "initialisation vector (%zd bytes)\n", peerblk,
1024  peerblk->segment, peerblk->block, len );
1025  return -ERANGE;
1026  }
1027 
1028  /* Check initialisation vector size */
1029  if ( ntohl ( msg->msg.iv.iv.blksize ) != blksize ) {
1030  DBGC ( peerblk, "PEERBLK %p %d.%d incorrect IV size %d\n",
1031  peerblk, peerblk->segment, peerblk->block,
1032  ntohl ( msg->msg.iv.iv.blksize ) );
1033  return -EPROTO;
1034  }
1035 
1036  /* Set initialisation vector */
1037  cipher_setiv ( peerblk->cipher, peerblk->cipherctx, msg->msg.iv.data,
1038  blksize );
1039 
1040  return 0;
1041 }
void * data
Data.
Definition: xferbuf.h:20
size_t blocksize
Block size.
Definition: crypto.h:60
struct xfer_buffer buffer
Data buffer.
Definition: peerblk.h:99
void msg(unsigned int row, const char *fmt,...)
Print message centred on specified row.
Definition: message.c:61
#define DBGC(...)
Definition: compiler.h:505
#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:22
ring len
Length.
Definition: dwmac.h:231
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
static void cipher_setiv(struct cipher_algorithm *cipher, void *ctx, const void *iv, size_t ivlen)
Definition: crypto.h:218
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 blksize
Cipher block size.
Definition: pccrr.h:14
uint32_t digestsize
Digest size (i.e.
Definition: pccrr.h:14

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

Referenced by peerblk_retrieval_close().

◆ peerblk_decrypt_read()

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

Read from decryption buffers.

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

Definition at line 1051 of file peerblk.c.

1052  {
1053  struct peerdist_block_decrypt *decrypt = peerblk->decrypt;
1054  size_t frag_len;
1055  int rc;
1056 
1057  /* Read from each decryption buffer in turn */
1058  for ( ; len ; decrypt++, data += frag_len, len -= frag_len ) {
1059 
1060  /* Calculate length to use from this buffer */
1061  frag_len = decrypt->len;
1062  if ( frag_len > len )
1063  frag_len = len;
1064  if ( ! frag_len )
1065  continue;
1066 
1067  /* Read from this buffer */
1068  if ( ( rc = xferbuf_read ( decrypt->xferbuf, decrypt->offset,
1069  data, frag_len ) ) != 0 )
1070  return rc;
1071  }
1072 
1073  return 0;
1074 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
A PeerDist retrieval protocol decryption buffer descriptor.
Definition: peerblk.h:24
ring len
Length.
Definition: dwmac.h:231
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:146
struct peerdist_block_decrypt decrypt[PEERBLK_NUM_BUFFERS]
Decryption data buffer descriptors.
Definition: peerblk.h:104
uint8_t data[48]
Additional event data.
Definition: ena.h:22
size_t len
Length to use from data transfer buffer.
Definition: peerblk.h:30

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

Referenced by peerblk_decrypt().

◆ peerblk_decrypt_write()

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

Write to decryption buffers and update offsets and lengths.

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

Definition at line 1084 of file peerblk.c.

1085  {
1086  struct peerdist_block_decrypt *decrypt = peerblk->decrypt;
1087  size_t frag_len;
1088  int rc;
1089 
1090  /* Write to each decryption buffer in turn */
1091  for ( ; len ; decrypt++, data += frag_len, len -= frag_len ) {
1092 
1093  /* Calculate length to use from this buffer */
1094  frag_len = decrypt->len;
1095  if ( frag_len > len )
1096  frag_len = len;
1097  if ( ! frag_len )
1098  continue;
1099 
1100  /* Write to this buffer */
1101  if ( ( rc = xferbuf_write ( decrypt->xferbuf, decrypt->offset,
1102  data, frag_len ) ) != 0 )
1103  return rc;
1104 
1105  /* Update offset and length */
1106  decrypt->offset += frag_len;
1107  decrypt->len -= frag_len;
1108  }
1109 
1110  return 0;
1111 }
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:112
ring len
Length.
Definition: dwmac.h:231
size_t offset
Offset within data transfer buffer.
Definition: peerblk.h:28
struct xfer_buffer * xferbuf
Data transfer buffer.
Definition: peerblk.h:26
struct peerdist_block_decrypt decrypt[PEERBLK_NUM_BUFFERS]
Decryption data buffer descriptors.
Definition: peerblk.h:104
uint8_t data[48]
Additional event data.
Definition: ena.h:22
size_t len
Length to use from data transfer buffer.
Definition: peerblk.h:30

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

Referenced by peerblk_decrypt().

◆ peerblk_decrypt()

static void peerblk_decrypt ( struct peerdist_block peerblk)
static

Decrypt one chunk of PeerDist retrieval protocol data.

Parameters
peerblkPeerDist block download

Definition at line 1118 of file peerblk.c.

1118  {
1119  struct cipher_algorithm *cipher = peerblk->cipher;
1120  struct digest_algorithm *digest = peerblk->digest;
1121  struct xfer_buffer *xferbuf;
1122  size_t cipher_len;
1123  size_t digest_len;
1124  void *data;
1125  int rc;
1126 
1127  /* Sanity check */
1128  assert ( ( PEERBLK_DECRYPT_CHUNKSIZE % cipher->blocksize ) == 0 );
1129 
1130  /* Get the underlying data transfer buffer */
1131  xferbuf = xfer_buffer ( &peerblk->xfer );
1132  if ( ! xferbuf ) {
1133  DBGC ( peerblk, "PEERBLK %p %d.%d has no underlying data "
1134  "transfer buffer\n", peerblk, peerblk->segment,
1135  peerblk->block );
1136  rc = -ENOTSUP;
1137  goto err_xfer_buffer;
1138  }
1139  peerblk->decrypt[PEERBLK_DURING].xferbuf = xferbuf;
1140 
1141  /* Calculate cipher and digest lengths */
1142  cipher_len = PEERBLK_DECRYPT_CHUNKSIZE;
1143  if ( cipher_len > peerblk->cipher_remaining )
1144  cipher_len = peerblk->cipher_remaining;
1145  digest_len = cipher_len;
1146  if ( digest_len > peerblk->digest_remaining )
1147  digest_len = peerblk->digest_remaining;
1148  assert ( ( cipher_len & ( cipher->blocksize - 1 ) ) == 0 );
1149 
1150  /* Allocate temporary data buffer */
1151  data = malloc ( cipher_len );
1152  if ( ! data ) {
1153  rc = -ENOMEM;
1154  goto err_alloc_data;
1155  }
1156 
1157  /* Read ciphertext */
1158  if ( ( rc = peerblk_decrypt_read ( peerblk, data, cipher_len ) ) != 0 ){
1159  DBGC ( peerblk, "PEERBLK %p %d.%d could not read ciphertext: "
1160  "%s\n", peerblk, peerblk->segment, peerblk->block,
1161  strerror ( rc ) );
1162  goto err_read;
1163  }
1164 
1165  /* Decrypt data */
1166  cipher_decrypt ( cipher, peerblk->cipherctx, data, data, cipher_len );
1167 
1168  /* Add data to digest */
1169  digest_update ( digest, peerblk->digestctx, data, digest_len );
1170 
1171  /* Write plaintext */
1172  if ( ( rc = peerblk_decrypt_write ( peerblk, data, cipher_len ) ) != 0){
1173  DBGC ( peerblk, "PEERBLK %p %d.%d could not write plaintext: "
1174  "%s\n", peerblk, peerblk->segment, peerblk->block,
1175  strerror ( rc ) );
1176  goto err_write;
1177  }
1178 
1179  /* Consume input */
1180  peerblk->cipher_remaining -= cipher_len;
1181  peerblk->digest_remaining -= digest_len;
1182 
1183  /* Free temporary data buffer */
1184  free ( data );
1185 
1186  /* Continue processing until all input is consumed */
1187  if ( peerblk->cipher_remaining )
1188  return;
1189 
1190  /* Complete download attempt */
1191  peerblk_done ( peerblk, 0 );
1192  return;
1193 
1194  err_write:
1195  err_read:
1196  free ( data );
1197  err_alloc_data:
1198  err_xfer_buffer:
1199  peerblk_done ( peerblk, rc );
1200 }
size_t blocksize
Block size.
Definition: crypto.h:60
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:201
size_t digest_remaining
Remaining digest length (excluding AES padding bytes)
Definition: peerblk.h:108
A data transfer buffer.
Definition: xferbuf.h:18
void * digestctx
Digest context (statically allocated at instantiation time)
Definition: peerblk.h:74
#define DBGC(...)
Definition: compiler.h:505
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:1084
#define PEERBLK_DECRYPT_CHUNKSIZE
PeerDist decryption chunksize.
Definition: peerblk.c:50
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:305
#define cipher_decrypt(cipher, ctx, src, dst, len)
Definition: crypto.h:238
static int peerblk_decrypt_read(struct peerdist_block *peerblk, void *data, size_t len)
Read from decryption buffers.
Definition: peerblk.c:1051
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:620
static void peerblk_done(struct peerdist_block *peerblk, int rc)
Finish PeerDist block download attempt.
Definition: peerblk.c:297
struct peerdist_block_decrypt decrypt[PEERBLK_NUM_BUFFERS]
Decryption data buffer descriptors.
Definition: peerblk.h:104
A message digest algorithm.
Definition: crypto.h:18
uint8_t data[48]
Additional event data.
Definition: ena.h:22
A cipher algorithm.
Definition: crypto.h:50
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, 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 1208 of file peerblk.c.

1208  {
1209  size_t buf_len;
1210  size_t vrf_len;
1211 
1212  /* Restart interface */
1213  intf_restart ( &peerblk->retrieval, rc );
1214 
1215  /* Fail immediately if we have an error */
1216  if ( rc != 0 )
1217  goto done;
1218 
1219  /* Abort download attempt (for testing) if applicable */
1220  if ( ( rc = inject_fault ( PEERBLK_ABORT_RATE ) ) != 0 )
1221  goto done;
1222 
1223  /* Parse message header */
1224  if ( ( rc = peerblk_parse_header ( peerblk ) ) != 0 )
1225  goto done;
1226 
1227  /* Parse message segment and block details */
1228  if ( ( rc = peerblk_parse_block ( peerblk, &buf_len ) ) != 0 )
1229  goto done;
1230 
1231  /* If the block was plaintext, then there is nothing more to do */
1232  if ( ! peerblk->cipher )
1233  goto done;
1234 
1235  /* Parse message useless details */
1236  if ( ( rc = peerblk_parse_useless ( peerblk, buf_len, &vrf_len ) ) != 0)
1237  goto done;
1238 
1239  /* Parse message initialisation vector details */
1240  if ( ( rc = peerblk_parse_iv ( peerblk, buf_len, vrf_len ) ) != 0 )
1241  goto done;
1242 
1243  /* Fail if decryption length is not aligned to the cipher block size */
1244  if ( peerblk->cipher_remaining & ( peerblk->cipher->blocksize - 1 ) ) {
1245  DBGC ( peerblk, "PEERBLK %p %d.%d unaligned data length %zd\n",
1246  peerblk, peerblk->segment, peerblk->block,
1247  peerblk->cipher_remaining );
1248  rc = -EPROTO;
1249  goto done;
1250  }
1251 
1252  /* Stop the download attempt timer: there is no point in
1253  * timing out while decrypting.
1254  */
1255  stop_timer ( &peerblk->timer );
1256 
1257  /* Start decryption process */
1258  process_add ( &peerblk->process );
1259  return;
1260 
1261  done:
1262  /* Complete download attempt */
1263  peerblk_done ( peerblk, rc );
1264 }
size_t blocksize
Block size.
Definition: crypto.h:60
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:343
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:983
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:789
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:297
static int peerblk_parse_block(struct peerdist_block *peerblk, size_t *buf_len)
Parse retrieval protocol message segment and block details.
Definition: peerblk.c:879
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:1012
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 1279 of file peerblk.c.

1279  {
1280  struct peerdist_block *peerblk =
1281  container_of ( timer, struct peerdist_block, timer );
1282  struct peerdisc_segment *segment = peerblk->discovery.segment;
1283  struct peerdisc_peer *head;
1284  unsigned long now = peerblk_timestamp();
1285  const char *location;
1286  int rc;
1287 
1288  /* Profile discovery timeout, if applicable */
1289  if ( ( peerblk->peer == NULL ) && ( timer->timeout != 0 ) ) {
1290  profile_custom ( &peerblk_discovery_timeout_profiler,
1291  ( now - peerblk->started ) );
1292  DBGC ( peerblk, "PEERBLK %p %d.%d discovery timed out after "
1293  "%ld ticks\n", peerblk, peerblk->segment,
1294  peerblk->block, timer->timeout );
1295  }
1296 
1297  /* Profile download timeout, if applicable */
1298  if ( ( peerblk->peer != NULL ) && ( timer->timeout != 0 ) ) {
1299  profile_custom ( &peerblk_attempt_timeout_profiler,
1300  ( now - peerblk->attempted ) );
1301  DBGC ( peerblk, "PEERBLK %p %d.%d timed out after %ld ticks\n",
1302  peerblk, peerblk->segment, peerblk->block,
1303  timer->timeout );
1304  }
1305 
1306  /* Abort any current download attempt */
1307  peerblk_reset ( peerblk, -ETIMEDOUT );
1308 
1309  /* Record attempt start time */
1310  peerblk->attempted = now;
1311 
1312  /* If we have exceeded our maximum number of attempt cycles
1313  * (each cycle comprising a retrieval protocol download from
1314  * each peer in the list followed by a raw download from the
1315  * origin server), then abort the overall download.
1316  */
1317  head = list_entry ( &segment->peers, struct peerdisc_peer, list );
1318  if ( ( peerblk->peer == head ) &&
1319  ( ++peerblk->cycles >= PEERBLK_MAX_ATTEMPT_CYCLES ) ) {
1320  rc = peerblk->rc;
1321  assert ( rc != 0 );
1322  goto err;
1323  }
1324 
1325  /* If we have not yet made any download attempts, then move to
1326  * the start of the peer list.
1327  */
1328  if ( peerblk->peer == NULL )
1329  peerblk->peer = head;
1330 
1331  /* Attempt retrieval protocol download from next usable peer */
1332  list_for_each_entry_continue ( peerblk->peer, &segment->peers, list ) {
1333 
1334  /* Attempt retrieval protocol download from this peer */
1335  location = peerblk->peer->location;
1336  if ( ( rc = peerblk_retrieval_open ( peerblk,
1337  location ) ) != 0 ) {
1338  /* Non-fatal: continue to try next peer */
1339  continue;
1340  }
1341 
1342  /* Peer download started */
1343  return;
1344  }
1345 
1346  /* Add to raw download queue */
1347  peerblk_enqueue ( peerblk, &peerblk_raw_queue );
1348 
1349  return;
1350 
1351  err:
1352  peerblk_close ( peerblk, rc );
1353 }
uint16_t segment
Code segment.
Definition: librm.h:138
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define PEERBLK_MAX_ATTEMPT_CYCLES
PeerDist maximum number of full download attempt cycles.
Definition: peerblk.c:104
#define list_for_each_entry_continue(pos, head, member)
Iterate over entries in a list, starting after current position.
Definition: list.h:473
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:200
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:138
static void peerblk_reset(struct peerdist_block *peerblk, int rc)
Reset PeerDist block download attempt.
Definition: peerblk.c:167
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:564
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:517
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:205
static int peerblk_retrieval_open(struct peerdist_block *peerblk, const char *location)
Open PeerDist retrieval protocol block download attempt.
Definition: peerblk.c:603
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:321
#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 1360 of file peerblk.c.

1360  {
1361  struct peerdist_block *peerblk =
1363  unsigned long now = peerblk_timestamp();
1364 
1365  /* Do nothing unless we are still waiting for the initial
1366  * discovery timeout.
1367  */
1368  if ( ( peerblk->peer != NULL ) || ( peerblk->timer.timeout == 0 ) )
1369  return;
1370 
1371  /* Schedule an immediate retry */
1372  start_timer_nodelay ( &peerblk->timer );
1373 
1374  /* Profile discovery success */
1375  profile_custom ( &peerblk_discovery_success_profiler,
1376  ( now - peerblk->started ) );
1377 }
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:200
struct peerdisc_client discovery
Discovery client.
Definition: peerblk.h:111
static unsigned long peerblk_timestamp(void)
Get profiling timestamp.
Definition: peerblk.c:138
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:321
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 1433 of file peerblk.c.

1434  {
1435  const struct peerdist_info_segment *segment = block->segment;
1436  const struct peerdist_info *info = segment->info;
1437  struct digest_algorithm *digest = info->digest;
1438  struct peerdist_block *peerblk;
1439  unsigned long timeout;
1440  size_t digestsize;
1441  int rc;
1442 
1443  /* Allocate and initialise structure */
1444  peerblk = zalloc ( sizeof ( *peerblk ) + digest->ctxsize );
1445  if ( ! peerblk ) {
1446  rc = -ENOMEM;
1447  goto err_alloc;
1448  }
1449  ref_init ( &peerblk->refcnt, peerblk_free );
1450  intf_init ( &peerblk->xfer, &peerblk_xfer_desc, &peerblk->refcnt );
1451  intf_init ( &peerblk->raw, &peerblk_raw_desc, &peerblk->refcnt );
1453  &peerblk->refcnt );
1454  peerblk->uri = uri_get ( uri );
1455  memcpy ( &peerblk->range, &block->range, sizeof ( peerblk->range ) );
1456  memcpy ( &peerblk->trim, &block->trim, sizeof ( peerblk->trim ) );
1457  peerblk->offset = ( block->trim.start - info->trim.start );
1458  peerblk->digest = info->digest;
1459  peerblk->digestsize = digestsize = info->digestsize;
1460  peerblk->digestctx = ( ( ( void * ) peerblk ) + sizeof ( *peerblk ) );
1461  peerblk->segment = segment->index;
1462  memcpy ( peerblk->id, segment->id, sizeof ( peerblk->id ) );
1463  memcpy ( peerblk->secret, segment->secret, sizeof ( peerblk->secret ) );
1464  peerblk->block = block->index;
1465  memcpy ( peerblk->hash, block->hash, sizeof ( peerblk->hash ) );
1466  xferbuf_malloc_init ( &peerblk->buffer );
1468  &peerblk->refcnt );
1470  INIT_LIST_HEAD ( &peerblk->queued );
1471  timer_init ( &peerblk->timer, peerblk_expired, &peerblk->refcnt );
1472  DBGC2 ( peerblk, "PEERBLK %p %d.%d id %02x%02x%02x%02x%02x..."
1473  "%02x%02x%02x [%08zx,%08zx)", peerblk, peerblk->segment,
1474  peerblk->block, peerblk->id[0], peerblk->id[1], peerblk->id[2],
1475  peerblk->id[3], peerblk->id[4], peerblk->id[ digestsize - 3 ],
1476  peerblk->id[ digestsize - 2 ], peerblk->id[ digestsize - 1 ],
1477  peerblk->range.start, peerblk->range.end );
1478  if ( ( peerblk->trim.start != peerblk->range.start ) ||
1479  ( peerblk->trim.end != peerblk->range.end ) ) {
1480  DBGC2 ( peerblk, " covers [%08zx,%08zx)",
1481  peerblk->trim.start, peerblk->trim.end );
1482  }
1483  DBGC2 ( peerblk, "\n" );
1484 
1485  /* Open discovery */
1486  if ( ( rc = peerdisc_open ( &peerblk->discovery, peerblk->id,
1487  peerblk->digestsize ) ) != 0 )
1488  goto err_open_discovery;
1489 
1490  /* Schedule a retry attempt either immediately (if we already
1491  * have some peers) or after the discovery timeout.
1492  */
1493  timeout = ( list_empty ( &peerblk->discovery.segment->peers ) ?
1495  start_timer_fixed ( &peerblk->timer, timeout );
1496 
1497  /* Record start time */
1498  peerblk->started = peerblk_timestamp();
1499 
1500  /* Attach to parent interface, mortalise self, and return */
1501  intf_plug_plug ( xfer, &peerblk->xfer );
1502  ref_put ( &peerblk->refcnt );
1503  return 0;
1504 
1505  err_open_discovery:
1506  peerblk_close ( peerblk, rc );
1507  err_alloc:
1508  return rc;
1509 }
struct list_head peers
List of discovered peers.
Definition: peerdisc.h:63
uint16_t segment
Code segment.
Definition: librm.h:138
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define TICKS_PER_SEC
Number of ticks per second.
Definition: timer.h:15
u32 info
Definition: ar9003_mac.h:67
A content information segment.
Definition: pccrc.h:346
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:194
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
size_t start
Start offset.
Definition: pccrc.h:310
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:107
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:1417
struct peerdisc_client discovery
Discovery client.
Definition: peerblk.h:111
struct process process
Decryption process.
Definition: peerblk.h:102
static unsigned long peerblk_timestamp(void)
Get profiling timestamp.
Definition: peerblk.c:138
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:559
static void peerblk_expired(struct retry_timer *timer, int over __unused)
Handle PeerDist retry timer expiry.
Definition: peerblk.c:1279
unsigned int segment
Segment index.
Definition: peerblk.h:82
struct interface raw
Raw data interface.
Definition: peerblk.h:52
static void xferbuf_malloc_init(struct xfer_buffer *xferbuf)
Initialise malloc()-based data transfer buffer.
Definition: xferbuf.h:53
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:316
static struct peerdisc_client_operations peerblk_discovery_operations
PeerDist block download discovery operations.
Definition: peerblk.c:1421
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:661
static void peerblk_free(struct refcnt *refcnt)
Free PeerDist block download.
Definition: peerblk.c:152
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:1412
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:205
size_t ctxsize
Context size.
Definition: crypto.h:22
#define DBGC2(...)
Definition: compiler.h:522
uint8_t block[3][8]
DES-encrypted blocks.
Definition: mschapv2.h:12
uint8_t secret[PEERDIST_DIGEST_MAX_SIZE]
Segment secret.
Definition: peerblk.h:86
A message digest algorithm.
Definition: crypto.h:18
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:1402
A Uniform Resource Identifier.
Definition: uri.h:64
void timeout(int)
static struct interface_descriptor peerblk_xfer_desc
PeerDist block download data transfer interface descriptor.
Definition: peerblk.c:1392
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:203
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106
size_t end
End offset.
Definition: pccrc.h:312
unsigned int peerdisc_timeout_secs
Recommended discovery timeout (in seconds)
Definition: peerdisc.c:74

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

Referenced by peermux_step().

Variable Documentation

◆ __profiler

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

PeerDist block download profiler.

PeerDist block download discovery timeout profiler.

PeerDist block download discovery success profiler.

PeerDist block download attempt timeout profiler.

PeerDist block download attempt failure profiler.

PeerDist block download attempt success profiler.

Definition at line 107 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:480
#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 560 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:560
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:564
static int peerblk_raw_open(struct peerdist_block *peerblk)
Open PeerDist raw block download attempt.
Definition: peerblk.c:359
#define PEERBLK_RAW_MAX
PeerDist maximum number of concurrent raw block downloads.
Definition: peerblk.c:69
#define LIST_HEAD_INIT(list)
Initialise a static list head.
Definition: list.h:30

Raw block download queue.

Definition at line 564 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:249
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:205

PeerDist block download data transfer interface operations.

Definition at line 1387 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:80
static struct interface_operation peerblk_xfer_operations[]
PeerDist block download data transfer interface operations.
Definition: peerblk.c:1387

PeerDist block download data transfer interface descriptor.

Definition at line 1392 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:249
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:194
static int peerblk_raw_rx(struct peerdist_block *peerblk, struct io_buffer *iobuf, struct xfer_metadata *meta)
Receive PeerDist raw data.
Definition: peerblk.c:402
static void peerblk_raw_close(struct peerdist_block *peerblk, int rc)
Close PeerDist raw block download attempt.
Definition: peerblk.c:450

PeerDist block download raw data interface operations.

Definition at line 1396 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:80
static struct interface_operation peerblk_raw_operations[]
PeerDist block download raw data interface operations.
Definition: peerblk.c:1396
__be32 raw[7]
Definition: CIB_PRM.h:28

PeerDist block download raw data interface descriptor.

Definition at line 1402 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:249
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:676
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:194
static void peerblk_retrieval_close(struct peerdist_block *peerblk, int rc)
Close PeerDist retrieval protocol block download attempt.
Definition: peerblk.c:1208

PeerDist block download retrieval protocol interface operations.

Definition at line 1406 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:1406
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:80

PeerDist block download retrieval protocol interface descriptor.

Definition at line 1412 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:1118
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 1417 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:1360

PeerDist block download discovery operations.

Definition at line 1421 of file peerblk.c.

Referenced by peerblk_open().