aboutsummaryrefslogtreecommitdiff
path: root/src/core/gnunet-service-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/gnunet-service-core.c')
-rw-r--r--src/core/gnunet-service-core.c364
1 files changed, 290 insertions, 74 deletions
diff --git a/src/core/gnunet-service-core.c b/src/core/gnunet-service-core.c
index c1ebdb9df..034f80060 100644
--- a/src/core/gnunet-service-core.c
+++ b/src/core/gnunet-service-core.c
@@ -391,6 +391,15 @@ struct MessageEntry
391}; 391};
392 392
393 393
394/**
395 * Record kept for each request for transmission issued by a
396 * client that is still pending.
397 */
398struct ClientActiveRequest;
399
400/**
401 * Data kept per neighbouring peer.
402 */
394struct Neighbour 403struct Neighbour
395{ 404{
396 /** 405 /**
@@ -416,6 +425,18 @@ struct Neighbour
416 struct MessageEntry *encrypted_tail; 425 struct MessageEntry *encrypted_tail;
417 426
418 /** 427 /**
428 * Head of list of requests from clients for transmission to
429 * this peer.
430 */
431 struct ClientActiveRequest *active_client_request_head;
432
433 /**
434 * Tail of list of requests from clients for transmission to
435 * this peer.
436 */
437 struct ClientActiveRequest *active_client_request_tail;
438
439 /**
419 * Handle for pending requests for transmission to this peer 440 * Handle for pending requests for transmission to this peer
420 * with the transport service. NULL if no request is pending. 441 * with the transport service. NULL if no request is pending.
421 */ 442 */
@@ -517,11 +538,6 @@ struct Neighbour
517 struct GNUNET_TIME_Absolute last_activity; 538 struct GNUNET_TIME_Absolute last_activity;
518 539
519 /** 540 /**
520 * Last latency observed from this peer.
521 */
522 struct GNUNET_TIME_Relative last_latency;
523
524 /**
525 * At what frequency are we currently re-trying SET_KEY messages? 541 * At what frequency are we currently re-trying SET_KEY messages?
526 */ 542 */
527 struct GNUNET_TIME_Relative set_key_retry_frequency; 543 struct GNUNET_TIME_Relative set_key_retry_frequency;
@@ -588,11 +604,6 @@ struct Neighbour
588 uint32_t ping_challenge; 604 uint32_t ping_challenge;
589 605
590 /** 606 /**
591 * What was the last distance to this peer as reported by the transports?
592 */
593 uint32_t last_distance;
594
595 /**
596 * What is our connection status? 607 * What is our connection status?
597 */ 608 */
598 enum PeerStateMachine status; 609 enum PeerStateMachine status;
@@ -628,6 +639,12 @@ struct Client
628 const uint16_t *types; 639 const uint16_t *types;
629 640
630 /** 641 /**
642 * Map of peer identities to active transmission requests of this
643 * client to the peer (of type 'struct ClientActiveRequest').
644 */
645 struct GNUNET_CONTAINER_MultiHashMap *requests;
646
647 /**
631 * Options for messages this client cares about, 648 * Options for messages this client cares about,
632 * see GNUNET_CORE_OPTION_ values. 649 * see GNUNET_CORE_OPTION_ values.
633 */ 650 */
@@ -643,6 +660,59 @@ struct Client
643 660
644 661
645/** 662/**
663 * Record kept for each request for transmission issued by a
664 * client that is still pending.
665 */
666struct ClientActiveRequest
667{
668
669 /**
670 * Active requests are kept in a doubly-linked list of
671 * the respective target peer.
672 */
673 struct ClientActiveRequest *next;
674
675 /**
676 * Active requests are kept in a doubly-linked list of
677 * the respective target peer.
678 */
679 struct ClientActiveRequest *prev;
680
681 /**
682 * Handle to the client.
683 */
684 struct Client *client;
685
686 /**
687 * By what time would the client want to see this message out?
688 */
689 struct GNUNET_TIME_Absolute deadline;
690
691 /**
692 * How important is this request.
693 */
694 uint32_t priority;
695
696 /**
697 * How many more requests does this client have?
698 */
699 uint32_t queue_size;
700
701 /**
702 * How many bytes does the client intend to send?
703 */
704 uint16_t msize;
705
706 /**
707 * Unique request ID (in big endian).
708 */
709 uint16_t smr_id;
710
711};
712
713
714
715/**
646 * Our public key. 716 * Our public key.
647 */ 717 */
648static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded my_public_key; 718static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded my_public_key;
@@ -917,8 +987,6 @@ handle_peer_status_change (struct Neighbour *n)
917#endif 987#endif
918 psnm.header.size = htons (sizeof (struct PeerStatusNotifyMessage)); 988 psnm.header.size = htons (sizeof (struct PeerStatusNotifyMessage));
919 psnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_STATUS_CHANGE); 989 psnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_STATUS_CHANGE);
920 psnm.distance = htonl (n->last_distance);
921 psnm.latency = GNUNET_TIME_relative_hton (n->last_latency);
922 psnm.timeout = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_add (n->last_activity, 990 psnm.timeout = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_add (n->last_activity,
923 GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT)); 991 GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT));
924 psnm.bandwidth_in = n->bw_in; 992 psnm.bandwidth_in = n->bw_in;
@@ -933,46 +1001,127 @@ handle_peer_status_change (struct Neighbour *n)
933 GNUNET_NO); 1001 GNUNET_NO);
934} 1002}
935 1003
1004
936/** 1005/**
937 * Handle CORE_ITERATE_PEERS request. 1006 * Go over our message queue and if it is not too long, go
1007 * over the pending requests from clients for this
1008 * neighbour and send some clients a 'READY' notification.
1009 *
1010 * @param n which peer to process
938 */ 1011 */
939static void 1012static void
940handle_client_iterate_peers (void *cls, 1013schedule_peer_messages (struct Neighbour *n)
941 struct GNUNET_SERVER_Client *client,
942 const struct GNUNET_MessageHeader *message)
943{ 1014{
944 struct Neighbour *n; 1015 struct SendMessageReady smr;
945 struct ConnectNotifyMessage cnm; 1016 struct ClientActiveRequest *car;
946 struct GNUNET_MessageHeader done_msg; 1017 struct ClientActiveRequest *pos;
947 struct GNUNET_SERVER_TransmitContext *tc; 1018 struct Client *c;
948 1019 struct MessageEntry *mqe;
949 /* notify new client about existing neighbours */ 1020 unsigned int queue_size;
950 cnm.header.size = htons (sizeof (struct ConnectNotifyMessage)); 1021
951 cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT); 1022 /* check if neighbour queue is empty enough! */
952 done_msg.size = htons (sizeof (struct GNUNET_MessageHeader)); 1023 queue_size = 0;
953 done_msg.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT); 1024 mqe = n->messages;
954 tc = GNUNET_SERVER_transmit_context_create (client); 1025 while (mqe != NULL)
955 n = neighbours;
956 while (n != NULL)
957 { 1026 {
958 if (n->status == PEER_STATE_KEY_CONFIRMED) 1027 queue_size++;
959 { 1028 mqe = mqe->next;
960#if DEBUG_CORE_CLIENT 1029 }
961 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1030 if (queue_size >= MAX_PEER_QUEUE_SIZE)
962 "Sending `%s' message to client.\n", "NOTIFY_CONNECT"); 1031 return; /* queue still full */
963#endif 1032 /* find highest priority request */
964 cnm.distance = htonl (n->last_distance); 1033 pos = n->active_client_request_head;
965 cnm.latency = GNUNET_TIME_relative_hton (n->last_latency); 1034 car = NULL;
966 cnm.peer = n->peer; 1035 while (pos != NULL)
967 GNUNET_SERVER_transmit_context_append_message (tc, &cnm.header); 1036 {
968 /*send_to_client (c, &cnm.header, GNUNET_NO);*/ 1037 if ( (car == NULL) ||
969 } 1038 (pos->priority > car->priority) )
970 n = n->next; 1039 car = pos;
1040 pos = pos->next;
971 } 1041 }
1042 if (car == NULL)
1043 return; /* no pending requests */
1044 c = car->client;
1045 GNUNET_CONTAINER_DLL_remove (n->active_client_request_head,
1046 n->active_client_request_tail,
1047 car);
1048 GNUNET_CONTAINER_multihashmap_remove (c->requests,
1049 &n->peer.hashPubKey,
1050 car);
1051 smr.header.size = htons (sizeof (struct SendMessageReady));
1052 smr.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_SEND_READY);
1053 smr.size = htons (car->msize);
1054 smr.smr_id = car->smr_id;
1055 smr.peer = n->peer;
1056 send_to_client (c, &smr.header, GNUNET_NO);
1057 GNUNET_free (car);
1058}
972 1059
973 GNUNET_SERVER_transmit_context_append_message (tc, &done_msg); 1060
974 GNUNET_SERVER_transmit_context_run (tc, 1061/**
975 GNUNET_TIME_UNIT_FOREVER_REL); 1062 * Handle CORE_SEND_REQUEST message.
1063 */
1064static void
1065handle_client_send_request (void *cls,
1066 struct GNUNET_SERVER_Client *client,
1067 const struct GNUNET_MessageHeader *message)
1068{
1069 const struct SendMessageRequest *req;
1070 struct Neighbour *n;
1071 struct Client *c;
1072 struct ClientActiveRequest *car;
1073
1074 req = (const struct SendMessageRequest*) message;
1075 n = find_neighbour (&req->peer);
1076 if ( (n == NULL) ||
1077 (GNUNET_YES != n->is_connected) )
1078 {
1079 /* neighbour must have disconnected since request was issued,
1080 ignore (client will realize it once it processes the
1081 disconnect notification) */
1082 GNUNET_STATISTICS_update (stats,
1083 gettext_noop ("# send requests dropped (disconnected)"),
1084 1,
1085 GNUNET_NO);
1086 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1087 return;
1088 }
1089 c = clients;
1090 while ( (c != NULL) &&
1091 (c->client_handle != client) )
1092 c = c->next;
1093 if (c == NULL)
1094 {
1095 /* client did not send INIT first! */
1096 GNUNET_break (0);
1097 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1098 return;
1099 }
1100 if (c->requests == NULL)
1101 c->requests = GNUNET_CONTAINER_multihashmap_create (16);
1102 car = GNUNET_CONTAINER_multihashmap_get (c->requests,
1103 &req->peer.hashPubKey);
1104 if (car == NULL)
1105 {
1106 /* create new entry */
1107 car = GNUNET_malloc (sizeof (struct ClientActiveRequest));
1108 GNUNET_assert (GNUNET_OK ==
1109 GNUNET_CONTAINER_multihashmap_put (c->requests,
1110 &req->peer.hashPubKey,
1111 car,
1112 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST));
1113 GNUNET_CONTAINER_DLL_insert (n->active_client_request_head,
1114 n->active_client_request_tail,
1115 car);
1116 car->client = c;
1117 }
1118 car->deadline = GNUNET_TIME_absolute_ntoh (req->deadline);
1119 car->priority = ntohl (req->priority);
1120 car->queue_size = ntohl (req->queue_size);
1121 car->msize = ntohs (req->size);
1122 car->smr_id = req->smr_id;
1123 schedule_peer_messages (n);
1124 GNUNET_SERVER_receive_done (client, GNUNET_OK);
976} 1125}
977 1126
978 1127
@@ -1064,8 +1213,6 @@ handle_client_init (void *cls,
1064 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1213 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1065 "Sending `%s' message to client.\n", "NOTIFY_CONNECT"); 1214 "Sending `%s' message to client.\n", "NOTIFY_CONNECT");
1066#endif 1215#endif
1067 cnm.distance = htonl (n->last_distance);
1068 cnm.latency = GNUNET_TIME_relative_hton (n->last_latency);
1069 cnm.peer = n->peer; 1216 cnm.peer = n->peer;
1070 send_to_client (c, &cnm.header, GNUNET_NO); 1217 send_to_client (c, &cnm.header, GNUNET_NO);
1071 } 1218 }
@@ -1077,6 +1224,33 @@ handle_client_init (void *cls,
1077 1224
1078 1225
1079/** 1226/**
1227 * Free client request records.
1228 *
1229 * @param cls NULL
1230 * @param key identity of peer for which this is an active request
1231 * @param value the 'struct ClientActiveRequest' to free
1232 * @return GNUNET_YES (continue iteration)
1233 */
1234static int
1235destroy_active_client_request (void *cls,
1236 const GNUNET_HashCode *key,
1237 void *value)
1238{
1239 struct ClientActiveRequest *car = cls;
1240 struct Neighbour *n;
1241 struct GNUNET_PeerIdentity peer;
1242
1243 peer.hashPubKey = *key;
1244 n = find_neighbour (&peer);
1245 GNUNET_CONTAINER_DLL_remove (n->active_client_request_head,
1246 n->active_client_request_tail,
1247 car);
1248 GNUNET_free (car);
1249 return GNUNET_YES;
1250}
1251
1252
1253/**
1080 * A client disconnected, clean up. 1254 * A client disconnected, clean up.
1081 * 1255 *
1082 * @param cls closure 1256 * @param cls closure
@@ -1100,18 +1274,27 @@ handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
1100 while (pos != NULL) 1274 while (pos != NULL)
1101 { 1275 {
1102 if (client == pos->client_handle) 1276 if (client == pos->client_handle)
1103 { 1277 break;
1104 if (prev == NULL)
1105 clients = pos->next;
1106 else
1107 prev->next = pos->next;
1108 GNUNET_free (pos);
1109 return;
1110 }
1111 prev = pos; 1278 prev = pos;
1112 pos = pos->next; 1279 pos = pos->next;
1113 } 1280 }
1114 /* client never sent INIT */ 1281 if (pos == NULL)
1282 {
1283 /* client never sent INIT */
1284 return;
1285 }
1286 if (prev == NULL)
1287 clients = pos->next;
1288 else
1289 prev->next = pos->next;
1290 if (pos->requests != NULL)
1291 {
1292 GNUNET_CONTAINER_multihashmap_iterate (pos->requests,
1293 &destroy_active_client_request,
1294 NULL);
1295 GNUNET_CONTAINER_multihashmap_destroy (pos->requests);
1296 }
1297 GNUNET_free (pos);
1115} 1298}
1116 1299
1117 1300
@@ -1192,7 +1375,7 @@ handle_client_request_info (void *cls,
1192 (int) got_reserv); 1375 (int) got_reserv);
1193#endif 1376#endif
1194 cim.reserved_amount = htonl (got_reserv); 1377 cim.reserved_amount = htonl (got_reserv);
1195 cim.bw_in = n->bw_in; 1378 cim.rim_id = rcm->rim_id;
1196 cim.bw_out = n->bw_out; 1379 cim.bw_out = n->bw_out;
1197 cim.preference = n->current_preference; 1380 cim.preference = n->current_preference;
1198 } 1381 }
@@ -1221,6 +1404,7 @@ static void
1221free_neighbour (struct Neighbour *n) 1404free_neighbour (struct Neighbour *n)
1222{ 1405{
1223 struct MessageEntry *m; 1406 struct MessageEntry *m;
1407 struct ClientActiveRequest *car;
1224 1408
1225#if DEBUG_CORE 1409#if DEBUG_CORE
1226 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1410 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1249,6 +1433,16 @@ free_neighbour (struct Neighbour *n)
1249 m); 1433 m);
1250 GNUNET_free (m); 1434 GNUNET_free (m);
1251 } 1435 }
1436 while (NULL != (car = n->active_client_request_head))
1437 {
1438 GNUNET_CONTAINER_DLL_remove (n->active_client_request_head,
1439 n->active_client_request_tail,
1440 car);
1441 GNUNET_CONTAINER_multihashmap_remove (car->client->requests,
1442 &n->peer.hashPubKey,
1443 car);
1444 GNUNET_free (car);
1445 }
1252 if (NULL != n->th) 1446 if (NULL != n->th)
1253 { 1447 {
1254 GNUNET_TRANSPORT_notify_transmit_ready_cancel (n->th); 1448 GNUNET_TRANSPORT_notify_transmit_ready_cancel (n->th);
@@ -1894,8 +2088,6 @@ batch_message (struct Neighbour *n,
1894 return 0; 2088 return 0;
1895 } 2089 }
1896 ntm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_OUTBOUND); 2090 ntm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_OUTBOUND);
1897 ntm->distance = htonl (n->last_distance);
1898 ntm->latency = GNUNET_TIME_relative_hton (n->last_latency);
1899 ntm->peer = n->peer; 2091 ntm->peer = n->peer;
1900 pos = n->messages; 2092 pos = n->messages;
1901 prev = NULL; 2093 prev = NULL;
@@ -1985,7 +2177,9 @@ discard_expired_messages (struct Neighbour *n)
1985 struct MessageEntry *pos; 2177 struct MessageEntry *pos;
1986 struct GNUNET_TIME_Absolute now; 2178 struct GNUNET_TIME_Absolute now;
1987 struct GNUNET_TIME_Relative delta; 2179 struct GNUNET_TIME_Relative delta;
2180 int disc;
1988 2181
2182 disc = GNUNET_NO;
1989 now = GNUNET_TIME_absolute_get (); 2183 now = GNUNET_TIME_absolute_get ();
1990 prev = NULL; 2184 prev = NULL;
1991 pos = n->messages; 2185 pos = n->messages;
@@ -2004,12 +2198,19 @@ discard_expired_messages (struct Neighbour *n)
2004 n->messages = next; 2198 n->messages = next;
2005 else 2199 else
2006 prev->next = next; 2200 prev->next = next;
2201 GNUNET_STATISTICS_update (stats,
2202 gettext_noop ("# messages discarded (expired prior to transmission)"),
2203 1,
2204 GNUNET_NO);
2205 disc = GNUNET_YES;
2007 GNUNET_free (pos); 2206 GNUNET_free (pos);
2008 } 2207 }
2009 else 2208 else
2010 prev = pos; 2209 prev = pos;
2011 pos = next; 2210 pos = next;
2012 } 2211 }
2212 if (GNUNET_YES == disc)
2213 schedule_peer_messages (n);
2013} 2214}
2014 2215
2015 2216
@@ -2217,6 +2418,7 @@ process_plaintext_neighbour_queue (struct Neighbour *n)
2217 n->encrypted_tail, 2418 n->encrypted_tail,
2218 me); 2419 me);
2219 process_encrypted_neighbour_queue (n); 2420 process_encrypted_neighbour_queue (n);
2421 schedule_peer_messages (n);
2220} 2422}
2221 2423
2222 2424
@@ -2342,8 +2544,15 @@ handle_client_send (void *cls,
2342 (unsigned int) msize, 2544 (unsigned int) msize,
2343 GNUNET_i2s (&sm->peer)); 2545 GNUNET_i2s (&sm->peer));
2344#endif 2546#endif
2345 /* bound queue size */
2346 discard_expired_messages (n); 2547 discard_expired_messages (n);
2548 /* bound queue size */
2549 /* NOTE: this entire block to bound the queue size should be
2550 obsolete with the new client-request code and the
2551 'schedule_peer_messages' mechanism; we still have this code in
2552 here for now as a sanity check for the new mechanmism;
2553 ultimately, we should probably simply reject SEND messages that
2554 are not 'approved' (or provide a new core API for very unreliable
2555 delivery that always sends with priority 0). Food for thought. */
2347 min_prio = UINT32_MAX; 2556 min_prio = UINT32_MAX;
2348 min_prio_entry = NULL; 2557 min_prio_entry = NULL;
2349 min_prio_prev = NULL; 2558 min_prio_prev = NULL;
@@ -2367,7 +2576,8 @@ handle_client_send (void *cls,
2367 /* queue full */ 2576 /* queue full */
2368 if (ntohl(sm->priority) <= min_prio) 2577 if (ntohl(sm->priority) <= min_prio)
2369 { 2578 {
2370 /* discard new entry */ 2579 /* discard new entry; this should no longer happen! */
2580 GNUNET_break (0);
2371#if DEBUG_CORE 2581#if DEBUG_CORE
2372 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2582 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2373 "Queue full (%u/%u), discarding new request (%u bytes of type %u)\n", 2583 "Queue full (%u/%u), discarding new request (%u bytes of type %u)\n",
@@ -2376,7 +2586,9 @@ handle_client_send (void *cls,
2376 (unsigned int) msize, 2586 (unsigned int) msize,
2377 (unsigned int) ntohs (message->type)); 2587 (unsigned int) ntohs (message->type));
2378#endif 2588#endif
2379 GNUNET_STATISTICS_update (stats, gettext_noop ("# discarded CORE_SEND requests"), 1, GNUNET_NO); 2589 GNUNET_STATISTICS_update (stats,
2590 gettext_noop ("# discarded CORE_SEND requests"),
2591 1, GNUNET_NO);
2380 2592
2381 if (client != NULL) 2593 if (client != NULL)
2382 GNUNET_SERVER_receive_done (client, GNUNET_OK); 2594 GNUNET_SERVER_receive_done (client, GNUNET_OK);
@@ -3087,8 +3299,6 @@ handle_pong (struct Neighbour *n,
3087 } 3299 }
3088 cnm.header.size = htons (sizeof (struct ConnectNotifyMessage)); 3300 cnm.header.size = htons (sizeof (struct ConnectNotifyMessage));
3089 cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT); 3301 cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT);
3090 cnm.distance = htonl (n->last_distance);
3091 cnm.latency = GNUNET_TIME_relative_hton (n->last_latency);
3092 cnm.peer = n->peer; 3302 cnm.peer = n->peer;
3093 send_to_all_clients (&cnm.header, GNUNET_YES, GNUNET_CORE_OPTION_SEND_CONNECT); 3303 send_to_all_clients (&cnm.header, GNUNET_YES, GNUNET_CORE_OPTION_SEND_CONNECT);
3094 process_encrypted_neighbour_queue (n); 3304 process_encrypted_neighbour_queue (n);
@@ -3308,8 +3518,6 @@ send_p2p_message_to_client (struct Neighbour *sender,
3308 ntm = (struct NotifyTrafficMessage *) buf; 3518 ntm = (struct NotifyTrafficMessage *) buf;
3309 ntm->header.size = htons (msize + sizeof (struct NotifyTrafficMessage)); 3519 ntm->header.size = htons (msize + sizeof (struct NotifyTrafficMessage));
3310 ntm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND); 3520 ntm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND);
3311 ntm->distance = htonl (sender->last_distance);
3312 ntm->latency = GNUNET_TIME_relative_hton (sender->last_latency);
3313 ntm->peer = sender->peer; 3521 ntm->peer = sender->peer;
3314 memcpy (&ntm[1], m, msize); 3522 memcpy (&ntm[1], m, msize);
3315 send_to_client (client, &ntm->header, GNUNET_YES); 3523 send_to_client (client, &ntm->header, GNUNET_YES);
@@ -3602,9 +3810,7 @@ handle_transport_receive (void *cls,
3602 n = find_neighbour (peer); 3810 n = find_neighbour (peer);
3603 if (n == NULL) 3811 if (n == NULL)
3604 n = create_neighbour (peer); 3812 n = create_neighbour (peer);
3605 changed = (latency.rel_value != n->last_latency.rel_value) || (distance != n->last_distance); 3813 changed = GNUNET_YES; /* FIXME... */
3606 n->last_latency = latency;
3607 n->last_distance = distance;
3608 up = (n->status == PEER_STATE_KEY_CONFIRMED); 3814 up = (n->status == PEER_STATE_KEY_CONFIRMED);
3609 type = ntohs (message->type); 3815 type = ntohs (message->type);
3610 size = ntohs (message->size); 3816 size = ntohs (message->size);
@@ -3832,8 +4038,6 @@ handle_transport_notify_connect (void *cls,
3832 1, 4038 1,
3833 GNUNET_NO); 4039 GNUNET_NO);
3834 n->is_connected = GNUNET_YES; 4040 n->is_connected = GNUNET_YES;
3835 n->last_latency = latency;
3836 n->last_distance = distance;
3837 GNUNET_BANDWIDTH_tracker_init (&n->available_send_window, 4041 GNUNET_BANDWIDTH_tracker_init (&n->available_send_window,
3838 n->bw_out, 4042 n->bw_out,
3839 MAX_WINDOW_TIME_S); 4043 MAX_WINDOW_TIME_S);
@@ -3868,6 +4072,7 @@ handle_transport_notify_disconnect (void *cls,
3868{ 4072{
3869 struct DisconnectNotifyMessage cnm; 4073 struct DisconnectNotifyMessage cnm;
3870 struct Neighbour *n; 4074 struct Neighbour *n;
4075 struct ClientActiveRequest *car;
3871 struct GNUNET_TIME_Relative left; 4076 struct GNUNET_TIME_Relative left;
3872 4077
3873#if DEBUG_CORE 4078#if DEBUG_CORE
@@ -3890,6 +4095,17 @@ handle_transport_notify_disconnect (void *cls,
3890 send_to_all_clients (&cnm.header, GNUNET_YES, GNUNET_CORE_OPTION_SEND_DISCONNECT); 4095 send_to_all_clients (&cnm.header, GNUNET_YES, GNUNET_CORE_OPTION_SEND_DISCONNECT);
3891 } 4096 }
3892 n->is_connected = GNUNET_NO; 4097 n->is_connected = GNUNET_NO;
4098 while (NULL != (car = n->active_client_request_head))
4099 {
4100 GNUNET_CONTAINER_DLL_remove (n->active_client_request_head,
4101 n->active_client_request_tail,
4102 car);
4103 GNUNET_CONTAINER_multihashmap_remove (car->client->requests,
4104 &n->peer.hashPubKey,
4105 car);
4106 GNUNET_free (car);
4107 }
4108
3893 GNUNET_STATISTICS_update (stats, 4109 GNUNET_STATISTICS_update (stats,
3894 gettext_noop ("# peers connected (transport)"), 4110 gettext_noop ("# peers connected (transport)"),
3895 -1, 4111 -1,
@@ -3964,9 +4180,9 @@ run (void *cls,
3964 {&handle_client_request_info, NULL, 4180 {&handle_client_request_info, NULL,
3965 GNUNET_MESSAGE_TYPE_CORE_REQUEST_INFO, 4181 GNUNET_MESSAGE_TYPE_CORE_REQUEST_INFO,
3966 sizeof (struct RequestInfoMessage)}, 4182 sizeof (struct RequestInfoMessage)},
3967 {&handle_client_iterate_peers, NULL, 4183 {&handle_client_send_request, NULL,
3968 GNUNET_MESSAGE_TYPE_CORE_ITERATE_PEERS, 4184 GNUNET_MESSAGE_TYPE_CORE_SEND_REQUEST,
3969 sizeof (struct GNUNET_MessageHeader)}, 4185 sizeof (struct SendMessageRequest)},
3970 {&handle_client_send, NULL, 4186 {&handle_client_send, NULL,
3971 GNUNET_MESSAGE_TYPE_CORE_SEND, 0}, 4187 GNUNET_MESSAGE_TYPE_CORE_SEND, 0},
3972 {&handle_client_request_connect, NULL, 4188 {&handle_client_request_connect, NULL,