aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSree Harsha Totakura <totakura@in.tum.de>2013-01-30 15:06:52 +0000
committerSree Harsha Totakura <totakura@in.tum.de>2013-01-30 15:06:52 +0000
commitff3529ccfc3f7df86531900b40dd37dc0617387b (patch)
treef3cbb4df96ae66cc194a4bb92e88362eb55006c0 /src
parentf3b225f570302afef710c58e22b75efd81e71e56 (diff)
downloadgnunet-ff3529ccfc3f7df86531900b40dd37dc0617387b.tar.gz
gnunet-ff3529ccfc3f7df86531900b40dd37dc0617387b.zip
towards caching CORE handles
Diffstat (limited to 'src')
-rw-r--r--src/testbed/gnunet-service-testbed_hc.c285
1 files changed, 245 insertions, 40 deletions
diff --git a/src/testbed/gnunet-service-testbed_hc.c b/src/testbed/gnunet-service-testbed_hc.c
index ecc2e5edc..7810d32ac 100644
--- a/src/testbed/gnunet-service-testbed_hc.c
+++ b/src/testbed/gnunet-service-testbed_hc.c
@@ -36,6 +36,26 @@
36 GNUNET_log_from (kind, "testbed-cache", __VA_ARGS__) 36 GNUNET_log_from (kind, "testbed-cache", __VA_ARGS__)
37 37
38 38
39/**
40 * Type of cache-get requests
41 */
42enum CacheGetType
43{
44 /**
45 * Get transport handle
46 */
47 CGT_TRANSPORT_HANDLE = 1,
48
49 /**
50 * Get core handle
51 */
52 CGT_CORE_HANDLE
53};
54
55
56/**
57 * The cache-get request handle
58 */
39struct GSTCacheGetHandle; 59struct GSTCacheGetHandle;
40 60
41 61
@@ -78,28 +98,49 @@ struct ConnectNotifyContext
78}; 98};
79 99
80 100
81enum CacheGetType 101/**
82{ 102 * The cache-get request handle
83 CGT_TRANSPORT_HANDLE = 1 103 */
84};
85
86
87struct GSTCacheGetHandle 104struct GSTCacheGetHandle
88{ 105{
106 /**
107 * The next ptr for the DLL. Used in struct CacheEntry
108 */
89 struct GSTCacheGetHandle *next; 109 struct GSTCacheGetHandle *next;
90 110
111 /**
112 * The prev ptr for the DLL. Used in struct CacheEntry
113 */
91 struct GSTCacheGetHandle *prev; 114 struct GSTCacheGetHandle *prev;
92 115
116 /**
117 * The cache entry object this handle corresponds to
118 */
93 struct CacheEntry *entry; 119 struct CacheEntry *entry;
94 120
121 /**
122 * The cache callback to call when a handle is available
123 */
95 GST_cache_callback cb; 124 GST_cache_callback cb;
96 125
126 /**
127 * The closure for the above callback
128 */
97 void *cb_cls; 129 void *cb_cls;
98 130
131 /**
132 * The peer connect notify context created for this handle; can be NULL
133 */
99 struct ConnectNotifyContext *nctxt; 134 struct ConnectNotifyContext *nctxt;
100 135
136 /**
137 * The type of this cache-get request
138 */
101 enum CacheGetType type; 139 enum CacheGetType type;
102 140
141 /**
142 * Did we call the cache callback already?
143 */
103 int notify_called; 144 int notify_called;
104}; 145};
105 146
@@ -121,12 +162,22 @@ struct CacheEntry
121 /** 162 /**
122 * The transport handle to the peer corresponding to this entry; can be NULL 163 * The transport handle to the peer corresponding to this entry; can be NULL
123 */ 164 */
124 struct GNUNET_TRANSPORT_Handle *transport_handle; 165 struct GNUNET_TRANSPORT_Handle *transport_handle_;
125 166
126 /** 167 /**
127 * The operation handle for transport handle 168 * The operation handle for transport handle
128 */ 169 */
129 struct GNUNET_TESTBED_Operation *transport_op; 170 struct GNUNET_TESTBED_Operation *transport_op_;
171
172 /**
173 * The core handle to the peer corresponding to this entry; can be NULL
174 */
175 struct GNUNET_CORE_Handle *core_handle;
176
177 /**
178 * The operation handle for core handle
179 */
180 struct GNUNET_TESTBED_Operation *core_op;
130 181
131 /** 182 /**
132 * The configuration of the peer. Should be not NULL as long as the core_handle 183 * The configuration of the peer. Should be not NULL as long as the core_handle
@@ -239,16 +290,19 @@ cache_lookup (const struct GNUNET_HashCode *key)
239 290
240static struct CacheEntry * 291static struct CacheEntry *
241cache_lookup_handles (const struct GNUNET_HashCode *pid, 292cache_lookup_handles (const struct GNUNET_HashCode *pid,
242 struct GNUNET_TRANSPORT_Handle **th) 293 struct GNUNET_TRANSPORT_Handle **th,
294 struct GNUNET_CORE_Handle **ch)
243{ 295{
244 struct CacheEntry *entry; 296 struct CacheEntry *entry;
245 297
246 GNUNET_assert (NULL != th); 298 GNUNET_assert ((NULL != th) || (NULL != ch));
247 entry = cache_lookup (pid); 299 entry = cache_lookup (pid);
248 if (NULL == entry) 300 if (NULL == entry)
249 return NULL; 301 return NULL;
250 if (NULL != entry->transport_handle) 302 if ((NULL != entry->transport_handle_) && (NULL != th))
251 *th = entry->transport_handle; 303 *th = entry->transport_handle_;
304 if ((NULL != entry->core_handle) && (NULL != ch))
305 *ch = entry->core_handle;
252 return entry; 306 return entry;
253} 307}
254 308
@@ -256,17 +310,30 @@ cache_lookup_handles (const struct GNUNET_HashCode *pid,
256static void 310static void
257cache_remove (struct CacheEntry *entry) 311cache_remove (struct CacheEntry *entry)
258{ 312{
313 struct ConnectNotifyContext *ctxt;
314
259 /* We keep the entry in the hash table so that the HELLO can still be found 315 /* We keep the entry in the hash table so that the HELLO can still be found
260 in cache; we will however disconnect the core and transport handles */ 316 in cache; we will however disconnect the core and transport handles */
261 GNUNET_assert (0 == entry->demand); 317 GNUNET_assert (0 == entry->demand);
262 if ((NULL != entry->next) || (NULL != entry->prev)) 318 if ((NULL != entry->next) || (NULL != entry->prev))
263 GNUNET_CONTAINER_DLL_remove (lru_cache_head, lru_cache_tail, entry); 319 GNUNET_CONTAINER_DLL_remove (lru_cache_head, lru_cache_tail, entry);
320 while (NULL != (ctxt = entry->nctxt_qhead))
321 {
322 GNUNET_CONTAINER_DLL_remove (entry->nctxt_qhead, entry->nctxt_qtail, ctxt);
323 GNUNET_free (ctxt);
324 }
264 LOG_DEBUG ("Cleaning up handles from an entry in cache\n"); 325 LOG_DEBUG ("Cleaning up handles from an entry in cache\n");
265 if (NULL != entry->transport_handle) 326 if (NULL != entry->transport_handle_)
327 {
328 GNUNET_assert (NULL != entry->transport_op_);
329 GNUNET_TESTBED_operation_done (entry->transport_op_);
330 entry->transport_op_ = NULL;
331 }
332 if (NULL != entry->core_handle)
266 { 333 {
267 GNUNET_assert (NULL != entry->transport_op); 334 GNUNET_assert (NULL != entry->core_op);
268 GNUNET_TESTBED_operation_done (entry->transport_op); 335 GNUNET_TESTBED_operation_done (entry->core_op);
269 entry->transport_op = NULL; 336 entry->core_op = NULL;
270 } 337 }
271 if (NULL != entry->cfg) 338 if (NULL != entry->cfg)
272 { 339 {
@@ -311,7 +378,10 @@ call_cgh_cb (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
311 switch (cgh->type) 378 switch (cgh->type)
312 { 379 {
313 case CGT_TRANSPORT_HANDLE: 380 case CGT_TRANSPORT_HANDLE:
314 cgh->cb (cgh->cb_cls, NULL, entry->transport_handle); 381 cgh->cb (cgh->cb_cls, NULL, entry->transport_handle_);
382 break;
383 case CGT_CORE_HANDLE:
384 cgh->cb (cgh->cb_cls, entry->core_handle, NULL);
315 break; 385 break;
316 } 386 }
317} 387}
@@ -361,17 +431,17 @@ opstart_get_handle_transport (void *cls)
361 431
362 GNUNET_assert (NULL != entry); 432 GNUNET_assert (NULL != entry);
363 LOG_DEBUG ("Opening a transport connection to peer %u\n", entry->peer_id); 433 LOG_DEBUG ("Opening a transport connection to peer %u\n", entry->peer_id);
364 entry->transport_handle = GNUNET_TRANSPORT_connect (entry->cfg, 434 entry->transport_handle_ = GNUNET_TRANSPORT_connect (entry->cfg,
365 NULL, entry, 435 NULL, entry,
366 NULL, 436 NULL,
367 &peer_connect_notify_cb, 437 &peer_connect_notify_cb,
368 NULL); 438 NULL);
369 if (NULL == entry->transport_handle) 439 if (NULL == entry->transport_handle_)
370 { 440 {
371 GNUNET_break (0); 441 GNUNET_break (0);
372 return; 442 return;
373 } 443 }
374 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == entry->notify_task); 444 //GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == entry->notify_task);
375 if (0 == entry->demand) 445 if (0 == entry->demand)
376 return; 446 return;
377 if (GNUNET_NO == entry->cgh_qhead->notify_called) 447 if (GNUNET_NO == entry->cgh_qhead->notify_called)
@@ -383,17 +453,97 @@ static void
383oprelease_get_handle_transport (void *cls) 453oprelease_get_handle_transport (void *cls)
384{ 454{
385 struct CacheEntry *entry = cls; 455 struct CacheEntry *entry = cls;
386 struct ConnectNotifyContext *ctxt;
387 456
388 while (NULL != (ctxt = entry->nctxt_qhead)) 457 if (NULL == entry->transport_handle_)
458 return;
459 GNUNET_TRANSPORT_disconnect (entry->transport_handle_);
460 entry->transport_handle_ = NULL;
461}
462
463
464/**
465 * Function called after GNUNET_CORE_connect has succeeded (or failed
466 * for good). Note that the private key of the peer is intentionally
467 * not exposed here; if you need it, your process should try to read
468 * the private key file directly (which should work if you are
469 * authorized...). Implementations of this function must not call
470 * GNUNET_CORE_disconnect (other than by scheduling a new task to
471 * do this later).
472 *
473 * @param cls closure
474 * @param server handle to the server, NULL if we failed
475 * @param my_identity ID of this peer, NULL if we failed
476 */
477static void core_startup_cb (void *cls,
478 struct GNUNET_CORE_Handle * server,
479 const struct GNUNET_PeerIdentity *
480 my_identity)
481{
482 GNUNET_break (0);
483}
484
485
486/**
487 * Method called whenever a given peer connects.
488 *
489 * @param cls closure
490 * @param peer peer identity this notification is about
491 * @param atsi performance data for the connection
492 * @param atsi_count number of records in 'atsi'
493 */
494static void
495core_peer_connect_cb (void *cls,
496 const struct GNUNET_PeerIdentity * peer,
497 const struct GNUNET_ATS_Information * atsi,
498 unsigned int atsi_count)
499{
500 struct CacheEntry *entry = cls;
501
502 if (0 == entry->demand)
503 return;
504 if (GNUNET_NO == entry->cgh_qhead->notify_called)
505 entry->notify_task = GNUNET_SCHEDULER_add_now (&call_cgh_cb, entry);
506}
507
508
509static void
510opstart_get_handle_core (void *cls)
511{
512 struct CacheEntry *entry = cls;
513 const struct GNUNET_CORE_MessageHandler no_handlers[] = {
514 {NULL, 0, 0}
515 };
516
517 GNUNET_assert (NULL != entry);
518 LOG_DEBUG ("Opening a CORE connection to peer %u\n", entry->peer_id);
519 entry->core_handle = GNUNET_CORE_connect (entry->cfg,
520 entry,
521 &core_startup_cb,
522 &core_peer_connect_cb,
523 NULL, /* disconnect cb */
524 NULL, /* inbound notify */
525 GNUNET_NO,
526 NULL, /* outbound notify */
527 GNUNET_NO,
528 no_handlers);
529 if (NULL == entry->core_handle)
389 { 530 {
390 GNUNET_CONTAINER_DLL_remove (entry->nctxt_qhead, entry->nctxt_qtail, ctxt); 531 GNUNET_break (0);
391 GNUNET_free (ctxt); 532 return;
392 } 533 }
393 if (NULL == entry->transport_handle) 534 //GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == entry->notify_task);
535}
536
537
538static void
539oprelease_get_handle_core (void *cls)
540{
541 struct CacheEntry *entry = cls;
542
543 if (NULL == entry->core_handle)
394 return; 544 return;
395 GNUNET_TRANSPORT_disconnect (entry->transport_handle); 545 GNUNET_CORE_disconnect (entry->core_handle);
396 entry->transport_handle = NULL; 546 entry->core_handle = NULL;
397} 547}
398 548
399 549
@@ -409,6 +559,7 @@ cache_get_handle (unsigned int peer_id,
409 void *handle; 559 void *handle;
410 struct CacheEntry *entry; 560 struct CacheEntry *entry;
411 struct ConnectNotifyContext *ctxt; 561 struct ConnectNotifyContext *ctxt;
562 struct GNUNET_TESTBED_Operation *op;
412 563
413 GNUNET_assert (0 != cgh->type); 564 GNUNET_assert (0 != cgh->type);
414 GNUNET_CRYPTO_hash (&peer_id, sizeof (peer_id), &key); 565 GNUNET_CRYPTO_hash (&peer_id, sizeof (peer_id), &key);
@@ -417,7 +568,12 @@ cache_get_handle (unsigned int peer_id,
417 switch (cgh->type) 568 switch (cgh->type)
418 { 569 {
419 case CGT_TRANSPORT_HANDLE: 570 case CGT_TRANSPORT_HANDLE:
420 entry = cache_lookup_handles (&key, (struct GNUNET_TRANSPORT_Handle **) &handle); 571 entry = cache_lookup_handles (&key, (struct GNUNET_TRANSPORT_Handle **)
572 &handle, NULL);
573 break;
574 case CGT_CORE_HANDLE:
575 entry = cache_lookup_handles (&key, NULL,
576 (struct GNUNET_CORE_Handle **) &handle);
421 break; 577 break;
422 } 578 }
423 if (NULL != handle) 579 if (NULL != handle)
@@ -445,25 +601,31 @@ cache_get_handle (unsigned int peer_id,
445 ctxt->cgh = cgh; 601 ctxt->cgh = cgh;
446 GNUNET_CONTAINER_DLL_insert_tail (entry->nctxt_qhead, entry->nctxt_qtail, ctxt); 602 GNUNET_CONTAINER_DLL_insert_tail (entry->nctxt_qhead, entry->nctxt_qtail, ctxt);
447 } 603 }
448 if ((NULL != entry->transport_handle) 604 if (NULL != handle)
449 && (GNUNET_SCHEDULER_NO_TASK == entry->notify_task))
450 { 605 {
451 entry->notify_task = GNUNET_SCHEDULER_add_now (&call_cgh_cb, entry); 606 if (GNUNET_SCHEDULER_NO_TASK == entry->notify_task)
607 entry->notify_task = GNUNET_SCHEDULER_add_now (&call_cgh_cb, entry);
452 return cgh; 608 return cgh;
453 } 609 }
454 if (NULL != entry->transport_op)
455 return cgh;
456 switch (cgh->type) 610 switch (cgh->type)
457 { 611 {
458 case CGT_TRANSPORT_HANDLE: 612 case CGT_TRANSPORT_HANDLE:
459 GNUNET_assert (NULL == entry->transport_op); 613 if (NULL != entry->transport_op_)
460 entry->transport_op = GNUNET_TESTBED_operation_create_ (entry, &opstart_get_handle_transport, 614 return cgh;
461 &oprelease_get_handle_transport); 615 op = GNUNET_TESTBED_operation_create_ (entry, &opstart_get_handle_transport,
462 GNUNET_TESTBED_operation_queue_insert_ (GST_opq_openfds, 616 &oprelease_get_handle_transport);
463 entry->transport_op); 617 entry->transport_op_ = op;
464 GNUNET_TESTBED_operation_begin_wait_ (entry->transport_op); 618 break;
619 case CGT_CORE_HANDLE:
620 if (NULL != entry->core_op)
621 return cgh;
622 op = GNUNET_TESTBED_operation_create_ (entry, &opstart_get_handle_core,
623 &oprelease_get_handle_core);
624 entry->core_op = op;
465 break; 625 break;
466 } 626 }
627 GNUNET_TESTBED_operation_queue_insert_ (GST_opq_openfds, op);
628 GNUNET_TESTBED_operation_begin_wait_ (op);
467 return cgh; 629 return cgh;
468} 630}
469 631
@@ -492,7 +654,10 @@ cache_clear_iterator (void *cls,
492 if (0 == entry->demand) 654 if (0 == entry->demand)
493 cache_remove (entry); 655 cache_remove (entry);
494 GNUNET_free_non_null (entry->hello); 656 GNUNET_free_non_null (entry->hello);
495 GNUNET_break (NULL == entry->transport_handle); 657 GNUNET_break (NULL == entry->transport_handle_);
658 GNUNET_break (NULL == entry->transport_op_);
659 GNUNET_break (NULL == entry->core_handle);
660 GNUNET_break (NULL == entry->core_op);
496 GNUNET_break (NULL == entry->cfg); 661 GNUNET_break (NULL == entry->cfg);
497 GNUNET_assert (NULL == entry->cgh_qhead); 662 GNUNET_assert (NULL == entry->cgh_qhead);
498 GNUNET_assert (NULL == entry->cgh_qtail); 663 GNUNET_assert (NULL == entry->cgh_qtail);
@@ -616,6 +781,46 @@ GST_cache_get_handle_transport (unsigned int peer_id,
616 781
617 782
618/** 783/**
784 * Get a transport handle with the given configuration. If the handle is already
785 * cached before, it will be retured in the given callback; the peer_id is used to lookup in the
786 * cache. If not a new operation is started to open the transport handle and
787 * will be given in the callback when it is available.
788 *
789 * @param peer_id the index of the peer
790 * @param cfg the configuration with which the transport handle has to be
791 * created if it was not present in the cache
792 * @param cb the callback to notify when the transport handle is available
793 * @param cb_cls the closure for the above callback
794 * @param target the peer identify of the peer whose connection to our TRANSPORT
795 * subsystem will be notified through the connect_notify_cb. Can be NULL
796 * @param connect_notify_cb the callback to call when the given target peer is
797 * connected. This callback will only be called once or never again (in
798 * case the target peer cannot be connected). Can be NULL
799 * @param connect_notify_cb_cls the closure for the above callback
800 * @return the handle which can be used cancel or mark that the handle is no
801 * longer being used
802 */
803struct GSTCacheGetHandle *
804GST_cache_get_handle_core (unsigned int peer_id,
805 const struct GNUNET_CONFIGURATION_Handle *cfg,
806 GST_cache_callback cb,
807 void *cb_cls,
808 const struct GNUNET_PeerIdentity *target,
809 GST_cache_peer_connect_notify connect_notify_cb,
810 void *connect_notify_cb_cls)
811{
812 struct GSTCacheGetHandle *cgh;
813
814 cgh = GNUNET_malloc (sizeof (struct GSTCacheGetHandle));
815 cgh->cb = cb;
816 cgh->cb_cls = cb_cls;
817 cgh->type = CGT_CORE_HANDLE;
818 return cache_get_handle (peer_id, cgh, cfg,
819 target, connect_notify_cb, connect_notify_cb_cls);
820}
821
822
823/**
619 * Looks up in the hello cache and returns the HELLO of the given peer 824 * Looks up in the hello cache and returns the HELLO of the given peer
620 * 825 *
621 * @param peer_id the index of the peer whose HELLO has to be looked up 826 * @param peer_id the index of the peer whose HELLO has to be looked up