diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2012-01-23 15:45:11 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2012-01-23 15:45:11 +0000 |
commit | 1d70588544ceb846af6926f508bc639613a91c2b (patch) | |
tree | fdb346316eaf96bbab69cce917ea49f4dc74d9ee /src/ats | |
parent | a7b0980eb7384cbc169e03d28e0382ffb59597de (diff) | |
download | gnunet-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.c | 135 |
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 | |||
38 | enum ATS_Mode | 40 | enum ATS_Mode |
39 | { | 41 | { |
40 | /** | 42 | /** |
@@ -197,7 +199,11 @@ destroy_address (struct ATS_Address *addr) | |||
197 | struct CompareAddressContext | 199 | struct 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 | |||
280 | static int | ||
281 | compare_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 | */ | ||
307 | struct ATS_Address * | ||
308 | find_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 |