iPXE
Macros | Functions | Variables
peerdisc.c File Reference

Peer Content Caching and Retrieval (PeerDist) protocol peer discovery. More...

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <assert.h>
#include <ipxe/xfer.h>
#include <ipxe/iobuf.h>
#include <ipxe/open.h>
#include <ipxe/tcpip.h>
#include <ipxe/uuid.h>
#include <ipxe/base16.h>
#include <ipxe/netdevice.h>
#include <ipxe/timer.h>
#include <ipxe/fault.h>
#include <ipxe/settings.h>
#include <ipxe/pccrd.h>
#include <ipxe/peerdisc.h>

Go to the source code of this file.

Macros

#define PEERDISC_REPEAT_COUNT   2
 Number of repeated discovery attempts. More...
 
#define PEERDISC_REPEAT_TIMEOUT   ( 1 * TICKS_PER_SEC )
 Time between repeated discovery attempts. More...
 
#define PEERDISC_DEFAULT_TIMEOUT_SECS   2
 Default discovery timeout (in seconds) More...
 

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
static LIST_HEAD (peerdisc_segments)
 List of discovery segments. More...
 
static struct peerdisc_segmentpeerdisc_find (const char *id)
 Find PeerDist discovery segment. More...
 
static int peerdisc_discovered (struct peerdisc_segment *segment, const char *location)
 Add discovered PeerDist peer. More...
 
void peerdisc_stat (struct interface *intf, struct peerdisc_peer *peer, struct list_head *peers)
 Report peer discovery statistics. More...
 
static int peerdisc_socket_open (void)
 Open all PeerDist discovery sockets. More...
 
static void peerdisc_socket_tx (const char *uuid, const char *id)
 Attempt to transmit PeerDist discovery requests on all sockets. More...
 
static int peerdisc_socket_rx (struct peerdisc_socket *socket, struct io_buffer *iobuf, struct xfer_metadata *meta __unused)
 Handle received PeerDist discovery reply. More...
 
static void peerdisc_socket_close (int rc)
 Close all PeerDist discovery sockets. More...
 
static void peerdisc_free (struct refcnt *refcnt)
 Free PeerDist discovery segment. More...
 
static void peerdisc_expired (struct retry_timer *timer, int over __unused)
 Handle discovery timer expiry. More...
 
static struct peerdisc_segmentpeerdisc_create (const char *id)
 Create PeerDist discovery segment. More...
 
static void peerdisc_destroy (struct peerdisc_segment *segment)
 Destroy PeerDist discovery segment. More...
 
int peerdisc_open (struct peerdisc_client *peerdisc, const void *id, size_t len)
 Open PeerDist discovery client. More...
 
void peerdisc_close (struct peerdisc_client *peerdisc)
 Close PeerDist discovery client. More...
 
const struct setting peerhost_setting __setting (SETTING_MISC, peerhost)
 PeerDist hosted cache server setting. More...
 
static int apply_peerdisc_settings (void)
 Apply PeerDist discovery settings. More...
 

Variables

unsigned int peerdisc_timeout_secs = PEERDISC_DEFAULT_TIMEOUT_SECS
 Recommended discovery timeout (in seconds) More...
 
static char * peerhost
 Hosted cache server. More...
 
static struct interface_operation peerdisc_socket_operations []
 PeerDist discovery socket interface operations. More...
 
static struct interface_descriptor peerdisc_socket_desc
 PeerDist discovery socket interface descriptor. More...
 
struct peerdisc_socket peerdisc_socket_ipv4 __peerdisc_socket
 PeerDist discovery IPv4 socket. More...
 
struct settings_applicator peerdisc_applicator __settings_applicator
 PeerDist discovery settings applicator. More...
 

Detailed Description

Peer Content Caching and Retrieval (PeerDist) protocol peer discovery.

Definition in file peerdisc.c.

Macro Definition Documentation

◆ PEERDISC_REPEAT_COUNT

#define PEERDISC_REPEAT_COUNT   2

Number of repeated discovery attempts.

Definition at line 54 of file peerdisc.c.

◆ PEERDISC_REPEAT_TIMEOUT

#define PEERDISC_REPEAT_TIMEOUT   ( 1 * TICKS_PER_SEC )

Time between repeated discovery attempts.

Definition at line 57 of file peerdisc.c.

◆ PEERDISC_DEFAULT_TIMEOUT_SECS

#define PEERDISC_DEFAULT_TIMEOUT_SECS   2

Default discovery timeout (in seconds)

Definition at line 60 of file peerdisc.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ LIST_HEAD()

static LIST_HEAD ( peerdisc_segments  )
static

List of discovery segments.

◆ peerdisc_find()

static struct peerdisc_segment * peerdisc_find ( const char *  id)
static

Find PeerDist discovery segment.

Parameters
idSegment ID
Return values
segmentPeerDist discovery segment, or NULL if not found

Definition at line 362 of file peerdisc.c.

362  {
363  struct peerdisc_segment *segment;
364 
365  /* Look for a matching segment */
366  list_for_each_entry ( segment, &peerdisc_segments, list ) {
367  if ( strcmp ( id, segment->id ) == 0 )
368  return segment;
369  }
370 
371  return NULL;
372 }
uint16_t segment
Code segment.
Definition: librm.h:252
A PeerDist discovery segment.
Definition: peerdisc.h:42
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:420
struct list_head list
List of segments.
Definition: peerdisc.h:46
int strcmp(const char *first, const char *second)
Compare strings.
Definition: string.c:157
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References peerdisc_segment::list, list_for_each_entry, NULL, segment, and strcmp().

Referenced by peerdisc_open(), and peerdisc_socket_rx().

◆ peerdisc_discovered()

static int peerdisc_discovered ( struct peerdisc_segment segment,
const char *  location 
)
static

Add discovered PeerDist peer.

Parameters
segmentPeerDist discovery segment
locationPeer location
Return values
rcReturn status code

Definition at line 381 of file peerdisc.c.

382  {
383  struct peerdisc_peer *peer;
384  struct peerdisc_client *peerdisc;
385  struct peerdisc_client *tmp;
386 
387  /* Ignore duplicate peers */
388  list_for_each_entry ( peer, &segment->peers, list ) {
389  if ( strcmp ( peer->location, location ) == 0 ) {
390  DBGC2 ( segment, "PEERDISC %p duplicate %s\n",
391  segment, location );
392  return 0;
393  }
394  }
395  DBGC2 ( segment, "PEERDISC %p discovered %s\n", segment, location );
396 
397  /* Allocate and initialise structure */
398  peer = zalloc ( sizeof ( *peer ) + strlen ( location ) + 1 /* NUL */ );
399  if ( ! peer )
400  return -ENOMEM;
401  strcpy ( peer->location, location );
402 
403  /* Add to end of list of peers */
404  list_add_tail ( &peer->list, &segment->peers );
405 
406  /* Notify all clients */
407  list_for_each_entry_safe ( peerdisc, tmp, &segment->clients, list )
408  peerdisc->op->discovered ( peerdisc );
409 
410  return 0;
411 }
uint16_t segment
Code segment.
Definition: librm.h:252
struct list_head list
List of clients.
Definition: peerdisc.h:83
#define ENOMEM
Not enough space.
Definition: errno.h:534
void(* discovered)(struct peerdisc_client *peerdisc)
New peers have been discovered.
Definition: peerdisc.h:94
A PeerDist discovery client.
Definition: peerdisc.h:79
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:420
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:93
char * strcpy(char *dest, const char *src)
Copy string.
Definition: string.c:296
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition: list.h:447
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
char location[0]
Peer location.
Definition: peerdisc.h:75
uint8_t * tmp
Definition: entropy.h:156
size_t strlen(const char *src)
Get length of string.
Definition: string.c:213
#define DBGC2(...)
Definition: compiler.h:522
int strcmp(const char *first, const char *second)
Compare strings.
Definition: string.c:157
struct peerdisc_client_operations * op
Operations.
Definition: peerdisc.h:85
struct list_head list
List of peers.
Definition: peerdisc.h:73
A PeerDist discovery peer.
Definition: peerdisc.h:71

References DBGC2, peerdisc_client_operations::discovered, ENOMEM, peerdisc_peer::list, peerdisc_client::list, list_add_tail, list_for_each_entry, list_for_each_entry_safe, peerdisc_peer::location, peerdisc_client::op, segment, strcmp(), strcpy(), strlen(), tmp, and zalloc().

Referenced by peerdisc_create(), and peerdisc_socket_rx().

◆ peerdisc_stat()

void peerdisc_stat ( struct interface intf,
struct peerdisc_peer peer,
struct list_head peers 
)

Report peer discovery statistics.

Parameters
intfInterface
peerSelected peer (or NULL)
peersList of available peers

Definition at line 97 of file peerdisc.c.

98  {
99  struct interface *dest;
100  peerdisc_stat_TYPE ( void * ) *op =
101  intf_get_dest_op ( intf, peerdisc_stat, &dest );
102  void *object = intf_object ( dest );
103 
104  if ( op ) {
105  op ( object, peer, peers );
106  } else {
107  /* Default is to do nothing */
108  }
109 
110  intf_put ( dest );
111 }
void * intf_object(struct interface *intf)
Get pointer to object containing object interface.
Definition: interface.c:154
void peerdisc_stat(struct interface *intf, struct peerdisc_peer *peer, struct list_head *peers)
Report peer discovery statistics.
Definition: peerdisc.c:97
An object interface.
Definition: interface.h:109
static void * dest
Definition: strings.h:176
static uint16_t struct vmbus_xfer_pages_operations * op
Definition: netvsc.h:327
#define peerdisc_stat_TYPE(object_type)
Definition: peerdisc.h:114
void intf_put(struct interface *intf)
Decrement reference count on an object interface.
Definition: interface.c:144
#define intf_get_dest_op(intf, type, dest)
Get object interface destination and operation method.
Definition: interface.h:214

References dest, intf_get_dest_op, intf_object(), intf_put(), op, peerdisc_stat(), and peerdisc_stat_TYPE.

Referenced by peerblk_done(), and peerdisc_stat().

◆ peerdisc_socket_open()

static int peerdisc_socket_open ( void  )
static

Open all PeerDist discovery sockets.

Return values
rcReturn status code

Definition at line 125 of file peerdisc.c.

125  {
126  struct peerdisc_socket *socket;
127  int rc;
128 
129  /* Open each socket */
131  if ( ( rc = xfer_open_socket ( &socket->xfer, SOCK_DGRAM,
132  &socket->address.sa,
133  NULL ) ) != 0 ) {
134  DBGC ( socket, "PEERDISC %s could not open socket: "
135  "%s\n", socket->name, strerror ( rc ) );
136  goto err;
137  }
138  }
139 
140  return 0;
141 
142  err:
144  intf_restart ( &socket->xfer, rc );
145  return rc;
146 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition: interface.c:337
union peerdisc_socket::@557 address
Socket address.
int xfer_open_socket(struct interface *intf, int semantics, struct sockaddr *peer, struct sockaddr *local)
Open socket.
Definition: open.c:141
A PeerDist discovery socket.
Definition: peerdisc.h:22
#define SOCK_DGRAM
Definition: socket.h:29
#define DBGC(...)
Definition: compiler.h:505
#define PEERDISC_SOCKETS
PeerDist discovery socket table.
Definition: peerdisc.h:36
struct interface xfer
Data transfer interface.
Definition: peerdisc.h:26
struct sockaddr sa
Definition: peerdisc.h:29
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:358
const char * name
Name.
Definition: peerdisc.h:24
#define for_each_table_entry_continue_reverse(pointer, table)
Iterate through all remaining entries within a linker table in reverse order.
Definition: tables.h:442
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References peerdisc_socket::address, DBGC, for_each_table_entry, for_each_table_entry_continue_reverse, intf_restart(), peerdisc_socket::name, NULL, PEERDISC_SOCKETS, rc, peerdisc_socket::sa, SOCK_DGRAM, strerror(), peerdisc_socket::xfer, and xfer_open_socket().

Referenced by peerdisc_open().

◆ peerdisc_socket_tx()

static void peerdisc_socket_tx ( const char *  uuid,
const char *  id 
)
static

Attempt to transmit PeerDist discovery requests on all sockets.

Parameters
uuidMessage UUID string
idSegment identifier string

Definition at line 154 of file peerdisc.c.

154  {
155  struct peerdisc_socket *socket;
156  struct net_device *netdev;
157  struct xfer_metadata meta;
158  union {
159  struct sockaddr sa;
160  struct sockaddr_tcpip st;
161  } address;
162  char *request;
163  size_t len;
164  int rc;
165 
166  /* Construct discovery request */
168  if ( ! request )
169  goto err_request;
170  len = strlen ( request );
171 
172  /* Initialise data transfer metadata */
173  memset ( &meta, 0, sizeof ( meta ) );
174  meta.dest = &address.sa;
175 
176  /* Send message on each socket */
178 
179  /* Initialise socket address */
180  memcpy ( &address.sa, &socket->address.sa,
181  sizeof ( address.sa ) );
182 
183  /* Send message on each open network device */
184  for_each_netdev ( netdev ) {
185 
186  /* Skip unopened network devices */
187  if ( ! netdev_is_open ( netdev ) )
188  continue;
189  address.st.st_scope_id = netdev->index;
190 
191  /* Discard request (for test purposes) if applicable */
192  if ( inject_fault ( PEERDISC_DISCARD_RATE ) )
193  continue;
194 
195  /* Transmit request */
196  if ( ( rc = xfer_deliver_raw_meta ( &socket->xfer,
197  request, len,
198  &meta ) ) != 0 ) {
199  DBGC ( socket, "PEERDISC %s could not transmit "
200  "via %s: %s\n", socket->name,
201  netdev->name, strerror ( rc ) );
202  /* Contine to try other net devices/sockets */
203  continue;
204  }
205  }
206  }
207 
208  free ( request );
209  err_request:
210  return;
211 }
TCP/IP socket address.
Definition: tcpip.h:75
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
Data transfer metadata.
Definition: xfer.h:22
union peerdisc_socket::@557 address
Socket address.
struct sockaddr sa
Definition: dns.c:68
int xfer_deliver_raw_meta(struct interface *intf, const void *data, size_t len, struct xfer_metadata *meta)
Deliver datagram as raw data.
Definition: xfer.c:267
A universally unique ID.
Definition: uuid.h:15
A PeerDist discovery socket.
Definition: peerdisc.h:22
uint64_t address
Base address.
Definition: ena.h:24
#define DBGC(...)
Definition: compiler.h:505
#define PEERDISC_SOCKETS
PeerDist discovery socket table.
Definition: peerdisc.h:36
#define PEERDISC_DISCARD_RATE
Definition: fault.h:18
struct interface xfer
Data transfer interface.
Definition: peerdisc.h:26
char * peerdist_discovery_request(const char *uuid, const char *id)
Construct discovery request.
Definition: pccrd.c:106
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static int netdev_is_open(struct net_device *netdev)
Check whether or not network device is open.
Definition: netdevice.h:652
struct sockaddr sa
Definition: peerdisc.h:29
struct sockaddr_tcpip st
Definition: dns.c:69
static struct net_device * netdev
Definition: gdbudp.c:52
int meta(WINDOW *, bool)
Generalized socket address structure.
Definition: socket.h:96
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
#define for_each_netdev(netdev)
Iterate over all network devices.
Definition: netdevice.h:526
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:358
A network device.
Definition: netdevice.h:348
size_t strlen(const char *src)
Get length of string.
Definition: string.c:213
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:358
uint32_t len
Length.
Definition: ena.h:14
unsigned int index
Index of this network device.
Definition: netdevice.h:356
u8 request[0]
List of IEs requested.
Definition: ieee80211.h:16
const char * name
Name.
Definition: peerdisc.h:24
void * memset(void *dest, int character, size_t len) __nonnull

References address, peerdisc_socket::address, DBGC, for_each_netdev, for_each_table_entry, free, net_device::index, len, memcpy(), memset(), meta(), peerdisc_socket::name, net_device::name, netdev, netdev_is_open(), PEERDISC_DISCARD_RATE, PEERDISC_SOCKETS, peerdist_discovery_request(), rc, request, peerdisc_socket::sa, sa, st, strerror(), strlen(), peerdisc_socket::xfer, and xfer_deliver_raw_meta().

Referenced by peerdisc_expired().

◆ peerdisc_socket_rx()

static int peerdisc_socket_rx ( struct peerdisc_socket socket,
struct io_buffer iobuf,
struct xfer_metadata *meta  __unused 
)
static

Handle received PeerDist discovery reply.

Parameters
socketPeerDist discovery socket
iobufI/O buffer
metaData transfer metadata
Return values
rcReturn status code

Definition at line 221 of file peerdisc.c.

223  {
224  struct peerdist_discovery_reply reply;
225  struct peerdisc_segment *segment;
226  char *id;
227  char *location;
228  int rc;
229 
230  /* Discard reply (for test purposes) if applicable */
231  if ( ( rc = inject_fault ( PEERDISC_DISCARD_RATE ) ) != 0 )
232  goto err;
233 
234  /* Parse reply */
235  if ( ( rc = peerdist_discovery_reply ( iobuf->data, iob_len ( iobuf ),
236  &reply ) ) != 0 ) {
237  DBGC ( socket, "PEERDISC %s could not parse reply: %s\n",
238  socket->name, strerror ( rc ) );
239  DBGC_HDA ( socket, 0, iobuf->data, iob_len ( iobuf ) );
240  goto err;
241  }
242 
243  /* Any kind of discovery reply indicates that there are active
244  * peers on a local network, so restore the recommended
245  * discovery timeout to its default value for future requests.
246  */
248  DBGC ( socket, "PEERDISC %s restoring timeout to %d seconds\n",
250  }
252 
253  /* Iterate over segment IDs */
254  for ( id = reply.ids ; *id ; id += ( strlen ( id ) + 1 /* NUL */ ) ) {
255 
256  /* Find corresponding segment */
257  segment = peerdisc_find ( id );
258  if ( ! segment ) {
259  DBGC ( socket, "PEERDISC %s ignoring reply for %s\n",
260  socket->name, id );
261  continue;
262  }
263 
264  /* Report all discovered peer locations */
265  for ( location = reply.locations ; *location ;
266  location += ( strlen ( location ) + 1 /* NUL */ ) ) {
267 
268  /* Report discovered peer location */
269  if ( ( rc = peerdisc_discovered ( segment,
270  location ) ) != 0 )
271  goto err;
272  }
273  }
274 
275  err:
276  free_iob ( iobuf );
277  return rc;
278 }
uint16_t segment
Code segment.
Definition: librm.h:252
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:145
A PeerDist discovery segment.
Definition: peerdisc.h:42
#define DBGC(...)
Definition: compiler.h:505
#define PEERDISC_DISCARD_RATE
Definition: fault.h:18
static struct peerdisc_segment * peerdisc_find(const char *id)
Find PeerDist discovery segment.
Definition: peerdisc.c:362
#define DBGC_HDA(...)
Definition: compiler.h:506
A PeerDist discovery reply.
Definition: pccrd.h:30
uint8_t id
Request identifier.
Definition: ena.h:12
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:151
size_t strlen(const char *src)
Get length of string.
Definition: string.c:213
void * data
Start of data.
Definition: iobuf.h:44
static int peerdisc_discovered(struct peerdisc_segment *segment, const char *location)
Add discovered PeerDist peer.
Definition: peerdisc.c:381
const char * name
Name.
Definition: peerdisc.h:24
#define PEERDISC_DEFAULT_TIMEOUT_SECS
Default discovery timeout (in seconds)
Definition: peerdisc.c:60
unsigned int peerdisc_timeout_secs
Recommended discovery timeout (in seconds)
Definition: peerdisc.c:74

References io_buffer::data, DBGC, DBGC_HDA, free_iob(), id, peerdist_discovery_reply::ids, iob_len(), peerdist_discovery_reply::locations, peerdisc_socket::name, PEERDISC_DEFAULT_TIMEOUT_SECS, PEERDISC_DISCARD_RATE, peerdisc_discovered(), peerdisc_find(), peerdisc_timeout_secs, rc, segment, strerror(), and strlen().

◆ peerdisc_socket_close()

static void peerdisc_socket_close ( int  rc)
static

Close all PeerDist discovery sockets.

Parameters
rcReason for close

Definition at line 285 of file peerdisc.c.

285  {
286  struct peerdisc_socket *socket;
287 
288  /* Close all sockets */
290  intf_restart ( &socket->xfer, rc );
291 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition: interface.c:337
A PeerDist discovery socket.
Definition: peerdisc.h:22
#define PEERDISC_SOCKETS
PeerDist discovery socket table.
Definition: peerdisc.h:36
struct interface xfer
Data transfer interface.
Definition: peerdisc.h:26
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:358

References for_each_table_entry, intf_restart(), PEERDISC_SOCKETS, rc, and peerdisc_socket::xfer.

Referenced by peerdisc_close().

◆ peerdisc_free()

static void peerdisc_free ( struct refcnt refcnt)
static

Free PeerDist discovery segment.

Parameters
refcntReference count

Definition at line 340 of file peerdisc.c.

340  {
341  struct peerdisc_segment *segment =
343  struct peerdisc_peer *peer;
344  struct peerdisc_peer *tmp;
345 
346  /* Free all discovered peers */
347  list_for_each_entry_safe ( peer, tmp, &segment->peers, list ) {
348  list_del ( &peer->list );
349  free ( peer );
350  }
351 
352  /* Free segment */
353  free ( segment );
354 }
uint16_t segment
Code segment.
Definition: librm.h:252
A PeerDist discovery segment.
Definition: peerdisc.h:42
A reference counter.
Definition: refcnt.h:26
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition: list.h:447
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
uint8_t * tmp
Definition: entropy.h:156
struct list_head list
List of peers.
Definition: peerdisc.h:73
A PeerDist discovery peer.
Definition: peerdisc.h:71

References container_of, free, peerdisc_peer::list, list_del, list_for_each_entry_safe, segment, and tmp.

Referenced by peerdisc_create().

◆ peerdisc_expired()

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

Handle discovery timer expiry.

Parameters
timerDiscovery timer
overFailure indicator

Definition at line 419 of file peerdisc.c.

419  {
420  struct peerdisc_segment *segment =
422 
423  /* Attempt to transmit discovery requests */
424  peerdisc_socket_tx ( segment->uuid, segment->id );
425 
426  /* Schedule next transmission, if applicable */
427  if ( timer->count < PEERDISC_REPEAT_COUNT )
429 }
uint16_t segment
Code segment.
Definition: librm.h:252
static void peerdisc_socket_tx(const char *uuid, const char *id)
Attempt to transmit PeerDist discovery requests on all sockets.
Definition: peerdisc.c:154
A PeerDist discovery segment.
Definition: peerdisc.h:42
A timer.
Definition: timer.h:28
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
#define PEERDISC_REPEAT_TIMEOUT
Time between repeated discovery attempts.
Definition: peerdisc.c:57
void start_timer_fixed(struct retry_timer *timer, unsigned long timeout)
Start timer with a specified timeout.
Definition: retry.c:64
#define PEERDISC_REPEAT_COUNT
Number of repeated discovery attempts.
Definition: peerdisc.c:54

References container_of, PEERDISC_REPEAT_COUNT, PEERDISC_REPEAT_TIMEOUT, peerdisc_socket_tx(), segment, and start_timer_fixed().

Referenced by peerdisc_create().

◆ peerdisc_create()

static struct peerdisc_segment* peerdisc_create ( const char *  id)
static

Create PeerDist discovery segment.

Parameters
idSegment ID
Return values
segmentPeerDist discovery segment, or NULL on error

Definition at line 437 of file peerdisc.c.

437  {
438  struct peerdisc_segment *segment;
439  union {
440  union uuid uuid;
441  uint32_t dword[ sizeof ( union uuid ) / sizeof ( uint32_t ) ];
442  } random_uuid;
443  size_t uuid_len;
444  size_t id_len;
445  const char *uuid;
446  char *uuid_copy;
447  char *id_copy;
448  unsigned int i;
449  int rc;
450 
451  /* Generate a random message UUID. This does not require high
452  * quality randomness.
453  */
454  for ( i = 0 ; i < ( sizeof ( random_uuid.dword ) /
455  sizeof ( random_uuid.dword[0] ) ) ; i++ )
456  random_uuid.dword[i] = random();
457  uuid = uuid_ntoa ( &random_uuid.uuid );
458 
459  /* Calculate string lengths */
460  id_len = ( strlen ( id ) + 1 /* NUL */ );
461  uuid_len = ( strlen ( uuid ) + 1 /* NUL */ );
462 
463  /* Allocate and initialise structure */
464  segment = zalloc ( sizeof ( *segment ) + id_len + uuid_len );
465  if ( ! segment )
466  goto err_alloc;
467  id_copy = ( ( ( void * ) segment ) + sizeof ( *segment ) );
468  memcpy ( id_copy, id, id_len );
469  uuid_copy = ( ( ( void * ) id_copy ) + id_len );
470  memcpy ( uuid_copy, uuid, uuid_len );
471  ref_init ( &segment->refcnt, peerdisc_free );
472  segment->id = id_copy;
473  segment->uuid = uuid_copy;
474  INIT_LIST_HEAD ( &segment->peers );
475  INIT_LIST_HEAD ( &segment->clients );
476  timer_init ( &segment->timer, peerdisc_expired, &segment->refcnt );
477 
478  /* Add hosted cache server or initiate discovery */
479  if ( peerhost ) {
480 
481  /* Add hosted cache server to list of peers */
482  if ( ( rc = peerdisc_discovered ( segment, peerhost ) ) != 0 )
483  goto err_peerhost;
484 
485  } else {
486 
487  /* Start discovery timer */
488  start_timer_nodelay ( &segment->timer );
489  DBGC2 ( segment, "PEERDISC %p discovering %s\n",
490  segment, segment->id );
491  }
492 
493  /* Add to list of segments, transfer reference to list, and return */
494  list_add_tail ( &segment->list, &peerdisc_segments );
495  return segment;
496 
497  err_peerhost:
498  ref_put ( &segment->refcnt );
499  err_alloc:
500  return NULL;
501 }
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
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
A universally unique ID.
Definition: uuid.h:15
A PeerDist discovery segment.
Definition: peerdisc.h:42
static void peerdisc_free(struct refcnt *refcnt)
Free PeerDist discovery segment.
Definition: peerdisc.c:340
void * memcpy(void *dest, const void *src, size_t len) __nonnull
uint8_t uuid[16]
UUID.
Definition: smbios.h:22
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:93
static char * peerhost
Hosted cache server.
Definition: peerdisc.c:77
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition: random.c:30
size_t strlen(const char *src)
Get length of string.
Definition: string.c:213
static void peerdisc_expired(struct retry_timer *timer, int over __unused)
Handle discovery timer expiry.
Definition: peerdisc.c:419
unsigned int uint32_t
Definition: stdint.h:12
const char * uuid_ntoa(const union uuid *uuid)
Convert UUID to printable string.
Definition: uuid.c:43
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:45
#define DBGC2(...)
Definition: compiler.h:522
static int peerdisc_discovered(struct peerdisc_segment *segment, const char *location)
Add discovered PeerDist peer.
Definition: peerdisc.c:381
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
unsigned long int dword
Definition: smc9000.h:40
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106

References DBGC2, INIT_LIST_HEAD, list_add_tail, memcpy(), NULL, peerdisc_discovered(), peerdisc_expired(), peerdisc_free(), peerhost, random(), rc, ref_init, ref_put, segment, start_timer_nodelay(), strlen(), uuid, uuid_ntoa(), and zalloc().

Referenced by peerdisc_open().

◆ peerdisc_destroy()

static void peerdisc_destroy ( struct peerdisc_segment segment)
static

Destroy PeerDist discovery segment.

Parameters
segmentPeerDist discovery segment

Definition at line 508 of file peerdisc.c.

508  {
509 
510  /* Sanity check */
511  assert ( list_empty ( &segment->clients ) );
512 
513  /* Stop timer */
514  stop_timer ( &segment->timer );
515 
516  /* Remove from list of segments and drop list's reference */
517  list_del ( &segment->list );
518  ref_put ( &segment->refcnt );
519 }
uint16_t segment
Code segment.
Definition: librm.h:252
#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)
void stop_timer(struct retry_timer *timer)
Stop timer.
Definition: retry.c:117
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106

References assert(), list_del, list_empty, ref_put, segment, and stop_timer().

Referenced by peerdisc_close().

◆ peerdisc_open()

int peerdisc_open ( struct peerdisc_client peerdisc,
const void *  id,
size_t  len 
)

Open PeerDist discovery client.

Parameters
peerdiscPeerDist discovery client
idSegment ID
lenLength of segment ID
Return values
rcReturn status code

Definition at line 536 of file peerdisc.c.

537  {
538  struct peerdisc_segment *segment;
539  char id_string[ base16_encoded_len ( len ) + 1 /* NUL */ ];
540  char *id_chr;
541  int rc;
542 
543  /* Construct ID string */
544  base16_encode ( id, len, id_string, sizeof ( id_string ) );
545  for ( id_chr = id_string ; *id_chr ; id_chr++ )
546  *id_chr = toupper ( *id_chr );
547 
548  /* Sanity check */
549  assert ( peerdisc->segment == NULL );
550 
551  /* Open socket if this is the first segment */
552  if ( list_empty ( &peerdisc_segments ) &&
553  ( ( rc = peerdisc_socket_open() ) != 0 ) )
554  return rc;
555 
556  /* Find or create segment */
557  if ( ! ( ( segment = peerdisc_find ( id_string ) ) ||
558  ( segment = peerdisc_create ( id_string ) ) ) )
559  return -ENOMEM;
560 
561  /* Add to list of clients */
562  ref_get ( &segment->refcnt );
563  peerdisc->segment = segment;
564  list_add_tail ( &peerdisc->list, &segment->clients );
565 
566  return 0;
567 }
uint16_t segment
Code segment.
Definition: librm.h:252
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
A PeerDist discovery segment.
Definition: peerdisc.h:42
struct list_head list
List of clients.
Definition: peerdisc.h:83
static struct peerdisc_segment * peerdisc_find(const char *id)
Find PeerDist discovery segment.
Definition: peerdisc.c:362
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:136
static size_t base16_encoded_len(size_t raw_len)
Calculate length of base16-encoded data.
Definition: base16.h:21
static int toupper(int character)
Convert character to upper case.
Definition: ctype.h:109
#define ENOMEM
Not enough space.
Definition: errno.h:534
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:93
uint8_t id_string[24]
ID string.
Definition: eltorito.h:24
#define ref_get(refcnt)
Get additional reference to object.
Definition: refcnt.h:92
struct peerdisc_segment * segment
Discovery segment.
Definition: peerdisc.h:81
static struct peerdisc_segment * peerdisc_create(const char *id)
Create PeerDist discovery segment.
Definition: peerdisc.c:437
uint32_t len
Length.
Definition: ena.h:14
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
static int peerdisc_socket_open(void)
Open all PeerDist discovery sockets.
Definition: peerdisc.c:125

References assert(), base16_encoded_len(), ENOMEM, id_string, len, peerdisc_client::list, list_add_tail, list_empty, NULL, peerdisc_create(), peerdisc_find(), peerdisc_socket_open(), rc, ref_get, peerdisc_client::segment, segment, and toupper().

Referenced by peerblk_open().

◆ peerdisc_close()

void peerdisc_close ( struct peerdisc_client peerdisc)

Close PeerDist discovery client.

Parameters
peerdiscPeerDist discovery client

Definition at line 574 of file peerdisc.c.

574  {
575  struct peerdisc_segment *segment = peerdisc->segment;
576 
577  /* Ignore if discovery is already closed */
578  if ( ! segment )
579  return;
580 
581  /* If no peers were discovered, reduce the recommended
582  * discovery timeout to minimise delays on future requests.
583  */
584  if ( list_empty ( &segment->peers ) && peerdisc_timeout_secs ) {
586  DBGC ( segment, "PEERDISC %p reducing timeout to %d "
587  "seconds\n", peerdisc, peerdisc_timeout_secs );
588  }
589 
590  /* Remove from list of clients */
591  peerdisc->segment = NULL;
592  list_del ( &peerdisc->list );
593  ref_put ( &segment->refcnt );
594 
595  /* If this was the last clients, destroy the segment */
596  if ( list_empty ( &segment->clients ) )
598 
599  /* If there are no more segments, close the socket */
600  if ( list_empty ( &peerdisc_segments ) )
601  peerdisc_socket_close ( 0 );
602 }
uint16_t segment
Code segment.
Definition: librm.h:252
static void peerdisc_socket_close(int rc)
Close all PeerDist discovery sockets.
Definition: peerdisc.c:285
A PeerDist discovery segment.
Definition: peerdisc.h:42
#define DBGC(...)
Definition: compiler.h:505
struct list_head list
List of clients.
Definition: peerdisc.h:83
#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
struct peerdisc_segment * segment
Discovery segment.
Definition: peerdisc.h:81
static void peerdisc_destroy(struct peerdisc_segment *segment)
Destroy PeerDist discovery segment.
Definition: peerdisc.c:508
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106
unsigned int peerdisc_timeout_secs
Recommended discovery timeout (in seconds)
Definition: peerdisc.c:74

References DBGC, peerdisc_client::list, list_del, list_empty, NULL, peerdisc_destroy(), peerdisc_socket_close(), peerdisc_timeout_secs, ref_put, peerdisc_client::segment, and segment.

Referenced by peerblk_close().

◆ __setting()

const struct setting peerhost_setting __setting ( SETTING_MISC  ,
peerhost   
)

PeerDist hosted cache server setting.

◆ apply_peerdisc_settings()

static int apply_peerdisc_settings ( void  )
static

Apply PeerDist discovery settings.

Return values
rcReturn status code

Definition at line 623 of file peerdisc.c.

623  {
624 
625  /* Free any existing hosted cache server */
626  free ( peerhost );
627  peerhost = NULL;
628 
629  /* Fetch hosted cache server */
630  fetch_string_setting_copy ( NULL, &peerhost_setting, &peerhost );
631  if ( peerhost ) {
632  DBGC ( &peerhost, "PEERDISC using hosted cache %s\n",
633  peerhost );
634  }
635 
636  return 0;
637 }
#define DBGC(...)
Definition: compiler.h:505
int fetch_string_setting_copy(struct settings *settings, const struct setting *setting, char **data)
Fetch value of string setting.
Definition: settings.c:877
static char * peerhost
Hosted cache server.
Definition: peerdisc.c:77
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References DBGC, fetch_string_setting_copy(), free, NULL, and peerhost.

Variable Documentation

◆ peerdisc_timeout_secs

unsigned int peerdisc_timeout_secs = PEERDISC_DEFAULT_TIMEOUT_SECS

Recommended discovery timeout (in seconds)

We reduce the recommended discovery timeout whenever a segment fails to discover any peers, and restore the default value whenever a valid discovery reply is received. We continue to send discovery requests even if the recommended timeout is reduced to zero.

This strategy is intended to minimise discovery delays when no peers are available on the network, while allowing downloads to quickly switch back to using PeerDist acceleration if new peers become available.

Definition at line 74 of file peerdisc.c.

Referenced by peerblk_open(), peerdisc_close(), and peerdisc_socket_rx().

◆ peerhost

char* peerhost
static

Hosted cache server.

Definition at line 77 of file peerdisc.c.

Referenced by apply_peerdisc_settings(), and peerdisc_create().

◆ peerdisc_socket_operations

struct interface_operation peerdisc_socket_operations[]
static
Initial value:
= {
}
A PeerDist discovery socket.
Definition: peerdisc.h:22
static int peerdisc_socket_rx(struct peerdisc_socket *socket, struct io_buffer *iobuf, struct xfer_metadata *meta __unused)
Handle received PeerDist discovery reply.
Definition: peerdisc.c:221
#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

PeerDist discovery socket interface operations.

Definition at line 294 of file peerdisc.c.

◆ peerdisc_socket_desc

struct interface_descriptor peerdisc_socket_desc
static
Initial value:
=
A PeerDist discovery socket.
Definition: peerdisc.h:22
static struct interface_operation peerdisc_socket_operations[]
PeerDist discovery socket interface operations.
Definition: peerdisc.c:294
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:65

PeerDist discovery socket interface descriptor.

Definition at line 299 of file peerdisc.c.

◆ __peerdisc_socket

struct peerdisc_socket peerdisc_socket_ipv6 __peerdisc_socket
Initial value:
= {
.name = "IPv4",
.address = {
.sin = {
.sin_family = AF_INET,
.sin_port = htons ( PEERDIST_DISCOVERY_PORT ),
.sin_addr.s_addr = htonl ( PEERDIST_DISCOVERY_IPV4 ),
},
},
}
#define INTF_INIT(descriptor)
Initialise a static object interface.
Definition: interface.h:187
#define PEERDIST_DISCOVERY_IPV4
PeerDist discovery IPv4 address (239.255.255.250)
Definition: pccrd.h:16
#define htonl(value)
Definition: byteswap.h:133
static struct interface_descriptor peerdisc_socket_desc
PeerDist discovery socket interface descriptor.
Definition: peerdisc.c:299
#define PEERDIST_DISCOVERY_PORT
PeerDist discovery port.
Definition: pccrd.h:13
#define htons(value)
Definition: byteswap.h:135
#define AF_INET
IPv4 Internet addresses.
Definition: socket.h:63

PeerDist discovery IPv4 socket.

PeerDist discovery IPv6 socket.

Definition at line 303 of file peerdisc.c.

◆ __settings_applicator

struct settings_applicator peerdisc_applicator __settings_applicator
Initial value:
= {
}
static int apply_peerdisc_settings(void)
Apply PeerDist discovery settings.
Definition: peerdisc.c:623

PeerDist discovery settings applicator.

Definition at line 640 of file peerdisc.c.