1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
|
/*
This file is part of GNUnet.
Copyright (C) 2001-2017 GNUnet e.V.
GNUnet is free software: you can redistribute it and/or modify it
under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License,
or (at your option) any later version.
GNUnet is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Affero General Public License for more details.
*/
/**
* @file cadet/gnunet-service-cadet_peer.h
* @brief Information we track per peer.
* @author Bartlomiej Polot
* @author Christian Grothoff
*/
#ifndef GNUNET_SERVICE_CADET_PEER_H
#define GNUNET_SERVICE_CADET_PEER_H
#include "gnunet-service-cadet.h"
#include "gnunet_hello_lib.h"
/**
* Get the static string for a peer ID.
*
* @param peer Peer.
*
* @return Static string for it's ID.
*/
const char *
GCP_2s (const struct CadetPeer *peer);
/**
* Retrieve the CadetPeer stucture associated with the
* peer. Optionally create one and insert it in the appropriate
* structures if the peer is not known yet.
*
* @param peer_id Full identity of the peer.
* @param create #GNUNET_YES if a new peer should be created if unknown.
* #GNUNET_NO to return NULL if peer is unknown.
* @return Existing or newly created peer structure.
* NULL if unknown and not requested @a create
*/
struct CadetPeer *
GCP_get (const struct GNUNET_PeerIdentity *peer_id,
int create);
/**
* Calculate how desirable a path is for @a cp if
* @a cp is at offset @a off in the path.
*
* @param cp a peer reachable via a path
* @param off offset of @a cp in a path
* @return score how useful a path is to reach @a cp,
* positive scores mean path is more desirable
*/
double
GCP_get_desirability_of_path (struct CadetPeer *cp,
unsigned int off);
/**
* Obtain the peer identity for a `struct CadetPeer`.
*
* @param cp our peer handle
* @return the peer identity
*/
const struct GNUNET_PeerIdentity *
GCP_get_id (struct CadetPeer *cp);
/**
* Iterate over all known peers.
*
* @param iter Iterator.
* @param cls Closure for @c iter.
*/
void
GCP_iterate_all (GNUNET_CONTAINER_PeerMapIterator iter,
void *cls);
/**
* Count the number of known paths toward the peer.
*
* @param cp Peer to get path info.
* @return Number of known paths.
*/
unsigned int
GCP_count_paths (const struct CadetPeer *cp);
/**
* Drop all paths owned by this peer, and do not
* allow new ones to be added: We are shutting down.
*
* @param cp peer to drop paths to
*/
void
GCP_drop_owned_paths (struct CadetPeer *cp);
/**
* Peer path iterator.
*
* @param cls Closure.
* @param path Path itself
* @param off offset of the target peer in @a path
* @return #GNUNET_YES if should keep iterating.
* #GNUNET_NO otherwise.
*/
typedef int
(*GCP_PathIterator) (void *cls,
struct CadetPeerPath *path,
unsigned int off);
/**
* Iterate over the paths to a peer.
*
* @param cp Peer to get path info.
* @param callback Function to call for every path.
* @param callback_cls Closure for @a callback.
* @return Number of iterated paths.
*/
unsigned int
GCP_iterate_paths (struct CadetPeer *cp,
GCP_PathIterator callback,
void *callback_cls);
/**
* Iterate over the paths to @a peer where
* @a peer is at distance @a dist from us.
*
* @param cp Peer to get path info.
* @param dist desired distance of @a peer to us on the path
* @param callback Function to call for every path.
* @param callback_cls Closure for @a callback.
* @return Number of iterated paths.
*/
unsigned int
GCP_iterate_paths_at (struct CadetPeer *cp,
unsigned int dist,
GCP_PathIterator callback,
void *callback_cls);
/**
* Remove an entry from the DLL of all of the paths that this peer is on.
*
* @param cp peer to modify
* @param entry an entry on a path
* @param off offset of this peer on the path
*/
void
GCP_path_entry_remove (struct CadetPeer *cp,
struct CadetPeerPathEntry *entry,
unsigned int off);
/**
* Add an entry to the DLL of all of the paths that this peer is on.
*
* @param cp peer to modify
* @param entry an entry on a path
* @param off offset of this peer on the path
*/
void
GCP_path_entry_add (struct CadetPeer *cp,
struct CadetPeerPathEntry *entry,
unsigned int off);
/**
* Get the tunnel towards a peer.
*
* @param cp Peer to get from.
* @param create #GNUNET_YES to create a tunnel if we do not have one
* @return Tunnel towards peer.
*/
struct CadetTunnel *
GCP_get_tunnel (struct CadetPeer *cp,
int create);
/**
* The tunnel to the given peer no longer exists, remove it from our
* data structures, and possibly clean up the peer itself.
*
* @param cp the peer affected
* @param t the dead tunnel
*/
void
GCP_drop_tunnel (struct CadetPeer *cp,
struct CadetTunnel *t);
/**
* Try adding a @a path to this @a cp. If the peer already
* has plenty of paths, return NULL.
*
* @param cp peer to which the @a path leads to
* @param path a path looking for an owner; may not be fully initialized yet!
* @param off offset of @a cp in @a path
* @param force for attaching the path
* @return NULL if this peer does not care to become a new owner,
* otherwise the node in the peer's path heap for the @a path.
*/
struct GNUNET_CONTAINER_HeapNode *
GCP_attach_path (struct CadetPeer *cp,
struct CadetPeerPath *path,
unsigned int off,
int force);
/**
* This peer can no longer own @a path as the path
* has been extended and a peer further down the line
* is now the new owner.
*
* @param cp old owner of the @a path
* @param path path where the ownership is lost
* @param hn note in @a cp's path heap that must be deleted
*/
void
GCP_detach_path (struct CadetPeer *cp,
struct CadetPeerPath *path,
struct GNUNET_CONTAINER_HeapNode *hn);
/**
* Add a @a connection to this @a cp.
*
* @param cp peer via which the @a connection goes
* @param cc the connection to add
*/
void
GCP_add_connection (struct CadetPeer *cp,
struct CadetConnection *cc);
/**
* Remove a @a connection that went via this @a cp.
*
* @param cp peer via which the @a connection went
* @param cc the connection to remove
*/
void
GCP_remove_connection (struct CadetPeer *cp,
struct CadetConnection *cc);
/**
* We got a HELLO for a @a cp, remember it, and possibly
* trigger adequate actions (like trying to connect).
*
* @param cp the peer we got a HELLO for
* @param hello the HELLO to remember
*/
void
GCP_set_hello (struct CadetPeer *cp,
const struct GNUNET_HELLO_Message *hello);
/**
* Clean up all entries about all peers.
* Must only be called after all tunnels, CORE-connections and
* connections are down.
*/
void
GCP_destroy_all_peers (void);
/**
* Data structure used to track whom we have to notify about changes
* in our ability to transmit to a given peer.
*
* All queue managers will be given equal chance for sending messages
* to @a cp. This construct this guarantees fairness for access to @a
* cp among the different message queues. Each connection or route
* will have its respective message queue managers for each direction.
*/
struct GCP_MessageQueueManager;
/**
* Function to call with updated message queue object.
*
* @param cls closure
* @param available #GNUNET_YES if sending is now possible,
* #GNUNET_NO if sending is no longer possible
* #GNUNET_SYSERR if sending is no longer possible
* and the last envelope was discarded
*/
typedef void
(*GCP_MessageQueueNotificationCallback)(void *cls,
int available);
/**
* Start message queue change notifications. Will create a new slot
* to manage the message queue to the given @a cp.
*
* @param cp peer to notify for
* @param cb function to call if mq becomes available or unavailable
* @param cb_cls closure for @a cb
* @return handle to cancel request
*/
struct GCP_MessageQueueManager *
GCP_request_mq (struct CadetPeer *cp,
GCP_MessageQueueNotificationCallback cb,
void *cb_cls);
/**
* Test if @a cp has a core-level connection
*
* @param cp peer to test
* @return #GNUNET_YES if @a cp has a core-level connection
*/
int
GCP_has_core_connection (struct CadetPeer *cp);
/**
* Send the message in @a env via a @a mqm. Must only be called at
* most once after the respective
* #GCP_MessageQueueNotificationCallback was called with `available`
* set to #GNUNET_YES, and not after the callback was called with
* `available` set to #GNUNET_NO or #GNUNET_SYSERR.
*
* @param mqm message queue manager for the transmission
* @param env envelope with the message to send; must NOT
* yet have a #GNUNET_MQ_notify_sent() callback attached to it
*/
void
GCP_send (struct GCP_MessageQueueManager *mqm,
struct GNUNET_MQ_Envelope *env);
/**
* Send the message in @a env to @a cp, overriding queueing logic.
* This function should only be used to send error messages outside
* of flow and congestion control, similar to ICMP. Note that
* the envelope may be silently discarded as well.
*
* @param cp peer to send the message to
* @param env envelope with the message to send
*/
void
GCP_send_ooo (struct CadetPeer *cp,
struct GNUNET_MQ_Envelope *env);
/**
* Stops message queue change notifications and sends a last message.
* In practice, this is implemented by sending that @a last_env
* message immediately (if any), ignoring queue order.
*
* @param mqm handle matching request to cancel
* @param last_env final message to transmit, or NULL
*/
void
GCP_request_mq_cancel (struct GCP_MessageQueueManager *mqm,
struct GNUNET_MQ_Envelope *last_env);
/**
* Set the message queue to @a mq for peer @a cp and notify watchers.
*
* @param cp peer to modify
* @param mq message queue to set (can be NULL)
*/
void
GCP_set_mq (struct CadetPeer *cp,
struct GNUNET_MQ_Handle *mq);
#endif
|