diff options
Diffstat (limited to 'src/testbed/gnunet-service-testbed_cache.c')
-rw-r--r-- | src/testbed/gnunet-service-testbed_cache.c | 791 |
1 files changed, 0 insertions, 791 deletions
diff --git a/src/testbed/gnunet-service-testbed_cache.c b/src/testbed/gnunet-service-testbed_cache.c index 9db2155fc..9f2b15579 100644 --- a/src/testbed/gnunet-service-testbed_cache.c +++ b/src/testbed/gnunet-service-testbed_cache.c | |||
@@ -43,115 +43,6 @@ | |||
43 | 43 | ||
44 | 44 | ||
45 | /** | 45 | /** |
46 | * Type of cache-get requests | ||
47 | */ | ||
48 | enum CacheGetType | ||
49 | { | ||
50 | /** | ||
51 | * Get transport handle | ||
52 | */ | ||
53 | CGT_TRANSPORT_HANDLE = 1, | ||
54 | |||
55 | /** | ||
56 | * Get core handle | ||
57 | */ | ||
58 | CGT_CORE_HANDLE | ||
59 | }; | ||
60 | |||
61 | |||
62 | /** | ||
63 | * The cache-get request handle | ||
64 | */ | ||
65 | struct GSTCacheGetHandle; | ||
66 | |||
67 | |||
68 | /** | ||
69 | * This context structure is used to maintain a queue of notifications to check | ||
70 | * which of them are to be notified when a peer is connected. | ||
71 | */ | ||
72 | struct ConnectNotifyContext | ||
73 | { | ||
74 | /** | ||
75 | * The next ptr for the DLL | ||
76 | */ | ||
77 | struct ConnectNotifyContext *next; | ||
78 | |||
79 | /** | ||
80 | * The prev ptr for the DLL | ||
81 | */ | ||
82 | struct ConnectNotifyContext *prev; | ||
83 | |||
84 | /** | ||
85 | * The peer identity of the target peer. When this target peer is connected, | ||
86 | * call the notify callback | ||
87 | */ | ||
88 | const struct GNUNET_PeerIdentity *target; | ||
89 | |||
90 | /** | ||
91 | * The notify callback to be called when the target peer is connected | ||
92 | */ | ||
93 | GST_cache_peer_connect_notify cb; | ||
94 | |||
95 | /** | ||
96 | * The closure for the notify callback | ||
97 | */ | ||
98 | void *cb_cls; | ||
99 | |||
100 | /** | ||
101 | * The GSTCacheGetHandle reposible for creating this context | ||
102 | */ | ||
103 | struct GSTCacheGetHandle *cgh; | ||
104 | |||
105 | }; | ||
106 | |||
107 | |||
108 | /** | ||
109 | * The cache-get request handle | ||
110 | */ | ||
111 | struct GSTCacheGetHandle | ||
112 | { | ||
113 | /** | ||
114 | * The next ptr for the DLL. Used in struct CacheEntry | ||
115 | */ | ||
116 | struct GSTCacheGetHandle *next; | ||
117 | |||
118 | /** | ||
119 | * The prev ptr for the DLL. Used in struct CacheEntry | ||
120 | */ | ||
121 | struct GSTCacheGetHandle *prev; | ||
122 | |||
123 | /** | ||
124 | * The cache entry object this handle corresponds to | ||
125 | */ | ||
126 | struct CacheEntry *entry; | ||
127 | |||
128 | /** | ||
129 | * The cache callback to call when a handle is available | ||
130 | */ | ||
131 | GST_cache_handle_ready_cb cb; | ||
132 | |||
133 | /** | ||
134 | * The closure for the above callback | ||
135 | */ | ||
136 | void *cb_cls; | ||
137 | |||
138 | /** | ||
139 | * The peer connect notify context created for this handle; can be NULL | ||
140 | */ | ||
141 | struct ConnectNotifyContext *nctxt; | ||
142 | |||
143 | /** | ||
144 | * The type of this cache-get request | ||
145 | */ | ||
146 | enum CacheGetType type; | ||
147 | |||
148 | /** | ||
149 | * Did we call the cache callback already? | ||
150 | */ | ||
151 | int notify_called; | ||
152 | }; | ||
153 | |||
154 | /** | ||
155 | * Cache entry | 46 | * Cache entry |
156 | */ | 47 | */ |
157 | struct CacheEntry | 48 | struct CacheEntry |
@@ -167,26 +58,6 @@ struct CacheEntry | |||
167 | struct CacheEntry *prev; | 58 | struct CacheEntry *prev; |
168 | 59 | ||
169 | /** | 60 | /** |
170 | * The transport handle to the peer corresponding to this entry; can be NULL | ||
171 | */ | ||
172 | struct GNUNET_TRANSPORT_Handle *transport_handle; | ||
173 | |||
174 | /** | ||
175 | * The operation handle for transport handle | ||
176 | */ | ||
177 | struct GNUNET_TESTBED_Operation *transport_op; | ||
178 | |||
179 | /** | ||
180 | * The core handle to the peer corresponding to this entry; can be NULL | ||
181 | */ | ||
182 | struct GNUNET_CORE_Handle *core_handle; | ||
183 | |||
184 | /** | ||
185 | * The operation handle for core handle | ||
186 | */ | ||
187 | struct GNUNET_TESTBED_Operation *core_op; | ||
188 | |||
189 | /** | ||
190 | * The peer identity of this peer. Will be set upon opening a connection to | 61 | * The peer identity of this peer. Will be set upon opening a connection to |
191 | * the peers CORE service. Will be NULL until then and after the CORE | 62 | * the peers CORE service. Will be NULL until then and after the CORE |
192 | * connection is closed | 63 | * connection is closed |
@@ -194,12 +65,6 @@ struct CacheEntry | |||
194 | struct GNUNET_PeerIdentity *peer_identity; | 65 | struct GNUNET_PeerIdentity *peer_identity; |
195 | 66 | ||
196 | /** | 67 | /** |
197 | * The configuration of the peer. Should be not NULL as long as the core_handle | ||
198 | * or transport_handle are valid | ||
199 | */ | ||
200 | struct GNUNET_CONFIGURATION_Handle *cfg; | ||
201 | |||
202 | /** | ||
203 | * The key for this entry | 68 | * The key for this entry |
204 | */ | 69 | */ |
205 | struct GNUNET_HashCode key; | 70 | struct GNUNET_HashCode key; |
@@ -210,44 +75,6 @@ struct CacheEntry | |||
210 | struct GNUNET_MessageHeader *hello; | 75 | struct GNUNET_MessageHeader *hello; |
211 | 76 | ||
212 | /** | 77 | /** |
213 | * the head of the CacheGetHandle queue | ||
214 | */ | ||
215 | struct GSTCacheGetHandle *cgh_qhead; | ||
216 | |||
217 | /** | ||
218 | * the tail of the CacheGetHandle queue | ||
219 | */ | ||
220 | struct GSTCacheGetHandle *cgh_qtail; | ||
221 | |||
222 | /** | ||
223 | * DLL head for the queue of notifications contexts to check which of them are to | ||
224 | * be notified when a peer is connected. | ||
225 | */ | ||
226 | struct ConnectNotifyContext *nctxt_qhead; | ||
227 | |||
228 | /** | ||
229 | * DLL tail for the queue of notifications contexts to check which of them are to | ||
230 | * be notified when a peer is connected. | ||
231 | */ | ||
232 | struct ConnectNotifyContext *nctxt_qtail; | ||
233 | |||
234 | /** | ||
235 | * The task that calls the cache callback | ||
236 | */ | ||
237 | GNUNET_SCHEDULER_TaskIdentifier notify_task; | ||
238 | |||
239 | /** | ||
240 | * The task to expire this cache entry, free any handlers it has opened and | ||
241 | * mark their corresponding operations as done. | ||
242 | */ | ||
243 | GNUNET_SCHEDULER_TaskIdentifier expire_task; | ||
244 | |||
245 | /** | ||
246 | * Number of operations this cache entry is being used | ||
247 | */ | ||
248 | unsigned int demand; | ||
249 | |||
250 | /** | ||
251 | * The id of the peer this entry corresponds to | 78 | * The id of the peer this entry corresponds to |
252 | */ | 79 | */ |
253 | unsigned int peer_id; | 80 | unsigned int peer_id; |
@@ -316,77 +143,6 @@ cache_lookup (const struct GNUNET_HashCode *key) | |||
316 | 143 | ||
317 | 144 | ||
318 | /** | 145 | /** |
319 | * Function to disconnect the core and transport handles; free the existing | ||
320 | * configuration; and remove from the LRU cache list. The entry is left to be in | ||
321 | * the hash table so that the HELLO can still be found later | ||
322 | * | ||
323 | * @param entry the cache entry | ||
324 | */ | ||
325 | static void | ||
326 | close_handles (struct CacheEntry *entry) | ||
327 | { | ||
328 | struct ConnectNotifyContext *ctxt; | ||
329 | |||
330 | GNUNET_assert (0 == entry->demand); | ||
331 | if (GNUNET_YES == entry->in_lru) | ||
332 | { | ||
333 | GNUNET_assert (0 < lru_cache_size); | ||
334 | if (GNUNET_SCHEDULER_NO_TASK != entry->expire_task) | ||
335 | { | ||
336 | GNUNET_SCHEDULER_cancel (entry->expire_task); | ||
337 | entry->expire_task = GNUNET_SCHEDULER_NO_TASK; | ||
338 | } | ||
339 | GNUNET_CONTAINER_DLL_remove (lru_cache_head, lru_cache_tail, entry); | ||
340 | lru_cache_size--; | ||
341 | entry->in_lru = GNUNET_NO; | ||
342 | } | ||
343 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == entry->expire_task); | ||
344 | while (NULL != (ctxt = entry->nctxt_qhead)) | ||
345 | { | ||
346 | GNUNET_CONTAINER_DLL_remove (entry->nctxt_qhead, entry->nctxt_qtail, ctxt); | ||
347 | GNUNET_free (ctxt); | ||
348 | } | ||
349 | LOG_DEBUG ("Cleaning up handles from an entry in cache\n"); | ||
350 | if (NULL != entry->transport_handle) | ||
351 | GNUNET_assert (NULL != entry->transport_op); | ||
352 | if (NULL != entry->transport_op) | ||
353 | { | ||
354 | GNUNET_TESTBED_operation_done (entry->transport_op); | ||
355 | entry->transport_op = NULL; | ||
356 | } | ||
357 | if (NULL != entry->core_op) | ||
358 | { | ||
359 | GNUNET_TESTBED_operation_done (entry->core_op); | ||
360 | entry->core_op = NULL; | ||
361 | } | ||
362 | GNUNET_assert (NULL == entry->core_handle); | ||
363 | if (NULL != entry->cfg) | ||
364 | { | ||
365 | GNUNET_CONFIGURATION_destroy (entry->cfg); | ||
366 | entry->cfg = NULL; | ||
367 | } | ||
368 | } | ||
369 | |||
370 | |||
371 | /** | ||
372 | * The task to expire this cache entry, free any handlers it has opened and | ||
373 | * mark their corresponding operations as done. | ||
374 | * | ||
375 | * @param cls the CacheEntry | ||
376 | * @param tc the scheduler task context | ||
377 | */ | ||
378 | static void | ||
379 | expire_cache_entry (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
380 | { | ||
381 | struct CacheEntry *entry = cls; | ||
382 | |||
383 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != entry->expire_task); | ||
384 | entry->expire_task = GNUNET_SCHEDULER_NO_TASK; | ||
385 | close_handles (entry); | ||
386 | } | ||
387 | |||
388 | |||
389 | /** | ||
390 | * Creates a new cache entry and then puts it into the cache's hashtable. | 146 | * Creates a new cache entry and then puts it into the cache's hashtable. |
391 | * | 147 | * |
392 | * @param key the hash code to use for inserting the newly created entry | 148 | * @param key the hash code to use for inserting the newly created entry |
@@ -410,414 +166,6 @@ add_entry (const struct GNUNET_HashCode *key, unsigned int peer_id) | |||
410 | 166 | ||
411 | 167 | ||
412 | /** | 168 | /** |
413 | * Function to find a suitable GSTCacheGetHandle which is waiting for one of the | ||
414 | * handles in given entry to be available. | ||
415 | * | ||
416 | * @param entry the cache entry whose GSTCacheGetHandle list has to be searched | ||
417 | * @param head the starting list element in the GSTCacheGetHandle where the | ||
418 | * search has to be begin | ||
419 | * @return a suitable GSTCacheGetHandle whose handle ready notify callback | ||
420 | * hasn't been called yet. NULL if no such suitable GSTCacheGetHandle | ||
421 | * is found | ||
422 | */ | ||
423 | static struct GSTCacheGetHandle * | ||
424 | search_suitable_cgh (const struct CacheEntry *entry, | ||
425 | const struct GSTCacheGetHandle *head) | ||
426 | { | ||
427 | const struct GSTCacheGetHandle *cgh; | ||
428 | |||
429 | for (cgh = head; NULL != cgh; cgh = cgh->next) | ||
430 | { | ||
431 | if (GNUNET_YES == cgh->notify_called) | ||
432 | return NULL; | ||
433 | switch (cgh->type) | ||
434 | { | ||
435 | case CGT_TRANSPORT_HANDLE: | ||
436 | if (NULL == entry->transport_handle) | ||
437 | continue; | ||
438 | break; | ||
439 | case CGT_CORE_HANDLE: | ||
440 | if (NULL == entry->core_handle) | ||
441 | continue; | ||
442 | if (NULL == entry->peer_identity) /* Our CORE connection isn't ready yet */ | ||
443 | continue; | ||
444 | break; | ||
445 | } | ||
446 | break; | ||
447 | } | ||
448 | return (struct GSTCacheGetHandle *) cgh; | ||
449 | } | ||
450 | |||
451 | |||
452 | /** | ||
453 | * Task to call the handle ready notify callback of a queued GSTCacheGetHandle | ||
454 | * of an entry when one or all of its handles are available. | ||
455 | * | ||
456 | * @param cls the cache entry | ||
457 | * @param tc the task context from scheduler | ||
458 | */ | ||
459 | static void | ||
460 | call_cgh_cb (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
461 | { | ||
462 | struct CacheEntry *entry = cls; | ||
463 | struct GSTCacheGetHandle *cgh; | ||
464 | const struct GSTCacheGetHandle *cgh2; | ||
465 | |||
466 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != entry->notify_task); | ||
467 | entry->notify_task = GNUNET_SCHEDULER_NO_TASK; | ||
468 | cgh = search_suitable_cgh (entry, entry->cgh_qhead); | ||
469 | GNUNET_assert (NULL != cgh); | ||
470 | cgh2 = NULL; | ||
471 | if (NULL != cgh->next) | ||
472 | cgh2 = search_suitable_cgh (entry, cgh->next); | ||
473 | GNUNET_CONTAINER_DLL_remove (entry->cgh_qhead, entry->cgh_qtail, cgh); | ||
474 | cgh->notify_called = GNUNET_YES; | ||
475 | GNUNET_CONTAINER_DLL_insert_tail (entry->cgh_qhead, entry->cgh_qtail, cgh); | ||
476 | if (NULL != cgh2) | ||
477 | entry->notify_task = GNUNET_SCHEDULER_add_now (&call_cgh_cb, entry); | ||
478 | if (NULL != cgh->nctxt) | ||
479 | { /* Register the peer connect notify callback */ | ||
480 | GNUNET_CONTAINER_DLL_insert_tail (entry->nctxt_qhead, entry->nctxt_qtail, | ||
481 | cgh->nctxt); | ||
482 | } | ||
483 | LOG_DEBUG ("Calling notify for handle type %u\n", cgh->type); | ||
484 | cgh->cb (cgh->cb_cls, entry->core_handle, entry->transport_handle, | ||
485 | entry->peer_identity); | ||
486 | } | ||
487 | |||
488 | |||
489 | /** | ||
490 | * Function called from peer connect notify callbacks from CORE and TRANSPORT | ||
491 | * connections. This function calls the pendning peer connect notify callbacks | ||
492 | * which are queued in an entry. | ||
493 | * | ||
494 | * @param cls the cache entry | ||
495 | * @param peer the peer that connected | ||
496 | * @param type the type of the handle this notification corresponds to | ||
497 | */ | ||
498 | static void | ||
499 | peer_connect_notify_cb (void *cls, const struct GNUNET_PeerIdentity *peer, | ||
500 | const enum CacheGetType type) | ||
501 | { | ||
502 | struct CacheEntry *entry = cls; | ||
503 | struct ConnectNotifyContext *ctxt; | ||
504 | struct ConnectNotifyContext *ctxt2; | ||
505 | GST_cache_peer_connect_notify cb; | ||
506 | void *cb_cls; | ||
507 | |||
508 | |||
509 | for (ctxt = entry->nctxt_qhead; NULL != ctxt;) | ||
510 | { | ||
511 | GNUNET_assert (NULL != ctxt->cgh); | ||
512 | if (type != ctxt->cgh->type) | ||
513 | { | ||
514 | ctxt = ctxt->next; | ||
515 | continue; | ||
516 | } | ||
517 | if (0 != memcmp (ctxt->target, peer, sizeof (struct GNUNET_PeerIdentity))) | ||
518 | { | ||
519 | ctxt = ctxt->next; | ||
520 | continue; | ||
521 | } | ||
522 | cb = ctxt->cb; | ||
523 | cb_cls = ctxt->cb_cls; | ||
524 | ctxt->cgh->nctxt = NULL; | ||
525 | ctxt2 = ctxt->next; | ||
526 | GNUNET_CONTAINER_DLL_remove (entry->nctxt_qhead, entry->nctxt_qtail, ctxt); | ||
527 | GNUNET_free (ctxt); | ||
528 | ctxt = ctxt2; | ||
529 | cb (cb_cls, peer); | ||
530 | } | ||
531 | if (NULL == ctxt) | ||
532 | return; | ||
533 | |||
534 | } | ||
535 | |||
536 | |||
537 | /** | ||
538 | * Function called to notify transport users that another | ||
539 | * peer connected to us. | ||
540 | * | ||
541 | * @param cls closure | ||
542 | * @param peer the peer that connected | ||
543 | */ | ||
544 | static void | ||
545 | transport_peer_connect_notify_cb (void *cls, | ||
546 | const struct GNUNET_PeerIdentity *peer) | ||
547 | { | ||
548 | peer_connect_notify_cb (cls, peer, CGT_TRANSPORT_HANDLE); | ||
549 | } | ||
550 | |||
551 | |||
552 | /** | ||
553 | * Function called when resources for opening a connection to TRANSPORT are | ||
554 | * available. | ||
555 | * | ||
556 | * @param cls the cache entry | ||
557 | */ | ||
558 | static void | ||
559 | opstart_get_handle_transport (void *cls) | ||
560 | { | ||
561 | struct CacheEntry *entry = cls; | ||
562 | |||
563 | GNUNET_assert (NULL != entry); | ||
564 | LOG_DEBUG ("Opening a transport connection to peer %u\n", entry->peer_id); | ||
565 | entry->transport_handle = | ||
566 | GNUNET_TRANSPORT_connect (entry->cfg, NULL, entry, NULL, | ||
567 | &transport_peer_connect_notify_cb, NULL); | ||
568 | if (NULL == entry->transport_handle) | ||
569 | { | ||
570 | GNUNET_break (0); | ||
571 | return; | ||
572 | } | ||
573 | if (0 == entry->demand) | ||
574 | return; | ||
575 | if (GNUNET_SCHEDULER_NO_TASK != entry->notify_task) | ||
576 | return; | ||
577 | if (NULL != search_suitable_cgh (entry, entry->cgh_qhead)) | ||
578 | entry->notify_task = GNUNET_SCHEDULER_add_now (&call_cgh_cb, entry); | ||
579 | } | ||
580 | |||
581 | |||
582 | /** | ||
583 | * Function called when the operation responsible for opening a TRANSPORT | ||
584 | * connection is marked as done. | ||
585 | * | ||
586 | * @param cls the cache entry | ||
587 | */ | ||
588 | static void | ||
589 | oprelease_get_handle_transport (void *cls) | ||
590 | { | ||
591 | struct CacheEntry *entry = cls; | ||
592 | |||
593 | if (NULL == entry->transport_handle) | ||
594 | return; | ||
595 | GNUNET_TRANSPORT_disconnect (entry->transport_handle); | ||
596 | entry->transport_handle = NULL; | ||
597 | } | ||
598 | |||
599 | |||
600 | /** | ||
601 | * Function called after GNUNET_CORE_connect has succeeded (or failed | ||
602 | * for good). Note that the private key of the peer is intentionally | ||
603 | * not exposed here; if you need it, your process should try to read | ||
604 | * the private key file directly (which should work if you are | ||
605 | * authorized...). Implementations of this function must not call | ||
606 | * GNUNET_CORE_disconnect (other than by scheduling a new task to | ||
607 | * do this later). | ||
608 | * | ||
609 | * @param cls closure | ||
610 | * @param my_identity ID of this peer, NULL if we failed | ||
611 | */ | ||
612 | static void | ||
613 | core_startup_cb (void *cls, | ||
614 | const struct GNUNET_PeerIdentity *my_identity) | ||
615 | { | ||
616 | struct CacheEntry *entry = cls; | ||
617 | |||
618 | if (NULL == my_identity) | ||
619 | { | ||
620 | GNUNET_break (0); | ||
621 | return; | ||
622 | } | ||
623 | GNUNET_assert (NULL == entry->peer_identity); | ||
624 | // FIXME: why is this dynamically allocated? | ||
625 | entry->peer_identity = GNUNET_new (struct GNUNET_PeerIdentity); | ||
626 | memcpy (entry->peer_identity, my_identity, | ||
627 | sizeof (struct GNUNET_PeerIdentity)); | ||
628 | if (0 == entry->demand) | ||
629 | return; | ||
630 | if (GNUNET_SCHEDULER_NO_TASK != entry->notify_task) | ||
631 | return; | ||
632 | if (NULL != search_suitable_cgh (entry, entry->cgh_qhead)) | ||
633 | entry->notify_task = GNUNET_SCHEDULER_add_now (&call_cgh_cb, entry); | ||
634 | } | ||
635 | |||
636 | |||
637 | /** | ||
638 | * Method called whenever a given peer connects at CORE level | ||
639 | * | ||
640 | * @param cls closure | ||
641 | * @param peer peer identity this notification is about | ||
642 | */ | ||
643 | static void | ||
644 | core_peer_connect_cb (void *cls, const struct GNUNET_PeerIdentity *peer) | ||
645 | { | ||
646 | peer_connect_notify_cb (cls, peer, CGT_CORE_HANDLE); | ||
647 | } | ||
648 | |||
649 | |||
650 | /** | ||
651 | * Function called when resources for opening a connection to CORE are | ||
652 | * available. | ||
653 | * | ||
654 | * @param cls the cache entry | ||
655 | */ | ||
656 | static void | ||
657 | opstart_get_handle_core (void *cls) | ||
658 | { | ||
659 | struct CacheEntry *entry = cls; | ||
660 | |||
661 | const struct GNUNET_CORE_MessageHandler no_handlers[] = { | ||
662 | {NULL, 0, 0} | ||
663 | }; | ||
664 | |||
665 | GNUNET_assert (NULL != entry); | ||
666 | LOG_DEBUG ("Opening a CORE connection to peer %u\n", entry->peer_id); | ||
667 | entry->core_handle = | ||
668 | GNUNET_CORE_connect (entry->cfg, entry, /* closure */ | ||
669 | &core_startup_cb, /* core startup notify */ | ||
670 | &core_peer_connect_cb, /* peer connect notify */ | ||
671 | NULL, /* peer disconnect notify */ | ||
672 | NULL, /* inbound notify */ | ||
673 | GNUNET_NO, /* inbound header only? */ | ||
674 | NULL, /* outbound notify */ | ||
675 | GNUNET_NO, /* outbound header only? */ | ||
676 | no_handlers); | ||
677 | } | ||
678 | |||
679 | |||
680 | /** | ||
681 | * Function called when the operation responsible for opening a TRANSPORT | ||
682 | * connection is marked as done. | ||
683 | * | ||
684 | * @param cls the cache entry | ||
685 | */ | ||
686 | static void | ||
687 | oprelease_get_handle_core (void *cls) | ||
688 | { | ||
689 | struct CacheEntry *entry = cls; | ||
690 | |||
691 | if (NULL == entry->core_handle) | ||
692 | return; | ||
693 | GNUNET_CORE_disconnect (entry->core_handle); | ||
694 | entry->core_handle = NULL; | ||
695 | GNUNET_free_non_null (entry->peer_identity); | ||
696 | entry->peer_identity = NULL; | ||
697 | } | ||
698 | |||
699 | |||
700 | /** | ||
701 | * Function to get a handle with given configuration. The type of the handle is | ||
702 | * implicitly provided in the GSTCacheGetHandle. If the handle is already cached | ||
703 | * before, it will be retured in the given callback; the peer_id is used to | ||
704 | * lookup in the cache; if not, a new operation is started to open the transport | ||
705 | * handle and will be given in the callback when it is available. | ||
706 | * | ||
707 | * @param peer_id the index of the peer | ||
708 | * @param cgh the CacheGetHandle | ||
709 | * @param cfg the configuration with which the transport handle has to be | ||
710 | * created if it was not present in the cache | ||
711 | * @param target the peer identify of the peer whose connection to | ||
712 | * TRANSPORT/CORE (depending on the type of 'cgh') subsystem will be | ||
713 | * notified through the connect_notify_cb. Can be NULL | ||
714 | * @param connect_notify_cb the callback to call when the given target peer is | ||
715 | * connected. This callback will only be called once or never again (in | ||
716 | * case the target peer cannot be connected). Can be NULL | ||
717 | * @param connect_notify_cb_cls the closure for the above callback | ||
718 | * @return the handle which can be used to cancel or mark that the handle is no | ||
719 | * longer being used | ||
720 | */ | ||
721 | static struct GSTCacheGetHandle * | ||
722 | cache_get_handle (unsigned int peer_id, struct GSTCacheGetHandle *cgh, | ||
723 | const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
724 | const struct GNUNET_PeerIdentity *target, | ||
725 | GST_cache_peer_connect_notify connect_notify_cb, | ||
726 | void *connect_notify_cb_cls) | ||
727 | { | ||
728 | struct GNUNET_HashCode key; | ||
729 | void *handle; | ||
730 | struct CacheEntry *entry; | ||
731 | struct ConnectNotifyContext *ctxt; | ||
732 | struct GNUNET_TESTBED_Operation *op; | ||
733 | |||
734 | GNUNET_assert (0 != cgh->type); | ||
735 | GNUNET_CRYPTO_hash (&peer_id, sizeof (peer_id), &key); | ||
736 | handle = NULL; | ||
737 | entry = cache_lookup (&key); | ||
738 | if (NULL != entry) | ||
739 | { | ||
740 | if (GNUNET_YES == entry->in_lru) | ||
741 | { | ||
742 | GNUNET_assert (0 == entry->demand); | ||
743 | GNUNET_assert (0 < lru_cache_size); | ||
744 | if (GNUNET_SCHEDULER_NO_TASK != entry->expire_task) | ||
745 | { | ||
746 | GNUNET_SCHEDULER_cancel (entry->expire_task); | ||
747 | entry->expire_task = GNUNET_SCHEDULER_NO_TASK; | ||
748 | } | ||
749 | GNUNET_CONTAINER_DLL_remove (lru_cache_head, lru_cache_tail, entry); | ||
750 | lru_cache_size--; | ||
751 | entry->in_lru = GNUNET_NO; | ||
752 | } | ||
753 | switch (cgh->type) | ||
754 | { | ||
755 | case CGT_TRANSPORT_HANDLE: | ||
756 | handle = entry->transport_handle; | ||
757 | if (NULL != handle) | ||
758 | LOG_DEBUG ("Found TRANSPORT handle in cache for peer %u\n", | ||
759 | entry->peer_id); | ||
760 | break; | ||
761 | case CGT_CORE_HANDLE: | ||
762 | handle = entry->core_handle; | ||
763 | if (NULL != handle) | ||
764 | LOG_DEBUG ("Found CORE handle in cache for peer %u\n", entry->peer_id); | ||
765 | break; | ||
766 | } | ||
767 | } | ||
768 | if (NULL == entry) | ||
769 | entry = add_entry (&key, peer_id); | ||
770 | if (NULL == entry->cfg) | ||
771 | entry->cfg = GNUNET_CONFIGURATION_dup (cfg); | ||
772 | entry->demand++; | ||
773 | cgh->entry = entry; | ||
774 | GNUNET_CONTAINER_DLL_insert (entry->cgh_qhead, entry->cgh_qtail, cgh); | ||
775 | if ((NULL != target) && (NULL != connect_notify_cb)) | ||
776 | { | ||
777 | ctxt = GNUNET_malloc (sizeof (struct ConnectNotifyContext)); | ||
778 | ctxt->target = target; | ||
779 | ctxt->cb = connect_notify_cb; | ||
780 | ctxt->cb_cls = connect_notify_cb_cls; | ||
781 | GNUNET_assert (NULL == cgh->nctxt); | ||
782 | cgh->nctxt = ctxt; | ||
783 | ctxt->cgh = cgh; | ||
784 | } | ||
785 | if (NULL != handle) | ||
786 | { | ||
787 | if (GNUNET_SCHEDULER_NO_TASK == entry->notify_task) | ||
788 | { | ||
789 | if (NULL != search_suitable_cgh (entry, entry->cgh_qhead)) | ||
790 | entry->notify_task = GNUNET_SCHEDULER_add_now (&call_cgh_cb, entry); | ||
791 | } | ||
792 | return cgh; | ||
793 | } | ||
794 | op = NULL; | ||
795 | switch (cgh->type) | ||
796 | { | ||
797 | case CGT_TRANSPORT_HANDLE: | ||
798 | if (NULL != entry->transport_op) | ||
799 | return cgh; | ||
800 | op = GNUNET_TESTBED_operation_create_ (entry, &opstart_get_handle_transport, | ||
801 | &oprelease_get_handle_transport); | ||
802 | entry->transport_op = op; | ||
803 | break; | ||
804 | case CGT_CORE_HANDLE: | ||
805 | if (NULL != entry->core_op) | ||
806 | return cgh; | ||
807 | op = GNUNET_TESTBED_operation_create_ (entry, &opstart_get_handle_core, | ||
808 | &oprelease_get_handle_core); | ||
809 | entry->core_op = op; | ||
810 | break; | ||
811 | default: | ||
812 | GNUNET_assert (0); | ||
813 | } | ||
814 | GNUNET_TESTBED_operation_queue_insert_ (GST_opq_openfds, op); | ||
815 | GNUNET_TESTBED_operation_begin_wait_ (op); | ||
816 | return cgh; | ||
817 | } | ||
818 | |||
819 | |||
820 | /** | ||
821 | * Iterator over hash map entries. | 169 | * Iterator over hash map entries. |
822 | * | 170 | * |
823 | * @param cls closure | 171 | * @param cls closure |
@@ -834,22 +182,10 @@ cache_clear_iterator (void *cls, const struct GNUNET_HashCode *key, void *value) | |||
834 | static unsigned int ncleared; | 182 | static unsigned int ncleared; |
835 | 183 | ||
836 | GNUNET_assert (NULL != entry); | 184 | GNUNET_assert (NULL != entry); |
837 | GNUNET_break (0 == entry->demand); | ||
838 | LOG_DEBUG ("Clearing entry %u of %u\n", ++ncleared, cache_size); | 185 | LOG_DEBUG ("Clearing entry %u of %u\n", ++ncleared, cache_size); |
839 | GNUNET_assert (GNUNET_YES == | 186 | GNUNET_assert (GNUNET_YES == |
840 | GNUNET_CONTAINER_multihashmap_remove (cache, key, value)); | 187 | GNUNET_CONTAINER_multihashmap_remove (cache, key, value)); |
841 | close_handles (entry); | ||
842 | GNUNET_free_non_null (entry->hello); | 188 | GNUNET_free_non_null (entry->hello); |
843 | GNUNET_break (GNUNET_SCHEDULER_NO_TASK == entry->expire_task); | ||
844 | GNUNET_assert (NULL == entry->transport_handle); | ||
845 | GNUNET_assert (NULL == entry->transport_op); | ||
846 | GNUNET_assert (NULL == entry->core_handle); | ||
847 | GNUNET_assert (NULL == entry->core_op); | ||
848 | GNUNET_assert (NULL == entry->cfg); | ||
849 | GNUNET_assert (NULL == entry->cgh_qhead); | ||
850 | GNUNET_assert (NULL == entry->cgh_qtail); | ||
851 | GNUNET_assert (NULL == entry->nctxt_qhead); | ||
852 | GNUNET_assert (NULL == entry->nctxt_qtail); | ||
853 | GNUNET_free (entry); | 189 | GNUNET_free (entry); |
854 | return GNUNET_YES; | 190 | return GNUNET_YES; |
855 | } | 191 | } |
@@ -891,133 +227,6 @@ GST_cache_init (unsigned int size) | |||
891 | 227 | ||
892 | 228 | ||
893 | /** | 229 | /** |
894 | * Mark the GetCacheHandle as being done if a handle has been provided already | ||
895 | * or as being cancelled if the callback for the handle hasn't been called. | ||
896 | * | ||
897 | * @param cgh the CacheGetHandle handle | ||
898 | */ | ||
899 | void | ||
900 | GST_cache_get_handle_done (struct GSTCacheGetHandle *cgh) | ||
901 | { | ||
902 | struct CacheEntry *entry; | ||
903 | |||
904 | entry = cgh->entry; | ||
905 | GNUNET_assert (NULL != entry); | ||
906 | GNUNET_assert (0 < entry->demand); | ||
907 | entry->demand--; | ||
908 | if (GNUNET_SCHEDULER_NO_TASK != entry->notify_task) | ||
909 | { | ||
910 | GNUNET_SCHEDULER_cancel (entry->notify_task); | ||
911 | entry->notify_task = GNUNET_SCHEDULER_NO_TASK; | ||
912 | } | ||
913 | GNUNET_CONTAINER_DLL_remove (entry->cgh_qhead, entry->cgh_qtail, cgh); | ||
914 | if (NULL != cgh->nctxt) | ||
915 | { | ||
916 | GNUNET_assert (cgh == cgh->nctxt->cgh); | ||
917 | if (GNUNET_YES == cgh->notify_called) | ||
918 | GNUNET_CONTAINER_DLL_remove (entry->nctxt_qhead, entry->nctxt_qtail, | ||
919 | cgh->nctxt); | ||
920 | GNUNET_free (cgh->nctxt); | ||
921 | } | ||
922 | GNUNET_free (cgh); | ||
923 | if (0 == entry->demand) | ||
924 | { | ||
925 | entry->expire_task = | ||
926 | GNUNET_SCHEDULER_add_delayed (CACHE_EXPIRY, &expire_cache_entry, entry); | ||
927 | GNUNET_CONTAINER_DLL_insert_tail (lru_cache_head, lru_cache_tail, entry); | ||
928 | lru_cache_size++; | ||
929 | entry->in_lru = GNUNET_YES; | ||
930 | if (lru_cache_size > lru_cache_threshold_size) | ||
931 | close_handles (lru_cache_head); | ||
932 | } | ||
933 | else | ||
934 | { | ||
935 | if (NULL != search_suitable_cgh (entry, entry->cgh_qhead)) | ||
936 | entry->notify_task = GNUNET_SCHEDULER_add_now (&call_cgh_cb, entry); | ||
937 | } | ||
938 | } | ||
939 | |||
940 | |||
941 | /** | ||
942 | * Get a transport handle with the given configuration. If the handle is | ||
943 | * already cached before, it will be retured in the given callback; the peer_id | ||
944 | * is used to lookup in the cache; if not, a new operation is started to open the | ||
945 | * transport handle and will be given in the callback when it is available. | ||
946 | * | ||
947 | * @param peer_id the index of the peer | ||
948 | * @param cfg the configuration with which the transport handle has to be | ||
949 | * created if it was not present in the cache | ||
950 | * @param cb the callback to notify when the transport handle is available | ||
951 | * @param cb_cls the closure for the above callback | ||
952 | * @param target the peer identify of the peer whose connection to our TRANSPORT | ||
953 | * subsystem will be notified through the connect_notify_cb. Can be NULL | ||
954 | * @param connect_notify_cb the callback to call when the given target peer is | ||
955 | * connected. This callback will only be called once or never again (in | ||
956 | * case the target peer cannot be connected). Can be NULL | ||
957 | * @param connect_notify_cb_cls the closure for the above callback | ||
958 | * @return the handle which can be used to cancel or mark that the handle is no | ||
959 | * longer being used | ||
960 | */ | ||
961 | struct GSTCacheGetHandle * | ||
962 | GST_cache_get_handle_transport (unsigned int peer_id, | ||
963 | const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
964 | GST_cache_handle_ready_cb cb, void *cb_cls, | ||
965 | const struct GNUNET_PeerIdentity *target, | ||
966 | GST_cache_peer_connect_notify connect_notify_cb, | ||
967 | void *connect_notify_cb_cls) | ||
968 | { | ||
969 | struct GSTCacheGetHandle *cgh; | ||
970 | |||
971 | cgh = GNUNET_malloc (sizeof (struct GSTCacheGetHandle)); | ||
972 | cgh->cb = cb; | ||
973 | cgh->cb_cls = cb_cls; | ||
974 | cgh->type = CGT_TRANSPORT_HANDLE; | ||
975 | return cache_get_handle (peer_id, cgh, cfg, target, connect_notify_cb, | ||
976 | connect_notify_cb_cls); | ||
977 | } | ||
978 | |||
979 | |||
980 | /** | ||
981 | * Get a CORE handle with the given configuration. If the handle is already | ||
982 | * cached before, it will be retured in the given callback; the peer_id is used | ||
983 | * to lookup in the cache. If the handle is not cached before, a new operation | ||
984 | * is started to open the CORE handle and will be given in the callback when it | ||
985 | * is available along with the peer identity | ||
986 | * | ||
987 | * @param peer_id the index of the peer | ||
988 | * @param cfg the configuration with which the transport handle has to be | ||
989 | * created if it was not present in the cache | ||
990 | * @param cb the callback to notify when the transport handle is available | ||
991 | * @param cb_cls the closure for the above callback | ||
992 | * @param target the peer identify of the peer whose connection to our CORE | ||
993 | * subsystem will be notified through the connect_notify_cb. Can be NULL | ||
994 | * @param connect_notify_cb the callback to call when the given target peer is | ||
995 | * connected. This callback will only be called once or never again (in | ||
996 | * case the target peer cannot be connected). Can be NULL | ||
997 | * @param connect_notify_cb_cls the closure for the above callback | ||
998 | * @return the handle which can be used to cancel or mark that the handle is no | ||
999 | * longer being used | ||
1000 | */ | ||
1001 | struct GSTCacheGetHandle * | ||
1002 | GST_cache_get_handle_core (unsigned int peer_id, | ||
1003 | const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
1004 | GST_cache_handle_ready_cb cb, void *cb_cls, | ||
1005 | const struct GNUNET_PeerIdentity *target, | ||
1006 | GST_cache_peer_connect_notify connect_notify_cb, | ||
1007 | void *connect_notify_cb_cls) | ||
1008 | { | ||
1009 | struct GSTCacheGetHandle *cgh; | ||
1010 | |||
1011 | cgh = GNUNET_malloc (sizeof (struct GSTCacheGetHandle)); | ||
1012 | cgh->cb = cb; | ||
1013 | cgh->cb_cls = cb_cls; | ||
1014 | cgh->type = CGT_CORE_HANDLE; | ||
1015 | return cache_get_handle (peer_id, cgh, cfg, target, connect_notify_cb, | ||
1016 | connect_notify_cb_cls); | ||
1017 | } | ||
1018 | |||
1019 | |||
1020 | /** | ||
1021 | * Looks up in the hello cache and returns the HELLO of the given peer | 230 | * Looks up in the hello cache and returns the HELLO of the given peer |
1022 | * | 231 | * |
1023 | * @param peer_id the index of the peer whose HELLO has to be looked up | 232 | * @param peer_id the index of the peer whose HELLO has to be looked up |