diff options
-rw-r--r-- | TODO | 9 | ||||
-rw-r--r-- | src/core/core_api.c | 16 | ||||
-rw-r--r-- | src/core/gnunet-service-core.c | 406 | ||||
-rw-r--r-- | src/core/test_core_api.c | 8 | ||||
-rw-r--r-- | src/core/test_core_api_reliability.c | 9 | ||||
-rw-r--r-- | src/core/test_core_quota_compliance.c | 9 |
6 files changed, 281 insertions, 176 deletions
@@ -1,14 +1,6 @@ | |||
1 | 0.9.0pre2: | 1 | 0.9.0pre2: |
2 | * BIG CORE REFACTORING: | ||
3 | - fix transport plugin API (ATS!) [mw] | ||
4 | - fix DV [nate] | ||
5 | * Integration test: | 2 | * Integration test: |
6 | - test bootstrapping via hostlist + transport/core/dht connect | 3 | - test bootstrapping via hostlist + transport/core/dht connect |
7 | * CORE: | ||
8 | - Jun 27 11:51:54 core-7670 ERROR Assertion failed at gnunet-service-core.c:3616. | ||
9 | (transport notified us that we connected to ourselves!!!; can we still reproduce this?) | ||
10 | => Also, we may want to issue a 'connect to ourselves' automatically on start of | ||
11 | core_api AND allow messages to self [CG/phillip] | ||
12 | 4 | ||
13 | 0.9.0pre3: | 5 | 0.9.0pre3: |
14 | * TRANSPORT: [MW] | 6 | * TRANSPORT: [MW] |
@@ -35,6 +27,7 @@ | |||
35 | + insert | 27 | + insert |
36 | + download | 28 | + download |
37 | + search | 29 | + search |
30 | - implement anonymity level > 1 | ||
38 | * GNUNET-GTK: [CG] | 31 | * GNUNET-GTK: [CG] |
39 | - figure out where in the GUI we should show active upload operations and allow aborts | 32 | - figure out where in the GUI we should show active upload operations and allow aborts |
40 | - handle events: | 33 | - handle events: |
diff --git a/src/core/core_api.c b/src/core/core_api.c index 21622852b..f73e1f290 100644 --- a/src/core/core_api.c +++ b/src/core/core_api.c | |||
@@ -881,6 +881,22 @@ main_notify_handler (void *cls, | |||
881 | "Successfully reconnected to core service.\n"); | 881 | "Successfully reconnected to core service.\n"); |
882 | #endif | 882 | #endif |
883 | } | 883 | } |
884 | /* fake 'connect to self' */ | ||
885 | pr = GNUNET_CONTAINER_multihashmap_get (h->peers, | ||
886 | &h->me.hashPubKey); | ||
887 | GNUNET_assert (pr == NULL); | ||
888 | pr = GNUNET_malloc (sizeof (struct PeerRecord)); | ||
889 | pr->peer = h->me; | ||
890 | pr->ch = h; | ||
891 | GNUNET_assert (GNUNET_YES == | ||
892 | GNUNET_CONTAINER_multihashmap_put (h->peers, | ||
893 | &h->me.hashPubKey, | ||
894 | pr, | ||
895 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)); | ||
896 | if (NULL != h->connects) | ||
897 | h->connects (h->cls, | ||
898 | &h->me, | ||
899 | NULL); | ||
884 | break; | 900 | break; |
885 | case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT: | 901 | case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT: |
886 | if (msize < sizeof (struct ConnectNotifyMessage)) | 902 | if (msize < sizeof (struct ConnectNotifyMessage)) |
diff --git a/src/core/gnunet-service-core.c b/src/core/gnunet-service-core.c index 76e26cc8f..8bac3e7e7 100644 --- a/src/core/gnunet-service-core.c +++ b/src/core/gnunet-service-core.c | |||
@@ -153,9 +153,25 @@ | |||
153 | */ | 153 | */ |
154 | enum PeerStateMachine | 154 | enum PeerStateMachine |
155 | { | 155 | { |
156 | /** | ||
157 | * No handshake yet. | ||
158 | */ | ||
156 | PEER_STATE_DOWN, | 159 | PEER_STATE_DOWN, |
160 | |||
161 | /** | ||
162 | * We've sent our session key. | ||
163 | */ | ||
157 | PEER_STATE_KEY_SENT, | 164 | PEER_STATE_KEY_SENT, |
165 | |||
166 | /** | ||
167 | * We've received the other peers session key. | ||
168 | */ | ||
158 | PEER_STATE_KEY_RECEIVED, | 169 | PEER_STATE_KEY_RECEIVED, |
170 | |||
171 | /** | ||
172 | * The other peer has confirmed our session key with a message | ||
173 | * encrypted with his session key (which we got). Session is now fully up. | ||
174 | */ | ||
159 | PEER_STATE_KEY_CONFIRMED | 175 | PEER_STATE_KEY_CONFIRMED |
160 | }; | 176 | }; |
161 | 177 | ||
@@ -402,10 +418,6 @@ struct ClientActiveRequest; | |||
402 | */ | 418 | */ |
403 | struct Neighbour | 419 | struct Neighbour |
404 | { | 420 | { |
405 | /** | ||
406 | * We keep neighbours in a linked list (for now). | ||
407 | */ | ||
408 | struct Neighbour *next; | ||
409 | 421 | ||
410 | /** | 422 | /** |
411 | * Unencrypted messages destined for this peer. | 423 | * Unencrypted messages destined for this peer. |
@@ -769,9 +781,14 @@ static struct Client *clients; | |||
769 | static struct GNUNET_SERVER_NotificationContext *notifier; | 781 | static struct GNUNET_SERVER_NotificationContext *notifier; |
770 | 782 | ||
771 | /** | 783 | /** |
772 | * We keep neighbours in a linked list (for now). | 784 | * Map of peer identities to 'struct Neighbour'. |
785 | */ | ||
786 | static struct GNUNET_CONTAINER_MultiHashMap *neighbours; | ||
787 | |||
788 | /** | ||
789 | * Neighbour entry for "this" peer. | ||
773 | */ | 790 | */ |
774 | static struct Neighbour *neighbours; | 791 | static struct Neighbour self; |
775 | 792 | ||
776 | /** | 793 | /** |
777 | * For creating statistics. | 794 | * For creating statistics. |
@@ -784,13 +801,7 @@ static struct GNUNET_STATISTICS_Handle *stats; | |||
784 | static unsigned long long preference_sum; | 801 | static unsigned long long preference_sum; |
785 | 802 | ||
786 | /** | 803 | /** |
787 | * Total number of neighbours we have. | ||
788 | */ | ||
789 | static unsigned int neighbour_count; | ||
790 | |||
791 | /** | ||
792 | * How much inbound bandwidth are we supposed to be using per second? | 804 | * How much inbound bandwidth are we supposed to be using per second? |
793 | * FIXME: this value is not used! | ||
794 | */ | 805 | */ |
795 | static unsigned long long bandwidth_target_in_bps; | 806 | static unsigned long long bandwidth_target_in_bps; |
796 | 807 | ||
@@ -885,6 +896,23 @@ get_neighbour_timeout (struct Neighbour *n) | |||
885 | 896 | ||
886 | 897 | ||
887 | /** | 898 | /** |
899 | * Helper function for update_preference_sum. | ||
900 | */ | ||
901 | static int | ||
902 | update_preference (void *cls, | ||
903 | const GNUNET_HashCode *key, | ||
904 | void *value) | ||
905 | { | ||
906 | unsigned long long *ps = cls; | ||
907 | struct Neighbour *n = value; | ||
908 | |||
909 | n->current_preference /= 2; | ||
910 | *ps += n->current_preference; | ||
911 | return GNUNET_OK; | ||
912 | } | ||
913 | |||
914 | |||
915 | /** | ||
888 | * A preference value for a neighbour was update. Update | 916 | * A preference value for a neighbour was update. Update |
889 | * the preference sum accordingly. | 917 | * the preference sum accordingly. |
890 | * | 918 | * |
@@ -893,7 +921,6 @@ get_neighbour_timeout (struct Neighbour *n) | |||
893 | static void | 921 | static void |
894 | update_preference_sum (unsigned long long inc) | 922 | update_preference_sum (unsigned long long inc) |
895 | { | 923 | { |
896 | struct Neighbour *n; | ||
897 | unsigned long long os; | 924 | unsigned long long os; |
898 | 925 | ||
899 | os = preference_sum; | 926 | os = preference_sum; |
@@ -902,13 +929,9 @@ update_preference_sum (unsigned long long inc) | |||
902 | return; /* done! */ | 929 | return; /* done! */ |
903 | /* overflow! compensate by cutting all values in half! */ | 930 | /* overflow! compensate by cutting all values in half! */ |
904 | preference_sum = 0; | 931 | preference_sum = 0; |
905 | n = neighbours; | 932 | GNUNET_CONTAINER_multihashmap_iterate (neighbours, |
906 | while (n != NULL) | 933 | &update_preference, |
907 | { | 934 | &preference_sum); |
908 | n->current_preference /= 2; | ||
909 | preference_sum += n->current_preference; | ||
910 | n = n->next; | ||
911 | } | ||
912 | GNUNET_STATISTICS_set (stats, gettext_noop ("# total peer preference"), preference_sum, GNUNET_NO); | 935 | GNUNET_STATISTICS_set (stats, gettext_noop ("# total peer preference"), preference_sum, GNUNET_NO); |
913 | } | 936 | } |
914 | 937 | ||
@@ -923,14 +946,7 @@ update_preference_sum (unsigned long long inc) | |||
923 | static struct Neighbour * | 946 | static struct Neighbour * |
924 | find_neighbour (const struct GNUNET_PeerIdentity *peer) | 947 | find_neighbour (const struct GNUNET_PeerIdentity *peer) |
925 | { | 948 | { |
926 | struct Neighbour *ret; | 949 | return GNUNET_CONTAINER_multihashmap_get (neighbours, &peer->hashPubKey); |
927 | |||
928 | ret = neighbours; | ||
929 | while ((ret != NULL) && | ||
930 | (0 != memcmp (&ret->peer, | ||
931 | peer, sizeof (struct GNUNET_PeerIdentity)))) | ||
932 | ret = ret->next; | ||
933 | return ret; | ||
934 | } | 950 | } |
935 | 951 | ||
936 | 952 | ||
@@ -1068,33 +1084,42 @@ schedule_peer_messages (struct Neighbour *n) | |||
1068 | unsigned int queue_size; | 1084 | unsigned int queue_size; |
1069 | 1085 | ||
1070 | /* check if neighbour queue is empty enough! */ | 1086 | /* check if neighbour queue is empty enough! */ |
1071 | queue_size = 0; | 1087 | if (n != &self) |
1072 | mqe = n->messages; | ||
1073 | while (mqe != NULL) | ||
1074 | { | ||
1075 | queue_size++; | ||
1076 | mqe = mqe->next; | ||
1077 | } | ||
1078 | if (queue_size >= MAX_PEER_QUEUE_SIZE) | ||
1079 | { | 1088 | { |
1089 | queue_size = 0; | ||
1090 | mqe = n->messages; | ||
1091 | while (mqe != NULL) | ||
1092 | { | ||
1093 | queue_size++; | ||
1094 | mqe = mqe->next; | ||
1095 | } | ||
1096 | if (queue_size >= MAX_PEER_QUEUE_SIZE) | ||
1097 | { | ||
1080 | #if DEBUG_CORE_CLIENT | 1098 | #if DEBUG_CORE_CLIENT |
1081 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1099 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1082 | "Not considering client transmission requests: queue full\n"); | 1100 | "Not considering client transmission requests: queue full\n"); |
1083 | #endif | 1101 | #endif |
1084 | return; /* queue still full */ | 1102 | return; /* queue still full */ |
1103 | } | ||
1104 | /* find highest priority request */ | ||
1105 | pos = n->active_client_request_head; | ||
1106 | car = NULL; | ||
1107 | while (pos != NULL) | ||
1108 | { | ||
1109 | if ( (car == NULL) || | ||
1110 | (pos->priority > car->priority) ) | ||
1111 | car = pos; | ||
1112 | pos = pos->next; | ||
1113 | } | ||
1114 | if (car == NULL) | ||
1115 | return; /* no pending requests */ | ||
1085 | } | 1116 | } |
1086 | /* find highest priority request */ | 1117 | else |
1087 | pos = n->active_client_request_head; | ||
1088 | car = NULL; | ||
1089 | while (pos != NULL) | ||
1090 | { | 1118 | { |
1091 | if ( (car == NULL) || | 1119 | car = n->active_client_request_head; |
1092 | (pos->priority > car->priority) ) | 1120 | if (car == NULL) |
1093 | car = pos; | 1121 | return; |
1094 | pos = pos->next; | ||
1095 | } | 1122 | } |
1096 | if (car == NULL) | ||
1097 | return; /* no pending requests */ | ||
1098 | #if DEBUG_CORE_CLIENT | 1123 | #if DEBUG_CORE_CLIENT |
1099 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1124 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1100 | "Permitting client transmission request to `%s'\n", | 1125 | "Permitting client transmission request to `%s'\n", |
@@ -1131,7 +1156,12 @@ handle_client_send_request (void *cls, | |||
1131 | struct ClientActiveRequest *car; | 1156 | struct ClientActiveRequest *car; |
1132 | 1157 | ||
1133 | req = (const struct SendMessageRequest*) message; | 1158 | req = (const struct SendMessageRequest*) message; |
1134 | n = find_neighbour (&req->peer); | 1159 | if (0 == memcmp (&req->peer, |
1160 | &my_identity, | ||
1161 | sizeof (struct GNUNET_PeerIdentity))) | ||
1162 | n = &self; | ||
1163 | else | ||
1164 | n = find_neighbour (&req->peer); | ||
1135 | if ( (n == NULL) || | 1165 | if ( (n == NULL) || |
1136 | (GNUNET_YES != n->is_connected) || | 1166 | (GNUNET_YES != n->is_connected) || |
1137 | (n->status != PEER_STATE_KEY_CONFIRMED) ) | 1167 | (n->status != PEER_STATE_KEY_CONFIRMED) ) |
@@ -1194,6 +1224,57 @@ handle_client_send_request (void *cls, | |||
1194 | 1224 | ||
1195 | 1225 | ||
1196 | /** | 1226 | /** |
1227 | * Notify client about an existing connection to one of our neighbours. | ||
1228 | */ | ||
1229 | static int | ||
1230 | notify_client_about_neighbour (void *cls, | ||
1231 | const GNUNET_HashCode *key, | ||
1232 | void *value) | ||
1233 | { | ||
1234 | struct Client *c = cls; | ||
1235 | struct Neighbour *n = value; | ||
1236 | size_t size; | ||
1237 | char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1]; | ||
1238 | struct GNUNET_TRANSPORT_ATS_Information *ats; | ||
1239 | struct ConnectNotifyMessage *cnm; | ||
1240 | |||
1241 | size = sizeof (struct ConnectNotifyMessage) + | ||
1242 | (n->ats_count) * sizeof (struct GNUNET_TRANSPORT_ATS_Information); | ||
1243 | if (size >= GNUNET_SERVER_MAX_MESSAGE_SIZE) | ||
1244 | { | ||
1245 | GNUNET_break (0); | ||
1246 | /* recovery strategy: throw away performance data */ | ||
1247 | GNUNET_array_grow (n->ats, | ||
1248 | n->ats_count, | ||
1249 | 0); | ||
1250 | size = sizeof (struct ConnectNotifyMessage) + | ||
1251 | (n->ats_count) * sizeof (struct GNUNET_TRANSPORT_ATS_Information); | ||
1252 | } | ||
1253 | cnm = (struct ConnectNotifyMessage*) buf; | ||
1254 | cnm->header.size = htons (size); | ||
1255 | cnm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT); | ||
1256 | cnm->ats_count = htonl (n->ats_count); | ||
1257 | ats = &cnm->ats; | ||
1258 | memcpy (ats, | ||
1259 | n->ats, | ||
1260 | sizeof (struct GNUNET_TRANSPORT_ATS_Information) * n->ats_count); | ||
1261 | ats[n->ats_count].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR); | ||
1262 | ats[n->ats_count].value = htonl (0); | ||
1263 | if (n->status == PEER_STATE_KEY_CONFIRMED) | ||
1264 | { | ||
1265 | #if DEBUG_CORE_CLIENT | ||
1266 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1267 | "Sending `%s' message to client.\n", "NOTIFY_CONNECT"); | ||
1268 | #endif | ||
1269 | cnm->peer = n->peer; | ||
1270 | send_to_client (c, &cnm->header, GNUNET_NO); | ||
1271 | } | ||
1272 | return GNUNET_OK; | ||
1273 | } | ||
1274 | |||
1275 | |||
1276 | |||
1277 | /** | ||
1197 | * Handle CORE_INIT request. | 1278 | * Handle CORE_INIT request. |
1198 | */ | 1279 | */ |
1199 | static void | 1280 | static void |
@@ -1207,11 +1288,6 @@ handle_client_init (void *cls, | |||
1207 | uint16_t msize; | 1288 | uint16_t msize; |
1208 | const uint16_t *types; | 1289 | const uint16_t *types; |
1209 | uint16_t *wtypes; | 1290 | uint16_t *wtypes; |
1210 | struct Neighbour *n; | ||
1211 | struct ConnectNotifyMessage *cnm; | ||
1212 | char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1]; | ||
1213 | struct GNUNET_TRANSPORT_ATS_Information *ats; | ||
1214 | size_t size; | ||
1215 | unsigned int i; | 1291 | unsigned int i; |
1216 | 1292 | ||
1217 | #if DEBUG_CORE_CLIENT | 1293 | #if DEBUG_CORE_CLIENT |
@@ -1273,42 +1349,9 @@ handle_client_init (void *cls, | |||
1273 | if (0 != (c->options & GNUNET_CORE_OPTION_SEND_CONNECT)) | 1349 | if (0 != (c->options & GNUNET_CORE_OPTION_SEND_CONNECT)) |
1274 | { | 1350 | { |
1275 | /* notify new client about existing neighbours */ | 1351 | /* notify new client about existing neighbours */ |
1276 | n = neighbours; | 1352 | GNUNET_CONTAINER_multihashmap_iterate (neighbours, |
1277 | while (n != NULL) | 1353 | ¬ify_client_about_neighbour, |
1278 | { | 1354 | c); |
1279 | size = sizeof (struct ConnectNotifyMessage) + | ||
1280 | (n->ats_count) * sizeof (struct GNUNET_TRANSPORT_ATS_Information); | ||
1281 | if (size >= GNUNET_SERVER_MAX_MESSAGE_SIZE) | ||
1282 | { | ||
1283 | GNUNET_break (0); | ||
1284 | /* recovery strategy: throw away performance data */ | ||
1285 | GNUNET_array_grow (n->ats, | ||
1286 | n->ats_count, | ||
1287 | 0); | ||
1288 | size = sizeof (struct ConnectNotifyMessage) + | ||
1289 | (n->ats_count) * sizeof (struct GNUNET_TRANSPORT_ATS_Information); | ||
1290 | } | ||
1291 | cnm = (struct ConnectNotifyMessage*) buf; | ||
1292 | cnm->header.size = htons (size); | ||
1293 | cnm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT); | ||
1294 | cnm->ats_count = htonl (n->ats_count); | ||
1295 | ats = &cnm->ats; | ||
1296 | memcpy (ats, | ||
1297 | n->ats, | ||
1298 | sizeof (struct GNUNET_TRANSPORT_ATS_Information) * n->ats_count); | ||
1299 | ats[n->ats_count].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR); | ||
1300 | ats[n->ats_count].value = htonl (0); | ||
1301 | if (n->status == PEER_STATE_KEY_CONFIRMED) | ||
1302 | { | ||
1303 | #if DEBUG_CORE_CLIENT | ||
1304 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1305 | "Sending `%s' message to client.\n", "NOTIFY_CONNECT"); | ||
1306 | #endif | ||
1307 | cnm->peer = n->peer; | ||
1308 | send_to_client (c, &cnm->header, GNUNET_NO); | ||
1309 | } | ||
1310 | n = n->next; | ||
1311 | } | ||
1312 | } | 1355 | } |
1313 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 1356 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
1314 | } | 1357 | } |
@@ -1390,6 +1433,58 @@ handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client) | |||
1390 | 1433 | ||
1391 | 1434 | ||
1392 | /** | 1435 | /** |
1436 | * Helper function for handle_client_iterate_peers. | ||
1437 | */ | ||
1438 | static int | ||
1439 | queue_connect_message (void *cls, | ||
1440 | const GNUNET_HashCode *key, | ||
1441 | void *value) | ||
1442 | { | ||
1443 | struct GNUNET_SERVER_TransmitContext *tc = cls; | ||
1444 | struct Neighbour *n = value; | ||
1445 | char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1]; | ||
1446 | struct GNUNET_TRANSPORT_ATS_Information *ats; | ||
1447 | size_t size; | ||
1448 | struct ConnectNotifyMessage *cnm; | ||
1449 | |||
1450 | cnm = (struct ConnectNotifyMessage*) buf; | ||
1451 | if (n->status != PEER_STATE_KEY_CONFIRMED) | ||
1452 | return GNUNET_OK; | ||
1453 | size = sizeof (struct ConnectNotifyMessage) + | ||
1454 | (n->ats_count) * sizeof (struct GNUNET_TRANSPORT_ATS_Information); | ||
1455 | if (size >= GNUNET_SERVER_MAX_MESSAGE_SIZE) | ||
1456 | { | ||
1457 | GNUNET_break (0); | ||
1458 | /* recovery strategy: throw away performance data */ | ||
1459 | GNUNET_array_grow (n->ats, | ||
1460 | n->ats_count, | ||
1461 | 0); | ||
1462 | size = sizeof (struct PeerStatusNotifyMessage) + | ||
1463 | n->ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information); | ||
1464 | } | ||
1465 | cnm = (struct ConnectNotifyMessage*) buf; | ||
1466 | cnm->header.size = htons (size); | ||
1467 | cnm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT); | ||
1468 | cnm->ats_count = htonl (n->ats_count); | ||
1469 | ats = &cnm->ats; | ||
1470 | memcpy (ats, | ||
1471 | n->ats, | ||
1472 | n->ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information)); | ||
1473 | ats[n->ats_count].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR); | ||
1474 | ats[n->ats_count].value = htonl (0); | ||
1475 | #if DEBUG_CORE_CLIENT | ||
1476 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1477 | "Sending `%s' message to client.\n", | ||
1478 | "NOTIFY_CONNECT"); | ||
1479 | #endif | ||
1480 | cnm->peer = n->peer; | ||
1481 | GNUNET_SERVER_transmit_context_append_message (tc, | ||
1482 | &cnm->header); | ||
1483 | return GNUNET_OK; | ||
1484 | } | ||
1485 | |||
1486 | |||
1487 | /** | ||
1393 | * Handle CORE_ITERATE_PEERS request. | 1488 | * Handle CORE_ITERATE_PEERS request. |
1394 | * | 1489 | * |
1395 | * @param cls unused | 1490 | * @param cls unused |
@@ -1402,55 +1497,12 @@ handle_client_iterate_peers (void *cls, | |||
1402 | const struct GNUNET_MessageHeader *message) | 1497 | const struct GNUNET_MessageHeader *message) |
1403 | 1498 | ||
1404 | { | 1499 | { |
1405 | struct Neighbour *n; | ||
1406 | struct ConnectNotifyMessage *cnm; | ||
1407 | struct GNUNET_MessageHeader done_msg; | 1500 | struct GNUNET_MessageHeader done_msg; |
1408 | struct GNUNET_SERVER_TransmitContext *tc; | 1501 | struct GNUNET_SERVER_TransmitContext *tc; |
1409 | char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1]; | ||
1410 | struct GNUNET_TRANSPORT_ATS_Information *ats; | ||
1411 | size_t size; | ||
1412 | 1502 | ||
1413 | /* notify new client about existing neighbours */ | 1503 | /* notify new client about existing neighbours */ |
1414 | tc = GNUNET_SERVER_transmit_context_create (client); | 1504 | tc = GNUNET_SERVER_transmit_context_create (client); |
1415 | cnm = (struct ConnectNotifyMessage*) buf; | 1505 | GNUNET_CONTAINER_multihashmap_iterate (neighbours, &queue_connect_message, tc); |
1416 | n = neighbours; | ||
1417 | while (n != NULL) | ||
1418 | { | ||
1419 | if (n->status == PEER_STATE_KEY_CONFIRMED) | ||
1420 | { | ||
1421 | size = sizeof (struct ConnectNotifyMessage) + | ||
1422 | (n->ats_count) * sizeof (struct GNUNET_TRANSPORT_ATS_Information); | ||
1423 | if (size >= GNUNET_SERVER_MAX_MESSAGE_SIZE) | ||
1424 | { | ||
1425 | GNUNET_break (0); | ||
1426 | /* recovery strategy: throw away performance data */ | ||
1427 | GNUNET_array_grow (n->ats, | ||
1428 | n->ats_count, | ||
1429 | 0); | ||
1430 | size = sizeof (struct PeerStatusNotifyMessage) + | ||
1431 | n->ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information); | ||
1432 | } | ||
1433 | cnm = (struct ConnectNotifyMessage*) buf; | ||
1434 | cnm->header.size = htons (size); | ||
1435 | cnm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT); | ||
1436 | cnm->ats_count = htonl (n->ats_count); | ||
1437 | ats = &cnm->ats; | ||
1438 | memcpy (ats, | ||
1439 | n->ats, | ||
1440 | n->ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information)); | ||
1441 | ats[n->ats_count].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR); | ||
1442 | ats[n->ats_count].value = htonl (0); | ||
1443 | #if DEBUG_CORE_CLIENT | ||
1444 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1445 | "Sending `%s' message to client.\n", | ||
1446 | "NOTIFY_CONNECT"); | ||
1447 | #endif | ||
1448 | cnm->peer = n->peer; | ||
1449 | GNUNET_SERVER_transmit_context_append_message (tc, | ||
1450 | &cnm->header); | ||
1451 | } | ||
1452 | n = n->next; | ||
1453 | } | ||
1454 | done_msg.size = htons (sizeof (struct GNUNET_MessageHeader)); | 1506 | done_msg.size = htons (sizeof (struct GNUNET_MessageHeader)); |
1455 | done_msg.type = htons (GNUNET_MESSAGE_TYPE_CORE_ITERATE_PEERS_END); | 1507 | done_msg.type = htons (GNUNET_MESSAGE_TYPE_CORE_ITERATE_PEERS_END); |
1456 | GNUNET_SERVER_transmit_context_append_message (tc, &done_msg); | 1508 | GNUNET_SERVER_transmit_context_append_message (tc, &done_msg); |
@@ -1792,8 +1844,6 @@ consider_free_task (void *cls, | |||
1792 | static void | 1844 | static void |
1793 | consider_free_neighbour (struct Neighbour *n) | 1845 | consider_free_neighbour (struct Neighbour *n) |
1794 | { | 1846 | { |
1795 | struct Neighbour *pos; | ||
1796 | struct Neighbour *prev; | ||
1797 | struct GNUNET_TIME_Relative left; | 1847 | struct GNUNET_TIME_Relative left; |
1798 | 1848 | ||
1799 | if ( (n->th != NULL) || | 1849 | if ( (n->th != NULL) || |
@@ -1812,22 +1862,13 @@ consider_free_neighbour (struct Neighbour *n) | |||
1812 | return; | 1862 | return; |
1813 | } | 1863 | } |
1814 | /* actually free the neighbour... */ | 1864 | /* actually free the neighbour... */ |
1815 | prev = NULL; | 1865 | GNUNET_assert (GNUNET_OK == |
1816 | pos = neighbours; | 1866 | GNUNET_CONTAINER_multihashmap_remove (neighbours, |
1817 | while (pos != n) | 1867 | &n->peer.hashPubKey, |
1818 | { | 1868 | n)); |
1819 | prev = pos; | ||
1820 | pos = pos->next; | ||
1821 | } | ||
1822 | if (prev == NULL) | ||
1823 | neighbours = n->next; | ||
1824 | else | ||
1825 | prev->next = n->next; | ||
1826 | GNUNET_assert (neighbour_count > 0); | ||
1827 | neighbour_count--; | ||
1828 | GNUNET_STATISTICS_set (stats, | 1869 | GNUNET_STATISTICS_set (stats, |
1829 | gettext_noop ("# neighbour entries allocated"), | 1870 | gettext_noop ("# neighbour entries allocated"), |
1830 | neighbour_count, | 1871 | GNUNET_CONTAINER_multihashmap_size (neighbours), |
1831 | GNUNET_NO); | 1872 | GNUNET_NO); |
1832 | free_neighbour (n); | 1873 | free_neighbour (n); |
1833 | } | 1874 | } |
@@ -2643,10 +2684,6 @@ create_neighbour (const struct GNUNET_PeerIdentity *pid) | |||
2643 | GNUNET_i2s (pid)); | 2684 | GNUNET_i2s (pid)); |
2644 | #endif | 2685 | #endif |
2645 | n = GNUNET_malloc (sizeof (struct Neighbour)); | 2686 | n = GNUNET_malloc (sizeof (struct Neighbour)); |
2646 | n->next = neighbours; | ||
2647 | neighbours = n; | ||
2648 | neighbour_count++; | ||
2649 | GNUNET_STATISTICS_set (stats, gettext_noop ("# neighbour entries allocated"), neighbour_count, GNUNET_NO); | ||
2650 | n->peer = *pid; | 2687 | n->peer = *pid; |
2651 | GNUNET_CRYPTO_aes_create_session_key (&n->encrypt_key); | 2688 | GNUNET_CRYPTO_aes_create_session_key (&n->encrypt_key); |
2652 | now = GNUNET_TIME_absolute_get (); | 2689 | now = GNUNET_TIME_absolute_get (); |
@@ -2659,6 +2696,13 @@ create_neighbour (const struct GNUNET_PeerIdentity *pid) | |||
2659 | n->bw_out_external_limit = GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT; | 2696 | n->bw_out_external_limit = GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT; |
2660 | n->ping_challenge = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, | 2697 | n->ping_challenge = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, |
2661 | UINT32_MAX); | 2698 | UINT32_MAX); |
2699 | GNUNET_assert (GNUNET_OK == | ||
2700 | GNUNET_CONTAINER_multihashmap_put (neighbours, | ||
2701 | &n->peer.hashPubKey, | ||
2702 | n, | ||
2703 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | ||
2704 | GNUNET_STATISTICS_set (stats, gettext_noop ("# neighbour entries allocated"), | ||
2705 | GNUNET_CONTAINER_multihashmap_size (neighbours), GNUNET_NO); | ||
2662 | neighbour_quota_update (n, NULL); | 2706 | neighbour_quota_update (n, NULL); |
2663 | consider_free_neighbour (n); | 2707 | consider_free_neighbour (n); |
2664 | return n; | 2708 | return n; |
@@ -2702,10 +2746,15 @@ handle_client_send (void *cls, | |||
2702 | msize -= sizeof (struct SendMessage); | 2746 | msize -= sizeof (struct SendMessage); |
2703 | if (0 == memcmp (&sm->peer, &my_identity, sizeof (struct GNUNET_PeerIdentity))) | 2747 | if (0 == memcmp (&sm->peer, &my_identity, sizeof (struct GNUNET_PeerIdentity))) |
2704 | { | 2748 | { |
2705 | /* FIXME: should we not allow loopback-injection here? */ | 2749 | /* loopback */ |
2706 | GNUNET_break (0); | 2750 | GNUNET_SERVER_mst_receive (mst, |
2751 | &self, | ||
2752 | (const char*) &sm[1], | ||
2753 | msize, | ||
2754 | GNUNET_YES, | ||
2755 | GNUNET_NO); | ||
2707 | if (client != NULL) | 2756 | if (client != NULL) |
2708 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 2757 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
2709 | return; | 2758 | return; |
2710 | } | 2759 | } |
2711 | n = find_neighbour (&sm->peer); | 2760 | n = find_neighbour (&sm->peer); |
@@ -4225,6 +4274,7 @@ neighbour_quota_update (void *cls, | |||
4225 | unsigned long long distributable; | 4274 | unsigned long long distributable; |
4226 | uint64_t need_per_peer; | 4275 | uint64_t need_per_peer; |
4227 | uint64_t need_per_second; | 4276 | uint64_t need_per_second; |
4277 | unsigned int neighbour_count; | ||
4228 | 4278 | ||
4229 | #if DEBUG_CORE | 4279 | #if DEBUG_CORE |
4230 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 4280 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -4236,6 +4286,9 @@ neighbour_quota_update (void *cls, | |||
4236 | divides by a bit more to avoid division by zero AND to | 4286 | divides by a bit more to avoid division by zero AND to |
4237 | account for possibility of new neighbours joining any time | 4287 | account for possibility of new neighbours joining any time |
4238 | AND to convert to double... */ | 4288 | AND to convert to double... */ |
4289 | neighbour_count = GNUNET_CONTAINER_multihashmap_size (neighbours); | ||
4290 | if (neighbour_count == 0) | ||
4291 | return; | ||
4239 | if (preference_sum == 0) | 4292 | if (preference_sum == 0) |
4240 | { | 4293 | { |
4241 | pref_rel = 1.0 / (double) neighbour_count; | 4294 | pref_rel = 1.0 / (double) neighbour_count; |
@@ -4448,30 +4501,42 @@ handle_transport_notify_disconnect (void *cls, | |||
4448 | 4501 | ||
4449 | 4502 | ||
4450 | /** | 4503 | /** |
4504 | * Wrapper around 'free_neighbour'; helper for 'cleaning_task'. | ||
4505 | */ | ||
4506 | static int | ||
4507 | free_neighbour_helper (void *cls, | ||
4508 | const GNUNET_HashCode *key, | ||
4509 | void *value) | ||
4510 | { | ||
4511 | struct Neighbour *n = value; | ||
4512 | |||
4513 | free_neighbour (n); | ||
4514 | return GNUNET_OK; | ||
4515 | } | ||
4516 | |||
4517 | |||
4518 | /** | ||
4451 | * Last task run during shutdown. Disconnects us from | 4519 | * Last task run during shutdown. Disconnects us from |
4452 | * the transport. | 4520 | * the transport. |
4453 | */ | 4521 | */ |
4454 | static void | 4522 | static void |
4455 | cleaning_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 4523 | cleaning_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
4456 | { | 4524 | { |
4457 | struct Neighbour *n; | ||
4458 | struct Client *c; | 4525 | struct Client *c; |
4459 | 4526 | ||
4460 | #if DEBUG_CORE | 4527 | #if DEBUG_CORE |
4461 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 4528 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
4462 | "Core service shutting down.\n"); | 4529 | "Core service shutting down.\n"); |
4463 | #endif | 4530 | #endif |
4464 | while (NULL != (n = neighbours)) | 4531 | GNUNET_CONTAINER_multihashmap_iterate (neighbours, |
4465 | { | 4532 | &free_neighbour_helper, |
4466 | neighbours = n->next; | 4533 | NULL); |
4467 | GNUNET_assert (neighbour_count > 0); | 4534 | GNUNET_CONTAINER_multihashmap_destroy (neighbours); |
4468 | neighbour_count--; | 4535 | neighbours = NULL; |
4469 | free_neighbour (n); | 4536 | GNUNET_STATISTICS_set (stats, gettext_noop ("# neighbour entries allocated"), 0, GNUNET_NO); |
4470 | } | ||
4471 | GNUNET_assert (transport != NULL); | 4537 | GNUNET_assert (transport != NULL); |
4472 | GNUNET_TRANSPORT_disconnect (transport); | 4538 | GNUNET_TRANSPORT_disconnect (transport); |
4473 | transport = NULL; | 4539 | transport = NULL; |
4474 | GNUNET_STATISTICS_set (stats, gettext_noop ("# neighbour entries allocated"), neighbour_count, GNUNET_NO); | ||
4475 | GNUNET_SERVER_notification_context_destroy (notifier); | 4540 | GNUNET_SERVER_notification_context_destroy (notifier); |
4476 | notifier = NULL; | 4541 | notifier = NULL; |
4477 | while (NULL != (c = clients)) | 4542 | while (NULL != (c = clients)) |
@@ -4520,7 +4585,7 @@ run (void *cls, | |||
4520 | }; | 4585 | }; |
4521 | char *keyfile; | 4586 | char *keyfile; |
4522 | 4587 | ||
4523 | cfg = c; | 4588 | cfg = c; |
4524 | /* parse configuration */ | 4589 | /* parse configuration */ |
4525 | if ( | 4590 | if ( |
4526 | (GNUNET_OK != | 4591 | (GNUNET_OK != |
@@ -4563,9 +4628,14 @@ run (void *cls, | |||
4563 | GNUNET_SCHEDULER_shutdown (); | 4628 | GNUNET_SCHEDULER_shutdown (); |
4564 | return; | 4629 | return; |
4565 | } | 4630 | } |
4631 | neighbours = GNUNET_CONTAINER_multihashmap_create (128); | ||
4566 | GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &my_public_key); | 4632 | GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &my_public_key); |
4567 | GNUNET_CRYPTO_hash (&my_public_key, | 4633 | GNUNET_CRYPTO_hash (&my_public_key, |
4568 | sizeof (my_public_key), &my_identity.hashPubKey); | 4634 | sizeof (my_public_key), &my_identity.hashPubKey); |
4635 | self.public_key = &my_public_key; | ||
4636 | self.last_activity = GNUNET_TIME_UNIT_FOREVER_ABS; | ||
4637 | self.status = PEER_STATE_KEY_CONFIRMED; | ||
4638 | self.is_connected = GNUNET_YES; | ||
4569 | /* setup notification */ | 4639 | /* setup notification */ |
4570 | notifier = GNUNET_SERVER_notification_context_create (server, | 4640 | notifier = GNUNET_SERVER_notification_context_create (server, |
4571 | MAX_NOTIFY_QUEUE); | 4641 | MAX_NOTIFY_QUEUE); |
diff --git a/src/core/test_core_api.c b/src/core/test_core_api.c index 814ebe889..cec66f020 100644 --- a/src/core/test_core_api.c +++ b/src/core/test_core_api.c | |||
@@ -123,6 +123,10 @@ connect_notify (void *cls, | |||
123 | { | 123 | { |
124 | struct PeerContext *pc = cls; | 124 | struct PeerContext *pc = cls; |
125 | 125 | ||
126 | if (0 == memcmp (&pc->id, | ||
127 | peer, | ||
128 | sizeof (struct GNUNET_PeerIdentity))) | ||
129 | return; | ||
126 | GNUNET_assert (pc->connect_status == 0); | 130 | GNUNET_assert (pc->connect_status == 0); |
127 | pc->connect_status = 1; | 131 | pc->connect_status = 1; |
128 | if (pc == &p1) | 132 | if (pc == &p1) |
@@ -154,6 +158,10 @@ disconnect_notify (void *cls, | |||
154 | { | 158 | { |
155 | struct PeerContext *pc = cls; | 159 | struct PeerContext *pc = cls; |
156 | 160 | ||
161 | if (0 == memcmp (&pc->id, | ||
162 | peer, | ||
163 | sizeof (struct GNUNET_PeerIdentity))) | ||
164 | return; | ||
157 | pc->connect_status = 0; | 165 | pc->connect_status = 0; |
158 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 166 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
159 | "Encrypted connection to `%4s' cut\n", GNUNET_i2s (peer)); | 167 | "Encrypted connection to `%4s' cut\n", GNUNET_i2s (peer)); |
diff --git a/src/core/test_core_api_reliability.c b/src/core/test_core_api_reliability.c index 9192c9592..7eab92b12 100644 --- a/src/core/test_core_api_reliability.c +++ b/src/core/test_core_api_reliability.c | |||
@@ -221,6 +221,10 @@ connect_notify (void *cls, | |||
221 | { | 221 | { |
222 | struct PeerContext *pc = cls; | 222 | struct PeerContext *pc = cls; |
223 | 223 | ||
224 | if (0 == memcmp (&pc->id, | ||
225 | peer, | ||
226 | sizeof (struct GNUNET_PeerIdentity))) | ||
227 | return; | ||
224 | GNUNET_assert (pc->connect_status == 0); | 228 | GNUNET_assert (pc->connect_status == 0); |
225 | pc->connect_status = 1; | 229 | pc->connect_status = 1; |
226 | if (pc == &p1) | 230 | if (pc == &p1) |
@@ -252,6 +256,11 @@ disconnect_notify (void *cls, | |||
252 | const struct GNUNET_PeerIdentity *peer) | 256 | const struct GNUNET_PeerIdentity *peer) |
253 | { | 257 | { |
254 | struct PeerContext *pc = cls; | 258 | struct PeerContext *pc = cls; |
259 | |||
260 | if (0 == memcmp (&pc->id, | ||
261 | peer, | ||
262 | sizeof (struct GNUNET_PeerIdentity))) | ||
263 | return; | ||
255 | pc->connect_status = 0; | 264 | pc->connect_status = 0; |
256 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 265 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
257 | "Encrypted connection to `%4s' cut\n", GNUNET_i2s (peer)); | 266 | "Encrypted connection to `%4s' cut\n", GNUNET_i2s (peer)); |
diff --git a/src/core/test_core_quota_compliance.c b/src/core/test_core_quota_compliance.c index 7181564d8..d951113fc 100644 --- a/src/core/test_core_quota_compliance.c +++ b/src/core/test_core_quota_compliance.c | |||
@@ -370,6 +370,10 @@ connect_notify (void *cls, | |||
370 | { | 370 | { |
371 | struct PeerContext *pc = cls; | 371 | struct PeerContext *pc = cls; |
372 | 372 | ||
373 | if (0 == memcmp (&pc->id, | ||
374 | peer, | ||
375 | sizeof (struct GNUNET_PeerIdentity))) | ||
376 | return; | ||
373 | GNUNET_assert (pc->connect_status == 0); | 377 | GNUNET_assert (pc->connect_status == 0); |
374 | pc->connect_status = 1; | 378 | pc->connect_status = 1; |
375 | if (pc == &p1) | 379 | if (pc == &p1) |
@@ -405,6 +409,11 @@ disconnect_notify (void *cls, | |||
405 | const struct GNUNET_PeerIdentity *peer) | 409 | const struct GNUNET_PeerIdentity *peer) |
406 | { | 410 | { |
407 | struct PeerContext *pc = cls; | 411 | struct PeerContext *pc = cls; |
412 | |||
413 | if (0 == memcmp (&pc->id, | ||
414 | peer, | ||
415 | sizeof (struct GNUNET_PeerIdentity))) | ||
416 | return; | ||
408 | pc->connect_status = 0; | 417 | pc->connect_status = 0; |
409 | #if DEBUG_TRANSMISSION | 418 | #if DEBUG_TRANSMISSION |
410 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 419 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |