src: for every AGPL3.0 file, add SPDX identifier.
[oweals/gnunet.git] / src / include / gnunet_ats_service.h
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2010-2015 GNUnet e.V.
4
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  Affero General Public License for more details.
14
15  You should have received a copy of the GNU Affero General Public License
16  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18      SPDX-License-Identifier: AGPL3.0-or-later
19  */
20 /**
21  * @file
22  * Automatic transport selection and outbound bandwidth determination
23  *
24  * @author Christian Grothoff
25  * @author Matthias Wachs
26  *
27  * @defgroup ats  ATS service
28  * Automatic Transport Selection and outbound bandwidth determination
29  *
30  * @see [Documentation](https://gnunet.org/ats-subsystem)
31  *
32  * @{
33  */
34 #ifndef GNUNET_ATS_SERVICE_H
35 #define GNUNET_ATS_SERVICE_H
36
37 #include "gnunet_constants.h"
38 #include "gnunet_util_lib.h"
39 #include "gnunet_hello_lib.h"
40
41
42 /**
43  * Default bandwidth assigned to a network : 64 KB/s
44  */
45 #define GNUNET_ATS_DefaultBandwidth 65536
46
47 /**
48  * Undefined value for an `enum GNUNET_ATS_Property`
49  */
50 #define GNUNET_ATS_VALUE_UNDEFINED UINT32_MAX
51
52 /**
53  * String representation for GNUNET_ATS_VALUE_UNDEFINED
54  */
55 #define GNUNET_ATS_VALUE_UNDEFINED_STR "undefined"
56
57 /**
58  * Maximum bandwidth assigned to a network : 4095 MB/s
59  */
60 #define GNUNET_ATS_MaxBandwidth UINT32_MAX
61
62 /**
63  * Textual equivalent for GNUNET_ATS_MaxBandwidth
64  */
65 #define GNUNET_ATS_MaxBandwidthString "unlimited"
66
67
68 /**
69  * ATS performance characteristics for an address.
70  */
71 struct GNUNET_ATS_Properties
72 {
73
74   /**
75    * Delay.  Time between when the time packet is sent and the packet
76    * arrives.  FOREVER if we did not measure yet.
77    */
78   struct GNUNET_TIME_Relative delay;
79
80   /**
81    * Actual traffic on this connection from this peer to the other peer.
82    * Includes transport overhead.
83    *
84    * Unit: [bytes/second]
85    */
86   uint32_t utilization_out;
87
88   /**
89    * Actual traffic on this connection from the other peer to this peer.
90    * Includes transport overhead.
91    *
92    * Unit: [bytes/second]
93    */
94   uint32_t utilization_in;
95
96   /**
97    * Distance on network layer (required for distance-vector routing)
98    * in hops.  Zero for direct connections (i.e. plain TCP/UDP).
99    */
100   unsigned int distance;
101
102   /**
103    * Which network scope does the respective address belong to?
104    * This property does not change.
105    */
106   enum GNUNET_NetworkType scope;
107
108 };
109
110
111 /**
112  * ATS performance characteristics for an address in
113  * network byte order (for IPC).
114  */
115 struct GNUNET_ATS_PropertiesNBO
116 {
117
118   /**
119    * Actual traffic on this connection from this peer to the other peer.
120    * Includes transport overhead.
121    *
122    * Unit: [bytes/second]
123    */
124   uint32_t utilization_out GNUNET_PACKED;
125
126   /**
127    * Actual traffic on this connection from the other peer to this peer.
128    * Includes transport overhead.
129    *
130    * Unit: [bytes/second]
131    */
132   uint32_t utilization_in GNUNET_PACKED;
133
134   /**
135    * Which network scope does the respective address belong to?
136    * This property does not change.
137    */
138   uint32_t scope GNUNET_PACKED;
139
140   /**
141    * Distance on network layer (required for distance-vector routing)
142    * in hops.  Zero for direct connections (i.e. plain TCP/UDP).
143    */
144   uint32_t distance GNUNET_PACKED;
145
146   /**
147    * Delay.  Time between when the time packet is sent and the packet
148    * arrives.  FOREVER if we did not measure yet.
149    */
150   struct GNUNET_TIME_RelativeNBO delay;
151
152 };
153
154
155
156 /* ********************* LAN Characterization library ************************ */
157 /* Note: these functions do not really communicate with the ATS service */
158
159
160 /**
161  * Convert ATS properties from host to network byte order.
162  *
163  * @param nbo[OUT] value written
164  * @param hbo value read
165  */
166 void
167 GNUNET_ATS_properties_hton (struct GNUNET_ATS_PropertiesNBO *nbo,
168                             const struct GNUNET_ATS_Properties *hbo);
169
170
171 /**
172  * Convert ATS properties from network to host byte order.
173  *
174  * @param hbo[OUT] value written
175  * @param nbo value read
176  */
177 void
178 GNUNET_ATS_properties_ntoh (struct GNUNET_ATS_Properties *hbo,
179                             const struct GNUNET_ATS_PropertiesNBO *nbo);
180
181
182
183 /* ********************Connection Suggestion API ***************************** */
184
185 /**
186  * Handle to the ATS subsystem for making suggestions about
187  * connections the peer would like to have.
188  */
189 struct GNUNET_ATS_ConnectivityHandle;
190
191 /**
192  * Handle for address suggestion requests.
193  */
194 struct GNUNET_ATS_ConnectivitySuggestHandle;
195
196
197 /**
198  * Initialize the ATS connectivity suggestion client handle.
199  *
200  * @param cfg configuration to use
201  * @return ats connectivity handle, NULL on error
202  */
203 struct GNUNET_ATS_ConnectivityHandle *
204 GNUNET_ATS_connectivity_init (const struct GNUNET_CONFIGURATION_Handle *cfg);
205
206
207 /**
208  * Shutdown ATS connectivity suggestion client.
209  *
210  * @param ch handle to destroy
211  */
212 void
213 GNUNET_ATS_connectivity_done (struct GNUNET_ATS_ConnectivityHandle *ch);
214
215
216 /**
217  * We would like to establish a new connection with a peer.  ATS
218  * should suggest a good address to begin with.
219  *
220  * @param ch handle
221  * @param peer identity of the peer we need an address for
222  * @param strength how urgent is the need for such a suggestion
223  * @return suggestion handle, NULL if request is already pending
224  */
225 struct GNUNET_ATS_ConnectivitySuggestHandle *
226 GNUNET_ATS_connectivity_suggest (struct GNUNET_ATS_ConnectivityHandle *ch,
227                                  const struct GNUNET_PeerIdentity *peer,
228                                  uint32_t strength);
229
230
231 /**
232  * We no longer care about being connected to a peer.
233  *
234  * @param sh handle
235  */
236 void
237 GNUNET_ATS_connectivity_suggest_cancel (struct GNUNET_ATS_ConnectivitySuggestHandle *sh);
238
239
240 /* ******************************** Scheduling API ***************************** */
241
242 /**
243  * Handle to the ATS subsystem for bandwidth/transport scheduling information.
244  */
245 struct GNUNET_ATS_SchedulingHandle;
246
247 /**
248  * Opaque session handle, defined by plugins.  Contents not known to ATS.
249  */
250 struct GNUNET_ATS_Session;
251
252
253 /**
254  * Signature of a function called by ATS with the current bandwidth
255  * and address preferences as determined by ATS.  If our connection
256  * to ATS dies and thus all suggestions become invalid, this function
257  * is called ONCE with all arguments (except @a cls) being NULL/0.
258  *
259  * @param cls closure
260  * @param peer for which we suggest an address, NULL if ATS connection died
261  * @param address suggested address (including peer identity of the peer),
262  *             may be NULL to signal disconnect from peer
263  * @param session session to use, NULL to establish a new outgoing session
264  * @param bandwidth_out assigned outbound bandwidth for the connection,
265  *        0 to signal disconnect
266  * @param bandwidth_in assigned inbound bandwidth for the connection,
267  *        0 to signal disconnect
268  */
269 typedef void
270 (*GNUNET_ATS_AddressSuggestionCallback) (void *cls,
271                                          const struct GNUNET_PeerIdentity *peer,
272                                          const struct GNUNET_HELLO_Address *address,
273                                          struct GNUNET_ATS_Session *session,
274                                          struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
275                                          struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in);
276
277
278 /**
279  * Initialize the ATS scheduling subsystem.
280  *
281  * @param cfg configuration to use
282  * @param suggest_cb notification to call whenever the suggestation changed
283  * @param suggest_cb_cls closure for @a suggest_cb
284  * @return ats context
285  */
286 struct GNUNET_ATS_SchedulingHandle *
287 GNUNET_ATS_scheduling_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
288                             GNUNET_ATS_AddressSuggestionCallback suggest_cb,
289                             void *suggest_cb_cls);
290
291
292 /**
293  * Client is done with ATS scheduling, release resources.
294  *
295  * @param sh handle to release
296  */
297 void
298 GNUNET_ATS_scheduling_done (struct GNUNET_ATS_SchedulingHandle *sh);
299
300
301 /**
302  * Handle used within ATS to track an address.
303  */
304 struct GNUNET_ATS_AddressRecord;
305
306
307 /**
308  * We have a new address ATS should know. Addresses have to be added with this
309  * function before they can be: updated, set in use and destroyed
310  *
311  * @param sh handle
312  * @param address the address
313  * @param session session handle (if available, i.e. for incoming connections)
314  * @param prop performance data for the address
315  * @return handle to the address representation inside ATS, NULL
316  *         on error (i.e. ATS knows this exact address already, or
317  *         address is invalid)
318  */
319 struct GNUNET_ATS_AddressRecord *
320 GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh,
321                         const struct GNUNET_HELLO_Address *address,
322                         struct GNUNET_ATS_Session *session,
323                         const struct GNUNET_ATS_Properties *prop);
324
325
326 /**
327  * An address was used to initiate a session.
328  *
329  * @param ar address record to update information for
330  * @param session session handle
331  */
332 void
333 GNUNET_ATS_address_add_session (struct GNUNET_ATS_AddressRecord *ar,
334                                 struct GNUNET_ATS_Session *session);
335
336
337 /**
338  * A @a session was destroyed, disassociate it from the given address
339  * record.  If this was an incoming addess, destroys the address as
340  * well.
341  *
342  * @param ar address record to update information for
343  * @param session session handle
344  * @return #GNUNET_YES if the @a ar was destroyed because
345  *                     it was an incoming address,
346  *         #GNUNET_NO if the @ar was kept because we can
347  *                    use it still to establish a new session
348  */
349 int
350 GNUNET_ATS_address_del_session (struct GNUNET_ATS_AddressRecord *ar,
351                                 struct GNUNET_ATS_Session *session);
352
353
354 /**
355  * We have updated performance statistics for a given address.  Note
356  * that this function can be called for addresses that are currently
357  * in use as well as addresses that are valid but not actively in use.
358  * Furthermore, the peer may not even be connected to us right now (@a
359  * session value of NULL used to signal disconnect, or somehow we
360  * otherwise got updated on @a ats information).  Based on the
361  * information provided, ATS may update bandwidth assignments and
362  * suggest to switch addresses.
363  *
364  * @param ar address record to update information for
365  * @param prop performance data for the address
366  */
367 void
368 GNUNET_ATS_address_update (struct GNUNET_ATS_AddressRecord *ar,
369                            const struct GNUNET_ATS_Properties *prop);
370
371
372 /**
373  * An address got destroyed, stop using it as a valid address.
374  *
375  * @param ar address record to destroy, it's validation has
376  *           expired and ATS may no longer use it
377  */
378 void
379 GNUNET_ATS_address_destroy (struct GNUNET_ATS_AddressRecord *ar);
380
381
382
383 /* ******************************** Performance API ***************************** */
384
385 /**
386  * ATS Handle to obtain and/or modify performance information.
387  */
388 struct GNUNET_ATS_PerformanceHandle;
389
390 /**
391  * Signature of a function that is called with QoS information about an address.
392  *
393  * @param cls closure
394  * @param address the address, NULL if ATS service was disconnected or
395  *        when the iteration is completed in the case of
396  *        #GNUNET_ATS_performance_list_addresses()
397  * @param address_active #GNUNET_YES if this address is actively used
398  *        to maintain a connection to a peer;
399  *        #GNUNET_NO if the address is not actively used;
400  *        #GNUNET_SYSERR if this address is no longer available for ATS
401  * @param bandwidth_out assigned outbound bandwidth for the connection
402  * @param bandwidth_in assigned inbound bandwidth for the connection
403  * @param prop performance data for the address
404  */
405 typedef void
406 (*GNUNET_ATS_AddressInformationCallback) (void *cls,
407                                           const struct GNUNET_HELLO_Address *address,
408                                           int address_active,
409                                           struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
410                                           struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
411                                           const struct GNUNET_ATS_Properties *prop);
412
413
414 /**
415  * Handle for an address listing operation
416  */
417 struct GNUNET_ATS_AddressListHandle;
418
419
420 /**
421  * Get handle to access performance API of the ATS subsystem.
422  *
423  * @param cfg configuration to use
424  * @param addr_info_cb callback called when performance characteristics for
425  *      an address change
426  * @param addr_info_cb_cls closure for @a addr_info_cb
427  * @return ats performance context
428  */
429 struct GNUNET_ATS_PerformanceHandle *
430 GNUNET_ATS_performance_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
431                              GNUNET_ATS_AddressInformationCallback addr_info_cb,
432                              void *addr_info_cb_cls);
433
434
435 /**
436  * Get information about addresses known to the ATS subsystem.
437  *
438  * @param ph the performance handle to use
439  * @param peer peer idm can be NULL for all peers
440  * @param all #GNUNET_YES to get information about all addresses or #GNUNET_NO to
441  *        get only address currently used
442  * @param infocb callback to call with the addresses,
443  *        will callback with address == NULL when done
444  * @param infocb_cls closure for @a infocb
445  * @return handle to abort the operation
446  */
447 struct GNUNET_ATS_AddressListHandle *
448 GNUNET_ATS_performance_list_addresses (struct GNUNET_ATS_PerformanceHandle *ph,
449                                        const struct GNUNET_PeerIdentity *peer,
450                                        int all,
451                                        GNUNET_ATS_AddressInformationCallback infocb,
452                                        void *infocb_cls);
453
454
455 /**
456  * Cancel a pending address listing operation
457  *
458  * @param alh the `struct GNUNET_ATS_AddressListHandle` handle to cancel
459  */
460 void
461 GNUNET_ATS_performance_list_addresses_cancel (struct GNUNET_ATS_AddressListHandle *alh);
462
463
464 /**
465  * Client is done using the ATS performance subsystem, release resources.
466  *
467  * @param ph handle
468  */
469 void
470 GNUNET_ATS_performance_done (struct GNUNET_ATS_PerformanceHandle *ph);
471
472
473 /**
474  * Function called with reservation result.
475  *
476  * @param cls closure
477  * @param peer identifies the peer
478  * @param amount set to the amount that was actually reserved or unreserved;
479  *               either the full requested amount or zero (no partial reservations)
480  * @param res_delay if the reservation could not be satisfied (amount was 0), how
481  *        long should the client wait until re-trying?
482  */
483 typedef void
484 (*GNUNET_ATS_ReservationCallback) (void *cls,
485                                    const struct GNUNET_PeerIdentity *peer,
486                                    int32_t amount,
487                                    struct GNUNET_TIME_Relative res_delay);
488
489
490 /**
491  * Context that can be used to cancel a peer information request.
492  */
493 struct GNUNET_ATS_ReservationContext;
494
495
496 /**
497  * Reserve inbound bandwidth from the given peer.  ATS will look at
498  * the current amount of traffic we receive from the peer and ensure
499  * that the peer could add 'amount' of data to its stream.
500  *
501  * @param ph performance handle
502  * @param peer identifies the peer
503  * @param amount reserve N bytes for receiving, negative
504  *                amounts can be used to undo a (recent) reservation;
505  * @param rcb function to call with the resulting reservation information
506  * @param rcb_cls closure for @a rcb
507  * @return NULL on error
508  * @deprecated will be replaced soon
509  */
510 struct GNUNET_ATS_ReservationContext *
511 GNUNET_ATS_reserve_bandwidth (struct GNUNET_ATS_PerformanceHandle *ph,
512                               const struct GNUNET_PeerIdentity *peer,
513                               int32_t amount,
514                               GNUNET_ATS_ReservationCallback rcb,
515                               void *rcb_cls);
516
517
518 /**
519  * Cancel request for reserving bandwidth.
520  *
521  * @param rc context returned by the original GNUNET_ATS_reserve_bandwidth call
522  */
523 void
524 GNUNET_ATS_reserve_bandwidth_cancel (struct GNUNET_ATS_ReservationContext *rc);
525
526
527 /**
528  * ATS preference types as array initializer
529  */
530 #define GNUNET_ATS_PreferenceType {GNUNET_ATS_PREFERENCE_BANDWIDTH, GNUNET_ATS_PREFERENCE_LATENCY, GNUNET_ATS_PREFERENCE_END}
531
532 /**
533  * ATS preference types as string array initializer
534  */
535 #define GNUNET_ATS_PreferenceTypeString {"BANDWIDTH", "LATENCY", "END" }
536
537 /**
538  * Enum defining all known preference categories.
539  */
540 enum GNUNET_ATS_PreferenceKind
541 {
542
543   /**
544    * Change the peer's bandwidth value (value per byte of bandwidth in
545    * the goal function) to the given amount.  The argument is followed
546    * by a double value giving the desired value (can be negative).
547    * Preference changes are forgotten if peers disconnect.
548    */
549   GNUNET_ATS_PREFERENCE_BANDWIDTH = 0,
550
551   /**
552    * Change the peer's latency value to the given amount.  The
553    * argument is followed by a double value giving the desired value
554    * (can be negative).  The absolute score in the goal function is
555    * the inverse of the latency in microseconds (minimum: 1
556    * microsecond) multiplied by the latency preferences.
557    */
558   GNUNET_ATS_PREFERENCE_LATENCY = 1,
559
560   /**
561    * End of preference list.
562    */
563   GNUNET_ATS_PREFERENCE_END = 2
564
565 };
566
567
568 /**
569  * Convert a GNUNET_ATS_PreferenceType to a string
570  *
571  * @param type the preference type
572  * @return a string or NULL if invalid
573  */
574 const char *
575 GNUNET_ATS_print_preference_type (enum GNUNET_ATS_PreferenceKind type);
576
577
578 /**
579  * Change preferences for the given peer. Preference changes are forgotten if peers
580  * disconnect.
581  *
582  * @param ph performance handle @param peer identifies the peer
583  * @param ... #GNUNET_ATS_PREFERENCE_END-terminated specification of the
584  * desired changes
585  */
586 void
587 GNUNET_ATS_performance_change_preference (struct GNUNET_ATS_PerformanceHandle *ph,
588                                           const struct GNUNET_PeerIdentity *peer,
589                                           ...);
590
591
592 /**
593  * Application feedback on how good preference requirements are fulfilled
594  * for the preferences included in the given time scope [now - scope .. now]
595  *
596  * An application notifies ATS if (and only if) it has feedback information
597  * for specific properties. This values are valid until the feedback scores are
598  * updated by the application.
599  *
600  * If the application has no feedback for this preference kind the application
601  * will not explicitly call for this property and will not include it in this
602  * function call.
603  *
604  * @param ph performance handle
605  * @param scope the time interval this valid for: [now - scope .. now]
606  * @param peer identifies the peer
607  * @param ... #GNUNET_ATS_PREFERENCE_END-terminated specification of the desired changes
608  */
609 void
610 GNUNET_ATS_performance_give_feedback (struct GNUNET_ATS_PerformanceHandle *ph,
611                                       const struct GNUNET_PeerIdentity *peer,
612                                       const struct GNUNET_TIME_Relative scope,
613                                       ...);
614
615 #endif
616
617 /** @} */  /* end of group */
618
619 /* end of file gnunet-service-transport_ats.h */