iPXE
Macros | Functions | Variables
peerblk.c File Reference

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

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

Go to the source code of this file.

Macros

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

Functions

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

Variables

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

Detailed Description

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

Definition in file peerblk.c.

Macro Definition Documentation

◆ PEERBLK_DECRYPT_CHUNKSIZE

#define PEERBLK_DECRYPT_CHUNKSIZE   2048

PeerDist decryption chunksize.

This is a policy decision.

Definition at line 49 of file peerblk.c.

◆ PEERBLK_RAW_MAX

#define PEERBLK_RAW_MAX   2

PeerDist maximum number of concurrent raw block downloads.

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

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

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

This is a policy decision.

Definition at line 68 of file peerblk.c.

◆ PEERBLK_RAW_OPEN_TIMEOUT

#define PEERBLK_RAW_OPEN_TIMEOUT   ( 10 * TICKS_PER_SEC )

PeerDist raw block download attempt initial progress timeout.

This is a policy decision.

Definition at line 74 of file peerblk.c.

◆ PEERBLK_RAW_RX_TIMEOUT

#define PEERBLK_RAW_RX_TIMEOUT   ( 15 * TICKS_PER_SEC )

PeerDist raw block download attempt ongoing progress timeout.

This is a policy decision.

Definition at line 80 of file peerblk.c.

◆ PEERBLK_RETRIEVAL_OPEN_TIMEOUT

#define PEERBLK_RETRIEVAL_OPEN_TIMEOUT   ( 3 * TICKS_PER_SEC )

PeerDist retrieval protocol block download attempt initial progress timeout.

This is a policy decision.

Definition at line 86 of file peerblk.c.

◆ PEERBLK_RETRIEVAL_RX_TIMEOUT

#define PEERBLK_RETRIEVAL_RX_TIMEOUT   ( 5 * TICKS_PER_SEC )

PeerDist retrieval protocol block download attempt ongoing progress timeout.

This is a policy decision.

Definition at line 92 of file peerblk.c.

◆ PEERBLK_MAX_ATTEMPT_CYCLES

#define PEERBLK_MAX_ATTEMPT_CYCLES   4

PeerDist maximum number of full download attempt cycles.

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

This is a policy decision.

Definition at line 103 of file peerblk.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ peerblk_dequeue()

static void peerblk_dequeue ( struct peerdist_block peerblk)
static

Remove block from download queue.

Parameters
peerblkPeerDist block download

Definition at line 536 of file peerblk.c.

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

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

Referenced by peerblk_reset().

◆ peerblk_timestamp()

static unsigned long peerblk_timestamp ( void  )
inlinestatic

Get profiling timestamp.

Return values
timestampTimestamp

Definition at line 137 of file peerblk.c.

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

References currticks(), and PROFILING.

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

◆ peerblk_free()

static void peerblk_free ( struct refcnt refcnt)
static

Free PeerDist block download.

Parameters
refcntReference count

Definition at line 151 of file peerblk.c.

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

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

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

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

◆ peerblk_close()

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

Close PeerDist block download.

Parameters
peerblkPeerDist block download
rcReason for close

Definition at line 204 of file peerblk.c.

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

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

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

Referenced by peerblk_deliver(), and peerblk_parse_block().

◆ peerblk_deliver()

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

Deliver download attempt data block.

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

Definition at line 245 of file peerblk.c.

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

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

Referenced by peerblk_raw_rx(), and peerblk_retrieval_rx().

◆ peerblk_done()

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

Finish PeerDist block download attempt.

Parameters
peerblkPeerDist block download
rcReason for close

Definition at line 296 of file peerblk.c.

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

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

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

◆ peerblk_raw_open()

static int peerblk_raw_open ( struct peerdist_block peerblk)
static

Open PeerDist raw block download attempt.

Parameters
peerblkPeerDist block download
Return values
rcReturn status code

Definition at line 358 of file peerblk.c.

358  {
359  struct http_request_range range;
360  int rc;
361 
362  DBGC2 ( peerblk, "PEERBLK %p %d.%d attempting raw range request\n",
363  peerblk, peerblk->segment, peerblk->block );
364 
365  /* Construct HTTP range */
366  memset ( &range, 0, sizeof ( range ) );
367  range.start = peerblk->range.start;
368  range.len = ( peerblk->range.end - peerblk->range.start );
369 
370  /* Initiate range request to retrieve block */
371  if ( ( rc = http_open ( &peerblk->raw, &http_get, peerblk->uri,
372  &range, NULL ) ) != 0 ) {
373  DBGC ( peerblk, "PEERBLK %p %d.%d could not create range "
374  "request: %s\n", peerblk, peerblk->segment,
375  peerblk->block, strerror ( rc ) );
376  return rc;
377  }
378 
379  /* Annul HTTP connection (for testing) if applicable. Do not
380  * report as an immediate error, in order to test our ability
381  * to recover from a totally unresponsive HTTP server.
382  */
383  if ( inject_fault ( PEERBLK_ANNUL_RATE ) )
384  intf_restart ( &peerblk->raw, 0 );
385 
386  /* Start download attempt timer */
387  peerblk->rc = -ETIMEDOUT;
389 
390  return 0;
391 }
uint32_t start
Starting bus:dev.fn address.
Definition: pci_io.h:23
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:342
static __always_inline void struct pci_range * range
Definition: efi_pci_api.h:43
#define PEERBLK_RAW_OPEN_TIMEOUT
PeerDist raw block download attempt initial progress timeout.
Definition: peerblk.c:74
HTTP request range descriptor.
Definition: http.h:135
size_t start
Start offset.
Definition: pccrc.h:311
#define DBGC(...)
Definition: compiler.h:505
struct uri * uri
Original URI.
Definition: peerblk.h:57
int rc
Most recent attempt failure.
Definition: peerblk.h:123
struct peerdist_range range
Content range of this block.
Definition: peerblk.h:59
unsigned int segment
Segment index.
Definition: peerblk.h:82
struct interface raw
Raw data interface.
Definition: peerblk.h:52
unsigned int block
Block index.
Definition: peerblk.h:88
struct http_method http_get
HTTP GET method.
Definition: httpcore.c:139
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:601
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
#define ETIMEDOUT
Connection timed out.
Definition: errno.h:669
size_t end
End offset.
Definition: pccrc.h:313
void * memset(void *dest, int character, size_t len) __nonnull

References peerdist_block::block, DBGC, DBGC2, peerdist_range::end, ETIMEDOUT, http_get, http_open(), intf_restart(), memset(), NULL, PEERBLK_ANNUL_RATE, PEERBLK_RAW_OPEN_TIMEOUT, range, peerdist_block::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 401 of file peerblk.c.

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

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

◆ peerblk_raw_close()

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

Close PeerDist raw block download attempt.

Parameters
peerblkPeerDist block download
rcReason for close

Definition at line 449 of file peerblk.c.

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

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

◆ peerblk_step()

static void peerblk_step ( struct peerdist_block_queue queue)
static

PeerDist block download queue process.

Parameters
queueBlock download queue

Definition at line 479 of file peerblk.c.

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

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

◆ peerblk_enqueue()

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

Add block to download queue.

Parameters
peerblkPeerDist block download
queueBlock download queue

Definition at line 516 of file peerblk.c.

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

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

Referenced by peerblk_expired().

◆ peerblk_retrieval_uri()

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

Construct PeerDist retrieval protocol URI.

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

Definition at line 583 of file peerblk.c.

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

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

References peerdist_block::block, http_request_content::data, DBGC, DBGC2, digestsize, peerdist_block::digestsize, peerdist_block::end, ENOMEM, ETIMEDOUT, htonl, http_open(), http_post, peerdist_block::id, intf_restart(), http_request_content::len, memcpy(), memset(), msg(), NULL, offsetof, PEERBLK_ANNUL_RATE, peerblk_msg_blk_t, PEERBLK_RETRIEVAL_OPEN_TIMEOUT, peerblk_retrieval_uri(), PEERDIST_MSG_AES_128_CBC, peerdist_msg_getblks_t, PEERDIST_MSG_GETBLKS_TYPE, PEERDIST_MSG_GETBLKS_VERSION, peerdist_block::rc, rc, peerdist_block::retrieval, rsp, peerdist_block::segment, peerdist_block::start, start_timer_fixed(), strerror(), peerdist_block::timer, 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 675 of file peerblk.c.

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

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

◆ peerblk_parse_header()

static int peerblk_parse_header ( struct peerdist_block peerblk)
static

Parse retrieval protocol message header.

Parameters
peerblkPeerDist block download
Return values
rcReturn status code

Definition at line 788 of file peerblk.c.

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

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

Referenced by peerblk_retrieval_close().

◆ peerblk_parse_block()

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

Parse retrieval protocol message segment and block details.

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

Definition at line 878 of file peerblk.c.

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

References assert(), be32_to_cpu, peerdist_block::block, peerdist_block::buffer, peerdist_block::cipher_remaining, xfer_buffer::data, DBGC, peerdist_block::decrypt, peerdist_block::digest_remaining, digestsize, peerdist_block::digestsize, peerdist_block::end, peerdist_range::end, ENOENT, EPROTO, ERANGE, peerdist_block::id, len, xfer_buffer::len, peerdist_block_decrypt::len, memcmp(), msg(), ntohl, peerdist_block_decrypt::offset, offsetof, PEERBLK_AFTER, PEERBLK_BEFORE, PEERBLK_DURING, peerblk_msg_blk_t, peerblk_offset(), peerdist_block::range, peerdist_block::segment, peerdist_block::start, peerdist_range::start, 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 982 of file peerblk.c.

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

References be32_to_cpu, peerdist_block::block, peerdist_block::buffer, xfer_buffer::data, DBGC, digestsize, peerdist_block::digestsize, ERANGE, len, xfer_buffer::len, msg(), offsetof, peerblk_msg_blk_t, 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 1011 of file peerblk.c.

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

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

Referenced by peerblk_retrieval_close().

◆ peerblk_decrypt_read()

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

Read from decryption buffers.

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

Definition at line 1050 of file peerblk.c.

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

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

Referenced by peerblk_decrypt().

◆ peerblk_decrypt_write()

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

Write to decryption buffers and update offsets and lengths.

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

Definition at line 1083 of file peerblk.c.

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

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

Referenced by peerblk_decrypt().

◆ peerblk_decrypt()

static void peerblk_decrypt ( struct peerdist_block peerblk)
static

Decrypt one chunk of PeerDist retrieval protocol data.

Parameters
peerblkPeerDist block download

Definition at line 1117 of file peerblk.c.

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

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

◆ peerblk_retrieval_close()

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

Close PeerDist retrieval protocol block download attempt.

Parameters
peerblkPeerDist block download
rcReason for close

Definition at line 1207 of file peerblk.c.

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

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

◆ peerblk_expired()

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

Handle PeerDist retry timer expiry.

Parameters
timerRetry timer
overFailure indicator

Definition at line 1278 of file peerblk.c.

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

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

Referenced by peerblk_open().

◆ peerblk_discovered()

static void peerblk_discovered ( struct peerdisc_client discovery)
static

Handle PeerDist peer discovery.

Parameters
discoveryPeerDist discovery client

Definition at line 1359 of file peerblk.c.

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

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

◆ peerblk_open()

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

Open PeerDist block download.

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

Definition at line 1432 of file peerblk.c.

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

References block, peerdist_block::block, peerdist_block::buffer, DBGC2, digest, peerdist_block::digest, peerdist_block::digestctx, digestsize, peerdist_block::digestsize, peerdist_block::discovery, peerdist_range::end, ENOMEM, peerdist_block::hash, peerdist_block::id, info, INIT_LIST_HEAD, intf_init(), intf_plug_plug(), list_empty, memcpy(), peerdist_block::offset, peerblk_close(), peerblk_discovery_operations, peerblk_expired(), peerblk_free(), peerblk_process_desc, peerblk_raw_desc, peerblk_retrieval_desc, peerblk_timestamp(), peerblk_xfer_desc, peerdisc_init(), peerdisc_open(), peerdisc_timeout_secs, peerdisc_segment::peers, peerdist_block::process, process_init_stopped(), peerdist_block::queued, peerdist_block::range, peerdist_block::raw, rc, ref_init, ref_put, peerdist_block::refcnt, peerdist_block::retrieval, peerdist_block::secret, peerdisc_client::segment, peerdist_block::segment, segment, peerdist_range::start, start_timer_fixed(), peerdist_block::started, TICKS_PER_SEC, timeout(), peerdist_block::timer, peerdist_block::trim, peerdist_block::uri, uri_get(), peerdist_block::xfer, 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 106 of file peerblk.c.

◆ peerblk_queue_desc

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

PeerDist block download queue process descriptor.

Definition at line 559 of file peerblk.c.

◆ peerblk_raw_queue

struct peerdist_block_queue peerblk_raw_queue
static
Initial value:
= {
}
static struct process_descriptor peerblk_queue_desc
PeerDist block download queue process descriptor.
Definition: peerblk.c:559
struct list_head list
List of queued downloads.
Definition: peerblk.h:136
#define PROC_INIT(_process, _desc)
Initialise a static process.
Definition: process.h:131
struct process process
Download opening process.
Definition: peerblk.h:134
static struct peerdist_block_queue peerblk_raw_queue
Raw block download queue.
Definition: peerblk.c:563
static int peerblk_raw_open(struct peerdist_block *peerblk)
Open PeerDist raw block download attempt.
Definition: peerblk.c:358
#define PEERBLK_RAW_MAX
PeerDist maximum number of concurrent raw block downloads.
Definition: peerblk.c:68
#define LIST_HEAD_INIT(list)
Initialise a static list head.
Definition: list.h:30

Raw block download queue.

Definition at line 563 of file peerblk.c.

Referenced by peerblk_expired().

◆ peerblk_xfer_operations

struct interface_operation peerblk_xfer_operations[]
static
Initial value:
= {
}
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c: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:204

PeerDist block download data transfer interface operations.

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

PeerDist block download data transfer interface descriptor.

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

PeerDist block download raw data interface operations.

Definition at line 1395 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:1395
__be32 raw[7]
Definition: CIB_PRM.h:28

PeerDist block download raw data interface descriptor.

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

PeerDist block download retrieval protocol interface operations.

Definition at line 1405 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:1405
#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 1411 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:1117
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 1416 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:1359

PeerDist block download discovery operations.

Definition at line 1420 of file peerblk.c.

Referenced by peerblk_open().