aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2010-11-13 22:38:47 +0000
committerChristian Grothoff <christian@grothoff.org>2010-11-13 22:38:47 +0000
commit72761db34214aae9f6a9f4a3c0e717b1bd1389d6 (patch)
tree23b040167f2d9d18fc8772fce2b6f184f4538c85
parent314d8bdb2a4f6b0926bf8f8f1d057cc71c1fd0db (diff)
downloadgnunet-72761db34214aae9f6a9f4a3c0e717b1bd1389d6.tar.gz
gnunet-72761db34214aae9f6a9f4a3c0e717b1bd1389d6.zip
hxing
-rw-r--r--src/core/core.h4
-rw-r--r--src/core/core_api.c264
-rw-r--r--src/core/gnunet-service-core.c29
-rw-r--r--src/core/test_core_api_start_only.c61
4 files changed, 238 insertions, 120 deletions
diff --git a/src/core/core.h b/src/core/core.h
index a8d90b81a..6fd595b8b 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -41,12 +41,12 @@
41/** 41/**
42 * General core debugging. 42 * General core debugging.
43 */ 43 */
44#define DEBUG_CORE GNUNET_NO 44#define DEBUG_CORE GNUNET_YES
45 45
46/** 46/**
47 * Debugging interaction core-clients. 47 * Debugging interaction core-clients.
48 */ 48 */
49#define DEBUG_CORE_CLIENT GNUNET_NO 49#define DEBUG_CORE_CLIENT GNUNET_YES
50 50
51/** 51/**
52 * Definition of bits in the InitMessage's options field that specify 52 * Definition of bits in the InitMessage's options field that specify
diff --git a/src/core/core_api.c b/src/core/core_api.c
index ba61094b6..9cadaabeb 100644
--- a/src/core/core_api.c
+++ b/src/core/core_api.c
@@ -241,6 +241,11 @@ struct GNUNET_CORE_Handle
241 GNUNET_SCHEDULER_TaskIdentifier reconnect_task; 241 GNUNET_SCHEDULER_TaskIdentifier reconnect_task;
242 242
243 /** 243 /**
244 * Current delay we use for re-trying to connect to core.
245 */
246 struct GNUNET_TIME_Relative retry_backoff;
247
248 /**
244 * Request information ID generator. 249 * Request information ID generator.
245 */ 250 */
246 uint32_t rim_id_gen; 251 uint32_t rim_id_gen;
@@ -362,11 +367,111 @@ reconnect_task (void *cls,
362 struct GNUNET_CORE_Handle *h = cls; 367 struct GNUNET_CORE_Handle *h = cls;
363 368
364 h->reconnect_task = GNUNET_SCHEDULER_NO_TASK; 369 h->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
370#if DEBUG_CORE
371 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
372 "Connecting to CORE service after delay\n");
373#endif
365 reconnect (h); 374 reconnect (h);
366} 375}
367 376
368 377
369/** 378/**
379 * Notify clients about disconnect and free
380 * the entry for connected peer.
381 *
382 * @param cls the 'struct GNUNET_CORE_Handle*'
383 * @param key the peer identity (not used)
384 * @param value the 'struct PeerRecord' to free.
385 * @return GNUNET_YES (continue)
386 */
387static int
388disconnect_and_free_peer_entry (void *cls,
389 const GNUNET_HashCode *key,
390 void *value)
391{
392 static struct GNUNET_BANDWIDTH_Value32NBO zero;
393 struct GNUNET_CORE_Handle *h = cls;
394 struct GNUNET_CORE_TransmitHandle *th;
395 struct PeerRecord *pr = value;
396 GNUNET_CORE_PeerConfigurationInfoCallback pcic;
397
398 while (NULL != (th = pr->pending_head))
399 {
400 GNUNET_CONTAINER_DLL_remove (pr->pending_head,
401 pr->pending_tail,
402 th);
403 pr->queue_size--;
404 GNUNET_assert (0 ==
405 th->get_message (th->get_message_cls,
406 0, NULL));
407 GNUNET_free (th);
408 }
409 if (NULL != (pcic = pr->pcic))
410 {
411 pr->pcic = NULL;
412 pcic (pr->pcic_cls,
413 &pr->peer,
414 zero,
415 0, 0);
416 }
417 if (pr->timeout_task != GNUNET_SCHEDULER_NO_TASK)
418 {
419 GNUNET_SCHEDULER_cancel (pr->timeout_task);
420 pr->timeout_task = GNUNET_SCHEDULER_NO_TASK;
421 }
422 GNUNET_assert (pr->queue_size == 0);
423 if ( (pr->prev != NULL) ||
424 (pr->next != NULL) ||
425 (h->ready_peer_head == pr) )
426 GNUNET_CONTAINER_DLL_remove (h->ready_peer_head,
427 h->ready_peer_tail,
428 pr);
429 if (h->disconnects != NULL)
430 h->disconnects (h->cls,
431 &pr->peer);
432 GNUNET_assert (GNUNET_YES ==
433 GNUNET_CONTAINER_multihashmap_remove (h->peers,
434 key,
435 pr));
436 GNUNET_assert (pr->pending_head == NULL);
437 GNUNET_assert (pr->pending_tail == NULL);
438 GNUNET_assert (pr->ch = h);
439 GNUNET_assert (pr->queue_size == 0);
440 GNUNET_assert (pr->timeout_task == GNUNET_SCHEDULER_NO_TASK);
441 GNUNET_free (pr);
442 return GNUNET_YES;
443}
444
445
446/**
447 * Close down any existing connection to the CORE service and
448 * try re-establishing it later.
449 *
450 * @param h our handle
451 */
452static void
453reconnect_later (struct GNUNET_CORE_Handle *h)
454{
455 if (h->client != NULL)
456 {
457 GNUNET_CLIENT_disconnect (h->client, GNUNET_NO);
458 h->client = NULL;
459 GNUNET_CONTAINER_multihashmap_iterate (h->peers,
460 &disconnect_and_free_peer_entry,
461 h);
462 }
463 h->currently_down = GNUNET_YES;
464 GNUNET_assert (h->reconnect_task == GNUNET_SCHEDULER_NO_TASK);
465 h->retry_backoff = GNUNET_TIME_relative_min (GNUNET_TIME_UNIT_SECONDS,
466 h->retry_backoff);
467 h->reconnect_task = GNUNET_SCHEDULER_add_delayed (h->retry_backoff,
468 &reconnect_task,
469 h);
470 h->retry_backoff = GNUNET_TIME_relative_multiply (h->retry_backoff, 2);
471}
472
473
474/**
370 * Check the list of pending requests, send the next 475 * Check the list of pending requests, send the next
371 * one to the core. 476 * one to the core.
372 * 477 *
@@ -506,7 +611,11 @@ transmit_message (void *cls,
506 h->cth = NULL; 611 h->cth = NULL;
507 if (buf == NULL) 612 if (buf == NULL)
508 { 613 {
509 reconnect (h); 614#if DEBUG_CORE
615 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
616 "Transmission failed, initiating reconnect\n");
617#endif
618 reconnect_later (h);
510 return 0; 619 return 0;
511 } 620 }
512 /* first check for control messages */ 621 /* first check for control messages */
@@ -519,12 +628,20 @@ transmit_message (void *cls,
519 trigger_next_request (h, GNUNET_NO); 628 trigger_next_request (h, GNUNET_NO);
520 return 0; 629 return 0;
521 } 630 }
631#if DEBUG_CORE
632 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
633 "Transmitting control message with %u bytes of type %u to core.\n",
634 (unsigned int) msize,
635 (unsigned int) ntohs (hdr->type));
636#endif
522 memcpy (buf, hdr, msize); 637 memcpy (buf, hdr, msize);
523 GNUNET_CONTAINER_DLL_remove (h->pending_head, 638 GNUNET_CONTAINER_DLL_remove (h->pending_head,
524 h->pending_tail, 639 h->pending_tail,
525 cm); 640 cm);
526 if (NULL != cm->cont) 641 if (NULL != cm->cont)
527 GNUNET_SCHEDULER_add_now (cm->cont, cm->cont_cls); 642 GNUNET_SCHEDULER_add_continuation (cm->cont,
643 cm->cont_cls,
644 GNUNET_SCHEDULER_REASON_PREREQ_DONE);
528 GNUNET_free (cm); 645 GNUNET_free (cm);
529 trigger_next_request (h, GNUNET_NO); 646 trigger_next_request (h, GNUNET_NO);
530 return msize; 647 return msize;
@@ -550,7 +667,12 @@ transmit_message (void *cls,
550 GNUNET_SCHEDULER_cancel (pr->timeout_task); 667 GNUNET_SCHEDULER_cancel (pr->timeout_task);
551 pr->timeout_task = GNUNET_SCHEDULER_NO_TASK; 668 pr->timeout_task = GNUNET_SCHEDULER_NO_TASK;
552 } 669 }
553 670#if DEBUG_CORE
671 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
672 "Transmitting SEND request to `%s' with %u bytes.\n",
673 GNUNET_i2s (&pr->peer),
674 (unsigned int) th->msize);
675#endif
554 sm = (struct SendMessage *) buf; 676 sm = (struct SendMessage *) buf;
555 sm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_SEND); 677 sm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_SEND);
556 sm->priority = htonl (th->priority); 678 sm->priority = htonl (th->priority);
@@ -626,70 +748,6 @@ trigger_next_request (struct GNUNET_CORE_Handle *h,
626} 748}
627 749
628 750
629
630
631/**
632 * Notify clients about disconnect and free
633 * the entry for connected peer.
634 *
635 * @param cls the 'struct GNUNET_CORE_Handle*'
636 * @param key the peer identity (not used)
637 * @param value the 'struct PeerRecord' to free.
638 * @return GNUNET_YES (continue)
639 */
640static int
641disconnect_and_free_peer_entry (void *cls,
642 const GNUNET_HashCode *key,
643 void *value)
644{
645 struct GNUNET_CORE_Handle *h = cls;
646 struct GNUNET_CORE_TransmitHandle *th;
647 struct PeerRecord *pr = value;
648
649 while (NULL != (th = pr->pending_head))
650 {
651 GNUNET_CONTAINER_DLL_remove (pr->pending_head,
652 pr->pending_tail,
653 th);
654 pr->queue_size--;
655 GNUNET_assert (0 ==
656 th->get_message (th->get_message_cls,
657 0, NULL));
658 GNUNET_free (th);
659 }
660 if (pr->pcic != NULL)
661 {
662 // FIXME: call pcic callback!
663 }
664 if (pr->timeout_task != GNUNET_SCHEDULER_NO_TASK)
665 {
666 GNUNET_SCHEDULER_cancel (pr->timeout_task);
667 pr->timeout_task = GNUNET_SCHEDULER_NO_TASK;
668 }
669 GNUNET_assert (pr->queue_size == 0);
670 if ( (pr->prev != NULL) ||
671 (pr->next != NULL) ||
672 (h->ready_peer_head == pr) )
673 GNUNET_CONTAINER_DLL_remove (h->ready_peer_head,
674 h->ready_peer_tail,
675 pr);
676 if (h->disconnects != NULL)
677 h->disconnects (h->cls,
678 &pr->peer);
679 GNUNET_assert (GNUNET_YES ==
680 GNUNET_CONTAINER_multihashmap_remove (h->peers,
681 key,
682 pr));
683 GNUNET_assert (pr->pending_head == NULL);
684 GNUNET_assert (pr->pending_tail == NULL);
685 GNUNET_assert (pr->ch = h);
686 GNUNET_assert (pr->queue_size == 0);
687 GNUNET_assert (pr->timeout_task == GNUNET_SCHEDULER_NO_TASK);
688 GNUNET_free (pr);
689 return GNUNET_YES;
690}
691
692
693/** 751/**
694 * Handler for notification messages received from the core. 752 * Handler for notification messages received from the core.
695 * 753 *
@@ -725,7 +783,7 @@ main_notify_handler (void *cls,
725 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 783 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
726 _ 784 _
727 ("Client was disconnected from core service, trying to reconnect.\n")); 785 ("Client was disconnected from core service, trying to reconnect.\n"));
728 reconnect (h); 786 reconnect_later (h);
729 return; 787 return;
730 } 788 }
731 msize = ntohs (msg->size); 789 msize = ntohs (msg->size);
@@ -755,6 +813,7 @@ main_notify_handler (void *cls,
755 h->currently_down = GNUNET_NO; 813 h->currently_down = GNUNET_NO;
756 trigger_next_request (h, GNUNET_NO); 814 trigger_next_request (h, GNUNET_NO);
757 } 815 }
816 h->retry_backoff = GNUNET_TIME_UNIT_MILLISECONDS;
758 if (NULL != (init = h->init)) 817 if (NULL != (init = h->init))
759 { 818 {
760 /* mark so we don't call init on reconnect */ 819 /* mark so we don't call init on reconnect */
@@ -773,6 +832,11 @@ main_notify_handler (void *cls,
773 break; 832 break;
774 } 833 }
775 cnm = (const struct ConnectNotifyMessage *) msg; 834 cnm = (const struct ConnectNotifyMessage *) msg;
835#if DEBUG_CORE
836 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
837 "Received notification about connection from `%s'.\n",
838 GNUNET_i2s (&cnm->peer));
839#endif
776 pr = GNUNET_CONTAINER_multihashmap_get (h->peers, 840 pr = GNUNET_CONTAINER_multihashmap_get (h->peers,
777 &cnm->peer.hashPubKey); 841 &cnm->peer.hashPubKey);
778 if (pr != NULL) 842 if (pr != NULL)
@@ -801,6 +865,11 @@ main_notify_handler (void *cls,
801 break; 865 break;
802 } 866 }
803 dnm = (const struct DisconnectNotifyMessage *) msg; 867 dnm = (const struct DisconnectNotifyMessage *) msg;
868#if DEBUG_CORE
869 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
870 "Received notification about disconnect from `%s'.\n",
871 GNUNET_i2s (&dnm->peer));
872#endif
804 pr = GNUNET_CONTAINER_multihashmap_get (h->peers, 873 pr = GNUNET_CONTAINER_multihashmap_get (h->peers,
805 &dnm->peer.hashPubKey); 874 &dnm->peer.hashPubKey);
806 if (pr == NULL) 875 if (pr == NULL)
@@ -828,6 +897,11 @@ main_notify_handler (void *cls,
828 break; 897 break;
829 } 898 }
830 psnm = (const struct PeerStatusNotifyMessage *) msg; 899 psnm = (const struct PeerStatusNotifyMessage *) msg;
900#if DEBUG_CORE
901 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
902 "Received notification about status change by `%s'.\n",
903 GNUNET_i2s (&psnm->peer));
904#endif
831 pr = GNUNET_CONTAINER_multihashmap_get (h->peers, 905 pr = GNUNET_CONTAINER_multihashmap_get (h->peers,
832 &psnm->peer.hashPubKey); 906 &psnm->peer.hashPubKey);
833 if (pr == NULL) 907 if (pr == NULL)
@@ -916,6 +990,11 @@ main_notify_handler (void *cls,
916 reconnect (h); 990 reconnect (h);
917 return; 991 return;
918 } 992 }
993#if DEBUG_CORE
994 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
995 "Received notification about transmission to `%s'.\n",
996 GNUNET_i2s (&ntm->peer));
997#endif
919 if ((GNUNET_NO == h->outbound_hdr_only) && 998 if ((GNUNET_NO == h->outbound_hdr_only) &&
920 (msize != ntohs (em->size) + sizeof (struct NotifyTrafficMessage))) 999 (msize != ntohs (em->size) + sizeof (struct NotifyTrafficMessage)))
921 { 1000 {
@@ -945,6 +1024,11 @@ main_notify_handler (void *cls,
945 reconnect (h); 1024 reconnect (h);
946 return; 1025 return;
947 } 1026 }
1027#if DEBUG_CORE
1028 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1029 "Received notification about transmission readiness to `%s'.\n",
1030 GNUNET_i2s (&smr->peer));
1031#endif
948 th = pr->pending_head; 1032 th = pr->pending_head;
949 if (ntohs (smr->smr_id) != th->smr_id) 1033 if (ntohs (smr->smr_id) != th->smr_id)
950 { 1034 {
@@ -973,6 +1057,11 @@ main_notify_handler (void *cls,
973 break; 1057 break;
974 } 1058 }
975 cim = (const struct ConfigurationInfoMessage*) msg; 1059 cim = (const struct ConfigurationInfoMessage*) msg;
1060#if DEBUG_CORE
1061 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1062 "Received notification about configuration update for `%s'.\n",
1063 GNUNET_i2s (&cim->peer));
1064#endif
976 pr = GNUNET_CONTAINER_multihashmap_get (h->peers, 1065 pr = GNUNET_CONTAINER_multihashmap_get (h->peers,
977 &cim->peer.hashPubKey); 1066 &cim->peer.hashPubKey);
978 if (pr == NULL) 1067 if (pr == NULL)
@@ -997,7 +1086,8 @@ main_notify_handler (void *cls,
997 break; 1086 break;
998 } 1087 }
999 GNUNET_CLIENT_receive (h->client, 1088 GNUNET_CLIENT_receive (h->client,
1000 &main_notify_handler, h, GNUNET_TIME_UNIT_FOREVER_REL); 1089 &main_notify_handler, h,
1090 GNUNET_TIME_UNIT_FOREVER_REL);
1001} 1091}
1002 1092
1003 1093
@@ -1016,14 +1106,11 @@ init_done_task (void *cls,
1016 1106
1017 if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE)) 1107 if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE))
1018 { 1108 {
1019 if (h->client != NULL) 1109#if DEBUG_CORE
1020 { 1110 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1021 GNUNET_CLIENT_disconnect (h->client, GNUNET_NO); 1111 "Failed to exchange INIT with core, retrying\n");
1022 h->client = NULL; 1112#endif
1023 } 1113 reconnect_later (h);
1024 h->reconnect_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
1025 &reconnect_task,
1026 h);
1027 return; 1114 return;
1028 } 1115 }
1029 GNUNET_CLIENT_receive (h->client, 1116 GNUNET_CLIENT_receive (h->client,
@@ -1065,9 +1152,7 @@ reconnect (struct GNUNET_CORE_Handle *h)
1065 h->client = GNUNET_CLIENT_connect ("core", h->cfg); 1152 h->client = GNUNET_CLIENT_connect ("core", h->cfg);
1066 if (h->client == NULL) 1153 if (h->client == NULL)
1067 { 1154 {
1068 h->reconnect_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, 1155 reconnect_later (h);
1069 &reconnect_task,
1070 h);
1071 return; 1156 return;
1072 } 1157 }
1073 msize = h->hcnt * sizeof (uint16_t) + sizeof (struct InitMessage); 1158 msize = h->hcnt * sizeof (uint16_t) + sizeof (struct InitMessage);
@@ -1162,11 +1247,16 @@ GNUNET_CORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
1162 h->handlers = handlers; 1247 h->handlers = handlers;
1163 h->hcnt = 0; 1248 h->hcnt = 0;
1164 h->peers = GNUNET_CONTAINER_multihashmap_create (128); 1249 h->peers = GNUNET_CONTAINER_multihashmap_create (128);
1250 h->retry_backoff = GNUNET_TIME_UNIT_MILLISECONDS;
1165 while (handlers[h->hcnt].callback != NULL) 1251 while (handlers[h->hcnt].callback != NULL)
1166 h->hcnt++; 1252 h->hcnt++;
1167 GNUNET_assert (h->hcnt < 1253 GNUNET_assert (h->hcnt <
1168 (GNUNET_SERVER_MAX_MESSAGE_SIZE - 1254 (GNUNET_SERVER_MAX_MESSAGE_SIZE -
1169 sizeof (struct InitMessage)) / sizeof (uint16_t)); 1255 sizeof (struct InitMessage)) / sizeof (uint16_t));
1256#if DEBUG_CORE
1257 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1258 "Connecting to CORE service\n");
1259#endif
1170 reconnect (h); 1260 reconnect (h);
1171 return h; 1261 return h;
1172} 1262}
@@ -1184,11 +1274,10 @@ GNUNET_CORE_disconnect (struct GNUNET_CORE_Handle *handle)
1184{ 1274{
1185 struct ControlMessage *cm; 1275 struct ControlMessage *cm;
1186 1276
1187 if (handle->reconnect_task != GNUNET_SCHEDULER_NO_TASK) 1277#if DEBUG_CORE
1188 { 1278 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1189 GNUNET_SCHEDULER_cancel (handle->reconnect_task); 1279 "Disconnecting from CORE service\n");
1190 handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK; 1280#endif
1191 }
1192 if (handle->cth != NULL) 1281 if (handle->cth != NULL)
1193 { 1282 {
1194 GNUNET_CLIENT_notify_transmit_ready_cancel (handle->cth); 1283 GNUNET_CLIENT_notify_transmit_ready_cancel (handle->cth);
@@ -1199,6 +1288,11 @@ GNUNET_CORE_disconnect (struct GNUNET_CORE_Handle *handle)
1199 GNUNET_CLIENT_disconnect (handle->client, GNUNET_NO); 1288 GNUNET_CLIENT_disconnect (handle->client, GNUNET_NO);
1200 handle->client = NULL; 1289 handle->client = NULL;
1201 } 1290 }
1291 if (handle->reconnect_task != GNUNET_SCHEDULER_NO_TASK)
1292 {
1293 GNUNET_SCHEDULER_cancel (handle->reconnect_task);
1294 handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
1295 }
1202 while (NULL != (cm = handle->pending_head)) 1296 while (NULL != (cm = handle->pending_head))
1203 { 1297 {
1204 GNUNET_CONTAINER_DLL_remove (handle->pending_head, 1298 GNUNET_CONTAINER_DLL_remove (handle->pending_head,
diff --git a/src/core/gnunet-service-core.c b/src/core/gnunet-service-core.c
index 034f80060..4e4d61431 100644
--- a/src/core/gnunet-service-core.c
+++ b/src/core/gnunet-service-core.c
@@ -1153,11 +1153,7 @@ handle_client_init (void *cls,
1153 while (c != NULL) 1153 while (c != NULL)
1154 { 1154 {
1155 if (client == c->client_handle) 1155 if (client == c->client_handle)
1156 { 1156 break;
1157 GNUNET_break (0);
1158 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1159 return;
1160 }
1161 c = c->next; 1157 c = c->next;
1162 } 1158 }
1163 msize = ntohs (message->size); 1159 msize = ntohs (message->size);
@@ -1171,16 +1167,19 @@ handle_client_init (void *cls,
1171 im = (const struct InitMessage *) message; 1167 im = (const struct InitMessage *) message;
1172 types = (const uint16_t *) &im[1]; 1168 types = (const uint16_t *) &im[1];
1173 msize -= sizeof (struct InitMessage); 1169 msize -= sizeof (struct InitMessage);
1174 c = GNUNET_malloc (sizeof (struct Client) + msize); 1170 if (c == NULL)
1175 c->client_handle = client; 1171 {
1176 c->next = clients; 1172 c = GNUNET_malloc (sizeof (struct Client) + msize);
1177 clients = c; 1173 c->client_handle = client;
1178 c->tcnt = msize / sizeof (uint16_t); 1174 c->next = clients;
1179 c->types = (const uint16_t *) &c[1]; 1175 clients = c;
1180 wtypes = (uint16_t *) &c[1]; 1176 c->tcnt = msize / sizeof (uint16_t);
1181 for (i=0;i<c->tcnt;i++) 1177 c->types = (const uint16_t *) &c[1];
1182 wtypes[i] = ntohs (types[i]); 1178 wtypes = (uint16_t *) &c[1];
1183 c->options = ntohl (im->options); 1179 for (i=0;i<c->tcnt;i++)
1180 wtypes[i] = ntohs (types[i]);
1181 c->options = ntohl (im->options);
1182 }
1184#if DEBUG_CORE_CLIENT 1183#if DEBUG_CORE_CLIENT
1185 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1184 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1186 "Client %p is interested in %u message types\n", 1185 "Client %p is interested in %u message types\n",
diff --git a/src/core/test_core_api_start_only.c b/src/core/test_core_api_start_only.c
index 7f6768dd4..e03886e6e 100644
--- a/src/core/test_core_api_start_only.c
+++ b/src/core/test_core_api_start_only.c
@@ -51,6 +51,7 @@ static struct PeerContext p1;
51 51
52static struct PeerContext p2; 52static struct PeerContext p2;
53 53
54static GNUNET_SCHEDULER_TaskIdentifier timeout_task_id;
54 55
55static int ok; 56static int ok;
56 57
@@ -112,25 +113,26 @@ init_notify (void *cls,
112 struct PeerContext *p = cls; 113 struct PeerContext *p = cls;
113 114
114 GNUNET_assert (server != NULL); 115 GNUNET_assert (server != NULL);
115 p->ch = server; 116 GNUNET_assert (p->ch == server);
116 if (cls == &p1) 117 if (cls == &p1)
117 { 118 {
118 /* connect p2 */ 119 /* connect p2 */
119 GNUNET_CORE_connect (p2.cfg, 1, 120 p2.ch = GNUNET_CORE_connect (p2.cfg, 1,
120 &p2, 121 &p2,
121 &init_notify, 122 &init_notify,
122 &connect_notify, 123 &connect_notify,
123 &disconnect_notify, 124 &disconnect_notify,
124 NULL, 125 NULL,
125 &inbound_notify, 126 &inbound_notify,
126 GNUNET_YES, 127 GNUNET_YES,
127 &outbound_notify, GNUNET_YES, handlers); 128 &outbound_notify, GNUNET_YES, handlers);
128 } 129 }
129 else 130 else
130 { 131 {
131 GNUNET_assert (cls == &p2); 132 GNUNET_assert (cls == &p2);
132 GNUNET_CORE_disconnect (p1.ch); 133 GNUNET_CORE_disconnect (p1.ch);
133 GNUNET_CORE_disconnect (p2.ch); 134 GNUNET_CORE_disconnect (p2.ch);
135 GNUNET_SCHEDULER_cancel (timeout_task_id);
134 ok = 0; 136 ok = 0;
135 } 137 }
136} 138}
@@ -153,6 +155,26 @@ setup_peer (struct PeerContext *p, const char *cfgname)
153 155
154 156
155static void 157static void
158timeout_task (void *cls,
159 const struct GNUNET_SCHEDULER_TaskContext *tc)
160{
161 fprintf (stderr, "Timeout.\n");
162 if (p1.ch != NULL)
163 {
164 GNUNET_CORE_disconnect (p1.ch);
165 p1.ch = NULL;
166 }
167 if (p2.ch != NULL)
168 {
169 GNUNET_CORE_disconnect (p2.ch);
170 p2.ch = NULL;
171 }
172 ok = 42;
173}
174
175
176
177static void
156run (void *cls, 178run (void *cls,
157 char *const *args, 179 char *const *args,
158 const char *cfgfile, 180 const char *cfgfile,
@@ -162,14 +184,17 @@ run (void *cls,
162 OKPP; 184 OKPP;
163 setup_peer (&p1, "test_core_api_peer1.conf"); 185 setup_peer (&p1, "test_core_api_peer1.conf");
164 setup_peer (&p2, "test_core_api_peer2.conf"); 186 setup_peer (&p2, "test_core_api_peer2.conf");
165 GNUNET_CORE_connect (p1.cfg, 1, 187 timeout_task_id = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
166 &p1, 188 &timeout_task,
167 &init_notify, 189 NULL);
168 &connect_notify, 190 p1.ch = GNUNET_CORE_connect (p1.cfg, 1,
169 &disconnect_notify, 191 &p1,
170 NULL, 192 &init_notify,
171 &inbound_notify, 193 &connect_notify,
172 GNUNET_YES, &outbound_notify, GNUNET_YES, handlers); 194 &disconnect_notify,
195 NULL,
196 &inbound_notify,
197 GNUNET_YES, &outbound_notify, GNUNET_YES, handlers);
173} 198}
174 199
175 200