update tests to use new MQ API
[oweals/gnunet.git] / src / ats / gnunet-service-ats_addresses.h
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2011-2014 GNUnet e.V.
4
5  GNUnet is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published
7  by the Free Software Foundation; either version 3, or (at your
8  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  General Public License for more details.
14
15  You should have received a copy of the GNU General Public License
16  along with GNUnet; see the file COPYING.  If not, write to the
17  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  Boston, MA 02110-1301, USA.
19  */
20
21 /**
22  * @file ats/gnunet-service-ats_addresses.h
23  * @brief ats service address management
24  * @author Matthias Wachs
25  * @author Christian Grothoff
26  */
27 #ifndef GNUNET_SERVICE_ATS_ADDRESSES_H
28 #define GNUNET_SERVICE_ATS_ADDRESSES_H
29
30 #include "gnunet_util_lib.h"
31 #include "gnunet_ats_service.h"
32 #include "gnunet-service-ats.h"
33
34 /**
35  * NOTE: Do not change this documentation. This documentation is based on
36  * gnunet.org:/vcs/fsnsg/ats-paper.git/tech-doku/ats-tech-guide.tex
37  * use build_txt.sh to generate plaintext output
38  *
39  *   1 ATS addresses : ATS address management
40  *
41  *    This ATS addresses ("addresses") component manages the addresses known to
42  *    ATS service and suggests addresses to transport service when it is
43  *    interested in address suggestion for a peer. ATS addresses also
44  *    instantiates the bandwidth assignment mechanism (solver), notifies it
45  *    about changes to addresses and forwards changes to bandwidth assignments
46  *    to transport, depending if transport is interested in this change.
47  *
48  *     1.1 Input data
49  *
50  *       1.1.1 Addresses
51  *
52  *    Addresses are added by specifying peer ID, plugin, address, address length
53  *    and session, if available. ATS information can be specified if available.
54  *
55  *       1.1.2 Networks
56  *
57  *    ATS specifies a fix set of networks an address can belong to. For each
58  *    network an inbound and outbound quota will be specified. The available
59  *    networks and addtional helper varaibles are defined in
60  *    gnunet_ats_service.h. At the moment 5 networks are defined:
61  *      * GNUNET_ATS_NET_UNSPECIFIED
62  *      * GNUNET_ATS_NET_LOOPBACK
63  *      * GNUNET_ATS_NET_LAN
64  *      * GNUNET_ATS_NET_WAN
65  *      * GNUNET_ATS_NET_WLAN
66  *
67  *    The total number of networks defined is stored in
68  *    GNUNET_ATS_NetworkTypeCount GNUNET_ATS_NetworkType can be used array
69  *    initializer for an int array, while GNUNET_ATS_NetworkType is an
70  *    initializer for a char array containing a string description of all
71  *    networks
72  *
73  *       1.1.3 Quotas
74  *
75  *    An inbound and outbound quota for each of the networks mentioned in 1.1.2
76  *    is loaded from ats configuration during initialization. This quota defines
77  *    to total amount of inbound and outbound traffic allowed for a specific
78  *    network. The configuration values used are in section ats:
79  *      * "NETWORK"_QUOTA_IN = <value>
80  *      * "NETWORK"_QUOTA_IN = <value>
81  *
82  *    You can specify quotas by setting the <value> to a:
83  *      * unrestricted: unlimited
84  *      * number of bytes: e.g. 10240
85  *      * fancy value: e.g. 64 Kib
86  *
87  *    unlimited is defined as GNUNET_ATS_MaxBandwidthString and equivalent to
88  *    the value GNUNET_ATS_MaxBandwidth Important predefined values for quotas
89  *    are:
90  *      * GNUNET_ATS_DefaultBandwidth: 65536
91  *      * GNUNET_ATS_MaxBandwidth: UINT32_MAX
92  *      * GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT: 1024
93  *
94  *    Details of loading quotas and default values will be described on
95  *
96  *       1.1.4 Preference values
97  *
98  *     1.2 Data structures used
99  *
100  *    Addresse uses struct ATS_Address for each address. The structs are stored
101  *    in a linked list and provides a pointer void *solver_information for the
102  *    solver to store address specific information. It provides the int values
103  *    active which is set to GNUNET_YES if the address is select for transport
104  *    use and used, representing that transport service is actively using this
105  *    address. Address information are stored in peer, addr, addr_len, plugin.
106  *
107  *     1.3 Initialization
108  *
109  *    During initialization a hashmap to store addresses is created. The quotas
110  *    for all networks defined for ATS are loaded from configuration. For each
111  *    network first the logic will check if the string
112  *    GNUNET_ATS_MaxBandwidthString is configured, if not it will try to convert
113  *    the configured value as a fancy size and if this fails it will try to use
114  *    it as a value_number. If no configuration value is found it will assign
115  *    GNUNET_ATS_DefaultBandwidth. The most important step is to load the
116  *    configured solver using configuration "[ats]:MODE". Current solvers are
117  *    MODE_PROPORTIONAL, MODE_MLP. Interaction is done using a solver API
118  *
119  *     1.4 Solver API
120  *
121  *    Solver functions:
122  *      * s_init: init the solver with required information
123  *      * s_add: add a new address
124  *      * s_update: update ATS values or session for an address
125  *      * s_get: get prefered address for a peer
126  *      * s_del: delete an address
127  *      * s_pref: change preference value for a peer
128  *      * s_done: shutdown solver
129  *
130  *    Callbacks: addresses provides a bandwidth_changed_cb callback to the
131  *    solver which is called when bandwidth assigned to peer has changed
132  *
133  *     1.5 Shutdown
134  *
135  *    During shutdown all addresses are freed and the solver told to shutdown
136  *
137  *     1.6 Addresses and sessions
138  *
139  *    Addresses consist of the address itself and a numerical session. When a
140  *    new address without a session is added it has no session, so it gets
141  *    session 0 assigned. When an address with a session is added and an address
142  *    object with session 0 is found, this object is updated with the session
143  *    otherwise a new address object with this session assigned is created.
144  *
145  *       1.6.1 Terminology
146  *
147  *    Addresses a1,a2 with session s1, s2 are "exact" if:
148  *    (a1 == a2)&&(s1 == s2)
149  *    Addresses a1,a2 with session s1, s2 are "equivalent" if:
150  *    (a1 == a2)&&((s1 == s2)||(s1 == 0)||(s2 == 0)
151  *
152  *     1.7 Address management
153  *
154  *    Transport service notifies ATS about changes to the addresses known to
155  *    him.
156  *
157  *       1.7.1 Adding an address
158  *
159  *    When transport learns a new address it tells ATS and ATS is telling
160  *    addresses about it using GAS_address_add. If not known to addresses it
161  *    creates a new address object and calls solver's s_add. ATS information are
162  *    deserialized and solver is notified about the session and ATS information
163  *    using s_update.
164  *
165  *       1.7.2 Updating an address
166  *
167  *    Addresses does an lookup up for the existing address with the given
168  *    session. If disassembles included ATS information and notifies the solver
169  *    using s_update about the update.
170  *
171  *       1.7.3 Deleting an address
172  *
173  *    Addresses does an lookup for the exact address and session and if removes
174  *    this address. If session != 0 the session is set to 0 and the address is
175  *    kept. If session == 0, the addresses is removed.
176  *
177  *       1.7.4 Requesting an address suggestion
178  *
179  *    The address client issues a request address message to be notified about
180  *    address suggestions for a specific peer. Addresses asks the solver with
181  *    s_get. If no address is available, it will not send a response, otherwise
182  *    it will respond with the choosen address.
183  *
184  *       1.7.5 Address suggestions
185  *
186  *    Addresses will notify the client automatically on any bandwidth_changed_cb
187  *    by the solver if a address suggestion request is pending. If no address is
188  *    available it will not respond at all If the client is not interested
189  *    anymore, it has to cancel the address suggestion request.
190  *
191  *       1.7.6 Suggestions blocks and reset
192  *
193  *    After suggesting an address it is blocked for ATS_BLOCKING_DELTA sec. to
194  *    prevent the client from being thrashed. If the client requires immediately
195  *    it can reset this block using GAS_addresses_handle_backoff_reset.
196  *
197  *       1.7.7 Address lifecycle
198  *
199  *      * (add address)
200  *      * (updated address)
201  *      * (delete address)
202  *
203  *     1.8 Bandwidth assignment
204  *
205  *    The addresses are used to perform resource allocation operations. ATS
206  *    addresses takes care of instantiating the solver configured and notifies
207  *    the respective solver about address changes and receives changes to the
208  *    bandwidth assignment from the solver. The current bandwidth assignment is
209  *    sent to transport. The specific solvers will be described in the specific
210  *    section.
211  *
212  *     1.9 Changing peer preferences
213  *
214  *    The bandwidth assigned to a peer can be influenced by setting a preference
215  *    for a peer. The prefernce will be given to to the solver with s_pref which
216  *    has to take care of the preference value
217  */
218
219
220 /*
221  * How long will address suggestions blocked after a suggestion
222  */
223 #define ATS_BLOCKING_DELTA GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 100)
224
225 /**
226  * Information provided by ATS normalization
227  */
228 struct GAS_NormalizationInfo
229 {
230   /**
231    * Next index to use in averaging queue
232    */
233   unsigned int avg_queue_index;
234
235   /**
236    * Averaging queue
237    */
238   uint64_t atsi_abs[GAS_normalization_queue_length];
239
240   /**
241    * Averaged ATSI values from queue
242    */
243   uint64_t avg;
244
245   /**
246    * Normalized values from queue to a range of values [1.0...2.0]
247    */
248   double norm;
249 };
250
251
252 /**
253  * Address with additional information
254  */
255 struct ATS_Address
256 {
257   /**
258    * Peer ID this address is for.
259    */
260   struct GNUNET_PeerIdentity peer;
261
262   /**
263    * Address (in plugin-specific binary format).
264    */
265   const void *addr;
266
267   /**
268    * Plugin name
269    */
270   char *plugin;
271
272   /**
273    * Solver-specific information for this address
274    */
275   void *solver_information;
276
277   /**
278    * ATS performance information for this address
279    */
280   struct GNUNET_ATS_Properties properties;
281
282   /**
283    * Time when address had last activity (update, in uses)
284    */
285   struct GNUNET_TIME_Absolute t_last_activity;
286
287   /**
288    * Time when address was added
289    */
290   struct GNUNET_TIME_Absolute t_added;
291
292   /**
293    * Address length, number of bytes in @e addr.
294    */
295   size_t addr_len;
296
297   /**
298    * Session ID, can never be 0.
299    */
300   uint32_t session_id;
301
302   /**
303    * Field to store local flags.
304    */
305   enum GNUNET_HELLO_AddressInfo local_address_info;
306
307   /**
308    * ATS performance information for this address, size of the @e atsi array.
309    */
310   uint32_t atsi_count;
311
312   /**
313    * Inbound bandwidth assigned by solver
314    */
315   uint32_t assigned_bw_in;
316
317   /**
318    * Outbound bandwidth assigned by solver
319    */
320   uint32_t assigned_bw_out;
321
322   /**
323    * Inbound bandwidth assigned by solver in NBO
324    */
325   uint32_t last_notified_bw_in;
326
327   /**
328    * Outbound bandwidth assigned by solver in NBO
329    */
330   uint32_t last_notified_bw_out;
331
332   /**
333    * Is this the active address for this peer?
334    */
335   int active;
336
337   /**
338    * Normalized delay information for this address.
339    */
340   struct GAS_NormalizationInfo norm_delay;
341
342   /**
343    * Normalized distance information for this address.
344    */
345   struct GAS_NormalizationInfo norm_distance;
346
347   /**
348    * Normalized utilization inbound for this address.
349    */
350   struct GAS_NormalizationInfo norm_utilization_in;
351
352     /**
353    * Normalized utilization outbound for this address.
354    */
355   struct GAS_NormalizationInfo norm_utilization_out;
356
357 };
358
359
360 /**
361  * A multipeermap mapping peer identities to `struct ATS_Address`.
362  */
363 extern struct GNUNET_CONTAINER_MultiPeerMap *GSA_addresses;
364
365
366 /**
367  * Initialize address subsystem. The addresses subsystem manages the addresses
368  * known and current performance information.
369  *
370  * @param server handle to our server
371  */
372 void
373 GAS_addresses_init (struct GNUNET_SERVER_Handle *server);
374
375
376 /**
377  * Shutdown address subsystem.
378  */
379 void
380 GAS_addresses_done (void);
381
382
383 /**
384  * Add a new address for a peer.
385  *
386  * @param peer peer
387  * @param plugin_name transport plugin name
388  * @param plugin_addr plugin address
389  * @param plugin_addr_len length of the @a plugin_addr
390  * @param local_address_info the local address for the address
391  * @param session_id session id, can never be 0.
392  * @param prop performance information for this address
393  */
394 void
395 GAS_addresses_add (const struct GNUNET_PeerIdentity *peer,
396                    const char *plugin_name,
397                    const void *plugin_addr,
398                    size_t plugin_addr_len,
399                    uint32_t local_address_info,
400                    uint32_t session_id,
401                    const struct GNUNET_ATS_Properties *prop);
402
403
404 /**
405  * Update an address with new performance information for a peer.
406  *
407  * @param peer peer
408  * @param session_id session id, can never be 0
409  * @param prop performance information for this address
410  */
411 void
412 GAS_addresses_update (const struct GNUNET_PeerIdentity *peer,
413                       uint32_t session_id,
414                       const struct GNUNET_ATS_Properties *prop);
415
416
417 /**
418  * Remove an address for a peer.
419  *
420  * @param peer peer
421  * @param session_id session id, can never be 0
422  */
423 void
424 GAS_addresses_destroy (const struct GNUNET_PeerIdentity *peer,
425                        uint32_t session_id);
426
427
428 /**
429  * Remove all addresses.
430  */
431 void
432 GAS_addresses_destroy_all (void);
433
434
435 /**
436  * Iterator for #GAS_addresses_get_peer_info()
437  *
438  * @param cls closure
439  * @param id the peer id
440  * @param plugin_name plugin name
441  * @param plugin_addr address
442  * @param plugin_addr_len length of @a plugin_addr
443  * @param address_active is address actively used
444  * @param atsi ats performance information
445  * @param local_address_info flags for the address
446  * @param bandwidth_out current outbound bandwidth assigned to address
447  * @param bandwidth_in current inbound bandwidth assigned to address
448  */
449 typedef void
450 (*GNUNET_ATS_PeerInfo_Iterator) (void *cls,
451                                  const struct GNUNET_PeerIdentity *id,
452                                  const char *plugin_name,
453                                  const void *plugin_addr,
454                                  size_t plugin_addr_len,
455                                  const int address_active,
456                                  const struct GNUNET_ATS_Properties *prop,
457                                  enum GNUNET_HELLO_AddressInfo local_address_info,
458                                  struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
459                                  struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in);
460
461
462 /**
463  * Return information all peers currently known to ATS
464  *
465  * @param peer the respective peer
466  * @param pi_it the iterator to call for every peer
467  * @param pi_it_cls the closure for @a pi_it
468  */
469 void
470 GAS_addresses_get_peer_info (const struct GNUNET_PeerIdentity *peer,
471                              GNUNET_ATS_PeerInfo_Iterator pi_it,
472                              void *pi_it_cls);
473
474
475 /**
476  * Handle 'address list request' messages from clients.
477  *
478  * @param cls unused, NULL
479  * @param client client that sent the request
480  * @param message the request message
481  */
482 void
483 GAS_handle_request_address_list (void *cls,
484                                  struct GNUNET_SERVER_Client *client,
485                                  const struct GNUNET_MessageHeader *message);
486
487
488 #endif
489
490 /* end of gnunet-service-ats_addresses.h */