aboutsummaryrefslogtreecommitdiff
path: root/src/ats
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2012-01-23 15:45:11 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2012-01-23 15:45:11 +0000
commit1d70588544ceb846af6926f508bc639613a91c2b (patch)
treefdb346316eaf96bbab69cce917ea49f4dc74d9ee /src/ats
parenta7b0980eb7384cbc169e03d28e0382ffb59597de (diff)
downloadgnunet-1d70588544ceb846af6926f508bc639613a91c2b.tar.gz
gnunet-1d70588544ceb846af6926f508bc639613a91c2b.zip
fixing mantis 2098:
ats did not lookup addresses correctly ats overwrote existing session when updating addresses
Diffstat (limited to 'src/ats')
-rw-r--r--src/ats/gnunet-service-ats_addresses.c135
1 files changed, 118 insertions, 17 deletions
diff --git a/src/ats/gnunet-service-ats_addresses.c b/src/ats/gnunet-service-ats_addresses.c
index 1f31b9c5c..556214f80 100644
--- a/src/ats/gnunet-service-ats_addresses.c
+++ b/src/ats/gnunet-service-ats_addresses.c
@@ -35,6 +35,8 @@
35#include "gnunet-service-ats_addresses_mlp.h" 35#include "gnunet-service-ats_addresses_mlp.h"
36#endif 36#endif
37 37
38#define VERBOSE GNUNET_EXTRA_LOGGING
39
38enum ATS_Mode 40enum ATS_Mode
39{ 41{
40 /** 42 /**
@@ -197,7 +199,11 @@ destroy_address (struct ATS_Address *addr)
197struct CompareAddressContext 199struct CompareAddressContext
198{ 200{
199 const struct ATS_Address *search; 201 const struct ATS_Address *search;
200 struct ATS_Address *result; 202
203 /* exact_address != NULL if address and session is equal */
204 struct ATS_Address *exact_address;
205 /* exact_address != NULL if address and session is 0 */
206 struct ATS_Address *base_address;
201}; 207};
202 208
203 209
@@ -206,15 +212,35 @@ compare_address_it (void *cls, const GNUNET_HashCode * key, void *value)
206{ 212{
207 struct CompareAddressContext *cac = cls; 213 struct CompareAddressContext *cac = cls;
208 struct ATS_Address *aa = value; 214 struct ATS_Address *aa = value;
215/*
216 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
217 "Comparing to: %s %s %u session %u\n",
218 GNUNET_i2s (&aa->peer), aa->plugin, aa->addr_len, aa->session_id);
219
220*/
221 /* find an exact matching address: aa->addr == cac->search->addr && aa->session == cac->search->session */
222 if ((aa->addr_len == cac->search->addr_len) && (0 == strcmp (aa->plugin, cac->search->plugin)))
223 {
224 if ((0 == memcmp (aa->addr, cac->search->addr, aa->addr_len)) && (aa->session_id == cac->search->session_id))
225 {
226 cac->exact_address = aa;
227 }
228 }
209 229
210 if (((aa->addr_len != cac->search->addr_len) || 230 /* find an matching address: aa->addr == cac->search->addr && aa->session == 0 */
211 (0 != strcmp (aa->plugin, cac->search->plugin)) || 231 /* this address can be used to be updated */
212 (0 != memcmp (aa->addr, cac->search->addr, aa->addr_len))) && 232 if ((aa->addr_len == cac->search->addr_len) && (0 == strcmp (aa->plugin, cac->search->plugin)))
213 ((aa->session_id != cac->search->session_id) || 233 {
214 (cac->search->session_id == 0))) 234 if ((0 == memcmp (aa->addr, cac->search->addr, aa->addr_len)) && (aa->session_id == 0))
235 {
236 cac->base_address = aa;
237 }
238 }
239
240 if (cac->exact_address == NULL)
215 return GNUNET_YES; 241 return GNUNET_YES;
216 cac->result = aa; 242 else
217 return GNUNET_NO; 243 return GNUNET_NO;
218} 244}
219 245
220 246
@@ -233,11 +259,62 @@ find_address (const struct GNUNET_PeerIdentity *peer,
233{ 259{
234 struct CompareAddressContext cac; 260 struct CompareAddressContext cac;
235 261
236 cac.result = NULL; 262 cac.exact_address = NULL;
263 cac.base_address = NULL;
237 cac.search = addr; 264 cac.search = addr;
238 GNUNET_CONTAINER_multihashmap_get_multiple (addresses, &peer->hashPubKey, 265 GNUNET_CONTAINER_multihashmap_get_multiple (addresses, &peer->hashPubKey,
239 &compare_address_it, &cac); 266 &compare_address_it, &cac);
240 return cac.result; 267
268/*
269 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
270 "exact address: %s base address: %s\n",
271 (cac.exact_address != NULL) ? "YES" : "NO",
272 (cac.base_address != NULL) ? "YES" : "NO");
273*/
274 if (cac.exact_address == NULL)
275 return cac.base_address;
276 return cac.exact_address;
277}
278
279
280static int
281compare_address_session_it (void *cls, const GNUNET_HashCode * key, void *value)
282{
283 struct CompareAddressContext *cac = cls;
284 struct ATS_Address *aa = value;
285
286 if ((aa->addr_len == cac->search->addr_len) && (0 == strcmp (aa->plugin, cac->search->plugin)))
287 {
288 if ((0 == memcmp (aa->addr, cac->search->addr, aa->addr_len)) && (aa->session_id == cac->search->session_id))
289 {
290 cac->exact_address = aa;
291 return GNUNET_NO;
292 }
293 }
294 return GNUNET_YES;
295}
296
297
298/**
299 * Find an existing equivalent address record.
300 * Compares by peer identity and network address AND by session ID
301 * (one of the two must match).
302 *
303 * @param peer peer to lookup addresses for
304 * @param addr existing address record
305 * @return existing address record, NULL for none
306 */
307struct ATS_Address *
308find_exact_address (const struct GNUNET_PeerIdentity *peer,
309 const struct ATS_Address *addr)
310{
311 struct CompareAddressContext cac;
312
313 cac.exact_address = NULL;
314 cac.search = addr;
315 GNUNET_CONTAINER_multihashmap_get_multiple (addresses, &peer->hashPubKey,
316 &compare_address_session_it, &cac);
317 return cac.exact_address;
241} 318}
242 319
243 320
@@ -262,6 +339,12 @@ GAS_addresses_update (const struct GNUNET_PeerIdentity *peer,
262 aa->ats_count = atsi_count; 339 aa->ats_count = atsi_count;
263 memcpy (aa->ats, atsi, atsi_count * sizeof (struct GNUNET_ATS_Information)); 340 memcpy (aa->ats, atsi, atsi_count * sizeof (struct GNUNET_ATS_Information));
264 341
342#if DEBUG_ATS
343 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating address for peer `%s' %u\n",
344 GNUNET_i2s (peer),
345 session_id);
346#endif
347 /* Get existing address or address with session == 0 */
265 old = find_address (peer, aa); 348 old = find_address (peer, aa);
266 if (old == NULL) 349 if (old == NULL)
267 { 350 {
@@ -269,15 +352,20 @@ GAS_addresses_update (const struct GNUNET_PeerIdentity *peer,
269 GNUNET_CONTAINER_multihashmap_put (addresses, 352 GNUNET_CONTAINER_multihashmap_put (addresses,
270 &peer->hashPubKey, aa, 353 &peer->hashPubKey, aa,
271 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); 354 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
355#if DEBUG_ATS
272 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Added new address for peer `%s' %X\n", 356 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Added new address for peer `%s' %X\n",
273 GNUNET_i2s (peer), aa); 357 GNUNET_i2s (peer), aa);
358#endif
274 old = aa; 359 old = aa;
275 } 360 }
276 else 361 else
277 { 362 {
278 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 363#if DEBUG_ATS
279 "Updated existing address for peer `%s' %X \n", 364 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
280 GNUNET_i2s (peer), old); 365 "Updated existing address for peer `%s' %p old session %u new session %u\n",
366 GNUNET_i2s (peer), old,
367 old->session_id, session_id);
368#endif
281 GNUNET_free_non_null (old->ats); 369 GNUNET_free_non_null (old->ats);
282 old->session_id = session_id; 370 old->session_id = session_id;
283 old->ats = NULL; 371 old->ats = NULL;
@@ -354,9 +442,11 @@ destroy_by_session_id (void *cls, const GNUNET_HashCode * key, void *value)
354 (aa->addr_len == info->addr_len) && 442 (aa->addr_len == info->addr_len) &&
355 (0 == memcmp (info->addr, aa->addr, aa->addr_len))) 443 (0 == memcmp (info->addr, aa->addr, aa->addr_len)))
356 { 444 {
445#if VERBOSE
357 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 446 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
358 "Deleting address for peer `%s': `%s'\n", 447 "Deleting address for peer `%s': `%s' %u\n",
359 GNUNET_i2s (&aa->peer), aa->plugin); 448 GNUNET_i2s (&aa->peer), aa->plugin, aa->session_id);
449#endif
360 if (GNUNET_YES == destroy_address (aa)) 450 if (GNUNET_YES == destroy_address (aa))
361 recalculate_assigned_bw (); 451 recalculate_assigned_bw ();
362 return GNUNET_OK; 452 return GNUNET_OK;
@@ -367,6 +457,11 @@ destroy_by_session_id (void *cls, const GNUNET_HashCode * key, void *value)
367 if (aa->session_id != 0) 457 if (aa->session_id != 0)
368 GNUNET_break (0 == strcmp (info->plugin, aa->plugin)); 458 GNUNET_break (0 == strcmp (info->plugin, aa->plugin));
369 /* session died */ 459 /* session died */
460#if VERBOSE
461 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
462 "Deleting session for peer `%s': `%s' %u\n",
463 GNUNET_i2s (&aa->peer), aa->plugin, aa->session_id);
464#endif
370 aa->session_id = 0; 465 aa->session_id = 0;
371 466
372 if (GNUNET_YES == aa->active) 467 if (GNUNET_YES == aa->active)
@@ -379,6 +474,11 @@ destroy_by_session_id (void *cls, const GNUNET_HashCode * key, void *value)
379 /* session == 0 and addrlen == 0 : destroy address */ 474 /* session == 0 and addrlen == 0 : destroy address */
380 if (aa->addr_len == 0) 475 if (aa->addr_len == 0)
381 { 476 {
477#if VERBOSE
478 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
479 "Deleting session and address for peer `%s': `%s' %u\n",
480 GNUNET_i2s (&aa->peer), aa->plugin, aa->session_id);
481#endif
382 (void) destroy_address (aa); 482 (void) destroy_address (aa);
383 } 483 }
384 else 484 else
@@ -470,12 +570,13 @@ GAS_addresses_in_use (const struct GNUNET_PeerIdentity *peer,
470 struct ATS_Address *aa; 570 struct ATS_Address *aa;
471 struct ATS_Address *old; 571 struct ATS_Address *old;
472 572
573
473 aa = create_address(peer, plugin_name, plugin_addr, plugin_addr_len, session_id); 574 aa = create_address(peer, plugin_name, plugin_addr, plugin_addr_len, session_id);
474 old = find_address (peer, aa); 575 old = find_exact_address (peer, aa);
475 free_address (aa); 576 free_address (aa);
476 577
477 GNUNET_assert (old != NULL); 578 GNUNET_assert (old != NULL);
478 GNUNET_assert (in_use != old->used); 579 GNUNET_assert (old->used != in_use);
479 old->used = in_use; 580 old->used = in_use;
480 581
481#if HAVE_LIBGLPK 582#if HAVE_LIBGLPK