1 #ifndef _IPXE_PEERDISC_H
2 #define _IPXE_PEERDISC_H
3 
4 /** @file
5  *
6  * Peer Content Caching and Retrieval (PeerDist) protocol peer discovery
7  *
8  */
9 
10 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
11 
12 #include <stdint.h>
13 #include <ipxe/refcnt.h>
14 #include <ipxe/list.h>
15 #include <ipxe/tables.h>
16 #include <ipxe/retry.h>
17 #include <ipxe/socket.h>
18 #include <ipxe/interface.h>
19 #include <ipxe/pccrc.h>
20 
21 /** A PeerDist discovery socket */
22 struct peerdisc_socket {
23 	/** Name */
24 	const char *name;
25 	/** Data transfer interface */
26 	struct interface xfer;
27 	/** Socket address */
28 	union {
29 		struct sockaddr sa;
30 		struct sockaddr_in sin;
31 		struct sockaddr_in6 sin6;
32 	} address;
33 };
34 
35 /** PeerDist discovery socket table */
36 #define PEERDISC_SOCKETS __table ( struct peerdisc_socket, "peerdisc_sockets" )
37 
38 /** Declare a PeerDist discovery socket */
39 #define __peerdisc_socket __table_entry ( PEERDISC_SOCKETS, 01 )
40 
41 /** A PeerDist discovery segment */
42 struct peerdisc_segment {
43 	/** Reference count */
44 	struct refcnt refcnt;
45 	/** List of segments */
46 	struct list_head list;
47 	/** Segment identifier string
48 	 *
49 	 * This is MS-PCCRC's "HoHoDk", transcribed as an upper-case
50 	 * Base16-encoded string.
51 	 */
52 	const char *id;
53 	/** Message UUID string */
54 	const char *uuid;
55 	/** List of discovered peers
56 	 *
57 	 * The list of peers may be appended to during the lifetime of
58 	 * the discovery segment.  Discovered peers will not be
59 	 * removed from the list until the last discovery has been
60 	 * closed; this allows users to safely maintain a pointer to a
61 	 * current position within the list.
62 	 */
63 	struct list_head peers;
64 	/** List of active clients */
65 	struct list_head clients;
66 	/** Transmission timer */
67 	struct retry_timer timer;
68 };
69 
70 /** A PeerDist discovery peer */
71 struct peerdisc_peer {
72 	/** List of peers */
73 	struct list_head list;
74 	/** Peer location */
75 	char location[0];
76 };
77 
78 /** A PeerDist discovery client */
79 struct peerdisc_client {
80 	/** Discovery segment */
81 	struct peerdisc_segment *segment;
82 	/** List of clients */
83 	struct list_head list;
84 	/** Operations */
85 	struct peerdisc_client_operations *op;
86 };
87 
88 /** PeerDist discovery client operations */
89 struct peerdisc_client_operations {
90 	/** New peers have been discovered
91 	 *
92 	 * @v peerdisc		PeerDist discovery client
93 	 */
94 	void ( * discovered ) ( struct peerdisc_client *peerdisc );
95 };
96 
97 /**
98  * Initialise PeerDist discovery
99  *
100  * @v peerdisc		PeerDist discovery client
101  * @v op		Discovery operations
102  */
103 static inline __attribute__ (( always_inline )) void
peerdisc_init(struct peerdisc_client * peerdisc,struct peerdisc_client_operations * op)104 peerdisc_init ( struct peerdisc_client *peerdisc,
105 		struct peerdisc_client_operations *op ) {
106 
107 	peerdisc->op = op;
108 }
109 
110 extern unsigned int peerdisc_timeout_secs;
111 
112 extern void peerdisc_stat ( struct interface *intf, struct peerdisc_peer *peer,
113 			    struct list_head *peers );
114 #define peerdisc_stat_TYPE( object_type )				\
115 	typeof ( void ( object_type, struct peerdisc_peer *peer,	\
116 			struct list_head *peers ) )
117 
118 extern int peerdisc_open ( struct peerdisc_client *peerdisc, const void *id,
119 			   size_t len );
120 extern void peerdisc_close ( struct peerdisc_client *peerdisc );
121 
122 #endif /* _IPXE_PEERDISC_H */
123