2 This file is part of GNUnet.
3 (C) 2011 Christian Grothoff (and other contributing authors)
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.
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.
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., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
22 * @file ats/gnunet-service-ats_addresses_simplistic.h
23 * @brief ats simplistic ressource assignment
24 * @author Matthias Wachs
25 * @author Christian Grothoff
28 #include "gnunet_util_lib.h"
29 #include "gnunet-service-ats_addresses.h"
30 #include "gnunet_statistics_service.h"
32 #define LOG(kind,...) GNUNET_log_from (kind, "ats-simplistic",__VA_ARGS__)
35 * A handle for the simplistic solver
37 struct GAS_SIMPLISTIC_Handle
39 unsigned int active_addresses;
41 unsigned long long *quota_in;
42 unsigned long long *quota_out;
47 * Init the simplistic problem solving component
49 * @param cfg configuration handle
50 * @param stats the GNUNET_STATISTICS handle
51 * @return handle for the solver on success, NULL on fail
54 GAS_simplistic_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
55 const struct GNUNET_STATISTICS_Handle *stats,
57 unsigned long long *out_dest,
58 unsigned long long *in_dest,
61 struct GAS_SIMPLISTIC_Handle *solver = GNUNET_malloc (sizeof (struct GAS_SIMPLISTIC_Handle));
63 solver->quota_net = GNUNET_malloc (dest_length * sizeof (int));
64 memcpy (solver->quota_net, network, dest_length * sizeof (int));
66 solver->quota_in = GNUNET_malloc (dest_length * sizeof (unsigned long long));
67 memcpy (solver->quota_in, out_dest, dest_length * sizeof (int));
69 solver->quota_out = GNUNET_malloc (dest_length * sizeof (unsigned long long));
70 memcpy (solver->quota_out, out_dest, dest_length * sizeof (unsigned long long));
77 * Shutdown the simplistic problem solving component
79 * @param solver the respective handle to shutdown
82 GAS_simplistic_done (void *solver)
84 struct GAS_SIMPLISTIC_Handle *s = solver;
85 GNUNET_assert (s != NULL);
86 GNUNET_free (s->quota_net);
87 GNUNET_free (s->quota_in);
88 GNUNET_free (s->quota_out);
93 * Updates a single address in the solve
95 * @param solver the solver Handle
96 * @param addresses the address hashmap containing all addresses
97 * @param address the update address
100 GAS_simplistic_address_update (void *solver, struct GNUNET_CONTAINER_MultiHashMap * addresses, struct ATS_Address *address)
107 * Remove an address from the solver
109 * @param solver the solver handle
110 * @param addresses the address hashmap containing all addresses
111 * @param address the address to remove
114 GAS_simplistic_address_delete (void *solver, struct GNUNET_CONTAINER_MultiHashMap * addresses, struct ATS_Address *address)
122 * Find a "good" address to use for a peer. If we already have an existing
123 * address, we stick to it. Otherwise, we pick by lowest distance and then
126 * @param cls the 'struct ATS_Address**' where we store the result
128 * @param value another 'struct ATS_Address*' to consider using
129 * @return GNUNET_OK (continue to iterate)
132 find_address_it (void *cls, const struct GNUNET_HashCode * key, void *value)
134 struct ATS_Address **previous_p = cls;
135 struct ATS_Address *current = (struct ATS_Address *) value;
136 struct ATS_Address *previous = *previous_p;
137 struct GNUNET_TIME_Absolute now;
139 now = GNUNET_TIME_absolute_get();
141 if (current->blocked_until.abs_value == GNUNET_TIME_absolute_max (now, current->blocked_until).abs_value)
143 /* This address is blocked for suggestion */
144 LOG (GNUNET_ERROR_TYPE_DEBUG,
145 "Address %p blocked for suggestion for %llu ms \n",
147 GNUNET_TIME_absolute_get_difference(now, current->blocked_until).rel_value);
151 if (NULL != previous)
153 if ((0 == strcmp (previous->plugin, "tcp")) &&
154 (0 == strcmp (current->plugin, "tcp")))
156 if ((0 != previous->addr_len) &&
157 (0 == current->addr_len))
159 /* saved address was an outbound address, but we have an inbound address */
160 *previous_p = current;
163 if (0 == previous->addr_len)
165 /* saved address was an inbound address, so do not overwrite */
171 if (NULL == previous)
173 *previous_p = current;
176 if ((ntohl (previous->assigned_bw_in.value__) == 0) &&
177 (ntohl (current->assigned_bw_in.value__) > 0))
179 /* stick to existing connection */
180 *previous_p = current;
183 if (previous->atsp_distance > current->atsp_distance)
185 /* user shorter distance */
186 *previous_p = current;
189 if (previous->atsp_latency.rel_value > current->atsp_latency.rel_value)
191 /* user lower latency */
192 *previous_p = current;
200 update_bw_simple_it (void *cls, const struct GNUNET_HashCode * key, void *value)
202 struct GAS_SIMPLISTIC_Handle *s = cls;
203 struct ATS_Address *aa = value;
205 if (GNUNET_YES != aa->active)
207 GNUNET_assert (s->active_addresses > 0);
212 aa->assigned_bw_in.value__ = htonl (UINT32_MAX / s->active_addresses);
213 aa->assigned_bw_out.value__ = htonl (UINT32_MAX / s->active_addresses);
215 //send_bw_notification (aa);
221 * Some (significant) input changed, recalculate bandwidth assignment
225 recalculate_assigned_bw (void *solver,
226 struct GNUNET_CONTAINER_MultiHashMap * addresses)
228 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
229 "Recalculating bandwidth for all active connections\n");
230 GNUNET_CONTAINER_multihashmap_iterate (addresses, &update_bw_simple_it, solver);
236 * Get the prefered address for a specific peer
238 * @param solver the solver handle
239 * @param addresses the address hashmap containing all addresses
240 * @param peer the identity of the peer
242 const struct ATS_Address *
243 GAS_simplistic_get_preferred_address (void *solver,
244 struct GNUNET_CONTAINER_MultiHashMap * addresses,
245 const struct GNUNET_PeerIdentity *peer)
247 struct GAS_SIMPLISTIC_Handle *s = solver;
248 struct ATS_Address *aa;
250 GNUNET_assert (s != NULL);
252 /* Get address with: stick to current address, lower distance, lower latency */
253 GNUNET_CONTAINER_multihashmap_get_multiple (addresses, &peer->hashPubKey,
254 &find_address_it, &aa);
256 LOG (GNUNET_ERROR_TYPE_DEBUG, "Cannot suggest address for peer `%s'\n", GNUNET_i2s (peer));
259 LOG (GNUNET_ERROR_TYPE_DEBUG, "Suggesting address %p for peer `%s'\n", aa, GNUNET_i2s (peer));
261 if (GNUNET_NO == aa->active)
263 aa->active = GNUNET_YES;
264 s->active_addresses++;
265 recalculate_assigned_bw (s, addresses);
274 * Changes the preferences for a peer in the problem
276 * @param solver the solver handle
277 * @param peer the peer to change the preference for
278 * @param kind the kind to change the preference
279 * @param score the score
282 GAS_simplistic_address_change_preference (void *solver,
283 const struct GNUNET_PeerIdentity *peer,
284 enum GNUNET_ATS_PreferenceKind kind,
290 /* end of gnunet-service-ats_addresses_simplistic.c */