aboutsummaryrefslogtreecommitdiff
path: root/src/cadet/gnunet-service-cadet_paths.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cadet/gnunet-service-cadet_paths.c')
-rw-r--r--src/cadet/gnunet-service-cadet_paths.c701
1 files changed, 352 insertions, 349 deletions
diff --git a/src/cadet/gnunet-service-cadet_paths.c b/src/cadet/gnunet-service-cadet_paths.c
index 149ac659a..e4a8dc789 100644
--- a/src/cadet/gnunet-service-cadet_paths.c
+++ b/src/cadet/gnunet-service-cadet_paths.c
@@ -30,13 +30,14 @@
30#include "gnunet-service-cadet_paths.h" 30#include "gnunet-service-cadet_paths.h"
31 31
32 32
33#define LOG(level, ...) GNUNET_log_from(level, "cadet-pat", __VA_ARGS__) 33#define LOG(level, ...) GNUNET_log_from (level, "cadet-pat", __VA_ARGS__)
34 34
35 35
36/** 36/**
37 * Information regarding a possible path to reach a peer. 37 * Information regarding a possible path to reach a peer.
38 */ 38 */
39struct CadetPeerPath { 39struct CadetPeerPath
40{
40 /** 41 /**
41 * Array of all the peers on the path. If @e hn is non-NULL, the 42 * Array of all the peers on the path. If @e hn is non-NULL, the
42 * last one is our owner. 43 * last one is our owner.
@@ -68,18 +69,18 @@ struct CadetPeerPath {
68 * @param path path to calculate the score for 69 * @param path path to calculate the score for
69 */ 70 */
70static void 71static void
71recalculate_path_desirability(struct CadetPeerPath *path) 72recalculate_path_desirability (struct CadetPeerPath *path)
72{ 73{
73 double result = 0.0; 74 double result = 0.0;
74 75
75 for (unsigned int i = 0; i < path->entries_length; i++) 76 for (unsigned int i = 0; i < path->entries_length; i++)
76 { 77 {
77 struct CadetPeer *cp = path->entries[i]->peer; 78 struct CadetPeer *cp = path->entries[i]->peer;
78 79
79 result += GCP_get_desirability_of_path(cp, 80 result += GCP_get_desirability_of_path (cp,
80 i); 81 i);
81 } 82 }
82 path->desirability = (GNUNET_CONTAINER_HeapCostType)result; 83 path->desirability = (GNUNET_CONTAINER_HeapCostType) result;
83} 84}
84 85
85 86
@@ -97,7 +98,7 @@ recalculate_path_desirability(struct CadetPeerPath *path)
97 * @return desirability of the path, larger is more desirable 98 * @return desirability of the path, larger is more desirable
98 */ 99 */
99GNUNET_CONTAINER_HeapCostType 100GNUNET_CONTAINER_HeapCostType
100GCPP_get_desirability(const struct CadetPeerPath *path) 101GCPP_get_desirability (const struct CadetPeerPath *path)
101{ 102{
102 return path->desirability; 103 return path->desirability;
103} 104}
@@ -114,15 +115,15 @@ GCPP_get_desirability(const struct CadetPeerPath *path)
114 * otherwise connection from us to @a destination via @a path 115 * otherwise connection from us to @a destination via @a path
115 */ 116 */
116struct CadetConnection * 117struct CadetConnection *
117GCPP_get_connection(struct CadetPeerPath *path, 118GCPP_get_connection (struct CadetPeerPath *path,
118 struct CadetPeer *destination, 119 struct CadetPeer *destination,
119 unsigned int off) 120 unsigned int off)
120{ 121{
121 struct CadetPeerPathEntry *entry; 122 struct CadetPeerPathEntry *entry;
122 123
123 GNUNET_assert(off < path->entries_length); 124 GNUNET_assert (off < path->entries_length);
124 entry = path->entries[off]; 125 entry = path->entries[off];
125 GNUNET_assert(entry->peer == destination); 126 GNUNET_assert (entry->peer == destination);
126 return entry->cc; 127 return entry->cc;
127} 128}
128 129
@@ -136,21 +137,21 @@ GCPP_get_connection(struct CadetPeerPath *path,
136 * @param cc the connection to remember 137 * @param cc the connection to remember
137 */ 138 */
138void 139void
139GCPP_add_connection(struct CadetPeerPath *path, 140GCPP_add_connection (struct CadetPeerPath *path,
140 unsigned int off, 141 unsigned int off,
141 struct CadetConnection *cc) 142 struct CadetConnection *cc)
142{ 143{
143 struct CadetPeerPathEntry *entry; 144 struct CadetPeerPathEntry *entry;
144 145
145 LOG(GNUNET_ERROR_TYPE_DEBUG, 146 LOG (GNUNET_ERROR_TYPE_DEBUG,
146 "Adding %s to path %s at offset %u\n", 147 "Adding %s to path %s at offset %u\n",
147 GCC_2s(cc), 148 GCC_2s (cc),
148 GCPP_2s(path), 149 GCPP_2s (path),
149 off); 150 off);
150 GNUNET_assert(off < path->entries_length); 151 GNUNET_assert (off < path->entries_length);
151 entry = path->entries[off]; 152 entry = path->entries[off];
152 GNUNET_assert(NULL == entry->cc); 153 GNUNET_assert (NULL == entry->cc);
153 GNUNET_assert(NULL != cc); 154 GNUNET_assert (NULL != cc);
154 entry->cc = cc; 155 entry->cc = cc;
155} 156}
156 157
@@ -165,20 +166,20 @@ GCPP_add_connection(struct CadetPeerPath *path,
165 * @param cc the connection to forget 166 * @param cc the connection to forget
166 */ 167 */
167void 168void
168GCPP_del_connection(struct CadetPeerPath *path, 169GCPP_del_connection (struct CadetPeerPath *path,
169 unsigned int off, 170 unsigned int off,
170 struct CadetConnection *cc) 171 struct CadetConnection *cc)
171{ 172{
172 struct CadetPeerPathEntry *entry; 173 struct CadetPeerPathEntry *entry;
173 174
174 LOG(GNUNET_ERROR_TYPE_DEBUG, 175 LOG (GNUNET_ERROR_TYPE_DEBUG,
175 "Removing connection %s to path %s at offset %u\n", 176 "Removing connection %s to path %s at offset %u\n",
176 GCC_2s(cc), 177 GCC_2s (cc),
177 GCPP_2s(path), 178 GCPP_2s (path),
178 off); 179 off);
179 GNUNET_assert(off < path->entries_length); 180 GNUNET_assert (off < path->entries_length);
180 entry = path->entries[off]; 181 entry = path->entries[off];
181 GNUNET_assert(cc == entry->cc); 182 GNUNET_assert (cc == entry->cc);
182 entry->cc = NULL; 183 entry->cc = NULL;
183} 184}
184 185
@@ -193,42 +194,42 @@ GCPP_del_connection(struct CadetPeerPath *path,
193 * @param stop_at the path length at which to stop trying 194 * @param stop_at the path length at which to stop trying
194 */ 195 */
195static void 196static void
196attach_path(struct CadetPeerPath *path, unsigned int stop_at) 197attach_path (struct CadetPeerPath *path, unsigned int stop_at)
197{ 198{
198 GNUNET_assert(NULL == path->hn); 199 GNUNET_assert (NULL == path->hn);
199 200
200 /* Try to attach this path to a peer, working backwards from the end. */ 201 /* Try to attach this path to a peer, working backwards from the end. */
201 while (path->entries_length > stop_at) 202 while (path->entries_length > stop_at)
202 { 203 {
203 unsigned int end = path->entries_length - 1; 204 unsigned int end = path->entries_length - 1;
204 struct CadetPeerPathEntry *entry = path->entries[end]; 205 struct CadetPeerPathEntry *entry = path->entries[end];
205 int force = GNUNET_NO; 206 int force = GNUNET_NO;
206 207
207 recalculate_path_desirability(path); 208 recalculate_path_desirability (path);
208 /* If the entry already has a connection using it, force attach. */ 209 /* If the entry already has a connection using it, force attach. */
209 if (NULL != entry->cc) 210 if (NULL != entry->cc)
210 force = GNUNET_YES; 211 force = GNUNET_YES;
211 path->hn = GCP_attach_path(entry->peer, 212 path->hn = GCP_attach_path (entry->peer,
212 path, 213 path,
213 end, 214 end,
214 force); 215 force);
215 if (NULL != path->hn) 216 if (NULL != path->hn)
216 break; 217 break;
217 218
218 /* Attach failed, trim this entry from the path. */ 219 /* Attach failed, trim this entry from the path. */
219 GNUNET_assert(NULL == entry->cc); 220 GNUNET_assert (NULL == entry->cc);
220 GCP_path_entry_remove(entry->peer, 221 GCP_path_entry_remove (entry->peer,
221 entry, 222 entry,
222 end); 223 end);
223 GNUNET_free(entry); 224 GNUNET_free (entry);
224 path->entries[end] = NULL; 225 path->entries[end] = NULL;
225 path->entries_length--; 226 path->entries_length--;
226 } 227 }
227 228
228 /* Shrink array to actual path length. */ 229 /* Shrink array to actual path length. */
229 GNUNET_array_grow(path->entries, 230 GNUNET_array_grow (path->entries,
230 path->entries_length, 231 path->entries_length,
231 path->entries_length); 232 path->entries_length);
232} 233}
233 234
234 235
@@ -240,33 +241,33 @@ attach_path(struct CadetPeerPath *path, unsigned int stop_at)
240 * @param path the path that is being released 241 * @param path the path that is being released
241 */ 242 */
242void 243void
243GCPP_release(struct CadetPeerPath *path) 244GCPP_release (struct CadetPeerPath *path)
244{ 245{
245 struct CadetPeerPathEntry *entry; 246 struct CadetPeerPathEntry *entry;
246 247
247 LOG(GNUNET_ERROR_TYPE_DEBUG, 248 LOG (GNUNET_ERROR_TYPE_DEBUG,
248 "Owner releases path %s\n", 249 "Owner releases path %s\n",
249 GCPP_2s(path)); 250 GCPP_2s (path));
250 path->hn = NULL; 251 path->hn = NULL;
251 entry = path->entries[path->entries_length - 1]; 252 entry = path->entries[path->entries_length - 1];
252 GNUNET_assert(path == entry->path); 253 GNUNET_assert (path == entry->path);
253 GNUNET_assert(NULL == entry->cc); 254 GNUNET_assert (NULL == entry->cc);
254 /* cut 'off' end of path */ 255 /* cut 'off' end of path */
255 GCP_path_entry_remove(entry->peer, 256 GCP_path_entry_remove (entry->peer,
256 entry, 257 entry,
257 path->entries_length - 1); 258 path->entries_length - 1);
258 GNUNET_free(entry); 259 GNUNET_free (entry);
259 path->entries[path->entries_length - 1] = NULL; 260 path->entries[path->entries_length - 1] = NULL;
260 path->entries_length--; 261 path->entries_length--;
261 /* see if new peer at the end likes this path any better */ 262 /* see if new peer at the end likes this path any better */
262 attach_path(path, 0); 263 attach_path (path, 0);
263 if (NULL == path->hn) 264 if (NULL == path->hn)
264 { 265 {
265 /* nobody wants us, discard the path */ 266 /* nobody wants us, discard the path */
266 GNUNET_assert(0 == path->entries_length); 267 GNUNET_assert (0 == path->entries_length);
267 GNUNET_assert(NULL == path->entries); 268 GNUNET_assert (NULL == path->entries);
268 GNUNET_free(path); 269 GNUNET_free (path);
269 } 270 }
270} 271}
271 272
272 273
@@ -279,38 +280,39 @@ GCPP_release(struct CadetPeerPath *path)
279 * @param delta change in the score to apply 280 * @param delta change in the score to apply
280 */ 281 */
281void 282void
282GCPP_update_score(struct CadetPeerPath *path, 283GCPP_update_score (struct CadetPeerPath *path,
283 unsigned int off, 284 unsigned int off,
284 int delta) 285 int delta)
285{ 286{
286 struct CadetPeerPathEntry *entry; 287 struct CadetPeerPathEntry *entry;
287 288
288 GNUNET_assert(off < path->entries_length); 289 GNUNET_assert (off < path->entries_length);
289 entry = path->entries[off]; 290 entry = path->entries[off];
290 291
291 /* Add delta, with checks for overflows */ 292 /* Add delta, with checks for overflows */
292 if (delta >= 0) 293 if (delta >= 0)
293 { 294 {
294 if (delta + entry->score < entry->score) 295 if (delta + entry->score < entry->score)
295 entry->score = INT_MAX; 296 entry->score = INT_MAX;
296 else 297 else
297 entry->score += delta; 298 entry->score += delta;
298 } 299 }
299 else 300 else
300 { 301 {
301 if (delta + entry->score > entry->score) 302 if (delta + entry->score > entry->score)
302 entry->score = INT_MIN; 303 entry->score = INT_MIN;
303 else 304 else
304 entry->score += delta; 305 entry->score += delta;
305 } 306 }
306 recalculate_path_desirability(path); 307 recalculate_path_desirability (path);
307} 308}
308 309
309 310
310/** 311/**
311 * Closure for #find_peer_at() and #check_match(). 312 * Closure for #find_peer_at() and #check_match().
312 */ 313 */
313struct CheckMatchContext { 314struct CheckMatchContext
315{
314 /** 316 /**
315 * Set to a matching path, if any. 317 * Set to a matching path, if any.
316 */ 318 */
@@ -339,38 +341,38 @@ struct CheckMatchContext {
339 * @return #GNUNET_YES (continue to iterate), or if found #GNUNET_NO 341 * @return #GNUNET_YES (continue to iterate), or if found #GNUNET_NO
340 */ 342 */
341static int 343static int
342check_match(void *cls, 344check_match (void *cls,
343 struct CadetPeerPath *path, 345 struct CadetPeerPath *path,
344 unsigned int off) 346 unsigned int off)
345{ 347{
346 struct CheckMatchContext *cm_ctx = cls; 348 struct CheckMatchContext *cm_ctx = cls;
347 349
348 GNUNET_assert(path->entries_length > off); 350 GNUNET_assert (path->entries_length > off);
349 if ((path->entries_length != off + 1) && 351 if ((path->entries_length != off + 1) &&
350 (off + 1 != cm_ctx->cpath_length)) 352 (off + 1 != cm_ctx->cpath_length))
351 { 353 {
352 LOG(GNUNET_ERROR_TYPE_DEBUG, 354 LOG (GNUNET_ERROR_TYPE_DEBUG,
353 "check_match mismatch because path %s is too long (%u vs. %u vs. %u)\n", 355 "check_match mismatch because path %s is too long (%u vs. %u vs. %u)\n",
354 GCPP_2s(path), 356 GCPP_2s (path),
355 path->entries_length, 357 path->entries_length,
356 off + 1, 358 off + 1,
357 cm_ctx->cpath_length); 359 cm_ctx->cpath_length);
358 return GNUNET_YES; /* too long, goes somewhere else already, thus cannot be useful */ 360 return GNUNET_YES; /* too long, goes somewhere else already, thus cannot be useful */
359 } 361 }
360 for (unsigned int i = 0; i < off; i++) 362 for (unsigned int i = 0; i < off; i++)
361 if (cm_ctx->cpath[i] != 363 if (cm_ctx->cpath[i] !=
362 GCPP_get_peer_at_offset(path, 364 GCPP_get_peer_at_offset (path,
363 i)) 365 i))
364 { 366 {
365 LOG(GNUNET_ERROR_TYPE_DEBUG, 367 LOG (GNUNET_ERROR_TYPE_DEBUG,
366 "check_match path %s mismatches at offset %u\n", 368 "check_match path %s mismatches at offset %u\n",
367 GCPP_2s(path), 369 GCPP_2s (path),
368 i); 370 i);
369 return GNUNET_YES; /* mismatch, ignore */ 371 return GNUNET_YES; /* mismatch, ignore */
370 } 372 }
371 LOG(GNUNET_ERROR_TYPE_DEBUG, 373 LOG (GNUNET_ERROR_TYPE_DEBUG,
372 "check_match found match with path %s\n", 374 "check_match found match with path %s\n",
373 GCPP_2s(path)); 375 GCPP_2s (path));
374 cm_ctx->match = path; 376 cm_ctx->match = path;
375 return GNUNET_NO; /* match, we are done! */ 377 return GNUNET_NO; /* match, we are done! */
376} 378}
@@ -387,70 +389,70 @@ check_match(void *cls,
387 * paths already 389 * paths already
388 */ 390 */
389static void 391static void
390extend_path(struct CadetPeerPath *path, 392extend_path (struct CadetPeerPath *path,
391 struct CadetPeer **peers, 393 struct CadetPeer **peers,
392 unsigned int num_peers, 394 unsigned int num_peers,
393 int force) 395 int force)
394{ 396{
395 unsigned int old_len = path->entries_length; 397 unsigned int old_len = path->entries_length;
396 int i; 398 int i;
397 399
398 /* Expand path */ 400 /* Expand path */
399 GNUNET_array_grow(path->entries, 401 GNUNET_array_grow (path->entries,
400 path->entries_length, 402 path->entries_length,
401 old_len + num_peers); 403 old_len + num_peers);
402 for (i = num_peers - 1; i >= 0; i--) 404 for (i = num_peers - 1; i >= 0; i--)
403 { 405 {
404 struct CadetPeerPathEntry *entry = GNUNET_new(struct CadetPeerPathEntry); 406 struct CadetPeerPathEntry *entry = GNUNET_new (struct CadetPeerPathEntry);
405 407
406 path->entries[old_len + i] = entry; 408 path->entries[old_len + i] = entry;
407 entry->peer = peers[i]; 409 entry->peer = peers[i];
408 entry->path = path; 410 entry->path = path;
409 } 411 }
410 for (i = num_peers - 1; i >= 0; i--) 412 for (i = num_peers - 1; i >= 0; i--)
411 { 413 {
412 struct CadetPeerPathEntry *entry = path->entries[old_len + i]; 414 struct CadetPeerPathEntry *entry = path->entries[old_len + i];
413 415
414 GCP_path_entry_add(entry->peer, 416 GCP_path_entry_add (entry->peer,
415 entry, 417 entry,
416 old_len + i); 418 old_len + i);
417 } 419 }
418 420
419 /* If we extend an existing path, detach it from the 421 /* If we extend an existing path, detach it from the
420 old owner and re-attach to the new one */ 422 old owner and re-attach to the new one */
421 GCP_detach_path(path->entries[old_len - 1]->peer, 423 GCP_detach_path (path->entries[old_len - 1]->peer,
422 path, 424 path,
423 path->hn); 425 path->hn);
424 path->hn = NULL; 426 path->hn = NULL;
425 path->entries_length = old_len + num_peers; 427 path->entries_length = old_len + num_peers;
426 if (GNUNET_YES == force) 428 if (GNUNET_YES == force)
427 { 429 {
428 int end = path->entries_length - 1; 430 int end = path->entries_length - 1;
429 431
430 path->hn = GCP_attach_path(path->entries[end]->peer, 432 path->hn = GCP_attach_path (path->entries[end]->peer,
431 path, 433 path,
432 end, 434 end,
433 GNUNET_YES); 435 GNUNET_YES);
434 } 436 }
435 else 437 else
436 { 438 {
437 attach_path(path, old_len); 439 attach_path (path, old_len);
438 } 440 }
439 if (NULL == path->hn) 441 if (NULL == path->hn)
440 { 442 {
441 /* none of the peers is interested in this path; 443 /* none of the peers is interested in this path;
442 re-attach. */ 444 re-attach. */
443 GNUNET_assert(old_len == path->entries_length); 445 GNUNET_assert (old_len == path->entries_length);
444 path->hn = GCP_attach_path(path->entries[old_len - 1]->peer, 446 path->hn = GCP_attach_path (path->entries[old_len - 1]->peer,
445 path, 447 path,
446 old_len - 1, 448 old_len - 1,
447 GNUNET_YES); 449 GNUNET_YES);
448 GNUNET_assert(NULL != path->hn); 450 GNUNET_assert (NULL != path->hn);
449 return; 451 return;
450 } 452 }
451 LOG(GNUNET_ERROR_TYPE_DEBUG, 453 LOG (GNUNET_ERROR_TYPE_DEBUG,
452 "Extended path %s\n", 454 "Extended path %s\n",
453 GCPP_2s(path)); 455 GCPP_2s (path));
454} 456}
455 457
456 458
@@ -467,10 +469,10 @@ extend_path(struct CadetPeerPath *path,
467 * @return a path through the network 469 * @return a path through the network
468 */ 470 */
469void 471void
470GCPP_try_path_from_dht(const struct GNUNET_PeerIdentity *get_path, 472GCPP_try_path_from_dht (const struct GNUNET_PeerIdentity *get_path,
471 unsigned int get_path_length, 473 unsigned int get_path_length,
472 const struct GNUNET_PeerIdentity *put_path, 474 const struct GNUNET_PeerIdentity *put_path,
473 unsigned int put_path_length) 475 unsigned int put_path_length)
474{ 476{
475 struct CadetPeer *cpath[get_path_length + put_path_length]; 477 struct CadetPeer *cpath[get_path_length + put_path_length];
476 struct CheckMatchContext cm_ctx; 478 struct CheckMatchContext cm_ctx;
@@ -480,42 +482,42 @@ GCPP_try_path_from_dht(const struct GNUNET_PeerIdentity *get_path,
480 482
481 /* precompute 'cpath' so we can avoid doing the lookups lots of times */ 483 /* precompute 'cpath' so we can avoid doing the lookups lots of times */
482 skip = 0; 484 skip = 0;
483 memset(cpath, 485 memset (cpath,
484 0, 486 0,
485 sizeof(cpath)); /* Just to trigger harder errors later. */ 487 sizeof(cpath)); /* Just to trigger harder errors later. */
486 total_len = get_path_length + put_path_length; 488 total_len = get_path_length + put_path_length;
487 for (unsigned int off = 0; off < total_len; off++) 489 for (unsigned int off = 0; off < total_len; off++)
490 {
491 const struct GNUNET_PeerIdentity *pid;
492
493 pid = (off < get_path_length)
494 ? &get_path[get_path_length - off - 1]
495 : &put_path[get_path_length + put_path_length - off - 1];
496 /* Check that I am not in the path */
497 if (0 == GNUNET_memcmp (&my_full_id,
498 pid))
488 { 499 {
489 const struct GNUNET_PeerIdentity *pid; 500 skip = off + 1;
490 501 continue;
491 pid = (off < get_path_length)
492 ? &get_path[get_path_length - off - 1]
493 : &put_path[get_path_length + put_path_length - off - 1];
494 /* Check that I am not in the path */
495 if (0 == GNUNET_memcmp(&my_full_id,
496 pid))
497 {
498 skip = off + 1;
499 continue;
500 }
501 cpath[off - skip] = GCP_get(pid,
502 GNUNET_YES);
503 /* Check that no peer is twice on the path */
504 for (unsigned int i = 0; i < off - skip; i++)
505 {
506 if (cpath[i] == cpath[off - skip])
507 {
508 skip = off - i;
509 break;
510 }
511 }
512 } 502 }
513 if (skip >= total_len) 503 cpath[off - skip] = GCP_get (pid,
504 GNUNET_YES);
505 /* Check that no peer is twice on the path */
506 for (unsigned int i = 0; i < off - skip; i++)
514 { 507 {
515 LOG(GNUNET_ERROR_TYPE_DEBUG, 508 if (cpath[i] == cpath[off - skip])
516 "Path discovered from DHT is one big cycle?\n"); 509 {
517 return; 510 skip = off - i;
511 break;
512 }
518 } 513 }
514 }
515 if (skip >= total_len)
516 {
517 LOG (GNUNET_ERROR_TYPE_DEBUG,
518 "Path discovered from DHT is one big cycle?\n");
519 return;
520 }
519 total_len -= skip; 521 total_len -= skip;
520 522
521 /* First figure out if this path is a subset of an existing path, an 523 /* First figure out if this path is a subset of an existing path, an
@@ -524,72 +526,72 @@ GCPP_try_path_from_dht(const struct GNUNET_PeerIdentity *get_path,
524 cm_ctx.cpath = cpath; 526 cm_ctx.cpath = cpath;
525 cm_ctx.match = NULL; 527 cm_ctx.match = NULL;
526 for (int i = total_len - 1; i >= 0; i--) 528 for (int i = total_len - 1; i >= 0; i--)
529 {
530 GCP_iterate_paths_at (cpath[i],
531 (unsigned int) i,
532 &check_match,
533 &cm_ctx);
534 if (NULL != cm_ctx.match)
527 { 535 {
528 GCP_iterate_paths_at(cpath[i], 536 if (i == total_len - 1)
529 (unsigned int)i, 537 {
530 &check_match, 538 /* Existing path includes this one, nothing to do! */
531 &cm_ctx); 539 LOG (GNUNET_ERROR_TYPE_DEBUG,
532 if (NULL != cm_ctx.match) 540 "Path discovered from DHT is already known\n");
533 { 541 return;
534 if (i == total_len - 1) 542 }
535 { 543 if (cm_ctx.match->entries_length == i + 1)
536 /* Existing path includes this one, nothing to do! */ 544 {
537 LOG(GNUNET_ERROR_TYPE_DEBUG, 545 /* Existing path ends in the middle of new path, extend it! */
538 "Path discovered from DHT is already known\n"); 546 LOG (GNUNET_ERROR_TYPE_DEBUG,
539 return; 547 "Trying to extend existing path %s by additional links discovered from DHT\n",
540 } 548 GCPP_2s (cm_ctx.match));
541 if (cm_ctx.match->entries_length == i + 1) 549 extend_path (cm_ctx.match,
542 { 550 &cpath[i + 1],
543 /* Existing path ends in the middle of new path, extend it! */ 551 total_len - i - 1,
544 LOG(GNUNET_ERROR_TYPE_DEBUG, 552 GNUNET_NO);
545 "Trying to extend existing path %s by additional links discovered from DHT\n", 553 return;
546 GCPP_2s(cm_ctx.match)); 554 }
547 extend_path(cm_ctx.match,
548 &cpath[i + 1],
549 total_len - i - 1,
550 GNUNET_NO);
551 return;
552 }
553 }
554 } 555 }
556 }
555 557
556 /* No match at all, create completely new path */ 558 /* No match at all, create completely new path */
557 path = GNUNET_new(struct CadetPeerPath); 559 path = GNUNET_new (struct CadetPeerPath);
558 path->entries_length = total_len; 560 path->entries_length = total_len;
559 path->entries = GNUNET_new_array(path->entries_length, 561 path->entries = GNUNET_new_array (path->entries_length,
560 struct CadetPeerPathEntry *); 562 struct CadetPeerPathEntry *);
561 for (int i = path->entries_length - 1; i >= 0; i--) 563 for (int i = path->entries_length - 1; i >= 0; i--)
562 { 564 {
563 struct CadetPeerPathEntry *entry = GNUNET_new(struct CadetPeerPathEntry); 565 struct CadetPeerPathEntry *entry = GNUNET_new (struct CadetPeerPathEntry);
564 566
565 path->entries[i] = entry; 567 path->entries[i] = entry;
566 entry->peer = cpath[i]; 568 entry->peer = cpath[i];
567 entry->path = path; 569 entry->path = path;
568 } 570 }
569 for (int i = path->entries_length - 1; i >= 0; i--) 571 for (int i = path->entries_length - 1; i >= 0; i--)
570 { 572 {
571 struct CadetPeerPathEntry *entry = path->entries[i]; 573 struct CadetPeerPathEntry *entry = path->entries[i];
572 574
573 GCP_path_entry_add(entry->peer, 575 GCP_path_entry_add (entry->peer,
574 entry, 576 entry,
575 i); 577 i);
576 } 578 }
577 579
578 /* Finally, try to attach it */ 580 /* Finally, try to attach it */
579 attach_path(path, 0); 581 attach_path (path, 0);
580 if (NULL == path->hn) 582 if (NULL == path->hn)
581 { 583 {
582 /* None of the peers on the path care about it. */ 584 /* None of the peers on the path care about it. */
583 LOG(GNUNET_ERROR_TYPE_DEBUG, 585 LOG (GNUNET_ERROR_TYPE_DEBUG,
584 "Path discovered from DHT is not interesting to us\n"); 586 "Path discovered from DHT is not interesting to us\n");
585 GNUNET_assert(0 == path->entries_length); 587 GNUNET_assert (0 == path->entries_length);
586 GNUNET_assert(NULL == path->entries); 588 GNUNET_assert (NULL == path->entries);
587 GNUNET_free(path); 589 GNUNET_free (path);
588 return; 590 return;
589 } 591 }
590 LOG(GNUNET_ERROR_TYPE_DEBUG, 592 LOG (GNUNET_ERROR_TYPE_DEBUG,
591 "Created new path %s based on information from DHT\n", 593 "Created new path %s based on information from DHT\n",
592 GCPP_2s(path)); 594 GCPP_2s (path));
593} 595}
594 596
595 597
@@ -601,8 +603,8 @@ GCPP_try_path_from_dht(const struct GNUNET_PeerIdentity *get_path,
601 * @return corresponding path object 603 * @return corresponding path object
602 */ 604 */
603struct CadetPeerPath * 605struct CadetPeerPath *
604GCPP_get_path_from_route(unsigned int path_length, 606GCPP_get_path_from_route (unsigned int path_length,
605 const struct GNUNET_PeerIdentity *pids) 607 const struct GNUNET_PeerIdentity *pids)
606{ 608{
607 struct CheckMatchContext cm_ctx; 609 struct CheckMatchContext cm_ctx;
608 struct CadetPeer *cpath[path_length]; 610 struct CadetPeer *cpath[path_length];
@@ -611,8 +613,8 @@ GCPP_get_path_from_route(unsigned int path_length,
611 /* precompute inverted 'cpath' so we can avoid doing the lookups and 613 /* precompute inverted 'cpath' so we can avoid doing the lookups and
612 have the correct order */ 614 have the correct order */
613 for (unsigned int off = 0; off < path_length; off++) 615 for (unsigned int off = 0; off < path_length; off++)
614 cpath[off] = GCP_get(&pids[path_length - 1 - off], 616 cpath[off] = GCP_get (&pids[path_length - 1 - off],
615 GNUNET_YES); 617 GNUNET_YES);
616 618
617 /* First figure out if this path is a subset of an existing path, an 619 /* First figure out if this path is a subset of an existing path, an
618 extension of an existing path, or a new path. */ 620 extension of an existing path, or a new path. */
@@ -620,69 +622,69 @@ GCPP_get_path_from_route(unsigned int path_length,
620 cm_ctx.cpath_length = path_length; 622 cm_ctx.cpath_length = path_length;
621 cm_ctx.match = NULL; 623 cm_ctx.match = NULL;
622 for (int i = path_length - 1; i >= 0; i--) 624 for (int i = path_length - 1; i >= 0; i--)
625 {
626 GCP_iterate_paths_at (cpath[i],
627 (unsigned int) i,
628 &check_match,
629 &cm_ctx);
630 if (NULL != cm_ctx.match)
623 { 631 {
624 GCP_iterate_paths_at(cpath[i], 632 if (i == path_length - 1)
625 (unsigned int)i, 633 {
626 &check_match, 634 /* Existing path includes this one, return the match! */
627 &cm_ctx); 635 LOG (GNUNET_ERROR_TYPE_DEBUG,
628 if (NULL != cm_ctx.match) 636 "Returning existing path %s as inverse for incoming connection\n",
629 { 637 GCPP_2s (cm_ctx.match));
630 if (i == path_length - 1) 638 return cm_ctx.match;
631 { 639 }
632 /* Existing path includes this one, return the match! */ 640 if (cm_ctx.match->entries_length == i + 1)
633 LOG(GNUNET_ERROR_TYPE_DEBUG, 641 {
634 "Returning existing path %s as inverse for incoming connection\n", 642 /* Existing path ends in the middle of new path, extend it! */
635 GCPP_2s(cm_ctx.match)); 643 LOG (GNUNET_ERROR_TYPE_DEBUG,
636 return cm_ctx.match; 644 "Extending existing path %s to create inverse for incoming connection\n",
637 } 645 GCPP_2s (cm_ctx.match));
638 if (cm_ctx.match->entries_length == i + 1) 646 extend_path (cm_ctx.match,
639 { 647 &cpath[i + 1],
640 /* Existing path ends in the middle of new path, extend it! */ 648 path_length - i - 1,
641 LOG(GNUNET_ERROR_TYPE_DEBUG, 649 GNUNET_YES);
642 "Extending existing path %s to create inverse for incoming connection\n", 650 /* Check that extension was successful */
643 GCPP_2s(cm_ctx.match)); 651 GNUNET_assert (cm_ctx.match->entries_length == path_length);
644 extend_path(cm_ctx.match, 652 return cm_ctx.match;
645 &cpath[i + 1], 653 }
646 path_length - i - 1, 654 /* Eh, we found a match but couldn't use it? Something is wrong. */
647 GNUNET_YES); 655 GNUNET_break (0);
648 /* Check that extension was successful */
649 GNUNET_assert(cm_ctx.match->entries_length == path_length);
650 return cm_ctx.match;
651 }
652 /* Eh, we found a match but couldn't use it? Something is wrong. */
653 GNUNET_break(0);
654 }
655 } 656 }
657 }
656 658
657 /* No match at all, create completely new path */ 659 /* No match at all, create completely new path */
658 path = GNUNET_new(struct CadetPeerPath); 660 path = GNUNET_new (struct CadetPeerPath);
659 path->entries_length = path_length; 661 path->entries_length = path_length;
660 path->entries = GNUNET_new_array(path->entries_length, 662 path->entries = GNUNET_new_array (path->entries_length,
661 struct CadetPeerPathEntry *); 663 struct CadetPeerPathEntry *);
662 for (int i = path_length - 1; i >= 0; i--) 664 for (int i = path_length - 1; i >= 0; i--)
663 { 665 {
664 struct CadetPeerPathEntry *entry = GNUNET_new(struct CadetPeerPathEntry); 666 struct CadetPeerPathEntry *entry = GNUNET_new (struct CadetPeerPathEntry);
665 667
666 path->entries[i] = entry; 668 path->entries[i] = entry;
667 entry->peer = cpath[i]; 669 entry->peer = cpath[i];
668 entry->path = path; 670 entry->path = path;
669 } 671 }
670 for (int i = path_length - 1; i >= 0; i--) 672 for (int i = path_length - 1; i >= 0; i--)
671 { 673 {
672 struct CadetPeerPathEntry *entry = path->entries[i]; 674 struct CadetPeerPathEntry *entry = path->entries[i];
673 675
674 GCP_path_entry_add(entry->peer, 676 GCP_path_entry_add (entry->peer,
675 entry, 677 entry,
676 i); 678 i);
677 } 679 }
678 recalculate_path_desirability(path); 680 recalculate_path_desirability (path);
679 LOG(GNUNET_ERROR_TYPE_DEBUG, 681 LOG (GNUNET_ERROR_TYPE_DEBUG,
680 "Created new path %s to create inverse for incoming connection\n", 682 "Created new path %s to create inverse for incoming connection\n",
681 GCPP_2s(path)); 683 GCPP_2s (path));
682 path->hn = GCP_attach_path(cpath[path_length - 1], 684 path->hn = GCP_attach_path (cpath[path_length - 1],
683 path, 685 path,
684 path_length - 1, 686 path_length - 1,
685 GNUNET_YES); 687 GNUNET_YES);
686 return path; 688 return path;
687} 689}
688 690
@@ -695,7 +697,7 @@ GCPP_get_path_from_route(unsigned int path_length,
695 * @return number of peers on the path 697 * @return number of peers on the path
696 */ 698 */
697unsigned int 699unsigned int
698GCPP_get_length(struct CadetPeerPath *path) 700GCPP_get_length (struct CadetPeerPath *path)
699{ 701{
700 return path->entries_length; 702 return path->entries_length;
701} 703}
@@ -709,14 +711,14 @@ GCPP_get_length(struct CadetPeerPath *path)
709 * @return offset of @a cp on @a path, or UINT_MAX if not found 711 * @return offset of @a cp on @a path, or UINT_MAX if not found
710 */ 712 */
711unsigned int 713unsigned int
712GCPP_find_peer(struct CadetPeerPath *path, 714GCPP_find_peer (struct CadetPeerPath *path,
713 struct CadetPeer *cp) 715 struct CadetPeer *cp)
714{ 716{
715 for (unsigned int off = 0; 717 for (unsigned int off = 0;
716 off < path->entries_length; 718 off < path->entries_length;
717 off++) 719 off++)
718 if (cp == GCPP_get_peer_at_offset(path, 720 if (cp == GCPP_get_peer_at_offset (path,
719 off)) 721 off))
720 return off; 722 return off;
721 return UINT_MAX; 723 return UINT_MAX;
722} 724}
@@ -730,10 +732,10 @@ GCPP_find_peer(struct CadetPeerPath *path,
730 * @return the peer at offset @a off 732 * @return the peer at offset @a off
731 */ 733 */
732struct CadetPeer * 734struct CadetPeer *
733GCPP_get_peer_at_offset(struct CadetPeerPath *path, 735GCPP_get_peer_at_offset (struct CadetPeerPath *path,
734 unsigned int off) 736 unsigned int off)
735{ 737{
736 GNUNET_assert(off < path->entries_length); 738 GNUNET_assert (off < path->entries_length);
737 return path->entries[off]->peer; 739 return path->entries[off]->peer;
738} 740}
739 741
@@ -745,7 +747,7 @@ GCPP_get_peer_at_offset(struct CadetPeerPath *path,
745 * @return string, to be freed by caller (unlike other *_2s APIs!) 747 * @return string, to be freed by caller (unlike other *_2s APIs!)
746 */ 748 */
747const char * 749const char *
748GCPP_2s(struct CadetPeerPath *path) 750GCPP_2s (struct CadetPeerPath *path)
749{ 751{
750 static char buf[2048]; 752 static char buf[2048];
751 size_t off; 753 size_t off;
@@ -755,27 +757,28 @@ GCPP_2s(struct CadetPeerPath *path)
755 for (unsigned int i = 0; 757 for (unsigned int i = 0;
756 i < path->entries_length; 758 i < path->entries_length;
757 i++) 759 i++)
758 { 760 {
759 if ((path->entries_length > max_plen) && 761 if ((path->entries_length > max_plen) &&
760 (i == max_plen / 2)) 762 (i == max_plen / 2))
761 off += GNUNET_snprintf(&buf[off], 763 off += GNUNET_snprintf (&buf[off],
762 sizeof(buf) - off, 764 sizeof(buf) - off,
763 "...-"); 765 "...-");
764 if ((path->entries_length > max_plen) && 766 if ((path->entries_length > max_plen) &&
765 (i > max_plen / 2) && 767 (i > max_plen / 2) &&
766 (i < path->entries_length - max_plen / 2)) 768 (i < path->entries_length - max_plen / 2))
767 continue; 769 continue;
768 off += GNUNET_snprintf(&buf[off], 770 off += GNUNET_snprintf (&buf[off],
769 sizeof(buf) - off, 771 sizeof(buf) - off,
770 "%s%s", 772 "%s%s",
771 GNUNET_i2s(GCP_get_id(GCPP_get_peer_at_offset(path, 773 GNUNET_i2s (GCP_get_id (GCPP_get_peer_at_offset (
772 i))), 774 path,
773 (i == path->entries_length - 1) ? "" : "-"); 775 i))),
774 } 776 (i == path->entries_length - 1) ? "" : "-");
775 GNUNET_snprintf(&buf[off], 777 }
776 sizeof(buf) - off, 778 GNUNET_snprintf (&buf[off],
777 "(%p)", 779 sizeof(buf) - off,
778 path); 780 "(%p)",
781 path);
779 return buf; 782 return buf;
780} 783}
781 784