aboutsummaryrefslogtreecommitdiff
path: root/src/dht/gnunet-service-dht.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dht/gnunet-service-dht.c')
-rw-r--r--src/dht/gnunet-service-dht.c3691
1 files changed, 1871 insertions, 1820 deletions
diff --git a/src/dht/gnunet-service-dht.c b/src/dht/gnunet-service-dht.c
index 83cb84c9c..19250d07b 100644
--- a/src/dht/gnunet-service-dht.c
+++ b/src/dht/gnunet-service-dht.c
@@ -967,20 +967,21 @@ get_average_send_delay ()
967 unsigned int i; 967 unsigned int i;
968 unsigned int divisor; 968 unsigned int divisor;
969 struct GNUNET_TIME_Relative average_time; 969 struct GNUNET_TIME_Relative average_time;
970
970 average_time = GNUNET_TIME_relative_get_zero (); 971 average_time = GNUNET_TIME_relative_get_zero ();
971 divisor = 0; 972 divisor = 0;
972 for (i = 0; i < MAX_REPLY_TIMES; i++) 973 for (i = 0; i < MAX_REPLY_TIMES; i++)
973 { 974 {
974 average_time = GNUNET_TIME_relative_add (average_time, reply_times[i]); 975 average_time = GNUNET_TIME_relative_add (average_time, reply_times[i]);
975 if (reply_times[i].abs_value == (uint64_t) 0) 976 if (reply_times[i].abs_value == (uint64_t) 0)
976 continue; 977 continue;
977 else 978 else
978 divisor++; 979 divisor++;
979 } 980 }
980 if (divisor == 0) 981 if (divisor == 0)
981 { 982 {
982 return average_time; 983 return average_time;
983 } 984 }
984 985
985 average_time = GNUNET_TIME_relative_divide (average_time, divisor); 986 average_time = GNUNET_TIME_relative_divide (average_time, divisor);
986 fprintf (stderr, 987 fprintf (stderr,
@@ -999,14 +1000,15 @@ static void
999decrease_max_send_delay (struct GNUNET_TIME_Relative max_time) 1000decrease_max_send_delay (struct GNUNET_TIME_Relative max_time)
1000{ 1001{
1001 unsigned int i; 1002 unsigned int i;
1003
1002 for (i = 0; i < MAX_REPLY_TIMES; i++) 1004 for (i = 0; i < MAX_REPLY_TIMES; i++)
1005 {
1006 if (reply_times[i].rel_value == max_time.rel_value)
1003 { 1007 {
1004 if (reply_times[i].rel_value == max_time.rel_value) 1008 reply_times[i].rel_value = reply_times[i].rel_value / 2;
1005 { 1009 return;
1006 reply_times[i].rel_value = reply_times[i].rel_value / 2;
1007 return;
1008 }
1009 } 1010 }
1011 }
1010} 1012}
1011 1013
1012/** 1014/**
@@ -1020,13 +1022,14 @@ get_max_send_delay ()
1020{ 1022{
1021 unsigned int i; 1023 unsigned int i;
1022 struct GNUNET_TIME_Relative max_time; 1024 struct GNUNET_TIME_Relative max_time;
1025
1023 max_time = GNUNET_TIME_relative_get_zero (); 1026 max_time = GNUNET_TIME_relative_get_zero ();
1024 1027
1025 for (i = 0; i < MAX_REPLY_TIMES; i++) 1028 for (i = 0; i < MAX_REPLY_TIMES; i++)
1026 { 1029 {
1027 if (reply_times[i].rel_value > max_time.rel_value) 1030 if (reply_times[i].rel_value > max_time.rel_value)
1028 max_time.rel_value = reply_times[i].rel_value; 1031 max_time.rel_value = reply_times[i].rel_value;
1029 } 1032 }
1030#if DEBUG_DHT 1033#if DEBUG_DHT
1031 if (max_time.rel_value > MAX_REQUEST_TIME.rel_value) 1034 if (max_time.rel_value > MAX_REQUEST_TIME.rel_value)
1032 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Max send delay was %llu\n", 1035 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Max send delay was %llu\n",
@@ -1039,18 +1042,18 @@ static void
1039increment_stats (const char *value) 1042increment_stats (const char *value)
1040{ 1043{
1041 if (stats != NULL) 1044 if (stats != NULL)
1042 { 1045 {
1043 GNUNET_STATISTICS_update (stats, value, 1, GNUNET_NO); 1046 GNUNET_STATISTICS_update (stats, value, 1, GNUNET_NO);
1044 } 1047 }
1045} 1048}
1046 1049
1047static void 1050static void
1048decrement_stats (const char *value) 1051decrement_stats (const char *value)
1049{ 1052{
1050 if (stats != NULL) 1053 if (stats != NULL)
1051 { 1054 {
1052 GNUNET_STATISTICS_update (stats, value, -1, GNUNET_NO); 1055 GNUNET_STATISTICS_update (stats, value, -1, GNUNET_NO);
1053 } 1056 }
1054} 1057}
1055 1058
1056/** 1059/**
@@ -1065,7 +1068,7 @@ try_core_send (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1065 1068
1066 peer->send_task = GNUNET_SCHEDULER_NO_TASK; 1069 peer->send_task = GNUNET_SCHEDULER_NO_TASK;
1067 1070
1068 if ( (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) 1071 if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
1069 return; 1072 return;
1070 1073
1071 if (peer->th != NULL) 1074 if (peer->th != NULL)
@@ -1073,26 +1076,26 @@ try_core_send (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1073 1076
1074 pending = peer->head; 1077 pending = peer->head;
1075 if (pending != NULL) 1078 if (pending != NULL)
1076 { 1079 {
1077 ssize = ntohs (pending->msg->size); 1080 ssize = ntohs (pending->msg->size);
1078#if DEBUG_DHT > 1 1081#if DEBUG_DHT > 1
1079 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1082 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1080 "`%s:%s': Calling notify_transmit_ready with size %d for peer %s\n", 1083 "`%s:%s': Calling notify_transmit_ready with size %d for peer %s\n",
1081 my_short_id, "DHT", ssize, GNUNET_i2s (&peer->id)); 1084 my_short_id, "DHT", ssize, GNUNET_i2s (&peer->id));
1082#endif 1085#endif
1083 pending->scheduled = GNUNET_TIME_absolute_get (); 1086 pending->scheduled = GNUNET_TIME_absolute_get ();
1084 reply_counter++; 1087 reply_counter++;
1085 if (reply_counter >= MAX_REPLY_TIMES) 1088 if (reply_counter >= MAX_REPLY_TIMES)
1086 reply_counter = 0; 1089 reply_counter = 0;
1087 peer->th = 1090 peer->th =
1088 GNUNET_CORE_notify_transmit_ready (coreAPI, 1091 GNUNET_CORE_notify_transmit_ready (coreAPI,
1089 GNUNET_YES, 1092 GNUNET_YES,
1090 pending->importance, 1093 pending->importance,
1091 pending->timeout, &peer->id, ssize, 1094 pending->timeout, &peer->id, ssize,
1092 &core_transmit_notify, peer); 1095 &core_transmit_notify, peer);
1093 if (peer->th == NULL) 1096 if (peer->th == NULL)
1094 increment_stats ("# notify transmit ready failed"); 1097 increment_stats ("# notify transmit ready failed");
1095 } 1098 }
1096} 1099}
1097 1100
1098/** 1101/**
@@ -1115,13 +1118,15 @@ forward_result_message (const struct GNUNET_MessageHeader *msg,
1115 size_t psize; 1118 size_t psize;
1116 char *path_start; 1119 char *path_start;
1117 char *path_offset; 1120 char *path_offset;
1121
1118#if DEBUG_PATH 1122#if DEBUG_PATH
1119 unsigned int i; 1123 unsigned int i;
1120#endif 1124#endif
1121 1125
1122 increment_stats (STAT_RESULT_FORWARDS); 1126 increment_stats (STAT_RESULT_FORWARDS);
1123 msize = 1127 msize =
1124 sizeof (struct GNUNET_DHT_P2PRouteResultMessage) + ntohs (msg->size) + (sizeof(struct GNUNET_PeerIdentity) * msg_ctx->path_history_len); 1128 sizeof (struct GNUNET_DHT_P2PRouteResultMessage) + ntohs (msg->size) +
1129 (sizeof (struct GNUNET_PeerIdentity) * msg_ctx->path_history_len);
1125 GNUNET_assert (msize <= GNUNET_SERVER_MAX_MESSAGE_SIZE); 1130 GNUNET_assert (msize <= GNUNET_SERVER_MAX_MESSAGE_SIZE);
1126 psize = sizeof (struct P2PPendingMessage) + msize; 1131 psize = sizeof (struct P2PPendingMessage) + msize;
1127 pending = GNUNET_malloc (psize); 1132 pending = GNUNET_malloc (psize);
@@ -1131,23 +1136,28 @@ forward_result_message (const struct GNUNET_MessageHeader *msg,
1131 result_message = (struct GNUNET_DHT_P2PRouteResultMessage *) pending->msg; 1136 result_message = (struct GNUNET_DHT_P2PRouteResultMessage *) pending->msg;
1132 result_message->header.size = htons (msize); 1137 result_message->header.size = htons (msize);
1133 result_message->header.type = 1138 result_message->header.type =
1134 htons (GNUNET_MESSAGE_TYPE_DHT_P2P_ROUTE_RESULT); 1139 htons (GNUNET_MESSAGE_TYPE_DHT_P2P_ROUTE_RESULT);
1135 result_message->outgoing_path_length = htonl (msg_ctx->path_history_len); 1140 result_message->outgoing_path_length = htonl (msg_ctx->path_history_len);
1136 if (msg_ctx->path_history_len > 0) 1141 if (msg_ctx->path_history_len > 0)
1137 { 1142 {
1138 /* End of pending is where enc_msg starts */ 1143 /* End of pending is where enc_msg starts */
1139 path_start = (char *)&pending[1]; 1144 path_start = (char *) &pending[1];
1140 /* Offset by the size of the enc_msg */ 1145 /* Offset by the size of the enc_msg */
1141 path_start += ntohs (msg->size); 1146 path_start += ntohs (msg->size);
1142 memcpy(path_start, msg_ctx->path_history, msg_ctx->path_history_len * (sizeof(struct GNUNET_PeerIdentity))); 1147 memcpy (path_start, msg_ctx->path_history,
1148 msg_ctx->path_history_len * (sizeof (struct GNUNET_PeerIdentity)));
1143#if DEBUG_PATH 1149#if DEBUG_PATH
1144 for (i = 0; i < msg_ctx->path_history_len; i++) 1150 for (i = 0; i < msg_ctx->path_history_len; i++)
1145 { 1151 {
1146 path_offset = &msg_ctx->path_history[i * sizeof(struct GNUNET_PeerIdentity)]; 1152 path_offset =
1147 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "(forward_result) Key %s Found peer %d:%s\n", GNUNET_h2s(&msg_ctx->key), i, GNUNET_i2s((struct GNUNET_PeerIdentity *)path_offset)); 1153 &msg_ctx->path_history[i * sizeof (struct GNUNET_PeerIdentity)];
1148 } 1154 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1149#endif 1155 "(forward_result) Key %s Found peer %d:%s\n",
1156 GNUNET_h2s (&msg_ctx->key), i,
1157 GNUNET_i2s ((struct GNUNET_PeerIdentity *) path_offset));
1150 } 1158 }
1159#endif
1160 }
1151 result_message->options = htonl (msg_ctx->msg_options); 1161 result_message->options = htonl (msg_ctx->msg_options);
1152 result_message->hop_count = htonl (msg_ctx->hop_count + 1); 1162 result_message->hop_count = htonl (msg_ctx->hop_count + 1);
1153 GNUNET_assert (GNUNET_OK == 1163 GNUNET_assert (GNUNET_OK ==
@@ -1159,11 +1169,12 @@ forward_result_message (const struct GNUNET_MessageHeader *msg,
1159 memcpy (&result_message->key, &msg_ctx->key, sizeof (GNUNET_HashCode)); 1169 memcpy (&result_message->key, &msg_ctx->key, sizeof (GNUNET_HashCode));
1160 /* Copy the enc_msg, then the path history as well! */ 1170 /* Copy the enc_msg, then the path history as well! */
1161 memcpy (&result_message[1], msg, ntohs (msg->size)); 1171 memcpy (&result_message[1], msg, ntohs (msg->size));
1162 path_offset = (char *)&result_message[1]; 1172 path_offset = (char *) &result_message[1];
1163 path_offset += ntohs (msg->size); 1173 path_offset += ntohs (msg->size);
1164 /* If we have path history, copy it to the end of the whole thing */ 1174 /* If we have path history, copy it to the end of the whole thing */
1165 if (msg_ctx->path_history_len > 0) 1175 if (msg_ctx->path_history_len > 0)
1166 memcpy(path_offset, msg_ctx->path_history, msg_ctx->path_history_len * (sizeof(struct GNUNET_PeerIdentity))); 1176 memcpy (path_offset, msg_ctx->path_history,
1177 msg_ctx->path_history_len * (sizeof (struct GNUNET_PeerIdentity)));
1167#if DEBUG_DHT > 1 1178#if DEBUG_DHT > 1
1168 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1179 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1169 "%s:%s Adding pending message size %d for peer %s\n", 1180 "%s:%s Adding pending message size %d for peer %s\n",
@@ -1196,16 +1207,17 @@ core_transmit_notify (void *cls, size_t size, void *buf)
1196 1207
1197 size_t off; 1208 size_t off;
1198 size_t msize; 1209 size_t msize;
1210
1199 peer->th = NULL; 1211 peer->th = NULL;
1200 if (buf == NULL) 1212 if (buf == NULL)
1201 { 1213 {
1202 /* client disconnected */ 1214 /* client disconnected */
1203#if DEBUG_DHT 1215#if DEBUG_DHT
1204 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "`%s:%s': buffer was NULL\n", 1216 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "`%s:%s': buffer was NULL\n",
1205 my_short_id, "DHT"); 1217 my_short_id, "DHT");
1206#endif 1218#endif
1207 return 0; 1219 return 0;
1208 } 1220 }
1209 1221
1210 if (peer->head == NULL) 1222 if (peer->head == NULL)
1211 return 0; 1223 return 0;
@@ -1214,31 +1226,31 @@ core_transmit_notify (void *cls, size_t size, void *buf)
1214 pending = peer->head; 1226 pending = peer->head;
1215#if DUMB 1227#if DUMB
1216 reply_times[reply_counter] = 1228 reply_times[reply_counter] =
1217 GNUNET_TIME_absolute_get_difference (pending->scheduled, 1229 GNUNET_TIME_absolute_get_difference (pending->scheduled,
1218 GNUNET_TIME_absolute_get ()); 1230 GNUNET_TIME_absolute_get ());
1219 msize = ntohs (pending->msg->size); 1231 msize = ntohs (pending->msg->size);
1220 if (msize <= size) 1232 if (msize <= size)
1221 { 1233 {
1222 off = msize; 1234 off = msize;
1223 memcpy (cbuf, pending->msg, msize); 1235 memcpy (cbuf, pending->msg, msize);
1224 peer->pending_count--; 1236 peer->pending_count--;
1225 increment_stats ("# pending messages sent"); 1237 increment_stats ("# pending messages sent");
1226 GNUNET_assert (peer->pending_count >= 0); 1238 GNUNET_assert (peer->pending_count >= 0);
1227 GNUNET_CONTAINER_DLL_remove (peer->head, peer->tail, pending); 1239 GNUNET_CONTAINER_DLL_remove (peer->head, peer->tail, pending);
1228 GNUNET_free (pending); 1240 GNUNET_free (pending);
1229 } 1241 }
1230#else 1242#else
1231 while (NULL != pending && 1243 while (NULL != pending &&
1232 (size - off >= (msize = ntohs (pending->msg->size)))) 1244 (size - off >= (msize = ntohs (pending->msg->size))))
1233 { 1245 {
1234 memcpy (&cbuf[off], pending->msg, msize); 1246 memcpy (&cbuf[off], pending->msg, msize);
1235 off += msize; 1247 off += msize;
1236 peer->pending_count--; 1248 peer->pending_count--;
1237 increment_stats ("# pending messages sent"); 1249 increment_stats ("# pending messages sent");
1238 GNUNET_CONTAINER_DLL_remove (peer->head, peer->tail, pending); 1250 GNUNET_CONTAINER_DLL_remove (peer->head, peer->tail, pending);
1239 GNUNET_free (pending); 1251 GNUNET_free (pending);
1240 pending = peer->head; 1252 pending = peer->head;
1241 } 1253 }
1242#endif 1254#endif
1243 if ((peer->head != NULL) && (peer->send_task == GNUNET_SCHEDULER_NO_TASK)) 1255 if ((peer->head != NULL) && (peer->send_task == GNUNET_SCHEDULER_NO_TASK))
1244 peer->send_task = GNUNET_SCHEDULER_add_now (&try_core_send, peer); 1256 peer->send_task = GNUNET_SCHEDULER_add_now (&try_core_send, peer);
@@ -1265,43 +1277,43 @@ distance (const GNUNET_HashCode * target, const GNUNET_HashCode * have)
1265 unsigned int i; 1277 unsigned int i;
1266 1278
1267 /* We have to represent the distance between two 2^9 (=512)-bit 1279 /* We have to represent the distance between two 2^9 (=512)-bit
1268 numbers as a 2^5 (=32)-bit number with "0" being used for the 1280 * numbers as a 2^5 (=32)-bit number with "0" being used for the
1269 two numbers being identical; furthermore, we need to 1281 * two numbers being identical; furthermore, we need to
1270 guarantee that a difference in the number of matching 1282 * guarantee that a difference in the number of matching
1271 bits is always represented in the result. 1283 * bits is always represented in the result.
1272 1284 *
1273 We use 2^32/2^9 numerical values to distinguish between 1285 * We use 2^32/2^9 numerical values to distinguish between
1274 hash codes that have the same LSB bit distance and 1286 * hash codes that have the same LSB bit distance and
1275 use the highest 2^9 bits of the result to signify the 1287 * use the highest 2^9 bits of the result to signify the
1276 number of (mis)matching LSB bits; if we have 0 matching 1288 * number of (mis)matching LSB bits; if we have 0 matching
1277 and hence 512 mismatching LSB bits we return -1 (since 1289 * and hence 512 mismatching LSB bits we return -1 (since
1278 512 itself cannot be represented with 9 bits) */ 1290 * 512 itself cannot be represented with 9 bits) */
1279 1291
1280 /* first, calculate the most significant 9 bits of our 1292 /* first, calculate the most significant 9 bits of our
1281 result, aka the number of LSBs */ 1293 * result, aka the number of LSBs */
1282 bucket = GNUNET_CRYPTO_hash_matching_bits (target, have); 1294 bucket = GNUNET_CRYPTO_hash_matching_bits (target, have);
1283 /* bucket is now a value between 0 and 512 */ 1295 /* bucket is now a value between 0 and 512 */
1284 if (bucket == 512) 1296 if (bucket == 512)
1285 return 0; /* perfect match */ 1297 return 0; /* perfect match */
1286 if (bucket == 0) 1298 if (bucket == 0)
1287 return (unsigned int) -1; /* LSB differs; use max (if we did the bit-shifting 1299 return (unsigned int) -1; /* LSB differs; use max (if we did the bit-shifting
1288 below, we'd end up with max+1 (overflow)) */ 1300 * below, we'd end up with max+1 (overflow)) */
1289 1301
1290 /* calculate the most significant bits of the final result */ 1302 /* calculate the most significant bits of the final result */
1291 msb = (512 - bucket) << (32 - 9); 1303 msb = (512 - bucket) << (32 - 9);
1292 /* calculate the 32-9 least significant bits of the final result by 1304 /* calculate the 32-9 least significant bits of the final result by
1293 looking at the differences in the 32-9 bits following the 1305 * looking at the differences in the 32-9 bits following the
1294 mismatching bit at 'bucket' */ 1306 * mismatching bit at 'bucket' */
1295 lsb = 0; 1307 lsb = 0;
1296 for (i = bucket + 1; 1308 for (i = bucket + 1;
1297 (i < sizeof (GNUNET_HashCode) * 8) && (i < bucket + 1 + 32 - 9); i++) 1309 (i < sizeof (GNUNET_HashCode) * 8) && (i < bucket + 1 + 32 - 9); i++)
1298 { 1310 {
1299 if (GNUNET_CRYPTO_hash_get_bit (target, i) != 1311 if (GNUNET_CRYPTO_hash_get_bit (target, i) !=
1300 GNUNET_CRYPTO_hash_get_bit (have, i)) 1312 GNUNET_CRYPTO_hash_get_bit (have, i))
1301 lsb |= (1 << (bucket + 32 - 9 - i)); /* first bit set will be 10, 1313 lsb |= (1 << (bucket + 32 - 9 - i)); /* first bit set will be 10,
1302 last bit set will be 31 -- if 1314 * last bit set will be 31 -- if
1303 i does not reach 512 first... */ 1315 * i does not reach 512 first... */
1304 } 1316 }
1305 return msb | lsb; 1317 return msb | lsb;
1306} 1318}
1307 1319
@@ -1313,8 +1325,7 @@ distance (const GNUNET_HashCode * target, const GNUNET_HashCode * have)
1313 * Must fudge the value if NO bits match. 1325 * Must fudge the value if NO bits match.
1314 */ 1326 */
1315static unsigned int 1327static unsigned int
1316inverse_distance (const GNUNET_HashCode * target, 1328inverse_distance (const GNUNET_HashCode * target, const GNUNET_HashCode * have)
1317 const GNUNET_HashCode * have)
1318{ 1329{
1319 if (GNUNET_CRYPTO_hash_matching_bits (target, have) == 0) 1330 if (GNUNET_CRYPTO_hash_matching_bits (target, have) == 0)
1320 return 1; /* Never return 0! */ 1331 return 1; /* Never return 0! */
@@ -1359,11 +1370,11 @@ static int
1359find_current_bucket (const GNUNET_HashCode * hc) 1370find_current_bucket (const GNUNET_HashCode * hc)
1360{ 1371{
1361 int actual_bucket; 1372 int actual_bucket;
1362 1373
1363 actual_bucket = find_bucket (hc); 1374 actual_bucket = find_bucket (hc);
1364 if (actual_bucket == GNUNET_SYSERR) /* hc and our peer identity match! */ 1375 if (actual_bucket == GNUNET_SYSERR) /* hc and our peer identity match! */
1365 return lowest_bucket; 1376 return lowest_bucket;
1366 if (actual_bucket < lowest_bucket) /* actual_bucket not yet used */ 1377 if (actual_bucket < lowest_bucket) /* actual_bucket not yet used */
1367 return lowest_bucket; 1378 return lowest_bucket;
1368 return actual_bucket; 1379 return actual_bucket;
1369} 1380}
@@ -1383,15 +1394,15 @@ find_bucket_by_peer (const struct PeerInfo *peer)
1383 struct PeerInfo *pos; 1394 struct PeerInfo *pos;
1384 1395
1385 for (bucket = lowest_bucket; bucket < MAX_BUCKETS - 1; bucket++) 1396 for (bucket = lowest_bucket; bucket < MAX_BUCKETS - 1; bucket++)
1397 {
1398 pos = k_buckets[bucket].head;
1399 while (pos != NULL)
1386 { 1400 {
1387 pos = k_buckets[bucket].head; 1401 if (peer == pos)
1388 while (pos != NULL) 1402 return bucket;
1389 { 1403 pos = pos->next;
1390 if (peer == pos)
1391 return bucket;
1392 pos = pos->next;
1393 }
1394 } 1404 }
1405 }
1395 1406
1396 return GNUNET_SYSERR; /* No such peer. */ 1407 return GNUNET_SYSERR; /* No such peer. */
1397} 1408}
@@ -1408,30 +1419,30 @@ print_routing_table ()
1408 struct PeerInfo *pos; 1419 struct PeerInfo *pos;
1409 char char_buf[30000]; 1420 char char_buf[30000];
1410 int char_pos; 1421 int char_pos;
1422
1411 memset (char_buf, 0, sizeof (char_buf)); 1423 memset (char_buf, 0, sizeof (char_buf));
1412 char_pos = 0; 1424 char_pos = 0;
1413 char_pos += 1425 char_pos +=
1414 sprintf (&char_buf[char_pos], "Printing routing table for peer %s\n", 1426 sprintf (&char_buf[char_pos], "Printing routing table for peer %s\n",
1415 my_short_id); 1427 my_short_id);
1416 //fprintf(stderr, "Printing routing table for peer %s\n", my_short_id); 1428 //fprintf(stderr, "Printing routing table for peer %s\n", my_short_id);
1417 for (bucket = lowest_bucket; bucket < MAX_BUCKETS; bucket++) 1429 for (bucket = lowest_bucket; bucket < MAX_BUCKETS; bucket++)
1418 { 1430 {
1419 pos = k_buckets[bucket].head; 1431 pos = k_buckets[bucket].head;
1420 char_pos += sprintf (&char_buf[char_pos], "Bucket %d:\n", bucket); 1432 char_pos += sprintf (&char_buf[char_pos], "Bucket %d:\n", bucket);
1421 //fprintf(stderr, "Bucket %d:\n", bucket); 1433 //fprintf(stderr, "Bucket %d:\n", bucket);
1422 while (pos != NULL) 1434 while (pos != NULL)
1423 { 1435 {
1424 //fprintf(stderr, "\tPeer %s, best bucket %d, %d bits match\n", GNUNET_i2s(&pos->id), find_bucket(&pos->id.hashPubKey), GNUNET_CRYPTO_hash_matching_bits(&pos->id.hashPubKey, &my_identity.hashPubKey)); 1436 //fprintf(stderr, "\tPeer %s, best bucket %d, %d bits match\n", GNUNET_i2s(&pos->id), find_bucket(&pos->id.hashPubKey), GNUNET_CRYPTO_hash_matching_bits(&pos->id.hashPubKey, &my_identity.hashPubKey));
1425 char_pos += 1437 char_pos +=
1426 sprintf (&char_buf[char_pos], 1438 sprintf (&char_buf[char_pos],
1427 "\tPeer %s, best bucket %d, %d bits match\n", 1439 "\tPeer %s, best bucket %d, %d bits match\n",
1428 GNUNET_i2s (&pos->id), find_bucket (&pos->id.hashPubKey), 1440 GNUNET_i2s (&pos->id), find_bucket (&pos->id.hashPubKey),
1429 GNUNET_CRYPTO_hash_matching_bits (&pos->id.hashPubKey, 1441 GNUNET_CRYPTO_hash_matching_bits (&pos->id.hashPubKey,
1430 &my_identity. 1442 &my_identity.hashPubKey));
1431 hashPubKey)); 1443 pos = pos->next;
1432 pos = pos->next;
1433 }
1434 } 1444 }
1445 }
1435 fprintf (stderr, "%s", char_buf); 1446 fprintf (stderr, "%s", char_buf);
1436 fflush (stderr); 1447 fflush (stderr);
1437} 1448}
@@ -1449,6 +1460,7 @@ find_peer_by_id (const struct GNUNET_PeerIdentity *peer)
1449{ 1460{
1450 int bucket; 1461 int bucket;
1451 struct PeerInfo *pos; 1462 struct PeerInfo *pos;
1463
1452 bucket = find_current_bucket (&peer->hashPubKey); 1464 bucket = find_current_bucket (&peer->hashPubKey);
1453 1465
1454 if (0 == memcmp (&my_identity, peer, sizeof (struct GNUNET_PeerIdentity))) 1466 if (0 == memcmp (&my_identity, peer, sizeof (struct GNUNET_PeerIdentity)))
@@ -1456,11 +1468,11 @@ find_peer_by_id (const struct GNUNET_PeerIdentity *peer)
1456 1468
1457 pos = k_buckets[bucket].head; 1469 pos = k_buckets[bucket].head;
1458 while (pos != NULL) 1470 while (pos != NULL)
1459 { 1471 {
1460 if (0 == memcmp (&pos->id, peer, sizeof (struct GNUNET_PeerIdentity))) 1472 if (0 == memcmp (&pos->id, peer, sizeof (struct GNUNET_PeerIdentity)))
1461 return pos; 1473 return pos;
1462 pos = pos->next; 1474 pos = pos->next;
1463 } 1475 }
1464 return NULL; /* No such peer. */ 1476 return NULL; /* No such peer. */
1465} 1477}
1466 1478
@@ -1484,9 +1496,9 @@ static void
1484update_core_preference_finish (void *cls, 1496update_core_preference_finish (void *cls,
1485 const struct GNUNET_PeerIdentity *peer, 1497 const struct GNUNET_PeerIdentity *peer,
1486 struct GNUNET_BANDWIDTH_Value32NBO bpm_out, 1498 struct GNUNET_BANDWIDTH_Value32NBO bpm_out,
1487 int32_t amount, 1499 int32_t amount,
1488 struct GNUNET_TIME_Relative res_delay, 1500 struct GNUNET_TIME_Relative res_delay,
1489 uint64_t preference) 1501 uint64_t preference)
1490{ 1502{
1491 struct PeerInfo *peer_info = cls; 1503 struct PeerInfo *peer_info = cls;
1492 1504
@@ -1502,28 +1514,29 @@ update_core_preference (void *cls,
1502 struct PeerInfo *peer = cls; 1514 struct PeerInfo *peer = cls;
1503 uint64_t preference; 1515 uint64_t preference;
1504 unsigned int matching; 1516 unsigned int matching;
1505 if ( (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) 1517
1506 { 1518 if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
1507 return; 1519 {
1508 } 1520 return;
1521 }
1509 matching = 1522 matching =
1510 GNUNET_CRYPTO_hash_matching_bits (&my_identity.hashPubKey, 1523 GNUNET_CRYPTO_hash_matching_bits (&my_identity.hashPubKey,
1511 &peer->id.hashPubKey); 1524 &peer->id.hashPubKey);
1512 if (matching >= 64) 1525 if (matching >= 64)
1513 { 1526 {
1514#if DEBUG_DHT 1527#if DEBUG_DHT
1515 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1528 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1516 "Peer identifier matches by %u bits, only shifting as much as we can!\n", 1529 "Peer identifier matches by %u bits, only shifting as much as we can!\n",
1517 matching); 1530 matching);
1518#endif 1531#endif
1519 matching = 63; 1532 matching = 63;
1520 } 1533 }
1521 preference = 1LL << matching; 1534 preference = 1LL << matching;
1522 peer->info_ctx = GNUNET_CORE_peer_change_preference (coreAPI, 1535 peer->info_ctx = GNUNET_CORE_peer_change_preference (coreAPI,
1523 &peer->id, 1536 &peer->id,
1524 GNUNET_TIME_UNIT_FOREVER_REL, 1537 GNUNET_TIME_UNIT_FOREVER_REL,
1525 GNUNET_BANDWIDTH_VALUE_MAX, 1538 GNUNET_BANDWIDTH_VALUE_MAX,
1526 0, 1539 0,
1527 preference, 1540 preference,
1528 &update_core_preference_finish, 1541 &update_core_preference_finish,
1529 peer); 1542 peer);
@@ -1566,6 +1579,7 @@ delete_peer (struct PeerInfo *peer, unsigned int bucket)
1566{ 1579{
1567 struct P2PPendingMessage *pos; 1580 struct P2PPendingMessage *pos;
1568 struct P2PPendingMessage *next; 1581 struct P2PPendingMessage *next;
1582
1569#if EXTRA_CHECKS 1583#if EXTRA_CHECKS
1570 struct PeerInfo *peer_pos; 1584 struct PeerInfo *peer_pos;
1571 1585
@@ -1573,16 +1587,16 @@ delete_peer (struct PeerInfo *peer, unsigned int bucket)
1573 while ((peer_pos != NULL) && (peer_pos != peer)) 1587 while ((peer_pos != NULL) && (peer_pos != peer))
1574 peer_pos = peer_pos->next; 1588 peer_pos = peer_pos->next;
1575 if (peer_pos == NULL) 1589 if (peer_pos == NULL)
1576 { 1590 {
1577 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1591 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1578 "%s:%s: Expected peer `%s' in bucket %d\n", my_short_id, 1592 "%s:%s: Expected peer `%s' in bucket %d\n", my_short_id,
1579 "DHT", GNUNET_i2s (&peer->id), bucket); 1593 "DHT", GNUNET_i2s (&peer->id), bucket);
1580 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1594 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1581 "%s:%s: Lowest bucket: %d, find_current_bucket: %d, peer resides in bucket: %d\n", 1595 "%s:%s: Lowest bucket: %d, find_current_bucket: %d, peer resides in bucket: %d\n",
1582 my_short_id, "DHT", lowest_bucket, 1596 my_short_id, "DHT", lowest_bucket,
1583 find_current_bucket (&peer->id.hashPubKey), 1597 find_current_bucket (&peer->id.hashPubKey),
1584 find_bucket_by_peer (peer)); 1598 find_bucket_by_peer (peer));
1585 } 1599 }
1586 GNUNET_assert (peer_pos != NULL); 1600 GNUNET_assert (peer_pos != NULL);
1587#endif 1601#endif
1588 remove_peer (peer, bucket); /* First remove the peer from its bucket */ 1602 remove_peer (peer, bucket); /* First remove the peer from its bucket */
@@ -1594,13 +1608,13 @@ delete_peer (struct PeerInfo *peer, unsigned int bucket)
1594 1608
1595 pos = peer->head; 1609 pos = peer->head;
1596 while (pos != NULL) /* Remove any pending messages for this peer */ 1610 while (pos != NULL) /* Remove any pending messages for this peer */
1597 { 1611 {
1598 increment_stats 1612 increment_stats
1599 ("# dht pending messages discarded (due to disconnect/shutdown)"); 1613 ("# dht pending messages discarded (due to disconnect/shutdown)");
1600 next = pos->next; 1614 next = pos->next;
1601 GNUNET_free (pos); 1615 GNUNET_free (pos);
1602 pos = next; 1616 pos = next;
1603 } 1617 }
1604 1618
1605 GNUNET_assert (GNUNET_CONTAINER_multihashmap_contains 1619 GNUNET_assert (GNUNET_CONTAINER_multihashmap_contains
1606 (all_known_peers, &peer->id.hashPubKey)); 1620 (all_known_peers, &peer->id.hashPubKey));
@@ -1609,7 +1623,7 @@ delete_peer (struct PeerInfo *peer, unsigned int bucket)
1609 &peer->id.hashPubKey, 1623 &peer->id.hashPubKey,
1610 peer)); 1624 peer));
1611 GNUNET_free (peer); 1625 GNUNET_free (peer);
1612 decrement_stats(STAT_PEERS_KNOWN); 1626 decrement_stats (STAT_PEERS_KNOWN);
1613} 1627}
1614 1628
1615 1629
@@ -1650,6 +1664,7 @@ enable_next_bucket ()
1650{ 1664{
1651 struct GNUNET_CONTAINER_MultiHashMap *to_remove; 1665 struct GNUNET_CONTAINER_MultiHashMap *to_remove;
1652 struct PeerInfo *pos; 1666 struct PeerInfo *pos;
1667
1653 GNUNET_assert (lowest_bucket > 0); 1668 GNUNET_assert (lowest_bucket > 0);
1654 to_remove = GNUNET_CONTAINER_multihashmap_create (bucket_size); 1669 to_remove = GNUNET_CONTAINER_multihashmap_create (bucket_size);
1655 pos = k_buckets[lowest_bucket].head; 1670 pos = k_buckets[lowest_bucket].head;
@@ -1660,17 +1675,16 @@ enable_next_bucket ()
1660#endif 1675#endif
1661 /* Populate the array of peers which should be in the next lowest bucket */ 1676 /* Populate the array of peers which should be in the next lowest bucket */
1662 while (pos != NULL) 1677 while (pos != NULL)
1663 { 1678 {
1664 if (find_bucket (&pos->id.hashPubKey) < lowest_bucket) 1679 if (find_bucket (&pos->id.hashPubKey) < lowest_bucket)
1665 GNUNET_CONTAINER_multihashmap_put (to_remove, &pos->id.hashPubKey, 1680 GNUNET_CONTAINER_multihashmap_put (to_remove, &pos->id.hashPubKey,
1666 pos, 1681 pos,
1667 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); 1682 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
1668 pos = pos->next; 1683 pos = pos->next;
1669 } 1684 }
1670 1685
1671 /* Remove peers from lowest bucket, insert into next lowest bucket */ 1686 /* Remove peers from lowest bucket, insert into next lowest bucket */
1672 GNUNET_CONTAINER_multihashmap_iterate (to_remove, &move_lowest_bucket, 1687 GNUNET_CONTAINER_multihashmap_iterate (to_remove, &move_lowest_bucket, NULL);
1673 NULL);
1674 GNUNET_CONTAINER_multihashmap_destroy (to_remove); 1688 GNUNET_CONTAINER_multihashmap_destroy (to_remove);
1675 lowest_bucket = lowest_bucket - 1; 1689 lowest_bucket = lowest_bucket - 1;
1676#if PRINT_TABLES 1690#if PRINT_TABLES
@@ -1703,21 +1717,21 @@ find_closest_peer (const GNUNET_HashCode * hc)
1703 1717
1704 current_closest = NULL; 1718 current_closest = NULL;
1705 for (bucket = lowest_bucket; bucket < MAX_BUCKETS; bucket++) 1719 for (bucket = lowest_bucket; bucket < MAX_BUCKETS; bucket++)
1706 { 1720 {
1707 pos = k_buckets[bucket].head; 1721 pos = k_buckets[bucket].head;
1708 count = 0; 1722 count = 0;
1709 while ((pos != NULL) && (count < bucket_size)) 1723 while ((pos != NULL) && (count < bucket_size))
1710 { 1724 {
1711 temp_distance = distance (&pos->id.hashPubKey, hc); 1725 temp_distance = distance (&pos->id.hashPubKey, hc);
1712 if (temp_distance <= lowest_distance) 1726 if (temp_distance <= lowest_distance)
1713 { 1727 {
1714 lowest_distance = temp_distance; 1728 lowest_distance = temp_distance;
1715 current_closest = pos; 1729 current_closest = pos;
1716 } 1730 }
1717 pos = pos->next; 1731 pos = pos->next;
1718 count++; 1732 count++;
1719 }
1720 } 1733 }
1734 }
1721 GNUNET_assert (current_closest != NULL); 1735 GNUNET_assert (current_closest != NULL);
1722 return current_closest; 1736 return current_closest;
1723} 1737}
@@ -1748,7 +1762,9 @@ forward_message (const struct GNUNET_MessageHeader *msg,
1748 && (peer == find_closest_peer (&msg_ctx->key))) 1762 && (peer == find_closest_peer (&msg_ctx->key)))
1749 increment_stats (STAT_ROUTE_FORWARDS_CLOSEST); 1763 increment_stats (STAT_ROUTE_FORWARDS_CLOSEST);
1750 1764
1751 msize = sizeof (struct GNUNET_DHT_P2PRouteMessage) + ntohs (msg->size) + (msg_ctx->path_history_len * sizeof(struct GNUNET_PeerIdentity)); 1765 msize =
1766 sizeof (struct GNUNET_DHT_P2PRouteMessage) + ntohs (msg->size) +
1767 (msg_ctx->path_history_len * sizeof (struct GNUNET_PeerIdentity));
1752 GNUNET_assert (msize <= GNUNET_SERVER_MAX_MESSAGE_SIZE); 1768 GNUNET_assert (msize <= GNUNET_SERVER_MAX_MESSAGE_SIZE);
1753 psize = sizeof (struct P2PPendingMessage) + msize; 1769 psize = sizeof (struct P2PPendingMessage) + msize;
1754 pending = GNUNET_malloc (psize); 1770 pending = GNUNET_malloc (psize);
@@ -1771,16 +1787,18 @@ forward_message (const struct GNUNET_MessageHeader *msg,
1771 DHT_BLOOM_SIZE)); 1787 DHT_BLOOM_SIZE));
1772 memcpy (&route_message->key, &msg_ctx->key, sizeof (GNUNET_HashCode)); 1788 memcpy (&route_message->key, &msg_ctx->key, sizeof (GNUNET_HashCode));
1773 memcpy (&route_message[1], msg, ntohs (msg->size)); 1789 memcpy (&route_message[1], msg, ntohs (msg->size));
1774 if (GNUNET_DHT_RO_RECORD_ROUTE == (msg_ctx->msg_options & GNUNET_DHT_RO_RECORD_ROUTE)) 1790 if (GNUNET_DHT_RO_RECORD_ROUTE ==
1775 { 1791 (msg_ctx->msg_options & GNUNET_DHT_RO_RECORD_ROUTE))
1776 route_message->outgoing_path_length = htonl(msg_ctx->path_history_len); 1792 {
1777 /* Set pointer to start of enc_msg */ 1793 route_message->outgoing_path_length = htonl (msg_ctx->path_history_len);
1778 route_path = (char *)&route_message[1]; 1794 /* Set pointer to start of enc_msg */
1779 /* Offset to the end of the enc_msg */ 1795 route_path = (char *) &route_message[1];
1780 route_path += ntohs (msg->size); 1796 /* Offset to the end of the enc_msg */
1781 /* Copy the route_path after enc_msg */ 1797 route_path += ntohs (msg->size);
1782 memcpy (route_path, msg_ctx->path_history, msg_ctx->path_history_len * sizeof(struct GNUNET_PeerIdentity)); 1798 /* Copy the route_path after enc_msg */
1783 } 1799 memcpy (route_path, msg_ctx->path_history,
1800 msg_ctx->path_history_len * sizeof (struct GNUNET_PeerIdentity));
1801 }
1784#if DEBUG_DHT > 1 1802#if DEBUG_DHT > 1
1785 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1803 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1786 "%s:%s Adding pending message size %d for peer %s\n", 1804 "%s:%s Adding pending message size %d for peer %s\n",
@@ -1809,7 +1827,7 @@ periodic_ping_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1809 struct GNUNET_MessageHeader ping_message; 1827 struct GNUNET_MessageHeader ping_message;
1810 struct DHT_MessageContext msg_ctx; 1828 struct DHT_MessageContext msg_ctx;
1811 1829
1812 if ( (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) 1830 if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
1813 return; 1831 return;
1814 1832
1815 ping_message.size = htons (sizeof (struct GNUNET_MessageHeader)); 1833 ping_message.size = htons (sizeof (struct GNUNET_MessageHeader));
@@ -1823,8 +1841,8 @@ periodic_ping_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1823#endif 1841#endif
1824 forward_message (&ping_message, peer, &msg_ctx); 1842 forward_message (&ping_message, peer, &msg_ctx);
1825 peer->ping_task = 1843 peer->ping_task =
1826 GNUNET_SCHEDULER_add_delayed (DHT_DEFAULT_PING_DELAY, &periodic_ping_task, 1844 GNUNET_SCHEDULER_add_delayed (DHT_DEFAULT_PING_DELAY, &periodic_ping_task,
1827 peer); 1845 peer);
1828} 1846}
1829 1847
1830/** 1848/**
@@ -1837,25 +1855,25 @@ schedule_ping_messages ()
1837 unsigned int bucket; 1855 unsigned int bucket;
1838 unsigned int count; 1856 unsigned int count;
1839 struct PeerInfo *pos; 1857 struct PeerInfo *pos;
1858
1840 for (bucket = lowest_bucket; bucket < MAX_BUCKETS; bucket++) 1859 for (bucket = lowest_bucket; bucket < MAX_BUCKETS; bucket++)
1841 { 1860 {
1842 pos = k_buckets[bucket].head; 1861 pos = k_buckets[bucket].head;
1843 count = 0; 1862 count = 0;
1844 while (pos != NULL) 1863 while (pos != NULL)
1845 { 1864 {
1846 if ((count < bucket_size) 1865 if ((count < bucket_size) && (pos->ping_task == GNUNET_SCHEDULER_NO_TASK))
1847 && (pos->ping_task == GNUNET_SCHEDULER_NO_TASK)) 1866 GNUNET_SCHEDULER_add_now (&periodic_ping_task, pos);
1848 GNUNET_SCHEDULER_add_now (&periodic_ping_task, pos); 1867 else if ((count >= bucket_size)
1849 else if ((count >= bucket_size) 1868 && (pos->ping_task != GNUNET_SCHEDULER_NO_TASK))
1850 && (pos->ping_task != GNUNET_SCHEDULER_NO_TASK)) 1869 {
1851 { 1870 GNUNET_SCHEDULER_cancel (pos->ping_task);
1852 GNUNET_SCHEDULER_cancel (pos->ping_task); 1871 pos->ping_task = GNUNET_SCHEDULER_NO_TASK;
1853 pos->ping_task = GNUNET_SCHEDULER_NO_TASK; 1872 }
1854 } 1873 pos = pos->next;
1855 pos = pos->next; 1874 count++;
1856 count++;
1857 }
1858 } 1875 }
1876 }
1859} 1877}
1860#endif 1878#endif
1861 1879
@@ -1874,11 +1892,11 @@ process_pending_messages (struct ClientList *client)
1874 return; 1892 return;
1875 1893
1876 client->transmit_handle = 1894 client->transmit_handle =
1877 GNUNET_SERVER_notify_transmit_ready (client->client_handle, 1895 GNUNET_SERVER_notify_transmit_ready (client->client_handle,
1878 ntohs (client->pending_head-> 1896 ntohs (client->pending_head->
1879 msg->size), 1897 msg->size),
1880 GNUNET_TIME_UNIT_FOREVER_REL, 1898 GNUNET_TIME_UNIT_FOREVER_REL,
1881 &send_generic_reply, client); 1899 &send_generic_reply, client);
1882} 1900}
1883 1901
1884/** 1902/**
@@ -1904,20 +1922,20 @@ send_generic_reply (void *cls, size_t size, void *buf)
1904 1922
1905 client->transmit_handle = NULL; 1923 client->transmit_handle = NULL;
1906 if (buf == NULL) 1924 if (buf == NULL)
1907 { 1925 {
1908 /* client disconnected */ 1926 /* client disconnected */
1909 return 0; 1927 return 0;
1910 } 1928 }
1911 off = 0; 1929 off = 0;
1912 while ((NULL != (reply = client->pending_head)) && 1930 while ((NULL != (reply = client->pending_head)) &&
1913 (size >= off + (msize = ntohs (reply->msg->size)))) 1931 (size >= off + (msize = ntohs (reply->msg->size))))
1914 { 1932 {
1915 GNUNET_CONTAINER_DLL_remove (client->pending_head, 1933 GNUNET_CONTAINER_DLL_remove (client->pending_head,
1916 client->pending_tail, reply); 1934 client->pending_tail, reply);
1917 memcpy (&cbuf[off], reply->msg, msize); 1935 memcpy (&cbuf[off], reply->msg, msize);
1918 GNUNET_free (reply); 1936 GNUNET_free (reply);
1919 off += msize; 1937 off += msize;
1920 } 1938 }
1921 process_pending_messages (client); 1939 process_pending_messages (client);
1922#if DEBUG_DHT 1940#if DEBUG_DHT
1923 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1941 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1963,6 +1981,7 @@ send_reply_to_client (struct ClientList *client,
1963 uint16_t msize; 1981 uint16_t msize;
1964 size_t tsize; 1982 size_t tsize;
1965 char *reply_offset; 1983 char *reply_offset;
1984
1966#if DEBUG_PATH 1985#if DEBUG_PATH
1967 char *path_offset; 1986 char *path_offset;
1968 unsigned int i; 1987 unsigned int i;
@@ -1972,34 +1991,41 @@ send_reply_to_client (struct ClientList *client,
1972 "`%s:%s': Sending reply to client.\n", my_short_id, "DHT"); 1991 "`%s:%s': Sending reply to client.\n", my_short_id, "DHT");
1973#endif 1992#endif
1974 msize = ntohs (message->size); 1993 msize = ntohs (message->size);
1975 tsize = sizeof (struct GNUNET_DHT_RouteResultMessage) + msize + (msg_ctx->path_history_len * sizeof(struct GNUNET_PeerIdentity)); 1994 tsize =
1995 sizeof (struct GNUNET_DHT_RouteResultMessage) + msize +
1996 (msg_ctx->path_history_len * sizeof (struct GNUNET_PeerIdentity));
1976 if (tsize >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 1997 if (tsize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1977 { 1998 {
1978 GNUNET_break_op (0); 1999 GNUNET_break_op (0);
1979 return; 2000 return;
1980 } 2001 }
1981 pending_message = GNUNET_malloc (sizeof (struct PendingMessage) + tsize); 2002 pending_message = GNUNET_malloc (sizeof (struct PendingMessage) + tsize);
1982 pending_message->msg = (struct GNUNET_MessageHeader *) &pending_message[1]; 2003 pending_message->msg = (struct GNUNET_MessageHeader *) &pending_message[1];
1983 reply = (struct GNUNET_DHT_RouteResultMessage *) &pending_message[1]; 2004 reply = (struct GNUNET_DHT_RouteResultMessage *) &pending_message[1];
1984 reply->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_LOCAL_ROUTE_RESULT); 2005 reply->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_LOCAL_ROUTE_RESULT);
1985 reply->header.size = htons (tsize); 2006 reply->header.size = htons (tsize);
1986 reply->outgoing_path_length = htonl(msg_ctx->path_history_len); 2007 reply->outgoing_path_length = htonl (msg_ctx->path_history_len);
1987 reply->unique_id = GNUNET_htonll (msg_ctx->unique_id); 2008 reply->unique_id = GNUNET_htonll (msg_ctx->unique_id);
1988 memcpy (&reply->key, &msg_ctx->key, sizeof (GNUNET_HashCode)); 2009 memcpy (&reply->key, &msg_ctx->key, sizeof (GNUNET_HashCode));
1989 reply_offset = (char *)&reply[1]; 2010 reply_offset = (char *) &reply[1];
1990 memcpy (&reply[1], message, msize); 2011 memcpy (&reply[1], message, msize);
1991 if (msg_ctx->path_history_len > 0) 2012 if (msg_ctx->path_history_len > 0)
1992 { 2013 {
1993 reply_offset += msize; 2014 reply_offset += msize;
1994 memcpy(reply_offset, msg_ctx->path_history, msg_ctx->path_history_len * sizeof(struct GNUNET_PeerIdentity)); 2015 memcpy (reply_offset, msg_ctx->path_history,
1995 } 2016 msg_ctx->path_history_len * sizeof (struct GNUNET_PeerIdentity));
2017 }
1996#if DEBUG_PATH 2018#if DEBUG_PATH
1997 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Returning message with outgoing path length %d\n", msg_ctx->path_history_len); 2019 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2020 "Returning message with outgoing path length %d\n",
2021 msg_ctx->path_history_len);
1998 for (i = 0; i < msg_ctx->path_history_len; i++) 2022 for (i = 0; i < msg_ctx->path_history_len; i++)
1999 { 2023 {
2000 path_offset = &msg_ctx->path_history[i * sizeof(struct GNUNET_PeerIdentity)]; 2024 path_offset =
2001 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Found peer %d:%s\n", i, GNUNET_i2s((struct GNUNET_PeerIdentity *)path_offset)); 2025 &msg_ctx->path_history[i * sizeof (struct GNUNET_PeerIdentity)];
2002 } 2026 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found peer %d:%s\n", i,
2027 GNUNET_i2s ((struct GNUNET_PeerIdentity *) path_offset));
2028 }
2003#endif 2029#endif
2004 add_pending_message (client, pending_message); 2030 add_pending_message (client, pending_message);
2005} 2031}
@@ -2045,23 +2071,22 @@ consider_peer (struct GNUNET_PeerIdentity *peer)
2045 * @param tc context, reason, etc. 2071 * @param tc context, reason, etc.
2046 */ 2072 */
2047static void 2073static void
2048remove_forward_entry (void *cls, 2074remove_forward_entry (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2049 const struct GNUNET_SCHEDULER_TaskContext *tc)
2050{ 2075{
2051 struct DHTRouteSource *source_info = cls; 2076 struct DHTRouteSource *source_info = cls;
2052 struct DHTQueryRecord *record; 2077 struct DHTQueryRecord *record;
2053 source_info = 2078
2054 GNUNET_CONTAINER_heap_remove_node (source_info->hnode); 2079 source_info = GNUNET_CONTAINER_heap_remove_node (source_info->hnode);
2055 record = source_info->record; 2080 record = source_info->record;
2056 GNUNET_CONTAINER_DLL_remove (record->head, record->tail, source_info); 2081 GNUNET_CONTAINER_DLL_remove (record->head, record->tail, source_info);
2057 2082
2058 if (record->head == NULL) /* No more entries in DLL */ 2083 if (record->head == NULL) /* No more entries in DLL */
2059 { 2084 {
2060 GNUNET_assert (GNUNET_YES == 2085 GNUNET_assert (GNUNET_YES ==
2061 GNUNET_CONTAINER_multihashmap_remove 2086 GNUNET_CONTAINER_multihashmap_remove
2062 (forward_list.hashmap, &record->key, record)); 2087 (forward_list.hashmap, &record->key, record));
2063 GNUNET_free (record); 2088 GNUNET_free (record);
2064 } 2089 }
2065 if (source_info->find_peers_responded != NULL) 2090 if (source_info->find_peers_responded != NULL)
2066 GNUNET_CONTAINER_bloomfilter_free (source_info->find_peers_responded); 2091 GNUNET_CONTAINER_bloomfilter_free (source_info->find_peers_responded);
2067 GNUNET_free (source_info); 2092 GNUNET_free (source_info);
@@ -2086,6 +2111,7 @@ route_result_message (struct GNUNET_MessageHeader *msg,
2086 struct DHTRouteSource *pos; 2111 struct DHTRouteSource *pos;
2087 struct PeerInfo *peer_info; 2112 struct PeerInfo *peer_info;
2088 const struct GNUNET_MessageHeader *hello_msg; 2113 const struct GNUNET_MessageHeader *hello_msg;
2114
2089#if DEBUG_DHT > 1 2115#if DEBUG_DHT > 1
2090 unsigned int i; 2116 unsigned int i;
2091#endif 2117#endif
@@ -2096,188 +2122,186 @@ route_result_message (struct GNUNET_MessageHeader *msg,
2096 * HELLO for another peer, offer it to the transport service. 2122 * HELLO for another peer, offer it to the transport service.
2097 */ 2123 */
2098 if (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_DHT_FIND_PEER_RESULT) 2124 if (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_DHT_FIND_PEER_RESULT)
2125 {
2126 if (ntohs (msg->size) <= sizeof (struct GNUNET_MessageHeader))
2127 GNUNET_break_op (0);
2128
2129 hello_msg = &msg[1];
2130 if ((ntohs (hello_msg->type) != GNUNET_MESSAGE_TYPE_HELLO)
2131 || (GNUNET_SYSERR ==
2132 GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *)
2133 hello_msg, &new_peer)))
2099 { 2134 {
2100 if (ntohs (msg->size) <= sizeof (struct GNUNET_MessageHeader)) 2135 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2101 GNUNET_break_op (0); 2136 "%s:%s Received non-HELLO message type in find peer result message!\n",
2102 2137 my_short_id, "DHT");
2103 hello_msg = &msg[1]; 2138 GNUNET_break_op (0);
2104 if ((ntohs (hello_msg->type) != GNUNET_MESSAGE_TYPE_HELLO) 2139 return GNUNET_NO;
2105 || (GNUNET_SYSERR == 2140 }
2106 GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *) 2141 else /* We have a valid hello, and peer id stored in new_peer */
2107 hello_msg, &new_peer))) 2142 {
2108 { 2143 find_peer_context.count++;
2109 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 2144 increment_stats (STAT_FIND_PEER_REPLY);
2110 "%s:%s Received non-HELLO message type in find peer result message!\n", 2145 if (GNUNET_YES == consider_peer (&new_peer))
2111 my_short_id, "DHT"); 2146 {
2112 GNUNET_break_op (0); 2147 increment_stats (STAT_HELLOS_PROVIDED);
2113 return GNUNET_NO; 2148 GNUNET_TRANSPORT_offer_hello (transport_handle, hello_msg, NULL, NULL);
2114 } 2149 GNUNET_CORE_peer_request_connect (coreAPI, &new_peer, NULL, NULL);
2115 else /* We have a valid hello, and peer id stored in new_peer */ 2150 }
2116 {
2117 find_peer_context.count++;
2118 increment_stats (STAT_FIND_PEER_REPLY);
2119 if (GNUNET_YES == consider_peer (&new_peer))
2120 {
2121 increment_stats (STAT_HELLOS_PROVIDED);
2122 GNUNET_TRANSPORT_offer_hello (transport_handle, hello_msg, NULL, NULL);
2123 GNUNET_CORE_peer_request_connect (coreAPI,
2124 &new_peer, NULL, NULL);
2125 }
2126 }
2127 } 2151 }
2152 }
2128 2153
2129 if (malicious_dropper == GNUNET_YES) 2154 if (malicious_dropper == GNUNET_YES)
2130 record = NULL; 2155 record = NULL;
2131 else 2156 else
2132 record = 2157 record =
2133 GNUNET_CONTAINER_multihashmap_get (forward_list.hashmap, &msg_ctx->key); 2158 GNUNET_CONTAINER_multihashmap_get (forward_list.hashmap, &msg_ctx->key);
2134 2159
2135 if (record == NULL) /* No record of this message! */ 2160 if (record == NULL) /* No record of this message! */
2136 { 2161 {
2137#if DEBUG_DHT 2162#if DEBUG_DHT
2138 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2163 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2139 "`%s:%s': Have no record of response key %s uid %llu\n", 2164 "`%s:%s': Have no record of response key %s uid %llu\n",
2140 my_short_id, "DHT", GNUNET_h2s (&msg_ctx->key), 2165 my_short_id, "DHT", GNUNET_h2s (&msg_ctx->key),
2141 msg_ctx->unique_id); 2166 msg_ctx->unique_id);
2142#endif 2167#endif
2143#if DEBUG_DHT_ROUTING 2168#if DEBUG_DHT_ROUTING
2144 if ((debug_routes_extended) && (dhtlog_handle != NULL)) 2169 if ((debug_routes_extended) && (dhtlog_handle != NULL))
2145 { 2170 {
2146 dhtlog_handle->insert_route (NULL, 2171 dhtlog_handle->insert_route (NULL,
2147 msg_ctx->unique_id, 2172 msg_ctx->unique_id,
2148 DHTLOG_RESULT, 2173 DHTLOG_RESULT,
2149 msg_ctx->hop_count, 2174 msg_ctx->hop_count,
2150 GNUNET_SYSERR, 2175 GNUNET_SYSERR,
2151 &my_identity, 2176 &my_identity,
2152 &msg_ctx->key, msg_ctx->peer, NULL); 2177 &msg_ctx->key, msg_ctx->peer, NULL);
2153 } 2178 }
2154#endif 2179#endif
2155 if (msg_ctx->bloom != NULL) 2180 if (msg_ctx->bloom != NULL)
2156 { 2181 {
2157 GNUNET_CONTAINER_bloomfilter_free (msg_ctx->bloom); 2182 GNUNET_CONTAINER_bloomfilter_free (msg_ctx->bloom);
2158 msg_ctx->bloom = NULL; 2183 msg_ctx->bloom = NULL;
2159 }
2160 return 0;
2161 } 2184 }
2185 return 0;
2186 }
2162 2187
2163 pos = record->head; 2188 pos = record->head;
2164 while (pos != NULL) 2189 while (pos != NULL)
2165 { 2190 {
2166#if STRICT_FORWARDING 2191#if STRICT_FORWARDING
2167 if (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_DHT_FIND_PEER_RESULT) /* If we have already forwarded this peer id, don't do it again! */ 2192 if (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_DHT_FIND_PEER_RESULT) /* If we have already forwarded this peer id, don't do it again! */
2168 { 2193 {
2169 if (GNUNET_YES == 2194 if (GNUNET_YES ==
2170 GNUNET_CONTAINER_bloomfilter_test (pos->find_peers_responded, 2195 GNUNET_CONTAINER_bloomfilter_test (pos->find_peers_responded,
2171 &new_peer.hashPubKey)) 2196 &new_peer.hashPubKey))
2172 { 2197 {
2173 increment_stats 2198 increment_stats ("# find peer responses NOT forwarded (bloom match)");
2174 ("# find peer responses NOT forwarded (bloom match)"); 2199 pos = pos->next;
2175 pos = pos->next; 2200 continue;
2176 continue; 2201 }
2177 } 2202 else
2178 else 2203 GNUNET_CONTAINER_bloomfilter_add (pos->find_peers_responded,
2179 GNUNET_CONTAINER_bloomfilter_add (pos->find_peers_responded, 2204 &new_peer.hashPubKey);
2180 &new_peer.hashPubKey); 2205 }
2181 }
2182#endif 2206#endif
2183 2207
2184 if (0 == memcmp (&pos->source, &my_identity, sizeof (struct GNUNET_PeerIdentity))) /* Local client (or DHT) initiated request! */ 2208 if (0 == memcmp (&pos->source, &my_identity, sizeof (struct GNUNET_PeerIdentity))) /* Local client (or DHT) initiated request! */
2185 { 2209 {
2186#if DEBUG_DHT 2210#if DEBUG_DHT
2187 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2211 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2188 "`%s:%s': Sending response key %s uid %llu to client\n", 2212 "`%s:%s': Sending response key %s uid %llu to client\n",
2189 my_short_id, "DHT", GNUNET_h2s (&msg_ctx->key), 2213 my_short_id, "DHT", GNUNET_h2s (&msg_ctx->key),
2190 msg_ctx->unique_id); 2214 msg_ctx->unique_id);
2191#endif 2215#endif
2192#if DEBUG_DHT_ROUTING 2216#if DEBUG_DHT_ROUTING
2193 if ((debug_routes_extended) && (dhtlog_handle != NULL)) 2217 if ((debug_routes_extended) && (dhtlog_handle != NULL))
2194 { 2218 {
2195 dhtlog_handle->insert_route (NULL, msg_ctx->unique_id, 2219 dhtlog_handle->insert_route (NULL, msg_ctx->unique_id,
2196 DHTLOG_RESULT, msg_ctx->hop_count, 2220 DHTLOG_RESULT, msg_ctx->hop_count,
2197 GNUNET_YES, &my_identity, 2221 GNUNET_YES, &my_identity,
2198 &msg_ctx->key, msg_ctx->peer, 2222 &msg_ctx->key, msg_ctx->peer, NULL);
2199 NULL); 2223 }
2200 }
2201#endif 2224#endif
2202 increment_stats (STAT_RESULTS_TO_CLIENT); 2225 increment_stats (STAT_RESULTS_TO_CLIENT);
2203 if (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_DHT_GET_RESULT) 2226 if (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_DHT_GET_RESULT)
2204 increment_stats (STAT_GET_REPLY); 2227 increment_stats (STAT_GET_REPLY);
2205#if DEBUG_DHT > 1 2228#if DEBUG_DHT > 1
2206 for (i = 0; i < msg_ctx->path_history_len; i++) 2229 for (i = 0; i < msg_ctx->path_history_len; i++)
2207 { 2230 {
2208 char *path_offset; 2231 char *path_offset;
2209 2232
2210 path_offset = &msg_ctx->path_history[i * sizeof(struct GNUNET_PeerIdentity)]; 2233 path_offset =
2211 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 2234 &msg_ctx->path_history[i * sizeof (struct GNUNET_PeerIdentity)];
2212 "(before client) Key %s Found peer %d:%s\n", 2235 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2213 GNUNET_h2s(&msg_ctx->key), i, 2236 "(before client) Key %s Found peer %d:%s\n",
2214 GNUNET_i2s((struct GNUNET_PeerIdentity *)path_offset)); 2237 GNUNET_h2s (&msg_ctx->key), i,
2215 } 2238 GNUNET_i2s ((struct GNUNET_PeerIdentity *) path_offset));
2239 }
2216#endif 2240#endif
2217 send_reply_to_client (pos->client, msg, msg_ctx); 2241 send_reply_to_client (pos->client, msg, msg_ctx);
2218 } 2242 }
2219 else /* Send to peer */ 2243 else /* Send to peer */
2220 { 2244 {
2221 peer_info = find_peer_by_id (&pos->source); 2245 peer_info = find_peer_by_id (&pos->source);
2222 if (peer_info == NULL) /* Didn't find the peer in our routing table, perhaps peer disconnected! */ 2246 if (peer_info == NULL) /* Didn't find the peer in our routing table, perhaps peer disconnected! */
2223 { 2247 {
2224 pos = pos->next; 2248 pos = pos->next;
2225 continue; 2249 continue;
2226 } 2250 }
2227 2251
2228 if (msg_ctx->bloom == NULL) 2252 if (msg_ctx->bloom == NULL)
2229 msg_ctx->bloom = 2253 msg_ctx->bloom =
2230 GNUNET_CONTAINER_bloomfilter_init (NULL, DHT_BLOOM_SIZE, 2254 GNUNET_CONTAINER_bloomfilter_init (NULL, DHT_BLOOM_SIZE,
2231 DHT_BLOOM_K); 2255 DHT_BLOOM_K);
2232 GNUNET_CONTAINER_bloomfilter_add (msg_ctx->bloom, 2256 GNUNET_CONTAINER_bloomfilter_add (msg_ctx->bloom,
2233 &my_identity.hashPubKey); 2257 &my_identity.hashPubKey);
2234 if ((GNUNET_NO == 2258 if ((GNUNET_NO ==
2235 GNUNET_CONTAINER_bloomfilter_test (msg_ctx->bloom, 2259 GNUNET_CONTAINER_bloomfilter_test (msg_ctx->bloom,
2236 &peer_info->id.hashPubKey))) 2260 &peer_info->id.hashPubKey)))
2237 { 2261 {
2238#if DEBUG_DHT 2262#if DEBUG_DHT
2239 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2263 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2240 "`%s:%s': Forwarding response key %s uid %llu to peer %s\n", 2264 "`%s:%s': Forwarding response key %s uid %llu to peer %s\n",
2241 my_short_id, "DHT", GNUNET_h2s (&msg_ctx->key), 2265 my_short_id, "DHT", GNUNET_h2s (&msg_ctx->key),
2242 msg_ctx->unique_id, GNUNET_i2s (&peer_info->id)); 2266 msg_ctx->unique_id, GNUNET_i2s (&peer_info->id));
2243#endif 2267#endif
2244#if DEBUG_DHT_ROUTING 2268#if DEBUG_DHT_ROUTING
2245 if ((debug_routes_extended) && (dhtlog_handle != NULL)) 2269 if ((debug_routes_extended) && (dhtlog_handle != NULL))
2246 { 2270 {
2247 dhtlog_handle->insert_route (NULL, msg_ctx->unique_id, 2271 dhtlog_handle->insert_route (NULL, msg_ctx->unique_id,
2248 DHTLOG_RESULT, 2272 DHTLOG_RESULT,
2249 msg_ctx->hop_count, 2273 msg_ctx->hop_count,
2250 GNUNET_NO, &my_identity, 2274 GNUNET_NO, &my_identity,
2251 &msg_ctx->key, msg_ctx->peer, 2275 &msg_ctx->key, msg_ctx->peer,
2252 &pos->source); 2276 &pos->source);
2253 } 2277 }
2254#endif 2278#endif
2255 forward_result_message (msg, peer_info, msg_ctx); 2279 forward_result_message (msg, peer_info, msg_ctx);
2256 /* Try removing forward entries after sending once, only allows ONE response per request */ 2280 /* Try removing forward entries after sending once, only allows ONE response per request */
2257 if (pos->delete_task != GNUNET_SCHEDULER_NO_TASK) 2281 if (pos->delete_task != GNUNET_SCHEDULER_NO_TASK)
2258 { 2282 {
2259 GNUNET_SCHEDULER_cancel (pos->delete_task); 2283 GNUNET_SCHEDULER_cancel (pos->delete_task);
2260 pos->delete_task = 2284 pos->delete_task =
2261 GNUNET_SCHEDULER_add_now (&remove_forward_entry, pos); 2285 GNUNET_SCHEDULER_add_now (&remove_forward_entry, pos);
2262 } 2286 }
2263 } 2287 }
2264 else 2288 else
2265 { 2289 {
2266#if DEBUG_DHT 2290#if DEBUG_DHT
2267 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2291 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2268 "`%s:%s': NOT Forwarding response (bloom match) key %s uid %llu to peer %s\n", 2292 "`%s:%s': NOT Forwarding response (bloom match) key %s uid %llu to peer %s\n",
2269 my_short_id, "DHT", GNUNET_h2s (&msg_ctx->key), 2293 my_short_id, "DHT", GNUNET_h2s (&msg_ctx->key),
2270 msg_ctx->unique_id, GNUNET_i2s (&peer_info->id)); 2294 msg_ctx->unique_id, GNUNET_i2s (&peer_info->id));
2271#endif 2295#endif
2272 } 2296 }
2273 }
2274 pos = pos->next;
2275 } 2297 }
2298 pos = pos->next;
2299 }
2276 if (msg_ctx->bloom != NULL) 2300 if (msg_ctx->bloom != NULL)
2277 { 2301 {
2278 GNUNET_CONTAINER_bloomfilter_free (msg_ctx->bloom); 2302 GNUNET_CONTAINER_bloomfilter_free (msg_ctx->bloom);
2279 msg_ctx->bloom = NULL; 2303 msg_ctx->bloom = NULL;
2280 } 2304 }
2281 return 0; 2305 return 0;
2282} 2306}
2283 2307
@@ -2309,6 +2333,7 @@ datacache_get_iterator (void *cls,
2309 const struct DHTPutEntry *put_entry; 2333 const struct DHTPutEntry *put_entry;
2310 int get_size; 2334 int get_size;
2311 char *path_offset; 2335 char *path_offset;
2336
2312#if DEBUG_PATH 2337#if DEBUG_PATH
2313 unsigned int i; 2338 unsigned int i;
2314#endif 2339#endif
@@ -2319,114 +2344,129 @@ datacache_get_iterator (void *cls,
2319 "DHT", "GET"); 2344 "DHT", "GET");
2320#endif 2345#endif
2321 2346
2322 put_entry = (const struct DHTPutEntry *)data; 2347 put_entry = (const struct DHTPutEntry *) data;
2323
2324 if (size != sizeof(struct DHTPutEntry) +
2325 put_entry->data_size +
2326 (put_entry->path_length * sizeof(struct GNUNET_PeerIdentity)))
2327 {
2328 GNUNET_log(
2329 GNUNET_ERROR_TYPE_WARNING,
2330 "Path + data size doesn't add up for data inserted into datacache!\nData size %d, path length %d, expected %d, got %d\n",
2331 put_entry->data_size, put_entry->path_length,
2332 sizeof(struct DHTPutEntry) + put_entry->data_size
2333 + (put_entry->path_length * sizeof(struct GNUNET_PeerIdentity)),
2334 size);
2335 msg_ctx->do_forward = GNUNET_NO;
2336 return GNUNET_OK;
2337 }
2338 2348
2339 eval = GNUNET_BLOCK_evaluate (block_context, 2349 if (size != sizeof (struct DHTPutEntry) +
2340 type, 2350 put_entry->data_size +
2341 key, 2351 (put_entry->path_length * sizeof (struct GNUNET_PeerIdentity)))
2342 &msg_ctx->reply_bf, 2352 {
2343 msg_ctx->reply_bf_mutator, 2353 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2344 msg_ctx->xquery, 2354 "Path + data size doesn't add up for data inserted into datacache!\nData size %d, path length %d, expected %d, got %d\n",
2345 msg_ctx->xquery_size, &put_entry[1], put_entry->data_size); 2355 put_entry->data_size, put_entry->path_length,
2356 sizeof (struct DHTPutEntry) + put_entry->data_size
2357 +
2358 (put_entry->path_length * sizeof (struct GNUNET_PeerIdentity)),
2359 size);
2360 msg_ctx->do_forward = GNUNET_NO;
2361 return GNUNET_OK;
2362 }
2363
2364 eval = GNUNET_BLOCK_evaluate (block_context,
2365 type,
2366 key,
2367 &msg_ctx->reply_bf,
2368 msg_ctx->reply_bf_mutator,
2369 msg_ctx->xquery,
2370 msg_ctx->xquery_size, &put_entry[1],
2371 put_entry->data_size);
2346 2372
2347 switch (eval) 2373 switch (eval)
2374 {
2375 case GNUNET_BLOCK_EVALUATION_OK_LAST:
2376 msg_ctx->do_forward = GNUNET_NO;
2377 case GNUNET_BLOCK_EVALUATION_OK_MORE:
2378 new_msg_ctx = GNUNET_malloc (sizeof (struct DHT_MessageContext));
2379 memcpy (new_msg_ctx, msg_ctx, sizeof (struct DHT_MessageContext));
2380 if (GNUNET_DHT_RO_RECORD_ROUTE ==
2381 (msg_ctx->msg_options & GNUNET_DHT_RO_RECORD_ROUTE))
2348 { 2382 {
2349 case GNUNET_BLOCK_EVALUATION_OK_LAST: 2383 new_msg_ctx->msg_options = GNUNET_DHT_RO_RECORD_ROUTE;
2350 msg_ctx->do_forward = GNUNET_NO; 2384 new_msg_ctx->path_history_len = msg_ctx->path_history_len;
2351 case GNUNET_BLOCK_EVALUATION_OK_MORE: 2385 /* Assign to previous msg_ctx path history, caller should free after our return */
2352 new_msg_ctx = GNUNET_malloc (sizeof (struct DHT_MessageContext)); 2386 new_msg_ctx->path_history = msg_ctx->path_history;
2353 memcpy (new_msg_ctx, msg_ctx, sizeof (struct DHT_MessageContext));
2354 if (GNUNET_DHT_RO_RECORD_ROUTE == (msg_ctx->msg_options & GNUNET_DHT_RO_RECORD_ROUTE))
2355 {
2356 new_msg_ctx->msg_options = GNUNET_DHT_RO_RECORD_ROUTE;
2357 new_msg_ctx->path_history_len = msg_ctx->path_history_len;
2358 /* Assign to previous msg_ctx path history, caller should free after our return */
2359 new_msg_ctx->path_history = msg_ctx->path_history;
2360#if DEBUG_PATH 2387#if DEBUG_PATH
2361 for (i = 0; i < new_msg_ctx->path_history_len; i++) 2388 for (i = 0; i < new_msg_ctx->path_history_len; i++)
2362 { 2389 {
2363 path_offset = &new_msg_ctx->path_history[i * sizeof(struct GNUNET_PeerIdentity)]; 2390 path_offset =
2364 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "(get_iterator) Key %s Found peer %d:%s\n", GNUNET_h2s(&msg_ctx->key), i, GNUNET_i2s((struct GNUNET_PeerIdentity *)path_offset)); 2391 &new_msg_ctx->path_history[i * sizeof (struct GNUNET_PeerIdentity)];
2365 } 2392 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2393 "(get_iterator) Key %s Found peer %d:%s\n",
2394 GNUNET_h2s (&msg_ctx->key), i,
2395 GNUNET_i2s ((struct GNUNET_PeerIdentity *) path_offset));
2396 }
2366#endif 2397#endif
2367 } 2398 }
2368 2399
2369 get_size = sizeof (struct GNUNET_DHT_GetResultMessage) + put_entry->data_size + (put_entry->path_length * sizeof(struct GNUNET_PeerIdentity)); 2400 get_size =
2370 get_result = GNUNET_malloc (get_size); 2401 sizeof (struct GNUNET_DHT_GetResultMessage) + put_entry->data_size +
2371 get_result->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_GET_RESULT); 2402 (put_entry->path_length * sizeof (struct GNUNET_PeerIdentity));
2372 get_result->header.size = htons (get_size); 2403 get_result = GNUNET_malloc (get_size);
2373 get_result->expiration = GNUNET_TIME_absolute_hton (exp); 2404 get_result->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_GET_RESULT);
2374 get_result->type = htons (type); 2405 get_result->header.size = htons (get_size);
2375 get_result->put_path_length = htons(put_entry->path_length); 2406 get_result->expiration = GNUNET_TIME_absolute_hton (exp);
2376 path_offset = (char *)&put_entry[1]; 2407 get_result->type = htons (type);
2377 path_offset += put_entry->data_size; 2408 get_result->put_path_length = htons (put_entry->path_length);
2409 path_offset = (char *) &put_entry[1];
2410 path_offset += put_entry->data_size;
2378#if DEBUG_PATH 2411#if DEBUG_PATH
2379 for (i = 0; i < put_entry->path_length; i++) 2412 for (i = 0; i < put_entry->path_length; i++)
2380 { 2413 {
2381 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "(get_iterator PUT path) Key %s Found peer %d:%s\n", GNUNET_h2s(&msg_ctx->key), i, GNUNET_i2s((struct GNUNET_PeerIdentity *)&path_offset[i * sizeof(struct GNUNET_PeerIdentity)])); 2414 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2382 } 2415 "(get_iterator PUT path) Key %s Found peer %d:%s\n",
2416 GNUNET_h2s (&msg_ctx->key), i,
2417 GNUNET_i2s ((struct GNUNET_PeerIdentity *)
2418 &path_offset[i *
2419 sizeof (struct
2420 GNUNET_PeerIdentity)]));
2421 }
2383#endif 2422#endif
2384 /* Copy the actual data and the path_history to the end of the get result */ 2423 /* Copy the actual data and the path_history to the end of the get result */
2385 memcpy (&get_result[1], &put_entry[1], put_entry->data_size + (put_entry->path_length * sizeof(struct GNUNET_PeerIdentity))); 2424 memcpy (&get_result[1], &put_entry[1],
2386 new_msg_ctx->peer = &my_identity; 2425 put_entry->data_size +
2387 new_msg_ctx->bloom = 2426 (put_entry->path_length * sizeof (struct GNUNET_PeerIdentity)));
2427 new_msg_ctx->peer = &my_identity;
2428 new_msg_ctx->bloom =
2388 GNUNET_CONTAINER_bloomfilter_init (NULL, DHT_BLOOM_SIZE, DHT_BLOOM_K); 2429 GNUNET_CONTAINER_bloomfilter_init (NULL, DHT_BLOOM_SIZE, DHT_BLOOM_K);
2389 new_msg_ctx->hop_count = 0; 2430 new_msg_ctx->hop_count = 0;
2390 new_msg_ctx->importance = DHT_DEFAULT_P2P_IMPORTANCE + 2; /* Make result routing a higher priority */ 2431 new_msg_ctx->importance = DHT_DEFAULT_P2P_IMPORTANCE + 2; /* Make result routing a higher priority */
2391 new_msg_ctx->timeout = DHT_DEFAULT_P2P_TIMEOUT; 2432 new_msg_ctx->timeout = DHT_DEFAULT_P2P_TIMEOUT;
2392 increment_stats (STAT_GET_RESPONSE_START); 2433 increment_stats (STAT_GET_RESPONSE_START);
2393 route_result_message (&get_result->header, new_msg_ctx); 2434 route_result_message (&get_result->header, new_msg_ctx);
2394 GNUNET_free (new_msg_ctx); 2435 GNUNET_free (new_msg_ctx);
2395 GNUNET_free (get_result); 2436 GNUNET_free (get_result);
2396 break; 2437 break;
2397 case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE: 2438 case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE:
2398#if DEBUG_DHT 2439#if DEBUG_DHT
2399 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2440 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2400 "`%s:%s': Duplicate block error\n", my_short_id, "DHT"); 2441 "`%s:%s': Duplicate block error\n", my_short_id, "DHT");
2401#endif 2442#endif
2402 break; 2443 break;
2403 case GNUNET_BLOCK_EVALUATION_RESULT_INVALID: 2444 case GNUNET_BLOCK_EVALUATION_RESULT_INVALID:
2404#if DEBUG_DHT 2445#if DEBUG_DHT
2405 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 2446 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2406 "`%s:%s': Invalid request error\n", my_short_id, "DHT"); 2447 "`%s:%s': Invalid request error\n", my_short_id, "DHT");
2407#endif 2448#endif
2408 break; 2449 break;
2409 case GNUNET_BLOCK_EVALUATION_REQUEST_VALID: 2450 case GNUNET_BLOCK_EVALUATION_REQUEST_VALID:
2410#if DEBUG_DHT 2451#if DEBUG_DHT
2411 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2452 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2412 "`%s:%s': Valid request, no results.\n", my_short_id, 2453 "`%s:%s': Valid request, no results.\n", my_short_id, "DHT");
2413 "DHT");
2414#endif 2454#endif
2415 GNUNET_break (0); 2455 GNUNET_break (0);
2416 break; 2456 break;
2417 case GNUNET_BLOCK_EVALUATION_REQUEST_INVALID: 2457 case GNUNET_BLOCK_EVALUATION_REQUEST_INVALID:
2418 GNUNET_break_op (0); 2458 GNUNET_break_op (0);
2419 msg_ctx->do_forward = GNUNET_NO; 2459 msg_ctx->do_forward = GNUNET_NO;
2420 break; 2460 break;
2421 case GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED: 2461 case GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED:
2422#if DEBUG_DHT 2462#if DEBUG_DHT
2423 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 2463 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2424 "`%s:%s': Unsupported block type (%u) in response!\n", 2464 "`%s:%s': Unsupported block type (%u) in response!\n",
2425 my_short_id, "DHT", type); 2465 my_short_id, "DHT", type);
2426#endif 2466#endif
2427 /* msg_ctx->do_forward = GNUNET_NO; // not sure... */ 2467 /* msg_ctx->do_forward = GNUNET_NO; // not sure... */
2428 break; 2468 break;
2429 } 2469 }
2430 return GNUNET_OK; 2470 return GNUNET_OK;
2431} 2471}
2432 2472
@@ -2465,40 +2505,40 @@ handle_dht_get (const struct GNUNET_MessageHeader *msg,
2465 2505
2466 msize = ntohs (msg->size); 2506 msize = ntohs (msg->size);
2467 if (msize < sizeof (struct GNUNET_DHT_GetMessage)) 2507 if (msize < sizeof (struct GNUNET_DHT_GetMessage))
2468 { 2508 {
2469 GNUNET_break (0); 2509 GNUNET_break (0);
2470 return 0; 2510 return 0;
2471 } 2511 }
2472 get_msg = (const struct GNUNET_DHT_GetMessage *) msg; 2512 get_msg = (const struct GNUNET_DHT_GetMessage *) msg;
2473 bf_size = ntohs (get_msg->bf_size); 2513 bf_size = ntohs (get_msg->bf_size);
2474 msg_ctx->xquery_size = ntohs (get_msg->xquery_size); 2514 msg_ctx->xquery_size = ntohs (get_msg->xquery_size);
2475 msg_ctx->reply_bf_mutator = get_msg->bf_mutator; /* FIXME: ntohl? */ 2515 msg_ctx->reply_bf_mutator = get_msg->bf_mutator; /* FIXME: ntohl? */
2476 if (msize != 2516 if (msize !=
2477 sizeof (struct GNUNET_DHT_GetMessage) + bf_size + msg_ctx->xquery_size) 2517 sizeof (struct GNUNET_DHT_GetMessage) + bf_size + msg_ctx->xquery_size)
2478 { 2518 {
2479 GNUNET_break (0); 2519 GNUNET_break (0);
2480 return 0; 2520 return 0;
2481 } 2521 }
2482 end = (const char *) &get_msg[1]; 2522 end = (const char *) &get_msg[1];
2483 if (msg_ctx->xquery_size == 0) 2523 if (msg_ctx->xquery_size == 0)
2484 { 2524 {
2485 msg_ctx->xquery = NULL; 2525 msg_ctx->xquery = NULL;
2486 } 2526 }
2487 else 2527 else
2488 { 2528 {
2489 msg_ctx->xquery = (const void *) end; 2529 msg_ctx->xquery = (const void *) end;
2490 end += msg_ctx->xquery_size; 2530 end += msg_ctx->xquery_size;
2491 } 2531 }
2492 if (bf_size == 0) 2532 if (bf_size == 0)
2493 { 2533 {
2494 msg_ctx->reply_bf = NULL; 2534 msg_ctx->reply_bf = NULL;
2495 } 2535 }
2496 else 2536 else
2497 { 2537 {
2498 msg_ctx->reply_bf = GNUNET_CONTAINER_bloomfilter_init (end, 2538 msg_ctx->reply_bf = GNUNET_CONTAINER_bloomfilter_init (end,
2499 bf_size, 2539 bf_size,
2500 GNUNET_DHT_GET_BLOOMFILTER_K); 2540 GNUNET_DHT_GET_BLOOMFILTER_K);
2501 } 2541 }
2502 type = (enum GNUNET_BLOCK_Type) ntohl (get_msg->type); 2542 type = (enum GNUNET_BLOCK_Type) ntohl (get_msg->type);
2503#if DEBUG_DHT 2543#if DEBUG_DHT
2504 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2544 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -2511,69 +2551,69 @@ handle_dht_get (const struct GNUNET_MessageHeader *msg,
2511 results = 0; 2551 results = 0;
2512#if HAVE_MALICIOUS 2552#if HAVE_MALICIOUS
2513 if (type == GNUNET_BLOCK_DHT_MALICIOUS_MESSAGE_TYPE) 2553 if (type == GNUNET_BLOCK_DHT_MALICIOUS_MESSAGE_TYPE)
2514 { 2554 {
2515 GNUNET_CONTAINER_bloomfilter_free (msg_ctx->reply_bf); 2555 GNUNET_CONTAINER_bloomfilter_free (msg_ctx->reply_bf);
2516 return results; 2556 return results;
2517 } 2557 }
2518#endif 2558#endif
2519 msg_ctx->do_forward = GNUNET_YES; 2559 msg_ctx->do_forward = GNUNET_YES;
2520 if (datacache != NULL) 2560 if (datacache != NULL)
2521 results 2561 results
2522 = GNUNET_DATACACHE_get (datacache, 2562 = GNUNET_DATACACHE_get (datacache,
2523 &msg_ctx->key, type, 2563 &msg_ctx->key, type,
2524 &datacache_get_iterator, msg_ctx); 2564 &datacache_get_iterator, msg_ctx);
2525#if DEBUG_DHT 2565#if DEBUG_DHT
2526 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2566 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2527 "`%s:%s': Found %d results for `%s' request uid %llu\n", 2567 "`%s:%s': Found %d results for `%s' request uid %llu\n",
2528 my_short_id, "DHT", results, "GET", msg_ctx->unique_id); 2568 my_short_id, "DHT", results, "GET", msg_ctx->unique_id);
2529#endif 2569#endif
2530 if (results >= 1) 2570 if (results >= 1)
2531 { 2571 {
2532#if DEBUG_DHT_ROUTING 2572#if DEBUG_DHT_ROUTING
2533 if ((debug_routes) && (dhtlog_handle != NULL)) 2573 if ((debug_routes) && (dhtlog_handle != NULL))
2534 { 2574 {
2535 dhtlog_handle->insert_query (NULL, msg_ctx->unique_id, DHTLOG_GET, 2575 dhtlog_handle->insert_query (NULL, msg_ctx->unique_id, DHTLOG_GET,
2536 msg_ctx->hop_count, GNUNET_YES, 2576 msg_ctx->hop_count, GNUNET_YES,
2537 &my_identity, &msg_ctx->key); 2577 &my_identity, &msg_ctx->key);
2538 } 2578 }
2539 2579
2540 if ((debug_routes_extended) && (dhtlog_handle != NULL)) 2580 if ((debug_routes_extended) && (dhtlog_handle != NULL))
2541 { 2581 {
2542 dhtlog_handle->insert_route (NULL, msg_ctx->unique_id, DHTLOG_ROUTE, 2582 dhtlog_handle->insert_route (NULL, msg_ctx->unique_id, DHTLOG_ROUTE,
2543 msg_ctx->hop_count, GNUNET_YES, 2583 msg_ctx->hop_count, GNUNET_YES,
2544 &my_identity, &msg_ctx->key, 2584 &my_identity, &msg_ctx->key,
2545 msg_ctx->peer, NULL); 2585 msg_ctx->peer, NULL);
2546 }
2547#endif
2548 } 2586 }
2587#endif
2588 }
2549 else 2589 else
2590 {
2591 /* check query valid */
2592 if (GNUNET_BLOCK_EVALUATION_REQUEST_INVALID
2593 == GNUNET_BLOCK_evaluate (block_context,
2594 type,
2595 &msg_ctx->key,
2596 &msg_ctx->reply_bf,
2597 msg_ctx->reply_bf_mutator,
2598 msg_ctx->xquery,
2599 msg_ctx->xquery_size, NULL, 0))
2550 { 2600 {
2551 /* check query valid */ 2601 GNUNET_break_op (0);
2552 if (GNUNET_BLOCK_EVALUATION_REQUEST_INVALID 2602 msg_ctx->do_forward = GNUNET_NO;
2553 == GNUNET_BLOCK_evaluate (block_context,
2554 type,
2555 &msg_ctx->key,
2556 &msg_ctx->reply_bf,
2557 msg_ctx->reply_bf_mutator,
2558 msg_ctx->xquery,
2559 msg_ctx->xquery_size, NULL, 0))
2560 {
2561 GNUNET_break_op (0);
2562 msg_ctx->do_forward = GNUNET_NO;
2563 }
2564 } 2603 }
2604 }
2565 2605
2566 if (msg_ctx->hop_count == 0) /* Locally initiated request */ 2606 if (msg_ctx->hop_count == 0) /* Locally initiated request */
2567 { 2607 {
2568#if DEBUG_DHT_ROUTING 2608#if DEBUG_DHT_ROUTING
2569 if ((debug_routes) && (dhtlog_handle != NULL)) 2609 if ((debug_routes) && (dhtlog_handle != NULL))
2570 { 2610 {
2571 dhtlog_handle->insert_query (NULL, msg_ctx->unique_id, DHTLOG_GET, 2611 dhtlog_handle->insert_query (NULL, msg_ctx->unique_id, DHTLOG_GET,
2572 msg_ctx->hop_count, GNUNET_NO, 2612 msg_ctx->hop_count, GNUNET_NO,
2573 &my_identity, &msg_ctx->key); 2613 &my_identity, &msg_ctx->key);
2574 }
2575#endif
2576 } 2614 }
2615#endif
2616 }
2577 if (msg_ctx->do_forward == GNUNET_YES) 2617 if (msg_ctx->do_forward == GNUNET_YES)
2578 route_message (msg, msg_ctx); 2618 route_message (msg, msg_ctx);
2579 GNUNET_CONTAINER_bloomfilter_free (msg_ctx->reply_bf); 2619 GNUNET_CONTAINER_bloomfilter_free (msg_ctx->reply_bf);
@@ -2622,41 +2662,40 @@ handle_dht_find_peer (const struct GNUNET_MessageHeader *find_msg,
2622 other_hello = NULL; 2662 other_hello = NULL;
2623 other_hello_size = 0; 2663 other_hello_size = 0;
2624 if (ntohs (find_msg->size) > sizeof (struct GNUNET_DHT_FindPeerMessage)) 2664 if (ntohs (find_msg->size) > sizeof (struct GNUNET_DHT_FindPeerMessage))
2625 { 2665 {
2626 other_hello_size = 2666 other_hello_size =
2627 ntohs (find_msg->size) - sizeof (struct GNUNET_DHT_FindPeerMessage); 2667 ntohs (find_msg->size) - sizeof (struct GNUNET_DHT_FindPeerMessage);
2628 other_hello = GNUNET_malloc (other_hello_size); 2668 other_hello = GNUNET_malloc (other_hello_size);
2629 memcpy (other_hello, &find_peer_message[1], other_hello_size); 2669 memcpy (other_hello, &find_peer_message[1], other_hello_size);
2630 if ((GNUNET_HELLO_size ((struct GNUNET_HELLO_Message *) other_hello) == 2670 if ((GNUNET_HELLO_size ((struct GNUNET_HELLO_Message *) other_hello) ==
2631 0) 2671 0)
2632 || (GNUNET_OK != 2672 || (GNUNET_OK !=
2633 GNUNET_HELLO_get_id ((struct GNUNET_HELLO_Message *) 2673 GNUNET_HELLO_get_id ((struct GNUNET_HELLO_Message *)
2634 other_hello, &peer_id))) 2674 other_hello, &peer_id)))
2635 { 2675 {
2636 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 2676 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2637 "Received invalid HELLO message in find peer request!\n"); 2677 "Received invalid HELLO message in find peer request!\n");
2638 GNUNET_free (other_hello); 2678 GNUNET_free (other_hello);
2639 return; 2679 return;
2640 } 2680 }
2641#if FIND_PEER_WITH_HELLO 2681#if FIND_PEER_WITH_HELLO
2642 if (GNUNET_YES == consider_peer (&peer_id)) 2682 if (GNUNET_YES == consider_peer (&peer_id))
2643 { 2683 {
2644 increment_stats (STAT_HELLOS_PROVIDED); 2684 increment_stats (STAT_HELLOS_PROVIDED);
2645 GNUNET_TRANSPORT_offer_hello (transport_handle, other_hello, NULL, NULL); 2685 GNUNET_TRANSPORT_offer_hello (transport_handle, other_hello, NULL, NULL);
2646 GNUNET_CORE_peer_request_connect (coreAPI, 2686 GNUNET_CORE_peer_request_connect (coreAPI, &peer_id, NULL, NULL);
2647 &peer_id, NULL, NULL); 2687 route_message (find_msg, msg_ctx);
2648 route_message (find_msg, msg_ctx); 2688 GNUNET_free (other_hello);
2649 GNUNET_free (other_hello); 2689 return;
2650 return; 2690 }
2651 } 2691 else /* We don't want this peer! */
2652 else /* We don't want this peer! */ 2692 {
2653 { 2693 route_message (find_msg, msg_ctx);
2654 route_message (find_msg, msg_ctx); 2694 GNUNET_free (other_hello);
2655 GNUNET_free (other_hello); 2695 return;
2656 return;
2657 }
2658#endif
2659 } 2696 }
2697#endif
2698 }
2660 2699
2661#if DEBUG_DHT 2700#if DEBUG_DHT
2662 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2701 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -2665,29 +2704,29 @@ handle_dht_find_peer (const struct GNUNET_MessageHeader *find_msg,
2665 ntohs (find_msg->size), sizeof (struct GNUNET_MessageHeader)); 2704 ntohs (find_msg->size), sizeof (struct GNUNET_MessageHeader));
2666#endif 2705#endif
2667 if (my_hello == NULL) 2706 if (my_hello == NULL)
2668 { 2707 {
2669#if DEBUG_DHT 2708#if DEBUG_DHT
2670 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2709 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2671 "`%s': Our HELLO is null, can't return.\n", "DHT"); 2710 "`%s': Our HELLO is null, can't return.\n", "DHT");
2672#endif 2711#endif
2673 GNUNET_free_non_null (other_hello); 2712 GNUNET_free_non_null (other_hello);
2674 route_message (find_msg, msg_ctx); 2713 route_message (find_msg, msg_ctx);
2675 return; 2714 return;
2676 } 2715 }
2677 2716
2678 incoming_bloom = 2717 incoming_bloom =
2679 GNUNET_CONTAINER_bloomfilter_init (find_peer_message->bloomfilter, 2718 GNUNET_CONTAINER_bloomfilter_init (find_peer_message->bloomfilter,
2680 DHT_BLOOM_SIZE, DHT_BLOOM_K); 2719 DHT_BLOOM_SIZE, DHT_BLOOM_K);
2681 if (GNUNET_YES == 2720 if (GNUNET_YES ==
2682 GNUNET_CONTAINER_bloomfilter_test (incoming_bloom, 2721 GNUNET_CONTAINER_bloomfilter_test (incoming_bloom,
2683 &my_identity.hashPubKey)) 2722 &my_identity.hashPubKey))
2684 { 2723 {
2685 increment_stats (STAT_BLOOM_FIND_PEER); 2724 increment_stats (STAT_BLOOM_FIND_PEER);
2686 GNUNET_CONTAINER_bloomfilter_free (incoming_bloom); 2725 GNUNET_CONTAINER_bloomfilter_free (incoming_bloom);
2687 GNUNET_free_non_null (other_hello); 2726 GNUNET_free_non_null (other_hello);
2688 route_message (find_msg, msg_ctx); 2727 route_message (find_msg, msg_ctx);
2689 return; /* We match the bloomfilter, do not send a response to this peer (they likely already know us!) */ 2728 return; /* We match the bloomfilter, do not send a response to this peer (they likely already know us!) */
2690 } 2729 }
2691 GNUNET_CONTAINER_bloomfilter_free (incoming_bloom); 2730 GNUNET_CONTAINER_bloomfilter_free (incoming_bloom);
2692 2731
2693#if RESTRICT_FIND_PEER 2732#if RESTRICT_FIND_PEER
@@ -2696,11 +2735,11 @@ handle_dht_find_peer (const struct GNUNET_MessageHeader *find_msg,
2696 * Ignore any find peer requests from a peer we have seen very recently. 2735 * Ignore any find peer requests from a peer we have seen very recently.
2697 */ 2736 */
2698 if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (recent_find_peer_requests, &msg_ctx->key)) /* We have recently responded to a find peer request for this peer! */ 2737 if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (recent_find_peer_requests, &msg_ctx->key)) /* We have recently responded to a find peer request for this peer! */
2699 { 2738 {
2700 increment_stats ("# dht find peer requests ignored (recently seen!)"); 2739 increment_stats ("# dht find peer requests ignored (recently seen!)");
2701 GNUNET_free_non_null (other_hello); 2740 GNUNET_free_non_null (other_hello);
2702 return; 2741 return;
2703 } 2742 }
2704 2743
2705 /** 2744 /**
2706 * Use this check to only allow the peer to respond to find peer requests if 2745 * Use this check to only allow the peer to respond to find peer requests if
@@ -2712,12 +2751,12 @@ handle_dht_find_peer (const struct GNUNET_MessageHeader *find_msg,
2712 */ 2751 */
2713 memcpy (&peer_id.hashPubKey, &msg_ctx->key, sizeof (GNUNET_HashCode)); 2752 memcpy (&peer_id.hashPubKey, &msg_ctx->key, sizeof (GNUNET_HashCode));
2714 if (GNUNET_NO == consider_peer (&peer_id)) 2753 if (GNUNET_NO == consider_peer (&peer_id))
2715 { 2754 {
2716 increment_stats ("# dht find peer requests ignored (do not need!)"); 2755 increment_stats ("# dht find peer requests ignored (do not need!)");
2717 GNUNET_free_non_null (other_hello); 2756 GNUNET_free_non_null (other_hello);
2718 route_message (find_msg, msg_ctx); 2757 route_message (find_msg, msg_ctx);
2719 return; 2758 return;
2720 } 2759 }
2721#endif 2760#endif
2722 2761
2723 recent_hash = GNUNET_malloc (sizeof (GNUNET_HashCode)); 2762 recent_hash = GNUNET_malloc (sizeof (GNUNET_HashCode));
@@ -2726,36 +2765,36 @@ handle_dht_find_peer (const struct GNUNET_MessageHeader *find_msg,
2726 GNUNET_CONTAINER_multihashmap_put (recent_find_peer_requests, 2765 GNUNET_CONTAINER_multihashmap_put (recent_find_peer_requests,
2727 &msg_ctx->key, NULL, 2766 &msg_ctx->key, NULL,
2728 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) 2767 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
2729 { 2768 {
2730#if DEBUG_DHT 2769#if DEBUG_DHT
2731 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2770 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2732 "Adding recent remove task for key `%s`!\n", 2771 "Adding recent remove task for key `%s`!\n",
2733 GNUNET_h2s (&msg_ctx->key)); 2772 GNUNET_h2s (&msg_ctx->key));
2734#endif 2773#endif
2735 /* Only add a task if there wasn't one for this key already! */ 2774 /* Only add a task if there wasn't one for this key already! */
2736 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply 2775 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
2737 (GNUNET_TIME_UNIT_SECONDS, 30), 2776 (GNUNET_TIME_UNIT_SECONDS, 30),
2738 &remove_recent_find_peer, recent_hash); 2777 &remove_recent_find_peer, recent_hash);
2739 } 2778 }
2740 else 2779 else
2741 { 2780 {
2742 GNUNET_free (recent_hash); 2781 GNUNET_free (recent_hash);
2743#if DEBUG_DHT 2782#if DEBUG_DHT
2744 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2783 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2745 "Received duplicate find peer request too soon!\n"); 2784 "Received duplicate find peer request too soon!\n");
2746#endif 2785#endif
2747 } 2786 }
2748 2787
2749 /* Simplistic find_peer functionality, always return our hello */ 2788 /* Simplistic find_peer functionality, always return our hello */
2750 hello_size = ntohs (my_hello->size); 2789 hello_size = ntohs (my_hello->size);
2751 tsize = hello_size + sizeof (struct GNUNET_MessageHeader); 2790 tsize = hello_size + sizeof (struct GNUNET_MessageHeader);
2752 2791
2753 if (tsize >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 2792 if (tsize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
2754 { 2793 {
2755 GNUNET_break_op (0); 2794 GNUNET_break_op (0);
2756 GNUNET_free_non_null (other_hello); 2795 GNUNET_free_non_null (other_hello);
2757 return; 2796 return;
2758 } 2797 }
2759 2798
2760 find_peer_result = GNUNET_malloc (tsize); 2799 find_peer_result = GNUNET_malloc (tsize);
2761 find_peer_result->type = htons (GNUNET_MESSAGE_TYPE_DHT_FIND_PEER_RESULT); 2800 find_peer_result->type = htons (GNUNET_MESSAGE_TYPE_DHT_FIND_PEER_RESULT);
@@ -2771,27 +2810,28 @@ handle_dht_find_peer (const struct GNUNET_MessageHeader *find_msg,
2771 memcpy (new_msg_ctx, msg_ctx, sizeof (struct DHT_MessageContext)); 2810 memcpy (new_msg_ctx, msg_ctx, sizeof (struct DHT_MessageContext));
2772 new_msg_ctx->peer = &my_identity; 2811 new_msg_ctx->peer = &my_identity;
2773 new_msg_ctx->bloom = 2812 new_msg_ctx->bloom =
2774 GNUNET_CONTAINER_bloomfilter_init (NULL, DHT_BLOOM_SIZE, DHT_BLOOM_K); 2813 GNUNET_CONTAINER_bloomfilter_init (NULL, DHT_BLOOM_SIZE, DHT_BLOOM_K);
2775 new_msg_ctx->hop_count = 0; 2814 new_msg_ctx->hop_count = 0;
2776 new_msg_ctx->importance = DHT_DEFAULT_P2P_IMPORTANCE + 2; /* Make find peer requests a higher priority */ 2815 new_msg_ctx->importance = DHT_DEFAULT_P2P_IMPORTANCE + 2; /* Make find peer requests a higher priority */
2777 new_msg_ctx->timeout = DHT_DEFAULT_P2P_TIMEOUT; 2816 new_msg_ctx->timeout = DHT_DEFAULT_P2P_TIMEOUT;
2778 increment_stats (STAT_FIND_PEER_ANSWER); 2817 increment_stats (STAT_FIND_PEER_ANSWER);
2779 if (GNUNET_DHT_RO_RECORD_ROUTE == (msg_ctx->msg_options & GNUNET_DHT_RO_RECORD_ROUTE)) 2818 if (GNUNET_DHT_RO_RECORD_ROUTE ==
2780 { 2819 (msg_ctx->msg_options & GNUNET_DHT_RO_RECORD_ROUTE))
2781 new_msg_ctx->msg_options = GNUNET_DHT_RO_RECORD_ROUTE; 2820 {
2782 new_msg_ctx->path_history_len = msg_ctx->path_history_len; 2821 new_msg_ctx->msg_options = GNUNET_DHT_RO_RECORD_ROUTE;
2783 /* Assign to previous msg_ctx path history, caller should free after our return */ 2822 new_msg_ctx->path_history_len = msg_ctx->path_history_len;
2784 new_msg_ctx->path_history = msg_ctx->path_history; 2823 /* Assign to previous msg_ctx path history, caller should free after our return */
2785 } 2824 new_msg_ctx->path_history = msg_ctx->path_history;
2825 }
2786 route_result_message (find_peer_result, new_msg_ctx); 2826 route_result_message (find_peer_result, new_msg_ctx);
2787 GNUNET_free (new_msg_ctx); 2827 GNUNET_free (new_msg_ctx);
2788#if DEBUG_DHT_ROUTING 2828#if DEBUG_DHT_ROUTING
2789 if ((debug_routes) && (dhtlog_handle != NULL)) 2829 if ((debug_routes) && (dhtlog_handle != NULL))
2790 { 2830 {
2791 dhtlog_handle->insert_query (NULL, msg_ctx->unique_id, DHTLOG_FIND_PEER, 2831 dhtlog_handle->insert_query (NULL, msg_ctx->unique_id, DHTLOG_FIND_PEER,
2792 msg_ctx->hop_count, GNUNET_YES, 2832 msg_ctx->hop_count, GNUNET_YES,
2793 &my_identity, &msg_ctx->key); 2833 &my_identity, &msg_ctx->key);
2794 } 2834 }
2795#endif 2835#endif
2796 GNUNET_free_non_null (other_hello); 2836 GNUNET_free_non_null (other_hello);
2797 GNUNET_free (find_peer_result); 2837 GNUNET_free (find_peer_result);
@@ -2834,58 +2874,58 @@ handle_dht_put (const struct GNUNET_MessageHeader *msg,
2834 put_type = (enum GNUNET_BLOCK_Type) ntohl (put_msg->type); 2874 put_type = (enum GNUNET_BLOCK_Type) ntohl (put_msg->type);
2835#if HAVE_MALICIOUS 2875#if HAVE_MALICIOUS
2836 if (put_type == GNUNET_BLOCK_DHT_MALICIOUS_MESSAGE_TYPE) 2876 if (put_type == GNUNET_BLOCK_DHT_MALICIOUS_MESSAGE_TYPE)
2837 { 2877 {
2838#if DEBUG_DHT_ROUTING 2878#if DEBUG_DHT_ROUTING
2839 if ((debug_routes_extended) && (dhtlog_handle != NULL)) 2879 if ((debug_routes_extended) && (dhtlog_handle != NULL))
2840 { 2880 {
2841 /** Log routes that die due to high load! */ 2881 /** Log routes that die due to high load! */
2842 dhtlog_handle->insert_route (NULL, msg_ctx->unique_id, DHTLOG_ROUTE, 2882 dhtlog_handle->insert_route (NULL, msg_ctx->unique_id, DHTLOG_ROUTE,
2843 msg_ctx->hop_count, GNUNET_SYSERR, 2883 msg_ctx->hop_count, GNUNET_SYSERR,
2844 &my_identity, &msg_ctx->key, 2884 &my_identity, &msg_ctx->key,
2845 msg_ctx->peer, NULL); 2885 msg_ctx->peer, NULL);
2846 }
2847#endif
2848 return;
2849 } 2886 }
2850#endif 2887#endif
2888 return;
2889 }
2890#endif
2851 data_size = 2891 data_size =
2852 ntohs (put_msg->header.size) - sizeof (struct GNUNET_DHT_PutMessage); 2892 ntohs (put_msg->header.size) - sizeof (struct GNUNET_DHT_PutMessage);
2853 ret = 2893 ret =
2854 GNUNET_BLOCK_get_key (block_context, put_type, &put_msg[1], data_size, 2894 GNUNET_BLOCK_get_key (block_context, put_type, &put_msg[1], data_size,
2855 &key); 2895 &key);
2856 if (GNUNET_NO == ret) 2896 if (GNUNET_NO == ret)
2857 { 2897 {
2858#if DEBUG_DHT_ROUTING 2898#if DEBUG_DHT_ROUTING
2859 if ((debug_routes_extended) && (dhtlog_handle != NULL)) 2899 if ((debug_routes_extended) && (dhtlog_handle != NULL))
2860 { 2900 {
2861 dhtlog_handle->insert_route (NULL, msg_ctx->unique_id, DHTLOG_ROUTE, 2901 dhtlog_handle->insert_route (NULL, msg_ctx->unique_id, DHTLOG_ROUTE,
2862 msg_ctx->hop_count, GNUNET_SYSERR, 2902 msg_ctx->hop_count, GNUNET_SYSERR,
2863 &my_identity, &msg_ctx->key, 2903 &my_identity, &msg_ctx->key,
2864 msg_ctx->peer, NULL); 2904 msg_ctx->peer, NULL);
2865 }
2866#endif
2867 /* invalid reply */
2868 GNUNET_break_op (0);
2869 return;
2870 } 2905 }
2906#endif
2907 /* invalid reply */
2908 GNUNET_break_op (0);
2909 return;
2910 }
2871 if ((GNUNET_YES == ret) && 2911 if ((GNUNET_YES == ret) &&
2872 (0 != memcmp (&key, &msg_ctx->key, sizeof (GNUNET_HashCode)))) 2912 (0 != memcmp (&key, &msg_ctx->key, sizeof (GNUNET_HashCode))))
2873 { 2913 {
2874#if DEBUG_DHT_ROUTING 2914#if DEBUG_DHT_ROUTING
2875 if ((debug_routes_extended) && (dhtlog_handle != NULL)) 2915 if ((debug_routes_extended) && (dhtlog_handle != NULL))
2876 { 2916 {
2877 dhtlog_handle->insert_route (NULL, msg_ctx->unique_id, DHTLOG_ROUTE, 2917 dhtlog_handle->insert_route (NULL, msg_ctx->unique_id, DHTLOG_ROUTE,
2878 msg_ctx->hop_count, GNUNET_SYSERR, 2918 msg_ctx->hop_count, GNUNET_SYSERR,
2879 &my_identity, &msg_ctx->key, 2919 &my_identity, &msg_ctx->key,
2880 msg_ctx->peer, NULL); 2920 msg_ctx->peer, NULL);
2881 }
2882#endif
2883 /* invalid wrapper: key mismatch! */
2884 GNUNET_break_op (0);
2885 return;
2886 } 2921 }
2922#endif
2923 /* invalid wrapper: key mismatch! */
2924 GNUNET_break_op (0);
2925 return;
2926 }
2887 /* ret == GNUNET_SYSERR means that there is no known relationship between 2927 /* ret == GNUNET_SYSERR means that there is no known relationship between
2888 data and the key, so we cannot check it */ 2928 * data and the key, so we cannot check it */
2889#if DEBUG_DHT 2929#if DEBUG_DHT
2890 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2930 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2891 "`%s:%s': Received `%s' request (inserting data!), message type %d, key %s, uid %llu\n", 2931 "`%s:%s': Received `%s' request (inserting data!), message type %d, key %s, uid %llu\n",
@@ -2894,21 +2934,21 @@ handle_dht_put (const struct GNUNET_MessageHeader *msg,
2894#endif 2934#endif
2895#if DEBUG_DHT_ROUTING 2935#if DEBUG_DHT_ROUTING
2896 if (msg_ctx->hop_count == 0) /* Locally initiated request */ 2936 if (msg_ctx->hop_count == 0) /* Locally initiated request */
2937 {
2938 if ((debug_routes) && (dhtlog_handle != NULL))
2897 { 2939 {
2898 if ((debug_routes) && (dhtlog_handle != NULL)) 2940 dhtlog_handle->insert_query (NULL, msg_ctx->unique_id, DHTLOG_PUT,
2899 { 2941 msg_ctx->hop_count, GNUNET_NO,
2900 dhtlog_handle->insert_query (NULL, msg_ctx->unique_id, DHTLOG_PUT, 2942 &my_identity, &msg_ctx->key);
2901 msg_ctx->hop_count, GNUNET_NO,
2902 &my_identity, &msg_ctx->key);
2903 }
2904 } 2943 }
2944 }
2905#endif 2945#endif
2906 2946
2907 if (msg_ctx->closest != GNUNET_YES) 2947 if (msg_ctx->closest != GNUNET_YES)
2908 { 2948 {
2909 route_message (msg, msg_ctx); 2949 route_message (msg, msg_ctx);
2910 return; 2950 return;
2911 } 2951 }
2912 2952
2913#if DEBUG_DHT 2953#if DEBUG_DHT
2914 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2954 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -2919,54 +2959,57 @@ handle_dht_put (const struct GNUNET_MessageHeader *msg,
2919 2959
2920#if DEBUG_DHT_ROUTING 2960#if DEBUG_DHT_ROUTING
2921 if ((debug_routes_extended) && (dhtlog_handle != NULL)) 2961 if ((debug_routes_extended) && (dhtlog_handle != NULL))
2922 { 2962 {
2923 dhtlog_handle->insert_route (NULL, msg_ctx->unique_id, DHTLOG_ROUTE, 2963 dhtlog_handle->insert_route (NULL, msg_ctx->unique_id, DHTLOG_ROUTE,
2924 msg_ctx->hop_count, GNUNET_YES, 2964 msg_ctx->hop_count, GNUNET_YES,
2925 &my_identity, &msg_ctx->key, msg_ctx->peer, 2965 &my_identity, &msg_ctx->key, msg_ctx->peer,
2926 NULL); 2966 NULL);
2927 } 2967 }
2928 2968
2929 if ((debug_routes) && (dhtlog_handle != NULL)) 2969 if ((debug_routes) && (dhtlog_handle != NULL))
2930 { 2970 {
2931 dhtlog_handle->insert_query (NULL, msg_ctx->unique_id, DHTLOG_PUT, 2971 dhtlog_handle->insert_query (NULL, msg_ctx->unique_id, DHTLOG_PUT,
2932 msg_ctx->hop_count, GNUNET_YES, 2972 msg_ctx->hop_count, GNUNET_YES,
2933 &my_identity, &msg_ctx->key); 2973 &my_identity, &msg_ctx->key);
2934 } 2974 }
2935#endif 2975#endif
2936 2976
2937 increment_stats (STAT_PUTS_INSERTED); 2977 increment_stats (STAT_PUTS_INSERTED);
2938 if (datacache != NULL) 2978 if (datacache != NULL)
2939 { 2979 {
2940 /* Put size is actual data size plus struct overhead plus path length (if any) */ 2980 /* Put size is actual data size plus struct overhead plus path length (if any) */
2941 put_size = data_size + sizeof(struct DHTPutEntry) + (msg_ctx->path_history_len * sizeof(struct GNUNET_PeerIdentity)); 2981 put_size =
2942 put_entry = GNUNET_malloc(put_size); 2982 data_size + sizeof (struct DHTPutEntry) +
2943 put_entry->data_size = data_size; 2983 (msg_ctx->path_history_len * sizeof (struct GNUNET_PeerIdentity));
2944 put_entry->path_length = msg_ctx->path_history_len; 2984 put_entry = GNUNET_malloc (put_size);
2945 /* Copy data to end of put entry */ 2985 put_entry->data_size = data_size;
2946 memcpy(&put_entry[1], &put_msg[1], data_size); 2986 put_entry->path_length = msg_ctx->path_history_len;
2947 if (msg_ctx->path_history_len > 0) 2987 /* Copy data to end of put entry */
2948 { 2988 memcpy (&put_entry[1], &put_msg[1], data_size);
2949 /* Copy path after data */ 2989 if (msg_ctx->path_history_len > 0)
2950 path_offset = (char *)&put_entry[1]; 2990 {
2951 path_offset += data_size; 2991 /* Copy path after data */
2952 memcpy(path_offset, msg_ctx->path_history, msg_ctx->path_history_len * sizeof(struct GNUNET_PeerIdentity)); 2992 path_offset = (char *) &put_entry[1];
2953 } 2993 path_offset += data_size;
2954 2994 memcpy (path_offset, msg_ctx->path_history,
2955 ret = GNUNET_DATACACHE_put (datacache, &msg_ctx->key, put_size, 2995 msg_ctx->path_history_len * sizeof (struct GNUNET_PeerIdentity));
2956 (const char *) put_entry, put_type, 2996 }
2957 GNUNET_TIME_absolute_ntoh 2997
2958 (put_msg->expiration)); 2998 ret = GNUNET_DATACACHE_put (datacache, &msg_ctx->key, put_size,
2959 GNUNET_free (put_entry); 2999 (const char *) put_entry, put_type,
2960 3000 GNUNET_TIME_absolute_ntoh
2961 if ((ret == GNUNET_YES) && (do_republish == GNUNET_YES)) 3001 (put_msg->expiration));
2962 { 3002 GNUNET_free (put_entry);
2963 put_context = GNUNET_malloc (sizeof (struct RepublishContext)); 3003
2964 memcpy (&put_context->key, &msg_ctx->key, sizeof (GNUNET_HashCode)); 3004 if ((ret == GNUNET_YES) && (do_republish == GNUNET_YES))
2965 put_context->type = put_type; 3005 {
2966 GNUNET_SCHEDULER_add_delayed (dht_republish_frequency, 3006 put_context = GNUNET_malloc (sizeof (struct RepublishContext));
2967 &republish_content, put_context); 3007 memcpy (&put_context->key, &msg_ctx->key, sizeof (GNUNET_HashCode));
2968 } 3008 put_context->type = put_type;
2969 } 3009 GNUNET_SCHEDULER_add_delayed (dht_republish_frequency,
3010 &republish_content, put_context);
3011 }
3012 }
2970 else 3013 else
2971 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3014 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2972 "`%s:%s': %s request received, but have no datacache!\n", 3015 "`%s:%s': %s request received, but have no datacache!\n",
@@ -3027,70 +3070,75 @@ get_forward_count (unsigned int hop_count, size_t target_replication)
3027 * but then only send to 1 or 0 peers based strictly on the number of hops. 3070 * but then only send to 1 or 0 peers based strictly on the number of hops.
3028 */ 3071 */
3029 if (strict_kademlia == GNUNET_YES) 3072 if (strict_kademlia == GNUNET_YES)
3030 { 3073 {
3031 if (hop_count == 0) 3074 if (hop_count == 0)
3032 return kademlia_replication; 3075 return kademlia_replication;
3033 else if (hop_count < max_hops) 3076 else if (hop_count < max_hops)
3034 return 1; 3077 return 1;
3035 else 3078 else
3036 return 0; 3079 return 0;
3037 } 3080 }
3038 3081
3039 /* FIXME: the smaller we think the network is the more lenient we should be for 3082 /* FIXME: the smaller we think the network is the more lenient we should be for
3040 * routing right? The estimation below only works if we think we have reasonably 3083 * routing right? The estimation below only works if we think we have reasonably
3041 * full routing tables, which for our RR topologies may not be the case! 3084 * full routing tables, which for our RR topologies may not be the case!
3042 */ 3085 */
3043 if (hop_count > max_hops) 3086 if (hop_count > max_hops)
3044 { 3087 {
3045#if DEBUG_DHT 3088#if DEBUG_DHT
3046 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3089 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3047 "`%s:%s': Hop count too high (est %d, lowest %d), NOT Forwarding request\n", 3090 "`%s:%s': Hop count too high (est %d, lowest %d), NOT Forwarding request\n",
3048 my_short_id, "DHT", estimate_diameter (), lowest_bucket); 3091 my_short_id, "DHT", estimate_diameter (), lowest_bucket);
3049#endif 3092#endif
3050 /* FIXME: does this work as intended, isn't the decision to forward or not made based on closeness as well? */ 3093 /* FIXME: does this work as intended, isn't the decision to forward or not made based on closeness as well? */
3051 if (GNUNET_YES == paper_forwarding) /* Once we have reached our ideal number of hops, don't stop forwarding! */ 3094 if (GNUNET_YES == paper_forwarding) /* Once we have reached our ideal number of hops, don't stop forwarding! */
3052 { 3095 {
3053 return 1; 3096 return 1;
3054 }
3055
3056 return 0;
3057 } 3097 }
3058 3098
3099 return 0;
3100 }
3101
3059 if (GNUNET_YES == paper_forwarding) 3102 if (GNUNET_YES == paper_forwarding)
3103 {
3104 /* FIXME: re-run replication trials with this formula */
3105 target_value = 1 + (target_replication - 1.0) / (diameter
3106 +
3107 ((float)
3108 (target_replication -
3109 1.0) * hop_count));
3110 /* Set forward count to floor of target_value */
3111 forward_count = (unsigned int) target_value;
3112 /* Subtract forward_count (floor) from target_value (yields value between 0 and 1) */
3113 target_value = target_value - forward_count;
3114 random_value = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG,
3115 UINT32_MAX);
3116
3117 if (random_value < (target_value * UINT32_MAX))
3118 forward_count += 1;
3119 }
3120 else
3121 {
3122 random_value = 0;
3123 forward_count = 1;
3124 target_value = target_replication / (diameter
3125 +
3126 ((float) target_replication *
3127 hop_count));
3128 if (target_value > 1)
3060 { 3129 {
3061 /* FIXME: re-run replication trials with this formula */
3062 target_value = 1 + (target_replication - 1.0) / (diameter
3063 + ((float) (target_replication - 1.0) * hop_count));
3064 /* Set forward count to floor of target_value */ 3130 /* Set forward count to floor of target_value */
3065 forward_count = (unsigned int) target_value; 3131 forward_count = (unsigned int) target_value;
3066 /* Subtract forward_count (floor) from target_value (yields value between 0 and 1) */ 3132 /* Subtract forward_count (floor) from target_value (yields value between 0 and 1) */
3067 target_value = target_value - forward_count; 3133 target_value = target_value - forward_count;
3068 random_value = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_STRONG,
3069 UINT32_MAX);
3070
3071 if (random_value < (target_value * UINT32_MAX))
3072 forward_count += 1;
3073 } 3134 }
3074 else 3135 else
3075 { 3136 random_value = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG,
3076 random_value = 0; 3137 UINT32_MAX);
3077 forward_count = 1;
3078 target_value = target_replication / (diameter
3079 + ((float) target_replication * hop_count));
3080 if (target_value > 1)
3081 {
3082 /* Set forward count to floor of target_value */
3083 forward_count = (unsigned int) target_value;
3084 /* Subtract forward_count (floor) from target_value (yields value between 0 and 1) */
3085 target_value = target_value - forward_count;
3086 }
3087 else
3088 random_value = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_STRONG,
3089 UINT32_MAX);
3090 3138
3091 if (random_value < (target_value * UINT32_MAX)) 3139 if (random_value < (target_value * UINT32_MAX))
3092 forward_count += 1; 3140 forward_count += 1;
3093 } 3141 }
3094 3142
3095 return forward_count; 3143 return forward_count;
3096} 3144}
@@ -3127,28 +3175,27 @@ am_closest_peer (const GNUNET_HashCode * target,
3127 pos = k_buckets[bucket_num].head; 3175 pos = k_buckets[bucket_num].head;
3128 count = 0; 3176 count = 0;
3129 while ((pos != NULL) && (count < bucket_size)) 3177 while ((pos != NULL) && (count < bucket_size))
3178 {
3179 if ((bloom != NULL)
3180 && (GNUNET_YES ==
3181 GNUNET_CONTAINER_bloomfilter_test (bloom, &pos->id.hashPubKey)))
3130 { 3182 {
3131 if ((bloom != NULL) 3183 pos = pos->next;
3132 && (GNUNET_YES == 3184 continue; /* Skip already checked entries */
3133 GNUNET_CONTAINER_bloomfilter_test (bloom, &pos->id.hashPubKey))) 3185 }
3134 {
3135 pos = pos->next;
3136 continue; /* Skip already checked entries */
3137 }
3138 3186
3139 other_bits = 3187 other_bits = GNUNET_CRYPTO_hash_matching_bits (&pos->id.hashPubKey, target);
3140 GNUNET_CRYPTO_hash_matching_bits (&pos->id.hashPubKey, target); 3188 if (other_bits > bits)
3141 if (other_bits > bits) 3189 return GNUNET_NO;
3190 else if (other_bits == bits) /* We match the same number of bits */
3191 {
3192 if (strict_kademlia != GNUNET_YES) /* Return that we at as close as any other peer */
3193 return GNUNET_YES;
3194 else if (distance (&pos->id.hashPubKey, target) < my_distance) /* Check all known peers, only return if we are the true closest */
3142 return GNUNET_NO; 3195 return GNUNET_NO;
3143 else if (other_bits == bits) /* We match the same number of bits */
3144 {
3145 if (strict_kademlia != GNUNET_YES) /* Return that we at as close as any other peer */
3146 return GNUNET_YES;
3147 else if (distance (&pos->id.hashPubKey, target) < my_distance) /* Check all known peers, only return if we are the true closest */
3148 return GNUNET_NO;
3149 }
3150 pos = pos->next;
3151 } 3196 }
3197 pos = pos->next;
3198 }
3152 3199
3153 /* No peers closer, we are the closest! */ 3200 /* No peers closer, we are the closest! */
3154 return GNUNET_YES; 3201 return GNUNET_YES;
@@ -3188,42 +3235,42 @@ converge_distance (const GNUNET_HashCode * target,
3188 if (converge_modifier > 0) 3235 if (converge_modifier > 0)
3189 temp_modifier = converge_modifier * base_converge_modifier; 3236 temp_modifier = converge_modifier * base_converge_modifier;
3190 else 3237 else
3191 { 3238 {
3192 temp_modifier = base_converge_modifier; 3239 temp_modifier = base_converge_modifier;
3193 base_converge_modifier = 0.0; 3240 base_converge_modifier = 0.0;
3194 } 3241 }
3195 3242
3196 GNUNET_assert (temp_modifier > 0); 3243 GNUNET_assert (temp_modifier > 0);
3197 3244
3198 other_matching_bits = 3245 other_matching_bits =
3199 GNUNET_CRYPTO_hash_matching_bits (target, &peer->id.hashPubKey); 3246 GNUNET_CRYPTO_hash_matching_bits (target, &peer->id.hashPubKey);
3200 3247
3201 switch (converge_option) 3248 switch (converge_option)
3202 { 3249 {
3203 case DHT_CONVERGE_RANDOM: 3250 case DHT_CONVERGE_RANDOM:
3204 return 1; /* Always return 1, choose equally among all peers */ 3251 return 1; /* Always return 1, choose equally among all peers */
3205 case DHT_CONVERGE_LINEAR: 3252 case DHT_CONVERGE_LINEAR:
3206 calc_value = hops * curr_max_hops * temp_modifier; 3253 calc_value = hops * curr_max_hops * temp_modifier;
3207 break; 3254 break;
3208 case DHT_CONVERGE_SQUARE: 3255 case DHT_CONVERGE_SQUARE:
3209 /** 3256 /**
3210 * Simple square based curve. 3257 * Simple square based curve.
3211 */ 3258 */
3212 calc_value = 3259 calc_value =
3213 (sqrt (hops) / sqrt (curr_max_hops)) * (curr_max_hops / 3260 (sqrt (hops) / sqrt (curr_max_hops)) * (curr_max_hops /
3214 (curr_max_hops * 3261 (curr_max_hops *
3215 temp_modifier)); 3262 temp_modifier));
3216 break; 3263 break;
3217 case DHT_CONVERGE_EXPONENTIAL: 3264 case DHT_CONVERGE_EXPONENTIAL:
3218 /** 3265 /**
3219 * Simple exponential curve. 3266 * Simple exponential curve.
3220 */ 3267 */
3221 if (base_converge_modifier > 0) 3268 if (base_converge_modifier > 0)
3222 calc_value = (temp_modifier * hops * hops) / curr_max_hops; 3269 calc_value = (temp_modifier * hops * hops) / curr_max_hops;
3223 else 3270 else
3224 calc_value = (hops * hops) / curr_max_hops; 3271 calc_value = (hops * hops) / curr_max_hops;
3225 break; 3272 break;
3226 case DHT_CONVERGE_BINARY: 3273 case DHT_CONVERGE_BINARY:
3227 /** 3274 /**
3228 * If below the cutoff, route randomly (return 1), 3275 * If below the cutoff, route randomly (return 1),
3229 * If above the cutoff, return the maximum possible 3276 * If above the cutoff, return the maximum possible
@@ -3231,14 +3278,14 @@ converge_distance (const GNUNET_HashCode * target,
3231 * they are sorted.) 3278 * they are sorted.)
3232 */ 3279 */
3233 3280
3234 if (hops >= converge_modifier) /* Past cutoff */ 3281 if (hops >= converge_modifier) /* Past cutoff */
3235 { 3282 {
3236 return ULLONG_MAX; 3283 return ULLONG_MAX;
3237 }
3238 /* Fall through */
3239 default:
3240 return 1;
3241 } 3284 }
3285 /* Fall through */
3286 default:
3287 return 1;
3288 }
3242 3289
3243 /* Take the log (base e) of the number of bits matching the other peer */ 3290 /* Take the log (base e) of the number of bits matching the other peer */
3244 exponent = log (other_matching_bits); 3291 exponent = log (other_matching_bits);
@@ -3253,15 +3300,15 @@ converge_distance (const GNUNET_HashCode * target,
3253 ret = (unsigned long long) pow (other_matching_bits, calc_value); 3300 ret = (unsigned long long) pow (other_matching_bits, calc_value);
3254 if ((errno != 0) || fetestexcept (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | 3301 if ((errno != 0) || fetestexcept (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW |
3255 FE_UNDERFLOW)) 3302 FE_UNDERFLOW))
3256 { 3303 {
3257 if (0 != fetestexcept (FE_OVERFLOW)) 3304 if (0 != fetestexcept (FE_OVERFLOW))
3258 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "FE_OVERFLOW\n"); 3305 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "FE_OVERFLOW\n");
3259 if (0 != fetestexcept (FE_INVALID)) 3306 if (0 != fetestexcept (FE_INVALID))
3260 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "FE_INVALID\n"); 3307 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "FE_INVALID\n");
3261 if (0 != fetestexcept (FE_UNDERFLOW)) 3308 if (0 != fetestexcept (FE_UNDERFLOW))
3262 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "FE_UNDERFLOW\n"); 3309 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "FE_UNDERFLOW\n");
3263 return 0; 3310 return 0;
3264 } 3311 }
3265 else 3312 else
3266 return ret; 3313 return ret;
3267} 3314}
@@ -3322,6 +3369,7 @@ select_peer (const GNUNET_HashCode * target,
3322 unsigned long long temp_converge_distance; 3369 unsigned long long temp_converge_distance;
3323 unsigned long long total_distance; 3370 unsigned long long total_distance;
3324 unsigned long long selected; 3371 unsigned long long selected;
3372
3325#if DEBUG_DHT > 1 3373#if DEBUG_DHT > 1
3326 unsigned long long stats_total_distance; 3374 unsigned long long stats_total_distance;
3327 double sum; 3375 double sum;
@@ -3334,44 +3382,42 @@ select_peer (const GNUNET_HashCode * target,
3334 total_distance = 0; 3382 total_distance = 0;
3335 /** If we are doing kademlia routing, or converge is binary (saves some cycles) */ 3383 /** If we are doing kademlia routing, or converge is binary (saves some cycles) */
3336 if ((strict_kademlia == GNUNET_YES) || 3384 if ((strict_kademlia == GNUNET_YES) ||
3337 ((converge_option == DHT_CONVERGE_BINARY) 3385 ((converge_option == DHT_CONVERGE_BINARY) && (hops >= converge_modifier)))
3338 && (hops >= converge_modifier))) 3386 {
3387 largest_distance = 0;
3388 chosen = NULL;
3389 for (bc = lowest_bucket; bc < MAX_BUCKETS; bc++)
3339 { 3390 {
3340 largest_distance = 0; 3391 pos = k_buckets[bc].head;
3341 chosen = NULL; 3392 count = 0;
3342 for (bc = lowest_bucket; bc < MAX_BUCKETS; bc++) 3393 while ((pos != NULL) && (count < bucket_size))
3394 {
3395 /* If we are doing strict Kademlia routing, then checking the bloomfilter is basically cheating! */
3396 if (GNUNET_NO ==
3397 GNUNET_CONTAINER_bloomfilter_test (bloom, &pos->id.hashPubKey))
3343 { 3398 {
3344 pos = k_buckets[bc].head; 3399 distance = inverse_distance (target, &pos->id.hashPubKey);
3345 count = 0; 3400 if (distance > largest_distance)
3346 while ((pos != NULL) && (count < bucket_size)) 3401 {
3347 { 3402 chosen = pos;
3348 /* If we are doing strict Kademlia routing, then checking the bloomfilter is basically cheating! */ 3403 largest_distance = distance;
3349 if (GNUNET_NO == 3404 }
3350 GNUNET_CONTAINER_bloomfilter_test (bloom,
3351 &pos->id.hashPubKey))
3352 {
3353 distance = inverse_distance (target, &pos->id.hashPubKey);
3354 if (distance > largest_distance)
3355 {
3356 chosen = pos;
3357 largest_distance = distance;
3358 }
3359 }
3360 count++;
3361 pos = pos->next;
3362 }
3363 } 3405 }
3406 count++;
3407 pos = pos->next;
3408 }
3409 }
3364 3410
3365 if ((largest_distance > 0) && (chosen != NULL)) 3411 if ((largest_distance > 0) && (chosen != NULL))
3366 { 3412 {
3367 GNUNET_CONTAINER_bloomfilter_add (bloom, &chosen->id.hashPubKey); 3413 GNUNET_CONTAINER_bloomfilter_add (bloom, &chosen->id.hashPubKey);
3368 return chosen; 3414 return chosen;
3369 }
3370 else
3371 {
3372 return NULL;
3373 }
3374 } 3415 }
3416 else
3417 {
3418 return NULL;
3419 }
3420 }
3375 3421
3376 /* GNUnet-style */ 3422 /* GNUnet-style */
3377 total_distance = 0; 3423 total_distance = 0;
@@ -3388,21 +3434,21 @@ select_peer (const GNUNET_HashCode * target,
3388 memset (sorted_closest, 0, sizeof (sorted_closest)); 3434 memset (sorted_closest, 0, sizeof (sorted_closest));
3389 /* Put any peers in the closest bucket in the sorting array */ 3435 /* Put any peers in the closest bucket in the sorting array */
3390 while ((pos != NULL) && (count < bucket_size)) 3436 while ((pos != NULL) && (count < bucket_size))
3437 {
3438 if (GNUNET_YES ==
3439 GNUNET_CONTAINER_bloomfilter_test (bloom, &pos->id.hashPubKey))
3391 { 3440 {
3392 if (GNUNET_YES ==
3393 GNUNET_CONTAINER_bloomfilter_test (bloom, &pos->id.hashPubKey))
3394 {
3395 count++;
3396 pos = pos->next;
3397 continue; /* Ignore bloomfiltered peers */
3398 }
3399 pos->matching_bits =
3400 GNUNET_CRYPTO_hash_matching_bits (&pos->id.hashPubKey, target);
3401 sorted_closest[offset] = pos;
3402 pos = pos->next;
3403 offset++;
3404 count++; 3441 count++;
3442 pos = pos->next;
3443 continue; /* Ignore bloomfiltered peers */
3405 } 3444 }
3445 pos->matching_bits =
3446 GNUNET_CRYPTO_hash_matching_bits (&pos->id.hashPubKey, target);
3447 sorted_closest[offset] = pos;
3448 pos = pos->next;
3449 offset++;
3450 count++;
3451 }
3406 3452
3407 /* Sort the peers in descending order */ 3453 /* Sort the peers in descending order */
3408 qsort (&sorted_closest[0], offset, sizeof (struct PeerInfo *), 3454 qsort (&sorted_closest[0], offset, sizeof (struct PeerInfo *),
@@ -3410,73 +3456,72 @@ select_peer (const GNUNET_HashCode * target,
3410 3456
3411 /* Put the sorted closest peers into the possible bins first, in case of overflow. */ 3457 /* Put the sorted closest peers into the possible bins first, in case of overflow. */
3412 for (i = 0; i < offset; i++) 3458 for (i = 0; i < offset; i++)
3413 { 3459 {
3414 temp_converge_distance = 3460 temp_converge_distance =
3415 converge_distance (target, sorted_closest[i], hops); 3461 converge_distance (target, sorted_closest[i], hops);
3416 if (GNUNET_YES == 3462 if (GNUNET_YES ==
3417 GNUNET_CONTAINER_bloomfilter_test (bloom, 3463 GNUNET_CONTAINER_bloomfilter_test (bloom,
3418 &sorted_closest[i]->id. 3464 &sorted_closest[i]->id.hashPubKey))
3419 hashPubKey)) 3465 break; /* Ignore bloomfiltered peers */
3420 break; /* Ignore bloomfiltered peers */ 3466 if (total_distance + temp_converge_distance > total_distance) /* Handle largest case and overflow */
3421 if (total_distance + temp_converge_distance > total_distance) /* Handle largest case and overflow */ 3467 total_distance += temp_converge_distance;
3422 total_distance += temp_converge_distance; 3468 else
3423 else 3469 break; /* overflow case */
3424 break; /* overflow case */ 3470 }
3425 }
3426 3471
3427 /* Now handle peers in lower buckets (matches same # of bits as target) */ 3472 /* Now handle peers in lower buckets (matches same # of bits as target) */
3428 for (bc = lowest_bucket; bc < closest_bucket; bc++) 3473 for (bc = lowest_bucket; bc < closest_bucket; bc++)
3474 {
3475 pos = k_buckets[bc].head;
3476 count = 0;
3477 while ((pos != NULL) && (count < bucket_size))
3429 { 3478 {
3430 pos = k_buckets[bc].head; 3479 if (GNUNET_YES ==
3431 count = 0; 3480 GNUNET_CONTAINER_bloomfilter_test (bloom, &pos->id.hashPubKey))
3432 while ((pos != NULL) && (count < bucket_size)) 3481 {
3433 { 3482 count++;
3434 if (GNUNET_YES == 3483 pos = pos->next;
3435 GNUNET_CONTAINER_bloomfilter_test (bloom, &pos->id.hashPubKey)) 3484 continue; /* Ignore bloomfiltered peers */
3436 { 3485 }
3437 count++; 3486 temp_converge_distance = converge_distance (target, pos, hops);
3438 pos = pos->next; 3487 if (total_distance + temp_converge_distance > total_distance) /* Handle largest case and overflow */
3439 continue; /* Ignore bloomfiltered peers */ 3488 total_distance += temp_converge_distance;
3440 } 3489 else
3441 temp_converge_distance = converge_distance (target, pos, hops); 3490 break; /* overflow case */
3442 if (total_distance + temp_converge_distance > total_distance) /* Handle largest case and overflow */ 3491 pos = pos->next;
3443 total_distance += temp_converge_distance; 3492 count++;
3444 else
3445 break; /* overflow case */
3446 pos = pos->next;
3447 count++;
3448 }
3449 } 3493 }
3494 }
3450 3495
3451 /* Now handle all the further away peers */ 3496 /* Now handle all the further away peers */
3452 for (bc = closest_bucket + 1; bc < MAX_BUCKETS; bc++) 3497 for (bc = closest_bucket + 1; bc < MAX_BUCKETS; bc++)
3498 {
3499 pos = k_buckets[bc].head;
3500 count = 0;
3501 while ((pos != NULL) && (count < bucket_size))
3453 { 3502 {
3454 pos = k_buckets[bc].head; 3503 if (GNUNET_YES ==
3455 count = 0; 3504 GNUNET_CONTAINER_bloomfilter_test (bloom, &pos->id.hashPubKey))
3456 while ((pos != NULL) && (count < bucket_size)) 3505 {
3457 { 3506 count++;
3458 if (GNUNET_YES == 3507 pos = pos->next;
3459 GNUNET_CONTAINER_bloomfilter_test (bloom, &pos->id.hashPubKey)) 3508 continue; /* Ignore bloomfiltered peers */
3460 { 3509 }
3461 count++; 3510 temp_converge_distance = converge_distance (target, pos, hops);
3462 pos = pos->next; 3511 if (total_distance + temp_converge_distance > total_distance) /* Handle largest case and overflow */
3463 continue; /* Ignore bloomfiltered peers */ 3512 total_distance += temp_converge_distance;
3464 } 3513 else
3465 temp_converge_distance = converge_distance (target, pos, hops); 3514 break; /* overflow case */
3466 if (total_distance + temp_converge_distance > total_distance) /* Handle largest case and overflow */ 3515 pos = pos->next;
3467 total_distance += temp_converge_distance; 3516 count++;
3468 else
3469 break; /* overflow case */
3470 pos = pos->next;
3471 count++;
3472 }
3473 } 3517 }
3518 }
3474 3519
3475 if (total_distance == 0) /* No peers to select from! */ 3520 if (total_distance == 0) /* No peers to select from! */
3476 { 3521 {
3477 increment_stats ("# failed to select peer"); 3522 increment_stats ("# failed to select peer");
3478 return NULL; 3523 return NULL;
3479 } 3524 }
3480 3525
3481#if DEBUG_DHT_ROUTING > 1 3526#if DEBUG_DHT_ROUTING > 1
3482 sum = 0.0; 3527 sum = 0.0;
@@ -3484,164 +3529,160 @@ select_peer (const GNUNET_HashCode * target,
3484 /* Put the sorted closest peers into the possible bins first, in case of overflow. */ 3529 /* Put the sorted closest peers into the possible bins first, in case of overflow. */
3485 stats_total_distance = 0; 3530 stats_total_distance = 0;
3486 for (i = 0; i < offset; i++) 3531 for (i = 0; i < offset; i++)
3532 {
3533 if (GNUNET_YES ==
3534 GNUNET_CONTAINER_bloomfilter_test (bloom,
3535 &sorted_closest[i]->id.hashPubKey))
3536 break; /* Ignore bloomfiltered peers */
3537 temp_converge_distance =
3538 converge_distance (target, sorted_closest[i], hops);
3539 if (stats_total_distance + temp_converge_distance > stats_total_distance) /* Handle largest case and overflow */
3540 stats_total_distance += temp_converge_distance;
3541 else
3542 break; /* overflow case */
3543 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3544 "Choose %d matching bits (%d bits match me) (%.2f percent) converge ret %llu\n",
3545 GNUNET_CRYPTO_hash_matching_bits (&sorted_closest[i]->id.
3546 hashPubKey, target),
3547 GNUNET_CRYPTO_hash_matching_bits (&sorted_closest[i]->id.
3548 hashPubKey,
3549 &my_identity.hashPubKey),
3550 (temp_converge_distance / (double) total_distance) * 100,
3551 temp_converge_distance);
3552 }
3553
3554 /* Now handle peers in lower buckets (matches same # of bits as target) */
3555 for (bc = lowest_bucket; bc < closest_bucket; bc++)
3556 {
3557 pos = k_buckets[bc].head;
3558 count = 0;
3559 while ((pos != NULL) && (count < bucket_size))
3487 { 3560 {
3488 if (GNUNET_YES == 3561 if (GNUNET_YES ==
3489 GNUNET_CONTAINER_bloomfilter_test (bloom, 3562 GNUNET_CONTAINER_bloomfilter_test (bloom, &pos->id.hashPubKey))
3490 &sorted_closest[i]->id. 3563 {
3491 hashPubKey)) 3564 count++;
3492 break; /* Ignore bloomfiltered peers */ 3565 pos = pos->next;
3493 temp_converge_distance = 3566 continue; /* Ignore bloomfiltered peers */
3494 converge_distance (target, sorted_closest[i], hops); 3567 }
3495 if (stats_total_distance + temp_converge_distance > stats_total_distance) /* Handle largest case and overflow */ 3568 temp_converge_distance = converge_distance (target, pos, hops);
3569 if (stats_total_distance + temp_converge_distance > stats_total_distance) /* Handle largest case and overflow */
3496 stats_total_distance += temp_converge_distance; 3570 stats_total_distance += temp_converge_distance;
3497 else 3571 else
3498 break; /* overflow case */ 3572 break; /* overflow case */
3499 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3573 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3500 "Choose %d matching bits (%d bits match me) (%.2f percent) converge ret %llu\n", 3574 "Choose %d matching bits (%d bits match me) (%.2f percent) converge ret %llu\n",
3501 GNUNET_CRYPTO_hash_matching_bits (&sorted_closest[i]->id. 3575 GNUNET_CRYPTO_hash_matching_bits (&pos->id.hashPubKey,
3502 hashPubKey, target), 3576 target),
3503 GNUNET_CRYPTO_hash_matching_bits (&sorted_closest[i]->id. 3577 GNUNET_CRYPTO_hash_matching_bits (&pos->id.hashPubKey,
3504 hashPubKey,
3505 &my_identity.hashPubKey), 3578 &my_identity.hashPubKey),
3506 (temp_converge_distance / (double) total_distance) * 100, 3579 (temp_converge_distance / (double) total_distance) *
3507 temp_converge_distance); 3580 100, temp_converge_distance);
3508 } 3581 pos = pos->next;
3509 3582 count++;
3510 /* Now handle peers in lower buckets (matches same # of bits as target) */
3511 for (bc = lowest_bucket; bc < closest_bucket; bc++)
3512 {
3513 pos = k_buckets[bc].head;
3514 count = 0;
3515 while ((pos != NULL) && (count < bucket_size))
3516 {
3517 if (GNUNET_YES ==
3518 GNUNET_CONTAINER_bloomfilter_test (bloom, &pos->id.hashPubKey))
3519 {
3520 count++;
3521 pos = pos->next;
3522 continue; /* Ignore bloomfiltered peers */
3523 }
3524 temp_converge_distance = converge_distance (target, pos, hops);
3525 if (stats_total_distance + temp_converge_distance > stats_total_distance) /* Handle largest case and overflow */
3526 stats_total_distance += temp_converge_distance;
3527 else
3528 break; /* overflow case */
3529 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3530 "Choose %d matching bits (%d bits match me) (%.2f percent) converge ret %llu\n",
3531 GNUNET_CRYPTO_hash_matching_bits (&pos->id.hashPubKey,
3532 target),
3533 GNUNET_CRYPTO_hash_matching_bits (&pos->id.hashPubKey,
3534 &my_identity.
3535 hashPubKey),
3536 (temp_converge_distance / (double) total_distance) *
3537 100, temp_converge_distance);
3538 pos = pos->next;
3539 count++;
3540 }
3541 } 3583 }
3584 }
3542 3585
3543 /* Now handle all the further away peers */ 3586 /* Now handle all the further away peers */
3544 for (bc = closest_bucket + 1; bc < MAX_BUCKETS; bc++) 3587 for (bc = closest_bucket + 1; bc < MAX_BUCKETS; bc++)
3588 {
3589 pos = k_buckets[bc].head;
3590 count = 0;
3591 while ((pos != NULL) && (count < bucket_size))
3545 { 3592 {
3546 pos = k_buckets[bc].head; 3593 if (GNUNET_YES ==
3547 count = 0; 3594 GNUNET_CONTAINER_bloomfilter_test (bloom, &pos->id.hashPubKey))
3548 while ((pos != NULL) && (count < bucket_size)) 3595 {
3549 { 3596 count++;
3550 if (GNUNET_YES == 3597 pos = pos->next;
3551 GNUNET_CONTAINER_bloomfilter_test (bloom, &pos->id.hashPubKey)) 3598 continue; /* Ignore bloomfiltered peers */
3552 { 3599 }
3553 count++; 3600 temp_converge_distance = converge_distance (target, pos, hops);
3554 pos = pos->next; 3601 if (stats_total_distance + temp_converge_distance > stats_total_distance) /* Handle largest case and overflow */
3555 continue; /* Ignore bloomfiltered peers */ 3602 stats_total_distance += temp_converge_distance;
3556 } 3603 else
3557 temp_converge_distance = converge_distance (target, pos, hops); 3604 break; /* overflow case */
3558 if (stats_total_distance + temp_converge_distance > stats_total_distance) /* Handle largest case and overflow */ 3605 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3559 stats_total_distance += temp_converge_distance; 3606 "Choose %d matching bits (%d bits match me) (%.2f percent) converge ret %llu\n",
3560 else 3607 GNUNET_CRYPTO_hash_matching_bits (&pos->id.hashPubKey,
3561 break; /* overflow case */ 3608 target),
3562 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3609 GNUNET_CRYPTO_hash_matching_bits (&pos->id.hashPubKey,
3563 "Choose %d matching bits (%d bits match me) (%.2f percent) converge ret %llu\n", 3610 &my_identity.hashPubKey),
3564 GNUNET_CRYPTO_hash_matching_bits (&pos->id.hashPubKey, 3611 (temp_converge_distance / (double) total_distance) *
3565 target), 3612 100, temp_converge_distance);
3566 GNUNET_CRYPTO_hash_matching_bits (&pos->id.hashPubKey, 3613 pos = pos->next;
3567 &my_identity. 3614 count++;
3568 hashPubKey),
3569 (temp_converge_distance / (double) total_distance) *
3570 100, temp_converge_distance);
3571 pos = pos->next;
3572 count++;
3573 }
3574 } 3615 }
3616 }
3575 /* END PRINT STATS */ 3617 /* END PRINT STATS */
3576#endif 3618#endif
3577 3619
3578 /* Now actually choose a peer */ 3620 /* Now actually choose a peer */
3579 selected = 3621 selected =
3580 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, total_distance); 3622 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, total_distance);
3581 3623
3582 /* Go over closest sorted peers. */ 3624 /* Go over closest sorted peers. */
3583 for (i = 0; i < offset; i++) 3625 for (i = 0; i < offset; i++)
3584 { 3626 {
3585 if (GNUNET_YES == 3627 if (GNUNET_YES ==
3586 GNUNET_CONTAINER_bloomfilter_test (bloom, 3628 GNUNET_CONTAINER_bloomfilter_test (bloom,
3587 &sorted_closest[i]->id. 3629 &sorted_closest[i]->id.hashPubKey))
3588 hashPubKey)) 3630 break; /* Ignore bloomfiltered peers */
3589 break; /* Ignore bloomfiltered peers */ 3631 temp_converge_distance =
3590 temp_converge_distance =
3591 converge_distance (target, sorted_closest[i], hops); 3632 converge_distance (target, sorted_closest[i], hops);
3592 if (temp_converge_distance >= selected) 3633 if (temp_converge_distance >= selected)
3593 return sorted_closest[i]; 3634 return sorted_closest[i];
3594 else 3635 else
3595 selected -= temp_converge_distance; 3636 selected -= temp_converge_distance;
3596 } 3637 }
3597 3638
3598 /* Now handle peers in lower buckets (matches same # of bits as target) */ 3639 /* Now handle peers in lower buckets (matches same # of bits as target) */
3599 for (bc = lowest_bucket; bc < closest_bucket; bc++) 3640 for (bc = lowest_bucket; bc < closest_bucket; bc++)
3641 {
3642 pos = k_buckets[bc].head;
3643 count = 0;
3644 while ((pos != NULL) && (count < bucket_size))
3600 { 3645 {
3601 pos = k_buckets[bc].head; 3646 if (GNUNET_YES ==
3602 count = 0; 3647 GNUNET_CONTAINER_bloomfilter_test (bloom, &pos->id.hashPubKey))
3603 while ((pos != NULL) && (count < bucket_size)) 3648 {
3604 { 3649 count++;
3605 if (GNUNET_YES == 3650 pos = pos->next;
3606 GNUNET_CONTAINER_bloomfilter_test (bloom, &pos->id.hashPubKey)) 3651 continue; /* Ignore bloomfiltered peers */
3607 { 3652 }
3608 count++; 3653 temp_converge_distance = converge_distance (target, pos, hops);
3609 pos = pos->next; 3654 if (temp_converge_distance >= selected)
3610 continue; /* Ignore bloomfiltered peers */ 3655 return pos;
3611 } 3656 else
3612 temp_converge_distance = converge_distance (target, pos, hops); 3657 selected -= temp_converge_distance;
3613 if (temp_converge_distance >= selected) 3658 pos = pos->next;
3614 return pos; 3659 count++;
3615 else
3616 selected -= temp_converge_distance;
3617 pos = pos->next;
3618 count++;
3619 }
3620 } 3660 }
3661 }
3621 3662
3622 /* Now handle all the further away peers */ 3663 /* Now handle all the further away peers */
3623 for (bc = closest_bucket + 1; bc < MAX_BUCKETS; bc++) 3664 for (bc = closest_bucket + 1; bc < MAX_BUCKETS; bc++)
3665 {
3666 pos = k_buckets[bc].head;
3667 count = 0;
3668 while ((pos != NULL) && (count < bucket_size))
3624 { 3669 {
3625 pos = k_buckets[bc].head; 3670 if (GNUNET_YES ==
3626 count = 0; 3671 GNUNET_CONTAINER_bloomfilter_test (bloom, &pos->id.hashPubKey))
3627 while ((pos != NULL) && (count < bucket_size)) 3672 {
3628 { 3673 count++;
3629 if (GNUNET_YES == 3674 pos = pos->next;
3630 GNUNET_CONTAINER_bloomfilter_test (bloom, &pos->id.hashPubKey)) 3675 continue; /* Ignore bloomfiltered peers */
3631 { 3676 }
3632 count++; 3677 temp_converge_distance = converge_distance (target, pos, hops);
3633 pos = pos->next; 3678 if (temp_converge_distance >= selected)
3634 continue; /* Ignore bloomfiltered peers */ 3679 return pos;
3635 } 3680 else
3636 temp_converge_distance = converge_distance (target, pos, hops); 3681 selected -= temp_converge_distance;
3637 if (temp_converge_distance >= selected) 3682 pos = pos->next;
3638 return pos; 3683 count++;
3639 else
3640 selected -= temp_converge_distance;
3641 pos = pos->next;
3642 count++;
3643 }
3644 } 3684 }
3685 }
3645 3686
3646 increment_stats ("# failed to select peer"); 3687 increment_stats ("# failed to select peer");
3647 return NULL; 3688 return NULL;
@@ -3671,11 +3712,11 @@ remove_recent (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
3671 GNUNET_free (req); 3712 GNUNET_free (req);
3672 3713
3673 /* 3714 /*
3674 if ( (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) && (0 == GNUNET_CONTAINER_multihashmap_size(recent.hashmap)) && (0 == GNUNET_CONTAINER_heap_get_size(recent.minHeap))) 3715 * if ( (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) && (0 == GNUNET_CONTAINER_multihashmap_size(recent.hashmap)) && (0 == GNUNET_CONTAINER_heap_get_size(recent.minHeap)))
3675 { 3716 * {
3676 GNUNET_CONTAINER_multihashmap_destroy(recent.hashmap); 3717 * GNUNET_CONTAINER_multihashmap_destroy(recent.hashmap);
3677 GNUNET_CONTAINER_heap_destroy(recent.minHeap); 3718 * GNUNET_CONTAINER_heap_destroy(recent.minHeap);
3678 } 3719 * }
3679 */ 3720 */
3680} 3721}
3681 3722
@@ -3701,29 +3742,28 @@ cache_response (struct DHT_MessageContext *msg_ctx)
3701 3742
3702#if DELETE_WHEN_FULL 3743#if DELETE_WHEN_FULL
3703 while (current_size >= MAX_OUTSTANDING_FORWARDS) 3744 while (current_size >= MAX_OUTSTANDING_FORWARDS)
3745 {
3746 source_info = GNUNET_CONTAINER_heap_remove_root (forward_list.minHeap);
3747 GNUNET_assert (source_info != NULL);
3748 record = source_info->record;
3749 GNUNET_CONTAINER_DLL_remove (record->head, record->tail, source_info);
3750 if (record->head == NULL) /* No more entries in DLL */
3704 { 3751 {
3705 source_info = GNUNET_CONTAINER_heap_remove_root (forward_list.minHeap); 3752 GNUNET_assert (GNUNET_YES ==
3706 GNUNET_assert (source_info != NULL); 3753 GNUNET_CONTAINER_multihashmap_remove
3707 record = source_info->record; 3754 (forward_list.hashmap, &record->key, record));
3708 GNUNET_CONTAINER_DLL_remove (record->head, record->tail, source_info); 3755 GNUNET_free (record);
3709 if (record->head == NULL) /* No more entries in DLL */
3710 {
3711 GNUNET_assert (GNUNET_YES ==
3712 GNUNET_CONTAINER_multihashmap_remove
3713 (forward_list.hashmap, &record->key, record));
3714 GNUNET_free (record);
3715 }
3716 if (source_info->delete_task != GNUNET_SCHEDULER_NO_TASK)
3717 {
3718 GNUNET_SCHEDULER_cancel (source_info->delete_task);
3719 source_info->delete_task = GNUNET_SCHEDULER_NO_TASK;
3720 }
3721 if (source_info->find_peers_responded != NULL)
3722 GNUNET_CONTAINER_bloomfilter_free (source_info->find_peers_responded);
3723 GNUNET_free (source_info);
3724 current_size =
3725 GNUNET_CONTAINER_multihashmap_size (forward_list.hashmap);
3726 } 3756 }
3757 if (source_info->delete_task != GNUNET_SCHEDULER_NO_TASK)
3758 {
3759 GNUNET_SCHEDULER_cancel (source_info->delete_task);
3760 source_info->delete_task = GNUNET_SCHEDULER_NO_TASK;
3761 }
3762 if (source_info->find_peers_responded != NULL)
3763 GNUNET_CONTAINER_bloomfilter_free (source_info->find_peers_responded);
3764 GNUNET_free (source_info);
3765 current_size = GNUNET_CONTAINER_multihashmap_size (forward_list.hashmap);
3766 }
3727#endif 3767#endif
3728 /** Non-local request and have too many outstanding forwards, discard! */ 3768 /** Non-local request and have too many outstanding forwards, discard! */
3729 if ((current_size >= MAX_OUTSTANDING_FORWARDS) && (msg_ctx->client == NULL)) 3769 if ((current_size >= MAX_OUTSTANDING_FORWARDS) && (msg_ctx->client == NULL))
@@ -3731,54 +3771,54 @@ cache_response (struct DHT_MessageContext *msg_ctx)
3731 3771
3732 now = GNUNET_TIME_absolute_get (); 3772 now = GNUNET_TIME_absolute_get ();
3733 record = 3773 record =
3734 GNUNET_CONTAINER_multihashmap_get (forward_list.hashmap, &msg_ctx->key); 3774 GNUNET_CONTAINER_multihashmap_get (forward_list.hashmap, &msg_ctx->key);
3735 if (record != NULL) /* Already know this request! */ 3775 if (record != NULL) /* Already know this request! */
3736 { 3776 {
3737 pos = record->head; 3777 pos = record->head;
3738 while (pos != NULL) 3778 while (pos != NULL)
3739 { 3779 {
3740 if (0 == 3780 if (0 ==
3741 memcmp (msg_ctx->peer, &pos->source, 3781 memcmp (msg_ctx->peer, &pos->source,
3742 sizeof (struct GNUNET_PeerIdentity))) 3782 sizeof (struct GNUNET_PeerIdentity)))
3743 break; /* Already have this peer in reply list! */ 3783 break; /* Already have this peer in reply list! */
3744 pos = pos->next; 3784 pos = pos->next;
3745 }
3746 if ((pos != NULL) && (pos->client == msg_ctx->client)) /* Seen this already */
3747 {
3748 GNUNET_CONTAINER_heap_update_cost (forward_list.minHeap, pos->hnode,
3749 now.abs_value);
3750 return GNUNET_NO;
3751 }
3752 } 3785 }
3753 else 3786 if ((pos != NULL) && (pos->client == msg_ctx->client)) /* Seen this already */
3754 { 3787 {
3755 record = GNUNET_malloc (sizeof (struct DHTQueryRecord)); 3788 GNUNET_CONTAINER_heap_update_cost (forward_list.minHeap, pos->hnode,
3756 GNUNET_assert (GNUNET_OK == 3789 now.abs_value);
3757 GNUNET_CONTAINER_multihashmap_put (forward_list.hashmap, 3790 return GNUNET_NO;
3758 &msg_ctx->key, record,
3759 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
3760 memcpy (&record->key, &msg_ctx->key, sizeof (GNUNET_HashCode));
3761 } 3791 }
3792 }
3793 else
3794 {
3795 record = GNUNET_malloc (sizeof (struct DHTQueryRecord));
3796 GNUNET_assert (GNUNET_OK ==
3797 GNUNET_CONTAINER_multihashmap_put (forward_list.hashmap,
3798 &msg_ctx->key, record,
3799 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
3800 memcpy (&record->key, &msg_ctx->key, sizeof (GNUNET_HashCode));
3801 }
3762 3802
3763 source_info = GNUNET_malloc (sizeof (struct DHTRouteSource)); 3803 source_info = GNUNET_malloc (sizeof (struct DHTRouteSource));
3764 source_info->record = record; 3804 source_info->record = record;
3765 source_info->delete_task = 3805 source_info->delete_task =
3766 GNUNET_SCHEDULER_add_delayed (DHT_FORWARD_TIMEOUT, &remove_forward_entry, 3806 GNUNET_SCHEDULER_add_delayed (DHT_FORWARD_TIMEOUT, &remove_forward_entry,
3767 source_info); 3807 source_info);
3768 source_info->find_peers_responded = 3808 source_info->find_peers_responded =
3769 GNUNET_CONTAINER_bloomfilter_init (NULL, DHT_BLOOM_SIZE, DHT_BLOOM_K); 3809 GNUNET_CONTAINER_bloomfilter_init (NULL, DHT_BLOOM_SIZE, DHT_BLOOM_K);
3770 memcpy (&source_info->source, msg_ctx->peer, 3810 memcpy (&source_info->source, msg_ctx->peer,
3771 sizeof (struct GNUNET_PeerIdentity)); 3811 sizeof (struct GNUNET_PeerIdentity));
3772 GNUNET_CONTAINER_DLL_insert_after (record->head, record->tail, record->tail, 3812 GNUNET_CONTAINER_DLL_insert_after (record->head, record->tail, record->tail,
3773 source_info); 3813 source_info);
3774 if (msg_ctx->client != NULL) /* For local request, set timeout so high it effectively never gets pushed out */ 3814 if (msg_ctx->client != NULL) /* For local request, set timeout so high it effectively never gets pushed out */
3775 { 3815 {
3776 source_info->client = msg_ctx->client; 3816 source_info->client = msg_ctx->client;
3777 now = GNUNET_TIME_absolute_get_forever (); 3817 now = GNUNET_TIME_absolute_get_forever ();
3778 } 3818 }
3779 source_info->hnode = 3819 source_info->hnode =
3780 GNUNET_CONTAINER_heap_insert (forward_list.minHeap, source_info, 3820 GNUNET_CONTAINER_heap_insert (forward_list.minHeap, source_info,
3781 now.abs_value); 3821 now.abs_value);
3782#if DEBUG_DHT > 1 3822#if DEBUG_DHT > 1
3783 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3823 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3784 "`%s:%s': Created new forward source info for %s uid %llu\n", 3824 "`%s:%s': Created new forward source info for %s uid %llu\n",
@@ -3802,6 +3842,7 @@ route_message (const struct GNUNET_MessageHeader *msg,
3802{ 3842{
3803 int i; 3843 int i;
3804 struct PeerInfo *selected; 3844 struct PeerInfo *selected;
3845
3805#if DEBUG_DHT_ROUTING > 1 3846#if DEBUG_DHT_ROUTING > 1
3806 struct PeerInfo *nearest; 3847 struct PeerInfo *nearest;
3807#endif 3848#endif
@@ -3811,39 +3852,40 @@ route_message (const struct GNUNET_MessageHeader *msg,
3811 GNUNET_HashCode unique_hash; 3852 GNUNET_HashCode unique_hash;
3812 char *stat_forward_count; 3853 char *stat_forward_count;
3813 char *temp_stat_str; 3854 char *temp_stat_str;
3855
3814#if DEBUG_DHT_ROUTING 3856#if DEBUG_DHT_ROUTING
3815 int ret; 3857 int ret;
3816#endif 3858#endif
3817 3859
3818 if (malicious_dropper == GNUNET_YES) 3860 if (malicious_dropper == GNUNET_YES)
3819 { 3861 {
3820#if DEBUG_DHT_ROUTING 3862#if DEBUG_DHT_ROUTING
3821 if ((debug_routes_extended) && (dhtlog_handle != NULL)) 3863 if ((debug_routes_extended) && (dhtlog_handle != NULL))
3822 { 3864 {
3823 dhtlog_handle->insert_route (NULL, msg_ctx->unique_id, DHTLOG_ROUTE, 3865 dhtlog_handle->insert_route (NULL, msg_ctx->unique_id, DHTLOG_ROUTE,
3824 msg_ctx->hop_count, GNUNET_SYSERR, 3866 msg_ctx->hop_count, GNUNET_SYSERR,
3825 &my_identity, &msg_ctx->key, 3867 &my_identity, &msg_ctx->key,
3826 msg_ctx->peer, NULL); 3868 msg_ctx->peer, NULL);
3827 } 3869 }
3828#endif 3870#endif
3829 if (msg_ctx->bloom != NULL) 3871 if (msg_ctx->bloom != NULL)
3830 { 3872 {
3831 GNUNET_CONTAINER_bloomfilter_free (msg_ctx->bloom); 3873 GNUNET_CONTAINER_bloomfilter_free (msg_ctx->bloom);
3832 msg_ctx->bloom = NULL; 3874 msg_ctx->bloom = NULL;
3833 }
3834 return;
3835 } 3875 }
3876 return;
3877 }
3836 3878
3837 increment_stats (STAT_ROUTES); 3879 increment_stats (STAT_ROUTES);
3838 target_forward_count = 3880 target_forward_count =
3839 get_forward_count (msg_ctx->hop_count, msg_ctx->replication); 3881 get_forward_count (msg_ctx->hop_count, msg_ctx->replication);
3840 GNUNET_asprintf (&stat_forward_count, "# forward counts of %d", 3882 GNUNET_asprintf (&stat_forward_count, "# forward counts of %d",
3841 target_forward_count); 3883 target_forward_count);
3842 increment_stats (stat_forward_count); 3884 increment_stats (stat_forward_count);
3843 GNUNET_free (stat_forward_count); 3885 GNUNET_free (stat_forward_count);
3844 if (msg_ctx->bloom == NULL) 3886 if (msg_ctx->bloom == NULL)
3845 msg_ctx->bloom = 3887 msg_ctx->bloom =
3846 GNUNET_CONTAINER_bloomfilter_init (NULL, DHT_BLOOM_SIZE, DHT_BLOOM_K); 3888 GNUNET_CONTAINER_bloomfilter_init (NULL, DHT_BLOOM_SIZE, DHT_BLOOM_K);
3847 3889
3848 if ((stop_on_closest == GNUNET_YES) && (msg_ctx->closest == GNUNET_YES) 3890 if ((stop_on_closest == GNUNET_YES) && (msg_ctx->closest == GNUNET_YES)
3849 && (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_DHT_PUT)) 3891 && (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_DHT_PUT))
@@ -3874,109 +3916,106 @@ route_message (const struct GNUNET_MessageHeader *msg,
3874 hash_from_uid (msg_ctx->unique_id, &unique_hash); 3916 hash_from_uid (msg_ctx->unique_id, &unique_hash);
3875 if (GNUNET_YES == 3917 if (GNUNET_YES ==
3876 GNUNET_CONTAINER_multihashmap_contains (recent.hashmap, &unique_hash)) 3918 GNUNET_CONTAINER_multihashmap_contains (recent.hashmap, &unique_hash))
3877 { 3919 {
3878 recent_req = 3920 recent_req =
3879 GNUNET_CONTAINER_multihashmap_get (recent.hashmap, &unique_hash); 3921 GNUNET_CONTAINER_multihashmap_get (recent.hashmap, &unique_hash);
3880 GNUNET_assert (recent_req != NULL); 3922 GNUNET_assert (recent_req != NULL);
3881 if (0 != 3923 if (0 != memcmp (&recent_req->key, &msg_ctx->key, sizeof (GNUNET_HashCode)))
3882 memcmp (&recent_req->key, &msg_ctx->key, sizeof (GNUNET_HashCode))) 3924 increment_stats (STAT_DUPLICATE_UID);
3883 increment_stats (STAT_DUPLICATE_UID); 3925 else
3884 else 3926 {
3885 { 3927 increment_stats (STAT_RECENT_SEEN);
3886 increment_stats (STAT_RECENT_SEEN); 3928 GNUNET_CONTAINER_bloomfilter_or2 (msg_ctx->bloom, recent_req->bloom,
3887 GNUNET_CONTAINER_bloomfilter_or2 (msg_ctx->bloom, recent_req->bloom, 3929 DHT_BLOOM_SIZE);
3888 DHT_BLOOM_SIZE);
3889 }
3890 } 3930 }
3931 }
3891 else 3932 else
3892 { 3933 {
3893 recent_req = GNUNET_malloc (sizeof (struct RecentRequest)); 3934 recent_req = GNUNET_malloc (sizeof (struct RecentRequest));
3894 recent_req->uid = msg_ctx->unique_id; 3935 recent_req->uid = msg_ctx->unique_id;
3895 memcpy (&recent_req->key, &msg_ctx->key, sizeof (GNUNET_HashCode)); 3936 memcpy (&recent_req->key, &msg_ctx->key, sizeof (GNUNET_HashCode));
3896 recent_req->remove_task = 3937 recent_req->remove_task =
3897 GNUNET_SCHEDULER_add_delayed (DEFAULT_RECENT_REMOVAL, &remove_recent, 3938 GNUNET_SCHEDULER_add_delayed (DEFAULT_RECENT_REMOVAL, &remove_recent,
3898 recent_req); 3939 recent_req);
3899 recent_req->heap_node = 3940 recent_req->heap_node =
3900 GNUNET_CONTAINER_heap_insert (recent.minHeap, recent_req, 3941 GNUNET_CONTAINER_heap_insert (recent.minHeap, recent_req,
3901 GNUNET_TIME_absolute_get ().abs_value); 3942 GNUNET_TIME_absolute_get ().abs_value);
3902 recent_req->bloom = 3943 recent_req->bloom =
3903 GNUNET_CONTAINER_bloomfilter_init (NULL, DHT_BLOOM_SIZE, DHT_BLOOM_K); 3944 GNUNET_CONTAINER_bloomfilter_init (NULL, DHT_BLOOM_SIZE, DHT_BLOOM_K);
3904 GNUNET_CONTAINER_multihashmap_put (recent.hashmap, &unique_hash, 3945 GNUNET_CONTAINER_multihashmap_put (recent.hashmap, &unique_hash,
3905 recent_req, 3946 recent_req,
3906 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); 3947 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
3907 } 3948 }
3908 3949
3909 if (GNUNET_CONTAINER_multihashmap_size (recent.hashmap) > DHT_MAX_RECENT) 3950 if (GNUNET_CONTAINER_multihashmap_size (recent.hashmap) > DHT_MAX_RECENT)
3910 { 3951 {
3911 recent_req = GNUNET_CONTAINER_heap_peek (recent.minHeap); 3952 recent_req = GNUNET_CONTAINER_heap_peek (recent.minHeap);
3912 GNUNET_assert (recent_req != NULL); 3953 GNUNET_assert (recent_req != NULL);
3913 GNUNET_SCHEDULER_cancel (recent_req->remove_task); 3954 GNUNET_SCHEDULER_cancel (recent_req->remove_task);
3914 GNUNET_SCHEDULER_add_now (&remove_recent, recent_req); 3955 GNUNET_SCHEDULER_add_now (&remove_recent, recent_req);
3915 } 3956 }
3916 3957
3917 forward_count = 0; 3958 forward_count = 0;
3918 for (i = 0; i < target_forward_count; i++) 3959 for (i = 0; i < target_forward_count; i++)
3919 { 3960 {
3920 selected = 3961 selected = select_peer (&msg_ctx->key, msg_ctx->bloom, msg_ctx->hop_count);
3921 select_peer (&msg_ctx->key, msg_ctx->bloom, msg_ctx->hop_count); 3962
3922 3963 if (selected != NULL)
3923 if (selected != NULL) 3964 {
3924 { 3965 forward_count++;
3925 forward_count++; 3966 if (GNUNET_CRYPTO_hash_matching_bits
3926 if (GNUNET_CRYPTO_hash_matching_bits 3967 (&selected->id.hashPubKey,
3927 (&selected->id.hashPubKey, 3968 &msg_ctx->key) >=
3928 &msg_ctx->key) >= 3969 GNUNET_CRYPTO_hash_matching_bits (&my_identity.hashPubKey,
3929 GNUNET_CRYPTO_hash_matching_bits (&my_identity.hashPubKey, 3970 &msg_ctx->key))
3930 &msg_ctx->key)) 3971 GNUNET_asprintf (&temp_stat_str,
3931 GNUNET_asprintf (&temp_stat_str, 3972 "# requests routed to close(r) peer hop %u",
3932 "# requests routed to close(r) peer hop %u", 3973 msg_ctx->hop_count);
3933 msg_ctx->hop_count); 3974 else
3934 else 3975 GNUNET_asprintf (&temp_stat_str,
3935 GNUNET_asprintf (&temp_stat_str, 3976 "# requests routed to less close peer hop %u",
3936 "# requests routed to less close peer hop %u", 3977 msg_ctx->hop_count);
3937 msg_ctx->hop_count); 3978 if (temp_stat_str != NULL)
3938 if (temp_stat_str != NULL) 3979 {
3939 { 3980 increment_stats (temp_stat_str);
3940 increment_stats (temp_stat_str); 3981 GNUNET_free (temp_stat_str);
3941 GNUNET_free (temp_stat_str); 3982 }
3942 } 3983 GNUNET_CONTAINER_bloomfilter_add (msg_ctx->bloom,
3943 GNUNET_CONTAINER_bloomfilter_add (msg_ctx->bloom, 3984 &selected->id.hashPubKey);
3944 &selected->id.hashPubKey);
3945#if DEBUG_DHT_ROUTING > 1 3985#if DEBUG_DHT_ROUTING > 1
3946 nearest = find_closest_peer (&msg_ctx->key); 3986 nearest = find_closest_peer (&msg_ctx->key);
3947 nearest_buf = GNUNET_strdup (GNUNET_i2s (&nearest->id)); 3987 nearest_buf = GNUNET_strdup (GNUNET_i2s (&nearest->id));
3948 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3988 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3949 "`%s:%s': Forwarding request key %s uid %llu to peer %s (closest %s, bits %d, distance %u)\n", 3989 "`%s:%s': Forwarding request key %s uid %llu to peer %s (closest %s, bits %d, distance %u)\n",
3950 my_short_id, "DHT", GNUNET_h2s (&msg_ctx->key), 3990 my_short_id, "DHT", GNUNET_h2s (&msg_ctx->key),
3951 msg_ctx->unique_id, GNUNET_i2s (&selected->id), 3991 msg_ctx->unique_id, GNUNET_i2s (&selected->id),
3952 nearest_buf, 3992 nearest_buf,
3953 GNUNET_CRYPTO_hash_matching_bits (&nearest->id. 3993 GNUNET_CRYPTO_hash_matching_bits (&nearest->id.hashPubKey,
3954 hashPubKey, 3994 msg_ctx->key),
3955 msg_ctx->key), 3995 distance (&nearest->id.hashPubKey, msg_ctx->key));
3956 distance (&nearest->id.hashPubKey, msg_ctx->key)); 3996 GNUNET_free (nearest_buf);
3957 GNUNET_free (nearest_buf);
3958#endif 3997#endif
3959#if DEBUG_DHT_ROUTING 3998#if DEBUG_DHT_ROUTING
3960 if ((debug_routes_extended) && (dhtlog_handle != NULL)) 3999 if ((debug_routes_extended) && (dhtlog_handle != NULL))
3961 { 4000 {
3962 dhtlog_handle->insert_route (NULL, msg_ctx->unique_id, 4001 dhtlog_handle->insert_route (NULL, msg_ctx->unique_id,
3963 DHTLOG_ROUTE, msg_ctx->hop_count, 4002 DHTLOG_ROUTE, msg_ctx->hop_count,
3964 GNUNET_NO, &my_identity, 4003 GNUNET_NO, &my_identity,
3965 &msg_ctx->key, msg_ctx->peer, 4004 &msg_ctx->key, msg_ctx->peer,
3966 &selected->id); 4005 &selected->id);
3967 } 4006 }
3968#endif 4007#endif
3969 forward_message (msg, selected, msg_ctx); 4008 forward_message (msg, selected, msg_ctx);
3970 }
3971 } 4009 }
4010 }
3972 4011
3973 if (msg_ctx->bloom != NULL) 4012 if (msg_ctx->bloom != NULL)
3974 { 4013 {
3975 GNUNET_CONTAINER_bloomfilter_or2 (recent_req->bloom, msg_ctx->bloom, 4014 GNUNET_CONTAINER_bloomfilter_or2 (recent_req->bloom, msg_ctx->bloom,
3976 DHT_BLOOM_SIZE); 4015 DHT_BLOOM_SIZE);
3977 GNUNET_CONTAINER_bloomfilter_free (msg_ctx->bloom); 4016 GNUNET_CONTAINER_bloomfilter_free (msg_ctx->bloom);
3978 msg_ctx->bloom = NULL; 4017 msg_ctx->bloom = NULL;
3979 } 4018 }
3980 4019
3981#if DEBUG_DHT_ROUTING 4020#if DEBUG_DHT_ROUTING
3982 if (forward_count == 0) 4021 if (forward_count == 0)
@@ -3985,12 +4024,12 @@ route_message (const struct GNUNET_MessageHeader *msg,
3985 ret = GNUNET_NO; 4024 ret = GNUNET_NO;
3986 4025
3987 if ((debug_routes_extended) && (dhtlog_handle != NULL)) 4026 if ((debug_routes_extended) && (dhtlog_handle != NULL))
3988 { 4027 {
3989 dhtlog_handle->insert_route (NULL, msg_ctx->unique_id, DHTLOG_ROUTE, 4028 dhtlog_handle->insert_route (NULL, msg_ctx->unique_id, DHTLOG_ROUTE,
3990 msg_ctx->hop_count, ret, 4029 msg_ctx->hop_count, ret,
3991 &my_identity, &msg_ctx->key, msg_ctx->peer, 4030 &my_identity, &msg_ctx->key, msg_ctx->peer,
3992 NULL); 4031 NULL);
3993 } 4032 }
3994#endif 4033#endif
3995} 4034}
3996 4035
@@ -4011,51 +4050,50 @@ demultiplex_message (const struct GNUNET_MessageHeader *msg,
4011 msg_ctx->closest = am_closest_peer (&msg_ctx->key, msg_ctx->bloom); 4050 msg_ctx->closest = am_closest_peer (&msg_ctx->key, msg_ctx->bloom);
4012 4051
4013 switch (ntohs (msg->type)) 4052 switch (ntohs (msg->type))
4053 {
4054 case GNUNET_MESSAGE_TYPE_DHT_GET: /* Add to hashmap of requests seen, search for data (always) */
4055 cache_response (msg_ctx);
4056 handle_dht_get (msg, msg_ctx);
4057 break;
4058 case GNUNET_MESSAGE_TYPE_DHT_PUT: /* Check if closest, if so insert data. */
4059 increment_stats (STAT_PUTS);
4060 handle_dht_put (msg, msg_ctx);
4061 break;
4062 case GNUNET_MESSAGE_TYPE_DHT_FIND_PEER: /* Check if closest and not started by us, check options, add to requests seen */
4063 increment_stats (STAT_FIND_PEER);
4064 if (((msg_ctx->hop_count > 0)
4065 && (0 !=
4066 memcmp (msg_ctx->peer, &my_identity,
4067 sizeof (struct GNUNET_PeerIdentity))))
4068 || (msg_ctx->client != NULL))
4014 { 4069 {
4015 case GNUNET_MESSAGE_TYPE_DHT_GET: /* Add to hashmap of requests seen, search for data (always) */
4016 cache_response (msg_ctx); 4070 cache_response (msg_ctx);
4017 handle_dht_get (msg, msg_ctx); 4071 if ((msg_ctx->closest == GNUNET_YES)
4018 break; 4072 || (msg_ctx->msg_options == GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE))
4019 case GNUNET_MESSAGE_TYPE_DHT_PUT: /* Check if closest, if so insert data. */ 4073 handle_dht_find_peer (msg, msg_ctx);
4020 increment_stats (STAT_PUTS); 4074 }
4021 handle_dht_put (msg, msg_ctx); 4075 else
4022 break;
4023 case GNUNET_MESSAGE_TYPE_DHT_FIND_PEER: /* Check if closest and not started by us, check options, add to requests seen */
4024 increment_stats (STAT_FIND_PEER);
4025 if (((msg_ctx->hop_count > 0)
4026 && (0 !=
4027 memcmp (msg_ctx->peer, &my_identity,
4028 sizeof (struct GNUNET_PeerIdentity))))
4029 || (msg_ctx->client != NULL))
4030 {
4031 cache_response (msg_ctx);
4032 if ((msg_ctx->closest == GNUNET_YES)
4033 || (msg_ctx->msg_options ==
4034 GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE))
4035 handle_dht_find_peer (msg, msg_ctx);
4036 }
4037 else
4038 route_message (msg, msg_ctx);
4039#if DEBUG_DHT_ROUTING
4040 if (msg_ctx->hop_count == 0) /* Locally initiated request */
4041 {
4042 if ((debug_routes) && (dhtlog_handle != NULL))
4043 {
4044 dhtlog_handle->insert_dhtkey (NULL, &msg_ctx->key);
4045 dhtlog_handle->insert_query (NULL, msg_ctx->unique_id,
4046 DHTLOG_FIND_PEER,
4047 msg_ctx->hop_count, GNUNET_NO,
4048 &my_identity, &msg_ctx->key);
4049 }
4050 }
4051#endif
4052 break;
4053 default:
4054 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
4055 "`%s': Message type (%d) not handled, forwarding anyway!\n",
4056 "DHT", ntohs (msg->type));
4057 route_message (msg, msg_ctx); 4076 route_message (msg, msg_ctx);
4077#if DEBUG_DHT_ROUTING
4078 if (msg_ctx->hop_count == 0) /* Locally initiated request */
4079 {
4080 if ((debug_routes) && (dhtlog_handle != NULL))
4081 {
4082 dhtlog_handle->insert_dhtkey (NULL, &msg_ctx->key);
4083 dhtlog_handle->insert_query (NULL, msg_ctx->unique_id,
4084 DHTLOG_FIND_PEER,
4085 msg_ctx->hop_count, GNUNET_NO,
4086 &my_identity, &msg_ctx->key);
4087 }
4058 } 4088 }
4089#endif
4090 break;
4091 default:
4092 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
4093 "`%s': Message type (%d) not handled, forwarding anyway!\n",
4094 "DHT", ntohs (msg->type));
4095 route_message (msg, msg_ctx);
4096 }
4059} 4097}
4060 4098
4061 4099
@@ -4083,6 +4121,7 @@ republish_content_iterator (void *cls,
4083 4121
4084 struct DHT_MessageContext *new_msg_ctx; 4122 struct DHT_MessageContext *new_msg_ctx;
4085 struct GNUNET_DHT_PutMessage *put_msg; 4123 struct GNUNET_DHT_PutMessage *put_msg;
4124
4086#if DEBUG_DHT 4125#if DEBUG_DHT
4087 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 4126 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4088 "`%s:%s': Received `%s' response from datacache\n", my_short_id, 4127 "`%s:%s': Received `%s' response from datacache\n", my_short_id,
@@ -4097,14 +4136,14 @@ republish_content_iterator (void *cls,
4097 put_msg->type = htons (type); 4136 put_msg->type = htons (type);
4098 memcpy (&put_msg[1], data, size); 4137 memcpy (&put_msg[1], data, size);
4099 new_msg_ctx->unique_id = 4138 new_msg_ctx->unique_id =
4100 GNUNET_ntohll (GNUNET_CRYPTO_random_u64 4139 GNUNET_ntohll (GNUNET_CRYPTO_random_u64
4101 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX)); 4140 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX));
4102 new_msg_ctx->replication = ntohl (DEFAULT_PUT_REPLICATION); 4141 new_msg_ctx->replication = ntohl (DEFAULT_PUT_REPLICATION);
4103 new_msg_ctx->msg_options = ntohl (0); 4142 new_msg_ctx->msg_options = ntohl (0);
4104 new_msg_ctx->network_size = estimate_diameter (); 4143 new_msg_ctx->network_size = estimate_diameter ();
4105 new_msg_ctx->peer = &my_identity; 4144 new_msg_ctx->peer = &my_identity;
4106 new_msg_ctx->bloom = 4145 new_msg_ctx->bloom =
4107 GNUNET_CONTAINER_bloomfilter_init (NULL, DHT_BLOOM_SIZE, DHT_BLOOM_K); 4146 GNUNET_CONTAINER_bloomfilter_init (NULL, DHT_BLOOM_SIZE, DHT_BLOOM_K);
4108 new_msg_ctx->hop_count = 0; 4147 new_msg_ctx->hop_count = 0;
4109 new_msg_ctx->importance = DHT_DEFAULT_P2P_IMPORTANCE; 4148 new_msg_ctx->importance = DHT_DEFAULT_P2P_IMPORTANCE;
4110 new_msg_ctx->timeout = DHT_DEFAULT_P2P_TIMEOUT; 4149 new_msg_ctx->timeout = DHT_DEFAULT_P2P_TIMEOUT;
@@ -4129,16 +4168,16 @@ republish_content (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
4129 4168
4130 unsigned int results; 4169 unsigned int results;
4131 4170
4132 if ( (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) 4171 if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
4133 { 4172 {
4134 GNUNET_free (put_context); 4173 GNUNET_free (put_context);
4135 return; 4174 return;
4136 } 4175 }
4137 4176
4138 GNUNET_assert (datacache != NULL); /* If we have no datacache we never should have scheduled this! */ 4177 GNUNET_assert (datacache != NULL); /* If we have no datacache we never should have scheduled this! */
4139 results = 4178 results =
4140 GNUNET_DATACACHE_get (datacache, &put_context->key, put_context->type, 4179 GNUNET_DATACACHE_get (datacache, &put_context->key, put_context->type,
4141 &republish_content_iterator, NULL); 4180 &republish_content_iterator, NULL);
4142 if (results == 0) /* Data must have expired */ 4181 if (results == 0) /* Data must have expired */
4143 GNUNET_free (put_context); 4182 GNUNET_free (put_context);
4144 else /* Reschedule task for next time period */ 4183 else /* Reschedule task for next time period */
@@ -4164,33 +4203,34 @@ find_client_records (void *cls, const GNUNET_HashCode * key, void *value)
4164 struct ClientList *client = cls; 4203 struct ClientList *client = cls;
4165 struct DHTQueryRecord *record = value; 4204 struct DHTQueryRecord *record = value;
4166 struct DHTRouteSource *pos; 4205 struct DHTRouteSource *pos;
4206
4167 pos = record->head; 4207 pos = record->head;
4168 while (pos != NULL) 4208 while (pos != NULL)
4169 { 4209 {
4170 if (pos->client == client) 4210 if (pos->client == client)
4171 break; 4211 break;
4172 pos = pos->next; 4212 pos = pos->next;
4173 } 4213 }
4174 if (pos != NULL) 4214 if (pos != NULL)
4175 { 4215 {
4176 GNUNET_CONTAINER_DLL_remove (record->head, record->tail, pos); 4216 GNUNET_CONTAINER_DLL_remove (record->head, record->tail, pos);
4177 GNUNET_CONTAINER_heap_remove_node (pos->hnode); 4217 GNUNET_CONTAINER_heap_remove_node (pos->hnode);
4178 if (pos->delete_task != GNUNET_SCHEDULER_NO_TASK) 4218 if (pos->delete_task != GNUNET_SCHEDULER_NO_TASK)
4179 { 4219 {
4180 GNUNET_SCHEDULER_cancel (pos->delete_task); 4220 GNUNET_SCHEDULER_cancel (pos->delete_task);
4181 pos->delete_task = GNUNET_SCHEDULER_NO_TASK; 4221 pos->delete_task = GNUNET_SCHEDULER_NO_TASK;
4182 } 4222 }
4183 if (pos->find_peers_responded != NULL) 4223 if (pos->find_peers_responded != NULL)
4184 GNUNET_CONTAINER_bloomfilter_free (pos->find_peers_responded); 4224 GNUNET_CONTAINER_bloomfilter_free (pos->find_peers_responded);
4185 GNUNET_free (pos); 4225 GNUNET_free (pos);
4186 } 4226 }
4187 if (record->head == NULL) /* No more entries in DLL */ 4227 if (record->head == NULL) /* No more entries in DLL */
4188 { 4228 {
4189 GNUNET_assert (GNUNET_YES == 4229 GNUNET_assert (GNUNET_YES ==
4190 GNUNET_CONTAINER_multihashmap_remove 4230 GNUNET_CONTAINER_multihashmap_remove
4191 (forward_list.hashmap, &record->key, record)); 4231 (forward_list.hashmap, &record->key, record));
4192 GNUNET_free (record); 4232 GNUNET_free (record);
4193 } 4233 }
4194 return GNUNET_YES; 4234 return GNUNET_YES;
4195} 4235}
4196 4236
@@ -4213,36 +4253,35 @@ handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
4213 prev = NULL; 4253 prev = NULL;
4214 found = NULL; 4254 found = NULL;
4215 while (pos != NULL) 4255 while (pos != NULL)
4256 {
4257 if (pos->client_handle == client)
4216 { 4258 {
4217 if (pos->client_handle == client) 4259 if (prev != NULL)
4218 { 4260 prev->next = pos->next;
4219 if (prev != NULL) 4261 else
4220 prev->next = pos->next; 4262 client_list = pos->next;
4221 else 4263 found = pos;
4222 client_list = pos->next; 4264 break;
4223 found = pos;
4224 break;
4225 }
4226 prev = pos;
4227 pos = pos->next;
4228 } 4265 }
4266 prev = pos;
4267 pos = pos->next;
4268 }
4229 4269
4230 if (found != NULL) 4270 if (found != NULL)
4231 { 4271 {
4232 if (found->transmit_handle != NULL) 4272 if (found->transmit_handle != NULL)
4233 GNUNET_CONNECTION_notify_transmit_ready_cancel 4273 GNUNET_CONNECTION_notify_transmit_ready_cancel (found->transmit_handle);
4234 (found->transmit_handle);
4235 4274
4236 while (NULL != (reply = found->pending_head)) 4275 while (NULL != (reply = found->pending_head))
4237 { 4276 {
4238 GNUNET_CONTAINER_DLL_remove (found->pending_head, 4277 GNUNET_CONTAINER_DLL_remove (found->pending_head,
4239 found->pending_tail, reply); 4278 found->pending_tail, reply);
4240 GNUNET_free (reply); 4279 GNUNET_free (reply);
4241 }
4242 GNUNET_CONTAINER_multihashmap_iterate (forward_list.hashmap,
4243 &find_client_records, found);
4244 GNUNET_free (found);
4245 } 4280 }
4281 GNUNET_CONTAINER_multihashmap_iterate (forward_list.hashmap,
4282 &find_client_records, found);
4283 GNUNET_free (found);
4284 }
4246} 4285}
4247 4286
4248/** 4287/**
@@ -4259,11 +4298,11 @@ find_active_client (struct GNUNET_SERVER_Client *client)
4259 struct ClientList *ret; 4298 struct ClientList *ret;
4260 4299
4261 while (pos != NULL) 4300 while (pos != NULL)
4262 { 4301 {
4263 if (pos->client_handle == client) 4302 if (pos->client_handle == client)
4264 return pos; 4303 return pos;
4265 pos = pos->next; 4304 pos = pos->next;
4266 } 4305 }
4267 4306
4268 ret = GNUNET_malloc (sizeof (struct ClientList)); 4307 ret = GNUNET_malloc (sizeof (struct ClientList));
4269 ret->client_handle = client; 4308 ret->client_handle = client;
@@ -4288,21 +4327,21 @@ malicious_put_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
4288 static GNUNET_HashCode key; 4327 static GNUNET_HashCode key;
4289 uint32_t random_key; 4328 uint32_t random_key;
4290 4329
4291 if ( (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) 4330 if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
4292 return; 4331 return;
4293 put_message.header.size = htons (sizeof (struct GNUNET_DHT_PutMessage)); 4332 put_message.header.size = htons (sizeof (struct GNUNET_DHT_PutMessage));
4294 put_message.header.type = htons (GNUNET_MESSAGE_TYPE_DHT_PUT); 4333 put_message.header.type = htons (GNUNET_MESSAGE_TYPE_DHT_PUT);
4295 put_message.type = htonl (GNUNET_BLOCK_DHT_MALICIOUS_MESSAGE_TYPE); 4334 put_message.type = htonl (GNUNET_BLOCK_DHT_MALICIOUS_MESSAGE_TYPE);
4296 put_message.expiration = 4335 put_message.expiration =
4297 GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_forever ()); 4336 GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_forever ());
4298 memset (&msg_ctx, 0, sizeof (struct DHT_MessageContext)); 4337 memset (&msg_ctx, 0, sizeof (struct DHT_MessageContext));
4299 random_key = 4338 random_key =
4300 GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, UINT32_MAX); 4339 GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, UINT32_MAX);
4301 GNUNET_CRYPTO_hash (&random_key, sizeof (uint32_t), &key); 4340 GNUNET_CRYPTO_hash (&random_key, sizeof (uint32_t), &key);
4302 memcpy (&msg_ctx.key, &key, sizeof (GNUNET_HashCode)); 4341 memcpy (&msg_ctx.key, &key, sizeof (GNUNET_HashCode));
4303 msg_ctx.unique_id = 4342 msg_ctx.unique_id =
4304 GNUNET_ntohll (GNUNET_CRYPTO_random_u64 4343 GNUNET_ntohll (GNUNET_CRYPTO_random_u64
4305 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX)); 4344 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX));
4306 msg_ctx.replication = ntohl (DHT_DEFAULT_FIND_PEER_REPLICATION); 4345 msg_ctx.replication = ntohl (DHT_DEFAULT_FIND_PEER_REPLICATION);
4307 msg_ctx.msg_options = ntohl (0); 4346 msg_ctx.msg_options = ntohl (0);
4308 msg_ctx.network_size = estimate_diameter (); 4347 msg_ctx.network_size = estimate_diameter ();
@@ -4339,7 +4378,7 @@ malicious_get_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
4339 static GNUNET_HashCode key; 4378 static GNUNET_HashCode key;
4340 uint32_t random_key; 4379 uint32_t random_key;
4341 4380
4342 if ( (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) 4381 if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
4343 return; 4382 return;
4344 4383
4345 get_message.header.size = htons (sizeof (struct GNUNET_DHT_GetMessage)); 4384 get_message.header.size = htons (sizeof (struct GNUNET_DHT_GetMessage));
@@ -4347,12 +4386,12 @@ malicious_get_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
4347 get_message.type = htonl (GNUNET_BLOCK_DHT_MALICIOUS_MESSAGE_TYPE); 4386 get_message.type = htonl (GNUNET_BLOCK_DHT_MALICIOUS_MESSAGE_TYPE);
4348 memset (&msg_ctx, 0, sizeof (struct DHT_MessageContext)); 4387 memset (&msg_ctx, 0, sizeof (struct DHT_MessageContext));
4349 random_key = 4388 random_key =
4350 GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, UINT32_MAX); 4389 GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, UINT32_MAX);
4351 GNUNET_CRYPTO_hash (&random_key, sizeof (uint32_t), &key); 4390 GNUNET_CRYPTO_hash (&random_key, sizeof (uint32_t), &key);
4352 memcpy (&msg_ctx.key, &key, sizeof (GNUNET_HashCode)); 4391 memcpy (&msg_ctx.key, &key, sizeof (GNUNET_HashCode));
4353 msg_ctx.unique_id = 4392 msg_ctx.unique_id =
4354 GNUNET_ntohll (GNUNET_CRYPTO_random_u64 4393 GNUNET_ntohll (GNUNET_CRYPTO_random_u64
4355 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX)); 4394 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX));
4356 msg_ctx.replication = ntohl (DHT_DEFAULT_FIND_PEER_REPLICATION); 4395 msg_ctx.replication = ntohl (DHT_DEFAULT_FIND_PEER_REPLICATION);
4357 msg_ctx.msg_options = ntohl (0); 4396 msg_ctx.msg_options = ntohl (0);
4358 msg_ctx.network_size = estimate_diameter (); 4397 msg_ctx.network_size = estimate_diameter ();
@@ -4390,6 +4429,7 @@ static int
4390add_known_to_bloom (void *cls, const GNUNET_HashCode * key, void *value) 4429add_known_to_bloom (void *cls, const GNUNET_HashCode * key, void *value)
4391{ 4430{
4392 struct GNUNET_CONTAINER_BloomFilter *bloom = cls; 4431 struct GNUNET_CONTAINER_BloomFilter *bloom = cls;
4432
4393 GNUNET_CONTAINER_bloomfilter_add (bloom, key); 4433 GNUNET_CONTAINER_bloomfilter_add (bloom, key);
4394 return GNUNET_YES; 4434 return GNUNET_YES;
4395} 4435}
@@ -4410,62 +4450,63 @@ send_find_peer_message (void *cls,
4410 struct DHT_MessageContext msg_ctx; 4450 struct DHT_MessageContext msg_ctx;
4411 struct GNUNET_TIME_Relative next_send_time; 4451 struct GNUNET_TIME_Relative next_send_time;
4412 struct GNUNET_CONTAINER_BloomFilter *temp_bloom; 4452 struct GNUNET_CONTAINER_BloomFilter *temp_bloom;
4453
4413#if COUNT_INTERVAL 4454#if COUNT_INTERVAL
4414 struct GNUNET_TIME_Relative time_diff; 4455 struct GNUNET_TIME_Relative time_diff;
4415 struct GNUNET_TIME_Absolute end; 4456 struct GNUNET_TIME_Absolute end;
4416 double multiplier; 4457 double multiplier;
4417 double count_per_interval; 4458 double count_per_interval;
4418#endif 4459#endif
4419 if ( (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) 4460 if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
4420 return; 4461 return;
4421 4462
4422 if ((newly_found_peers > bucket_size) && (GNUNET_YES == do_find_peer)) /* If we are finding peers already, no need to send out our request right now! */ 4463 if ((newly_found_peers > bucket_size) && (GNUNET_YES == do_find_peer)) /* If we are finding peers already, no need to send out our request right now! */
4423 { 4464 {
4424 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 4465 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
4425 "Have %d newly found peers since last find peer message sent!\n", 4466 "Have %d newly found peers since last find peer message sent!\n",
4426 newly_found_peers); 4467 newly_found_peers);
4427 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, 4468 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
4428 &send_find_peer_message, NULL); 4469 &send_find_peer_message, NULL);
4429 newly_found_peers = 0; 4470 newly_found_peers = 0;
4430 return; 4471 return;
4431 } 4472 }
4432 4473
4433 increment_stats (STAT_FIND_PEER_START); 4474 increment_stats (STAT_FIND_PEER_START);
4434#if COUNT_INTERVAL 4475#if COUNT_INTERVAL
4435 end = GNUNET_TIME_absolute_get (); 4476 end = GNUNET_TIME_absolute_get ();
4436 time_diff = 4477 time_diff =
4437 GNUNET_TIME_absolute_get_difference (find_peer_context.start, end); 4478 GNUNET_TIME_absolute_get_difference (find_peer_context.start, end);
4438 4479
4439 if (time_diff.abs_value > FIND_PEER_CALC_INTERVAL.abs_value) 4480 if (time_diff.abs_value > FIND_PEER_CALC_INTERVAL.abs_value)
4440 { 4481 {
4441 multiplier = time_diff.abs_value / FIND_PEER_CALC_INTERVAL.abs_value; 4482 multiplier = time_diff.abs_value / FIND_PEER_CALC_INTERVAL.abs_value;
4442 count_per_interval = find_peer_context.count / multiplier; 4483 count_per_interval = find_peer_context.count / multiplier;
4443 } 4484 }
4444 else 4485 else
4445 { 4486 {
4446 multiplier = FIND_PEER_CALC_INTERVAL.abs_value / time_diff.abs_value; 4487 multiplier = FIND_PEER_CALC_INTERVAL.abs_value / time_diff.abs_value;
4447 count_per_interval = find_peer_context.count * multiplier; 4488 count_per_interval = find_peer_context.count * multiplier;
4448 } 4489 }
4449#endif 4490#endif
4450 4491
4451#if FIND_PEER_WITH_HELLO 4492#if FIND_PEER_WITH_HELLO
4452 find_peer_msg = 4493 find_peer_msg =
4453 GNUNET_malloc (sizeof (struct GNUNET_DHT_FindPeerMessage) + 4494 GNUNET_malloc (sizeof (struct GNUNET_DHT_FindPeerMessage) +
4454 GNUNET_HELLO_size ((struct GNUNET_HELLO_Message *) 4495 GNUNET_HELLO_size ((struct GNUNET_HELLO_Message *)
4455 my_hello)); 4496 my_hello));
4456 find_peer_msg->header.size = 4497 find_peer_msg->header.size =
4457 htons (sizeof (struct GNUNET_DHT_FindPeerMessage) + 4498 htons (sizeof (struct GNUNET_DHT_FindPeerMessage) +
4458 GNUNET_HELLO_size ((struct GNUNET_HELLO_Message *) my_hello)); 4499 GNUNET_HELLO_size ((struct GNUNET_HELLO_Message *) my_hello));
4459 memcpy (&find_peer_msg[1], my_hello, 4500 memcpy (&find_peer_msg[1], my_hello,
4460 GNUNET_HELLO_size ((struct GNUNET_HELLO_Message *) my_hello)); 4501 GNUNET_HELLO_size ((struct GNUNET_HELLO_Message *) my_hello));
4461#else 4502#else
4462 find_peer_msg = GNUNET_malloc (sizeof (struct GNUNET_DHT_FindPeerMessage)); 4503 find_peer_msg = GNUNET_malloc (sizeof (struct GNUNET_DHT_FindPeerMessage));
4463 find_peer_msg->header.size = 4504 find_peer_msg->header.size =
4464 htons (sizeof (struct GNUNET_DHT_FindPeerMessage)); 4505 htons (sizeof (struct GNUNET_DHT_FindPeerMessage));
4465#endif 4506#endif
4466 find_peer_msg->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_FIND_PEER); 4507 find_peer_msg->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_FIND_PEER);
4467 temp_bloom = 4508 temp_bloom =
4468 GNUNET_CONTAINER_bloomfilter_init (NULL, DHT_BLOOM_SIZE, DHT_BLOOM_K); 4509 GNUNET_CONTAINER_bloomfilter_init (NULL, DHT_BLOOM_SIZE, DHT_BLOOM_K);
4469 GNUNET_CONTAINER_multihashmap_iterate (all_known_peers, &add_known_to_bloom, 4510 GNUNET_CONTAINER_multihashmap_iterate (all_known_peers, &add_known_to_bloom,
4470 temp_bloom); 4511 temp_bloom);
4471 GNUNET_assert (GNUNET_OK == 4512 GNUNET_assert (GNUNET_OK ==
@@ -4477,8 +4518,8 @@ send_find_peer_message (void *cls,
4477 memset (&msg_ctx, 0, sizeof (struct DHT_MessageContext)); 4518 memset (&msg_ctx, 0, sizeof (struct DHT_MessageContext));
4478 memcpy (&msg_ctx.key, &my_identity.hashPubKey, sizeof (GNUNET_HashCode)); 4519 memcpy (&msg_ctx.key, &my_identity.hashPubKey, sizeof (GNUNET_HashCode));
4479 msg_ctx.unique_id = 4520 msg_ctx.unique_id =
4480 GNUNET_ntohll (GNUNET_CRYPTO_random_u64 4521 GNUNET_ntohll (GNUNET_CRYPTO_random_u64
4481 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX)); 4522 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX));
4482 msg_ctx.replication = DHT_DEFAULT_FIND_PEER_REPLICATION; 4523 msg_ctx.replication = DHT_DEFAULT_FIND_PEER_REPLICATION;
4483 msg_ctx.msg_options = DHT_DEFAULT_FIND_PEER_OPTIONS; 4524 msg_ctx.msg_options = DHT_DEFAULT_FIND_PEER_OPTIONS;
4484 msg_ctx.network_size = estimate_diameter (); 4525 msg_ctx.network_size = estimate_diameter ();
@@ -4492,30 +4533,29 @@ send_find_peer_message (void *cls,
4492 "`%s:%s': Sent `%s' request to some (?) peers\n", my_short_id, 4533 "`%s:%s': Sent `%s' request to some (?) peers\n", my_short_id,
4493 "DHT", "FIND PEER"); 4534 "DHT", "FIND PEER");
4494 if (newly_found_peers < bucket_size) 4535 if (newly_found_peers < bucket_size)
4495 { 4536 {
4496 next_send_time.rel_value = 4537 next_send_time.rel_value =
4497 (DHT_MAXIMUM_FIND_PEER_INTERVAL.rel_value / 2) + 4538 (DHT_MAXIMUM_FIND_PEER_INTERVAL.rel_value / 2) +
4498 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, 4539 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG,
4499 DHT_MAXIMUM_FIND_PEER_INTERVAL.rel_value / 4540 DHT_MAXIMUM_FIND_PEER_INTERVAL.rel_value / 2);
4500 2); 4541 }
4501 }
4502 else 4542 else
4503 { 4543 {
4504 next_send_time.rel_value = DHT_MINIMUM_FIND_PEER_INTERVAL.rel_value + 4544 next_send_time.rel_value = DHT_MINIMUM_FIND_PEER_INTERVAL.rel_value +
4505 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, 4545 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG,
4506 DHT_MAXIMUM_FIND_PEER_INTERVAL.rel_value - 4546 DHT_MAXIMUM_FIND_PEER_INTERVAL.rel_value -
4507 DHT_MINIMUM_FIND_PEER_INTERVAL.rel_value); 4547 DHT_MINIMUM_FIND_PEER_INTERVAL.rel_value);
4508 } 4548 }
4509 4549
4510 GNUNET_assert (next_send_time.rel_value != 0); 4550 GNUNET_assert (next_send_time.rel_value != 0);
4511 find_peer_context.count = 0; 4551 find_peer_context.count = 0;
4512 newly_found_peers = 0; 4552 newly_found_peers = 0;
4513 find_peer_context.start = GNUNET_TIME_absolute_get (); 4553 find_peer_context.start = GNUNET_TIME_absolute_get ();
4514 if (GNUNET_YES == do_find_peer) 4554 if (GNUNET_YES == do_find_peer)
4515 { 4555 {
4516 GNUNET_SCHEDULER_add_delayed (next_send_time, 4556 GNUNET_SCHEDULER_add_delayed (next_send_time,
4517 &send_find_peer_message, NULL); 4557 &send_find_peer_message, NULL);
4518 } 4558 }
4519} 4559}
4520 4560
4521/** 4561/**
@@ -4533,7 +4573,7 @@ handle_dht_local_route_request (void *cls,
4533 const struct GNUNET_MessageHeader *message) 4573 const struct GNUNET_MessageHeader *message)
4534{ 4574{
4535 const struct GNUNET_DHT_RouteMessage *dht_msg = 4575 const struct GNUNET_DHT_RouteMessage *dht_msg =
4536 (const struct GNUNET_DHT_RouteMessage *) message; 4576 (const struct GNUNET_DHT_RouteMessage *) message;
4537 const struct GNUNET_MessageHeader *enc_msg; 4577 const struct GNUNET_MessageHeader *enc_msg;
4538 struct DHT_MessageContext msg_ctx; 4578 struct DHT_MessageContext msg_ctx;
4539 4579
@@ -4558,12 +4598,14 @@ handle_dht_local_route_request (void *cls,
4558 msg_ctx.unique_id = GNUNET_ntohll (dht_msg->unique_id); 4598 msg_ctx.unique_id = GNUNET_ntohll (dht_msg->unique_id);
4559 msg_ctx.replication = ntohl (dht_msg->desired_replication_level); 4599 msg_ctx.replication = ntohl (dht_msg->desired_replication_level);
4560 msg_ctx.msg_options = ntohl (dht_msg->options); 4600 msg_ctx.msg_options = ntohl (dht_msg->options);
4561 if (GNUNET_DHT_RO_RECORD_ROUTE == (msg_ctx.msg_options & GNUNET_DHT_RO_RECORD_ROUTE)) 4601 if (GNUNET_DHT_RO_RECORD_ROUTE ==
4562 { 4602 (msg_ctx.msg_options & GNUNET_DHT_RO_RECORD_ROUTE))
4563 msg_ctx.path_history = GNUNET_malloc(sizeof(struct GNUNET_PeerIdentity)); 4603 {
4564 memcpy(msg_ctx.path_history, &my_identity, sizeof(struct GNUNET_PeerIdentity)); 4604 msg_ctx.path_history = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
4565 msg_ctx.path_history_len = 1; 4605 memcpy (msg_ctx.path_history, &my_identity,
4566 } 4606 sizeof (struct GNUNET_PeerIdentity));
4607 msg_ctx.path_history_len = 1;
4608 }
4567 msg_ctx.network_size = estimate_diameter (); 4609 msg_ctx.network_size = estimate_diameter ();
4568 msg_ctx.peer = &my_identity; 4610 msg_ctx.peer = &my_identity;
4569 msg_ctx.importance = DHT_DEFAULT_P2P_IMPORTANCE + 4; /* Make local routing a higher priority */ 4611 msg_ctx.importance = DHT_DEFAULT_P2P_IMPORTANCE + 4; /* Make local routing a higher priority */
@@ -4577,35 +4619,33 @@ handle_dht_local_route_request (void *cls,
4577 increment_stats (STAT_FIND_PEER_START); 4619 increment_stats (STAT_FIND_PEER_START);
4578 4620
4579 if (GNUNET_YES == malicious_dropper) 4621 if (GNUNET_YES == malicious_dropper)
4622 {
4623 if (ntohs (enc_msg->type) == GNUNET_MESSAGE_TYPE_DHT_GET)
4580 { 4624 {
4581 if (ntohs (enc_msg->type) == GNUNET_MESSAGE_TYPE_DHT_GET)
4582 {
4583#if DEBUG_DHT_ROUTING 4625#if DEBUG_DHT_ROUTING
4584 if ((debug_routes) && (dhtlog_handle != NULL)) 4626 if ((debug_routes) && (dhtlog_handle != NULL))
4585 { 4627 {
4586 dhtlog_handle->insert_query (NULL, msg_ctx.unique_id, 4628 dhtlog_handle->insert_query (NULL, msg_ctx.unique_id,
4587 DHTLOG_GET, msg_ctx.hop_count, 4629 DHTLOG_GET, msg_ctx.hop_count,
4588 GNUNET_NO, &my_identity, 4630 GNUNET_NO, &my_identity, &msg_ctx.key);
4589 &msg_ctx.key); 4631 }
4590 }
4591#endif 4632#endif
4592 } 4633 }
4593 else if (ntohs (enc_msg->type) == GNUNET_MESSAGE_TYPE_DHT_PUT) 4634 else if (ntohs (enc_msg->type) == GNUNET_MESSAGE_TYPE_DHT_PUT)
4594 { 4635 {
4595#if DEBUG_DHT_ROUTING 4636#if DEBUG_DHT_ROUTING
4596 if ((debug_routes) && (dhtlog_handle != NULL)) 4637 if ((debug_routes) && (dhtlog_handle != NULL))
4597 { 4638 {
4598 dhtlog_handle->insert_query (NULL, msg_ctx.unique_id, 4639 dhtlog_handle->insert_query (NULL, msg_ctx.unique_id,
4599 DHTLOG_PUT, msg_ctx.hop_count, 4640 DHTLOG_PUT, msg_ctx.hop_count,
4600 GNUNET_NO, &my_identity, 4641 GNUNET_NO, &my_identity, &msg_ctx.key);
4601 &msg_ctx.key); 4642 }
4602 }
4603#endif 4643#endif
4604 }
4605 GNUNET_SERVER_receive_done (client, GNUNET_OK);
4606 GNUNET_free_non_null(msg_ctx.path_history);
4607 return;
4608 } 4644 }
4645 GNUNET_SERVER_receive_done (client, GNUNET_OK);
4646 GNUNET_free_non_null (msg_ctx.path_history);
4647 return;
4648 }
4609 4649
4610 demultiplex_message (enc_msg, &msg_ctx); 4650 demultiplex_message (enc_msg, &msg_ctx);
4611 GNUNET_SERVER_receive_done (client, GNUNET_OK); 4651 GNUNET_SERVER_receive_done (client, GNUNET_OK);
@@ -4626,64 +4666,63 @@ handle_dht_control_message (void *cls, struct GNUNET_SERVER_Client *client,
4626 const struct GNUNET_MessageHeader *message) 4666 const struct GNUNET_MessageHeader *message)
4627{ 4667{
4628 const struct GNUNET_DHT_ControlMessage *dht_control_msg = 4668 const struct GNUNET_DHT_ControlMessage *dht_control_msg =
4629 (const struct GNUNET_DHT_ControlMessage *) message; 4669 (const struct GNUNET_DHT_ControlMessage *) message;
4630 4670
4631#if DEBUG_DHT 4671#if DEBUG_DHT
4632 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 4672 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4633 "`%s:%s': Received `%s' request from client, command %d\n", 4673 "`%s:%s': Received `%s' request from client, command %d\n",
4634 my_short_id, "DHT", "CONTROL", 4674 my_short_id, "DHT", "CONTROL", ntohs (dht_control_msg->command));
4635 ntohs (dht_control_msg->command));
4636#endif 4675#endif
4637 4676
4638 switch (ntohs (dht_control_msg->command)) 4677 switch (ntohs (dht_control_msg->command))
4639 { 4678 {
4640 case GNUNET_MESSAGE_TYPE_DHT_FIND_PEER: 4679 case GNUNET_MESSAGE_TYPE_DHT_FIND_PEER:
4641 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 4680 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4642 "Sending self seeking find peer request!\n"); 4681 "Sending self seeking find peer request!\n");
4643 GNUNET_SCHEDULER_add_now (&send_find_peer_message, NULL); 4682 GNUNET_SCHEDULER_add_now (&send_find_peer_message, NULL);
4644 break; 4683 break;
4645#if HAVE_MALICIOUS 4684#if HAVE_MALICIOUS
4646 case GNUNET_MESSAGE_TYPE_DHT_MALICIOUS_GET: 4685 case GNUNET_MESSAGE_TYPE_DHT_MALICIOUS_GET:
4647 if (ntohs (dht_control_msg->variable) > 0) 4686 if (ntohs (dht_control_msg->variable) > 0)
4648 malicious_get_frequency = ntohs (dht_control_msg->variable); 4687 malicious_get_frequency = ntohs (dht_control_msg->variable);
4649 if (malicious_get_frequency == 0) 4688 if (malicious_get_frequency == 0)
4650 malicious_get_frequency = DEFAULT_MALICIOUS_GET_FREQUENCY; 4689 malicious_get_frequency = DEFAULT_MALICIOUS_GET_FREQUENCY;
4651 if (malicious_getter != GNUNET_YES) 4690 if (malicious_getter != GNUNET_YES)
4652 GNUNET_SCHEDULER_add_now (&malicious_get_task, NULL); 4691 GNUNET_SCHEDULER_add_now (&malicious_get_task, NULL);
4653 malicious_getter = GNUNET_YES; 4692 malicious_getter = GNUNET_YES;
4654 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 4693 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4655 "%s:%s Initiating malicious GET behavior, frequency %d\n", 4694 "%s:%s Initiating malicious GET behavior, frequency %d\n",
4656 my_short_id, "DHT", malicious_get_frequency); 4695 my_short_id, "DHT", malicious_get_frequency);
4657 break; 4696 break;
4658 case GNUNET_MESSAGE_TYPE_DHT_MALICIOUS_PUT: 4697 case GNUNET_MESSAGE_TYPE_DHT_MALICIOUS_PUT:
4659 if (ntohs (dht_control_msg->variable) > 0) 4698 if (ntohs (dht_control_msg->variable) > 0)
4660 malicious_put_frequency = ntohs (dht_control_msg->variable); 4699 malicious_put_frequency = ntohs (dht_control_msg->variable);
4661 if (malicious_put_frequency == 0) 4700 if (malicious_put_frequency == 0)
4662 malicious_put_frequency = DEFAULT_MALICIOUS_PUT_FREQUENCY; 4701 malicious_put_frequency = DEFAULT_MALICIOUS_PUT_FREQUENCY;
4663 if (malicious_putter != GNUNET_YES) 4702 if (malicious_putter != GNUNET_YES)
4664 GNUNET_SCHEDULER_add_now (&malicious_put_task, NULL); 4703 GNUNET_SCHEDULER_add_now (&malicious_put_task, NULL);
4665 malicious_putter = GNUNET_YES; 4704 malicious_putter = GNUNET_YES;
4666 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 4705 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4667 "%s:%s Initiating malicious PUT behavior, frequency %d\n", 4706 "%s:%s Initiating malicious PUT behavior, frequency %d\n",
4668 my_short_id, "DHT", malicious_put_frequency); 4707 my_short_id, "DHT", malicious_put_frequency);
4669 break; 4708 break;
4670 case GNUNET_MESSAGE_TYPE_DHT_MALICIOUS_DROP: 4709 case GNUNET_MESSAGE_TYPE_DHT_MALICIOUS_DROP:
4671#if DEBUG_DHT_ROUTING 4710#if DEBUG_DHT_ROUTING
4672 if ((malicious_dropper != GNUNET_YES) && (dhtlog_handle != NULL)) 4711 if ((malicious_dropper != GNUNET_YES) && (dhtlog_handle != NULL))
4673 dhtlog_handle->set_malicious (&my_identity); 4712 dhtlog_handle->set_malicious (&my_identity);
4674#endif 4713#endif
4675 malicious_dropper = GNUNET_YES; 4714 malicious_dropper = GNUNET_YES;
4676 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 4715 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4677 "%s:%s Initiating malicious DROP behavior\n", my_short_id, 4716 "%s:%s Initiating malicious DROP behavior\n", my_short_id,
4678 "DHT"); 4717 "DHT");
4679 break; 4718 break;
4680#endif 4719#endif
4681 default: 4720 default:
4682 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 4721 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
4683 "%s:%s Unknown control command type `%d'!\n", 4722 "%s:%s Unknown control command type `%d'!\n",
4684 my_short_id, "DHT", ntohs (dht_control_msg->command)); 4723 my_short_id, "DHT", ntohs (dht_control_msg->command));
4685 break; 4724 break;
4686 } 4725 }
4687 4726
4688 GNUNET_SERVER_receive_done (client, GNUNET_OK); 4727 GNUNET_SERVER_receive_done (client, GNUNET_OK);
4689} 4728}
@@ -4703,9 +4742,10 @@ handle_dht_local_route_stop (void *cls, struct GNUNET_SERVER_Client *client,
4703{ 4742{
4704 4743
4705 const struct GNUNET_DHT_StopMessage *dht_stop_msg = 4744 const struct GNUNET_DHT_StopMessage *dht_stop_msg =
4706 (const struct GNUNET_DHT_StopMessage *) message; 4745 (const struct GNUNET_DHT_StopMessage *) message;
4707 struct DHTQueryRecord *record; 4746 struct DHTQueryRecord *record;
4708 struct DHTRouteSource *pos; 4747 struct DHTRouteSource *pos;
4748
4709#if DEBUG_DHT 4749#if DEBUG_DHT
4710 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 4750 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4711 "`%s:%s': Received `%s' request from client, uid %llu\n", 4751 "`%s:%s': Received `%s' request from client, uid %llu\n",
@@ -4713,24 +4753,25 @@ handle_dht_local_route_stop (void *cls, struct GNUNET_SERVER_Client *client,
4713 GNUNET_ntohll (dht_stop_msg->unique_id)); 4753 GNUNET_ntohll (dht_stop_msg->unique_id));
4714#endif 4754#endif
4715 record = 4755 record =
4716 GNUNET_CONTAINER_multihashmap_get (forward_list.hashmap, 4756 GNUNET_CONTAINER_multihashmap_get (forward_list.hashmap,
4717 &dht_stop_msg->key); 4757 &dht_stop_msg->key);
4718 if (record != NULL) 4758 if (record != NULL)
4719 { 4759 {
4720 pos = record->head; 4760 pos = record->head;
4721 4761
4722 while (pos != NULL) 4762 while (pos != NULL)
4723 { 4763 {
4724 /* If the client is non-null (local request) and the client matches the requesting client, remove the entry. */ 4764 /* If the client is non-null (local request) and the client matches the requesting client, remove the entry. */
4725 if ((pos->client != NULL) && (pos->client->client_handle == client)) 4765 if ((pos->client != NULL) && (pos->client->client_handle == client))
4726 { 4766 {
4727 if (pos->delete_task != GNUNET_SCHEDULER_NO_TASK) 4767 if (pos->delete_task != GNUNET_SCHEDULER_NO_TASK)
4728 GNUNET_SCHEDULER_cancel (pos->delete_task); 4768 GNUNET_SCHEDULER_cancel (pos->delete_task);
4729 pos->delete_task = GNUNET_SCHEDULER_add_now (&remove_forward_entry, pos); 4769 pos->delete_task =
4730 } 4770 GNUNET_SCHEDULER_add_now (&remove_forward_entry, pos);
4731 pos = pos->next; 4771 }
4732 } 4772 pos = pos->next;
4733 } 4773 }
4774 }
4734 4775
4735 GNUNET_SERVER_receive_done (client, GNUNET_OK); 4776 GNUNET_SERVER_receive_done (client, GNUNET_OK);
4736} 4777}
@@ -4758,99 +4799,103 @@ handle_dht_p2p_route_request (void *cls,
4758 "DHT", GNUNET_i2s (peer)); 4799 "DHT", GNUNET_i2s (peer));
4759#endif 4800#endif
4760 struct GNUNET_DHT_P2PRouteMessage *incoming = 4801 struct GNUNET_DHT_P2PRouteMessage *incoming =
4761 (struct GNUNET_DHT_P2PRouteMessage *) message; 4802 (struct GNUNET_DHT_P2PRouteMessage *) message;
4762 struct GNUNET_MessageHeader *enc_msg = 4803 struct GNUNET_MessageHeader *enc_msg =
4763 (struct GNUNET_MessageHeader *) &incoming[1]; 4804 (struct GNUNET_MessageHeader *) &incoming[1];
4764 struct DHT_MessageContext *msg_ctx; 4805 struct DHT_MessageContext *msg_ctx;
4765 char *route_path; 4806 char *route_path;
4766 int path_size; 4807 int path_size;
4767 4808
4768 if (ntohs (enc_msg->type) == GNUNET_MESSAGE_TYPE_DHT_P2P_PING) /* Throw these away. FIXME: Don't throw these away? (reply) */ 4809 if (ntohs (enc_msg->type) == GNUNET_MESSAGE_TYPE_DHT_P2P_PING) /* Throw these away. FIXME: Don't throw these away? (reply) */
4769 { 4810 {
4770#if DEBUG_PING 4811#if DEBUG_PING
4771 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 4812 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4772 "%s:%s Received P2P Ping message.\n", my_short_id, "DHT"); 4813 "%s:%s Received P2P Ping message.\n", my_short_id, "DHT");
4773#endif 4814#endif
4774 return GNUNET_YES; 4815 return GNUNET_YES;
4775 } 4816 }
4776 4817
4777 if (ntohs (enc_msg->size) >= GNUNET_SERVER_MAX_MESSAGE_SIZE - 1) 4818 if (ntohs (enc_msg->size) >= GNUNET_SERVER_MAX_MESSAGE_SIZE - 1)
4778 { 4819 {
4779 GNUNET_break_op (0); 4820 GNUNET_break_op (0);
4780 return GNUNET_YES; 4821 return GNUNET_YES;
4781 } 4822 }
4782 4823
4783 if (malicious_dropper == GNUNET_YES) 4824 if (malicious_dropper == GNUNET_YES)
4784 { 4825 {
4785#if DEBUG_DHT_ROUTING 4826#if DEBUG_DHT_ROUTING
4786 if ((debug_routes_extended) && (dhtlog_handle != NULL)) 4827 if ((debug_routes_extended) && (dhtlog_handle != NULL))
4787 { 4828 {
4788 /** Log routes that die due to high load! */ 4829 /** Log routes that die due to high load! */
4789 dhtlog_handle->insert_route (NULL, 4830 dhtlog_handle->insert_route (NULL,
4790 GNUNET_ntohll (incoming->unique_id), 4831 GNUNET_ntohll (incoming->unique_id),
4791 DHTLOG_ROUTE, 4832 DHTLOG_ROUTE,
4792 ntohl (incoming->hop_count), 4833 ntohl (incoming->hop_count),
4793 GNUNET_SYSERR, &my_identity, 4834 GNUNET_SYSERR, &my_identity,
4794 &incoming->key, peer, NULL); 4835 &incoming->key, peer, NULL);
4795 }
4796#endif
4797 return GNUNET_YES;
4798 } 4836 }
4837#endif
4838 return GNUNET_YES;
4839 }
4799 4840
4800 if (get_max_send_delay ().rel_value > MAX_REQUEST_TIME.rel_value) 4841 if (get_max_send_delay ().rel_value > MAX_REQUEST_TIME.rel_value)
4801 { 4842 {
4802 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 4843 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4803 "Sending of previous replies took too long, backing off!\n"); 4844 "Sending of previous replies took too long, backing off!\n");
4804 increment_stats ("# route requests dropped due to high load"); 4845 increment_stats ("# route requests dropped due to high load");
4805 decrease_max_send_delay (get_max_send_delay ()); 4846 decrease_max_send_delay (get_max_send_delay ());
4806#if DEBUG_DHT_ROUTING 4847#if DEBUG_DHT_ROUTING
4807 if ((debug_routes_extended) && (dhtlog_handle != NULL)) 4848 if ((debug_routes_extended) && (dhtlog_handle != NULL))
4808 { 4849 {
4809 /** Log routes that die due to high load! */ 4850 /** Log routes that die due to high load! */
4810 dhtlog_handle->insert_route (NULL, 4851 dhtlog_handle->insert_route (NULL,
4811 GNUNET_ntohll (incoming->unique_id), 4852 GNUNET_ntohll (incoming->unique_id),
4812 DHTLOG_ROUTE, 4853 DHTLOG_ROUTE,
4813 ntohl (incoming->hop_count), 4854 ntohl (incoming->hop_count),
4814 GNUNET_SYSERR, &my_identity, 4855 GNUNET_SYSERR, &my_identity,
4815 &incoming->key, peer, NULL); 4856 &incoming->key, peer, NULL);
4816 }
4817#endif
4818 return GNUNET_YES;
4819 } 4857 }
4858#endif
4859 return GNUNET_YES;
4860 }
4820 msg_ctx = GNUNET_malloc (sizeof (struct DHT_MessageContext)); 4861 msg_ctx = GNUNET_malloc (sizeof (struct DHT_MessageContext));
4821 msg_ctx->bloom = 4862 msg_ctx->bloom =
4822 GNUNET_CONTAINER_bloomfilter_init (incoming->bloomfilter, DHT_BLOOM_SIZE, 4863 GNUNET_CONTAINER_bloomfilter_init (incoming->bloomfilter, DHT_BLOOM_SIZE,
4823 DHT_BLOOM_K); 4864 DHT_BLOOM_K);
4824 GNUNET_assert (msg_ctx->bloom != NULL); 4865 GNUNET_assert (msg_ctx->bloom != NULL);
4825 msg_ctx->hop_count = ntohl (incoming->hop_count); 4866 msg_ctx->hop_count = ntohl (incoming->hop_count);
4826 memcpy (&msg_ctx->key, &incoming->key, sizeof (GNUNET_HashCode)); 4867 memcpy (&msg_ctx->key, &incoming->key, sizeof (GNUNET_HashCode));
4827 msg_ctx->replication = ntohl (incoming->desired_replication_level); 4868 msg_ctx->replication = ntohl (incoming->desired_replication_level);
4828 msg_ctx->unique_id = GNUNET_ntohll (incoming->unique_id); 4869 msg_ctx->unique_id = GNUNET_ntohll (incoming->unique_id);
4829 msg_ctx->msg_options = ntohl (incoming->options); 4870 msg_ctx->msg_options = ntohl (incoming->options);
4830 if (GNUNET_DHT_RO_RECORD_ROUTE == (msg_ctx->msg_options & GNUNET_DHT_RO_RECORD_ROUTE)) 4871 if (GNUNET_DHT_RO_RECORD_ROUTE ==
4831 { 4872 (msg_ctx->msg_options & GNUNET_DHT_RO_RECORD_ROUTE))
4832 path_size = ntohl(incoming->outgoing_path_length) * sizeof(struct GNUNET_PeerIdentity); 4873 {
4833 GNUNET_assert(ntohs(message->size) == 4874 path_size =
4834 (sizeof(struct GNUNET_DHT_P2PRouteMessage) + 4875 ntohl (incoming->outgoing_path_length) *
4835 ntohs(enc_msg->size) + 4876 sizeof (struct GNUNET_PeerIdentity);
4836 path_size)); 4877 GNUNET_assert (ntohs (message->size) ==
4837 route_path = (char *)&incoming[1]; 4878 (sizeof (struct GNUNET_DHT_P2PRouteMessage) +
4838 route_path = route_path + ntohs(enc_msg->size); 4879 ntohs (enc_msg->size) + path_size));
4839 msg_ctx->path_history = GNUNET_malloc(sizeof(struct GNUNET_PeerIdentity) + path_size); 4880 route_path = (char *) &incoming[1];
4840 memcpy(msg_ctx->path_history, route_path, path_size); 4881 route_path = route_path + ntohs (enc_msg->size);
4841 memcpy(&msg_ctx->path_history[path_size], &my_identity, sizeof(struct GNUNET_PeerIdentity)); 4882 msg_ctx->path_history =
4842 msg_ctx->path_history_len = ntohl(incoming->outgoing_path_length) + 1; 4883 GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) + path_size);
4843 } 4884 memcpy (msg_ctx->path_history, route_path, path_size);
4885 memcpy (&msg_ctx->path_history[path_size], &my_identity,
4886 sizeof (struct GNUNET_PeerIdentity));
4887 msg_ctx->path_history_len = ntohl (incoming->outgoing_path_length) + 1;
4888 }
4844 msg_ctx->network_size = ntohl (incoming->network_size); 4889 msg_ctx->network_size = ntohl (incoming->network_size);
4845 msg_ctx->peer = peer; 4890 msg_ctx->peer = peer;
4846 msg_ctx->importance = DHT_DEFAULT_P2P_IMPORTANCE; 4891 msg_ctx->importance = DHT_DEFAULT_P2P_IMPORTANCE;
4847 msg_ctx->timeout = DHT_DEFAULT_P2P_TIMEOUT; 4892 msg_ctx->timeout = DHT_DEFAULT_P2P_TIMEOUT;
4848 demultiplex_message (enc_msg, msg_ctx); 4893 demultiplex_message (enc_msg, msg_ctx);
4849 if (msg_ctx->bloom != NULL) 4894 if (msg_ctx->bloom != NULL)
4850 { 4895 {
4851 GNUNET_CONTAINER_bloomfilter_free (msg_ctx->bloom); 4896 GNUNET_CONTAINER_bloomfilter_free (msg_ctx->bloom);
4852 msg_ctx->bloom = NULL; 4897 msg_ctx->bloom = NULL;
4853 } 4898 }
4854 GNUNET_free (msg_ctx); 4899 GNUNET_free (msg_ctx);
4855 return GNUNET_YES; 4900 return GNUNET_YES;
4856} 4901}
@@ -4878,36 +4923,37 @@ handle_dht_p2p_route_result (void *cls,
4878 GNUNET_i2s (peer)); 4923 GNUNET_i2s (peer));
4879#endif 4924#endif
4880 struct GNUNET_DHT_P2PRouteResultMessage *incoming = 4925 struct GNUNET_DHT_P2PRouteResultMessage *incoming =
4881 (struct GNUNET_DHT_P2PRouteResultMessage *) message; 4926 (struct GNUNET_DHT_P2PRouteResultMessage *) message;
4882 struct GNUNET_MessageHeader *enc_msg = 4927 struct GNUNET_MessageHeader *enc_msg =
4883 (struct GNUNET_MessageHeader *) &incoming[1]; 4928 (struct GNUNET_MessageHeader *) &incoming[1];
4884 struct DHT_MessageContext msg_ctx; 4929 struct DHT_MessageContext msg_ctx;
4930
4885#if DEBUG_PATH 4931#if DEBUG_PATH
4886 char *path_offset; 4932 char *path_offset;
4887 unsigned int i; 4933 unsigned int i;
4888#endif 4934#endif
4889 if (ntohs (enc_msg->size) >= GNUNET_SERVER_MAX_MESSAGE_SIZE - 1) 4935 if (ntohs (enc_msg->size) >= GNUNET_SERVER_MAX_MESSAGE_SIZE - 1)
4890 { 4936 {
4891 GNUNET_break_op (0); 4937 GNUNET_break_op (0);
4892 return GNUNET_YES; 4938 return GNUNET_YES;
4893 } 4939 }
4894 4940
4895 if (malicious_dropper == GNUNET_YES) 4941 if (malicious_dropper == GNUNET_YES)
4896 { 4942 {
4897#if DEBUG_DHT_ROUTING 4943#if DEBUG_DHT_ROUTING
4898 if ((debug_routes_extended) && (dhtlog_handle != NULL)) 4944 if ((debug_routes_extended) && (dhtlog_handle != NULL))
4899 { 4945 {
4900 /** Log routes that die due to high load! */ 4946 /** Log routes that die due to high load! */
4901 dhtlog_handle->insert_route (NULL, 4947 dhtlog_handle->insert_route (NULL,
4902 GNUNET_ntohll (incoming->unique_id), 4948 GNUNET_ntohll (incoming->unique_id),
4903 DHTLOG_ROUTE, 4949 DHTLOG_ROUTE,
4904 ntohl (incoming->hop_count), 4950 ntohl (incoming->hop_count),
4905 GNUNET_SYSERR, &my_identity, 4951 GNUNET_SYSERR, &my_identity,
4906 &incoming->key, peer, NULL); 4952 &incoming->key, peer, NULL);
4907 }
4908#endif
4909 return GNUNET_YES;
4910 } 4953 }
4954#endif
4955 return GNUNET_YES;
4956 }
4911 4957
4912 memset (&msg_ctx, 0, sizeof (struct DHT_MessageContext)); 4958 memset (&msg_ctx, 0, sizeof (struct DHT_MessageContext));
4913 // FIXME: call GNUNET_BLOCK_evaluate (...) -- instead of doing your own bloomfilter! 4959 // FIXME: call GNUNET_BLOCK_evaluate (...) -- instead of doing your own bloomfilter!
@@ -4918,40 +4964,48 @@ handle_dht_p2p_route_result (void *cls,
4918 msg_ctx.peer = peer; 4964 msg_ctx.peer = peer;
4919 msg_ctx.importance = DHT_DEFAULT_P2P_IMPORTANCE + 2; /* Make result routing a higher priority */ 4965 msg_ctx.importance = DHT_DEFAULT_P2P_IMPORTANCE + 2; /* Make result routing a higher priority */
4920 msg_ctx.timeout = DHT_DEFAULT_P2P_TIMEOUT; 4966 msg_ctx.timeout = DHT_DEFAULT_P2P_TIMEOUT;
4921 if ((GNUNET_DHT_RO_RECORD_ROUTE == (msg_ctx.msg_options & GNUNET_DHT_RO_RECORD_ROUTE)) && (ntohl (incoming->outgoing_path_length) > 0)) 4967 if ((GNUNET_DHT_RO_RECORD_ROUTE ==
4968 (msg_ctx.msg_options & GNUNET_DHT_RO_RECORD_ROUTE)) &&
4969 (ntohl (incoming->outgoing_path_length) > 0))
4970 {
4971 if (ntohs (message->size) -
4972 sizeof (struct GNUNET_DHT_P2PRouteResultMessage) -
4973 ntohs (enc_msg->size) !=
4974 ntohl (incoming->outgoing_path_length) *
4975 sizeof (struct GNUNET_PeerIdentity))
4922 { 4976 {
4923 if (ntohs(message->size) - sizeof(struct GNUNET_DHT_P2PRouteResultMessage) - ntohs(enc_msg->size) !=
4924 ntohl (incoming->outgoing_path_length) * sizeof(struct GNUNET_PeerIdentity))
4925 {
4926#if DEBUG_DHT 4977#if DEBUG_DHT
4927 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 4978 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4928 "Return message indicated a path was included, but sizes are wrong: Total size %d, enc size %d, left %d, expected %d\n", 4979 "Return message indicated a path was included, but sizes are wrong: Total size %d, enc size %d, left %d, expected %d\n",
4929 ntohs(message->size), 4980 ntohs (message->size),
4930 ntohs(enc_msg->size), 4981 ntohs (enc_msg->size),
4931 ntohs(message->size) - sizeof(struct GNUNET_DHT_P2PRouteResultMessage) - ntohs(enc_msg->size), 4982 ntohs (message->size) -
4932 ntohl(incoming->outgoing_path_length) * sizeof(struct GNUNET_PeerIdentity)); 4983 sizeof (struct GNUNET_DHT_P2PRouteResultMessage) -
4984 ntohs (enc_msg->size),
4985 ntohl (incoming->outgoing_path_length) *
4986 sizeof (struct GNUNET_PeerIdentity));
4933#endif 4987#endif
4934 GNUNET_break_op (0); 4988 GNUNET_break_op (0);
4935 return GNUNET_NO; 4989 return GNUNET_NO;
4936 } 4990 }
4937 msg_ctx.path_history = (char *)&incoming[1]; 4991 msg_ctx.path_history = (char *) &incoming[1];
4938 msg_ctx.path_history += ntohs(enc_msg->size); 4992 msg_ctx.path_history += ntohs (enc_msg->size);
4939 msg_ctx.path_history_len = ntohl (incoming->outgoing_path_length); 4993 msg_ctx.path_history_len = ntohl (incoming->outgoing_path_length);
4940#if DEBUG_PATH 4994#if DEBUG_PATH
4941 for (i = 0; i < msg_ctx.path_history_len; i++) 4995 for (i = 0; i < msg_ctx.path_history_len; i++)
4942 { 4996 {
4943 path_offset = &msg_ctx.path_history[i * sizeof(struct GNUNET_PeerIdentity)]; 4997 path_offset =
4944 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 4998 &msg_ctx.path_history[i * sizeof (struct GNUNET_PeerIdentity)];
4945 "(handle_p2p_route_result) Key %s Found peer %d:%s\n", 4999 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4946 GNUNET_h2s(&msg_ctx.key), 5000 "(handle_p2p_route_result) Key %s Found peer %d:%s\n",
4947 i, 5001 GNUNET_h2s (&msg_ctx.key), i,
4948 GNUNET_i2s((struct GNUNET_PeerIdentity *)path_offset)); 5002 GNUNET_i2s ((struct GNUNET_PeerIdentity *) path_offset));
4949 }
4950#endif
4951 } 5003 }
5004#endif
5005 }
4952 msg_ctx.bloom = 5006 msg_ctx.bloom =
4953 GNUNET_CONTAINER_bloomfilter_init (incoming->bloomfilter, DHT_BLOOM_SIZE, 5007 GNUNET_CONTAINER_bloomfilter_init (incoming->bloomfilter, DHT_BLOOM_SIZE,
4954 DHT_BLOOM_K); 5008 DHT_BLOOM_K);
4955 GNUNET_assert (msg_ctx.bloom != NULL); 5009 GNUNET_assert (msg_ctx.bloom != NULL);
4956 route_result_message (enc_msg, &msg_ctx); 5010 route_result_message (enc_msg, &msg_ctx);
4957 return GNUNET_YES; 5011 return GNUNET_YES;
@@ -4993,59 +5047,57 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
4993 struct PeerInfo *pos; 5047 struct PeerInfo *pos;
4994 5048
4995 if (transport_handle != NULL) 5049 if (transport_handle != NULL)
4996 { 5050 {
4997 GNUNET_free_non_null (my_hello); 5051 GNUNET_free_non_null (my_hello);
4998 GNUNET_TRANSPORT_get_hello_cancel (transport_handle, &process_hello, 5052 GNUNET_TRANSPORT_get_hello_cancel (transport_handle, &process_hello, NULL);
4999 NULL); 5053 GNUNET_TRANSPORT_disconnect (transport_handle);
5000 GNUNET_TRANSPORT_disconnect (transport_handle); 5054 }
5001 }
5002 if (coreAPI != NULL) 5055 if (coreAPI != NULL)
5003 { 5056 {
5004#if DEBUG_DHT 5057#if DEBUG_DHT
5005 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 5058 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5006 "%s:%s Disconnecting core!\n", my_short_id, "DHT"); 5059 "%s:%s Disconnecting core!\n", my_short_id, "DHT");
5007#endif 5060#endif
5008 GNUNET_CORE_disconnect (coreAPI); 5061 GNUNET_CORE_disconnect (coreAPI);
5009 coreAPI = NULL; 5062 coreAPI = NULL;
5010 } 5063 }
5011 for (bucket_count = lowest_bucket; bucket_count < MAX_BUCKETS; 5064 for (bucket_count = lowest_bucket; bucket_count < MAX_BUCKETS; bucket_count++)
5012 bucket_count++) 5065 {
5013 { 5066 while (k_buckets[bucket_count].head != NULL)
5014 while (k_buckets[bucket_count].head != NULL) 5067 {
5015 { 5068 pos = k_buckets[bucket_count].head;
5016 pos = k_buckets[bucket_count].head;
5017#if DEBUG_DHT 5069#if DEBUG_DHT
5018 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 5070 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5019 "%s:%s Removing peer %s from bucket %d!\n", my_short_id, 5071 "%s:%s Removing peer %s from bucket %d!\n", my_short_id,
5020 "DHT", GNUNET_i2s (&pos->id), bucket_count); 5072 "DHT", GNUNET_i2s (&pos->id), bucket_count);
5021#endif 5073#endif
5022 delete_peer (pos, bucket_count); 5074 delete_peer (pos, bucket_count);
5023 }
5024 } 5075 }
5076 }
5025 if (datacache != NULL) 5077 if (datacache != NULL)
5026 { 5078 {
5027#if DEBUG_DHT 5079#if DEBUG_DHT
5028 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 5080 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5029 "%s:%s Destroying datacache!\n", my_short_id, "DHT"); 5081 "%s:%s Destroying datacache!\n", my_short_id, "DHT");
5030#endif 5082#endif
5031 GNUNET_DATACACHE_destroy (datacache); 5083 GNUNET_DATACACHE_destroy (datacache);
5032 datacache = NULL; 5084 datacache = NULL;
5033 } 5085 }
5034 if (stats != NULL) 5086 if (stats != NULL)
5035 { 5087 {
5036 GNUNET_STATISTICS_destroy (stats, GNUNET_YES); 5088 GNUNET_STATISTICS_destroy (stats, GNUNET_YES);
5037 stats = NULL; 5089 stats = NULL;
5038 } 5090 }
5039 if (dhtlog_handle != NULL) 5091 if (dhtlog_handle != NULL)
5040 { 5092 {
5041 GNUNET_DHTLOG_disconnect (dhtlog_handle); 5093 GNUNET_DHTLOG_disconnect (dhtlog_handle);
5042 dhtlog_handle = NULL; 5094 dhtlog_handle = NULL;
5043 } 5095 }
5044 if (block_context != NULL) 5096 if (block_context != NULL)
5045 { 5097 {
5046 GNUNET_BLOCK_context_destroy (block_context); 5098 GNUNET_BLOCK_context_destroy (block_context);
5047 block_context = NULL; 5099 block_context = NULL;
5048 } 5100 }
5049 GNUNET_free_non_null (my_short_id); 5101 GNUNET_free_non_null (my_short_id);
5050 my_short_id = NULL; 5102 my_short_id = NULL;
5051} 5103}
@@ -5067,16 +5119,16 @@ core_init (void *cls,
5067{ 5119{
5068 5120
5069 if (server == NULL) 5121 if (server == NULL)
5070 { 5122 {
5071#if DEBUG_DHT 5123#if DEBUG_DHT
5072 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 5124 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5073 "%s: Connection to core FAILED!\n", "dht", 5125 "%s: Connection to core FAILED!\n", "dht",
5074 GNUNET_i2s (identity)); 5126 GNUNET_i2s (identity));
5075#endif 5127#endif
5076 GNUNET_SCHEDULER_cancel (cleanup_task); 5128 GNUNET_SCHEDULER_cancel (cleanup_task);
5077 GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); 5129 GNUNET_SCHEDULER_add_now (&shutdown_task, NULL);
5078 return; 5130 return;
5079 } 5131 }
5080#if DEBUG_DHT 5132#if DEBUG_DHT
5081 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 5133 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5082 "%s: Core connection initialized, I am peer: %s\n", "dht", 5134 "%s: Core connection initialized, I am peer: %s\n", "dht",
@@ -5132,7 +5184,7 @@ handle_core_connect (void *cls,
5132 int peer_bucket; 5184 int peer_bucket;
5133 5185
5134 /* Check for connect to self message */ 5186 /* Check for connect to self message */
5135 if (0 == memcmp(&my_identity, peer, sizeof(struct GNUNET_PeerIdentity))) 5187 if (0 == memcmp (&my_identity, peer, sizeof (struct GNUNET_PeerIdentity)))
5136 return; 5188 return;
5137 5189
5138#if DEBUG_DHT 5190#if DEBUG_DHT
@@ -5144,30 +5196,34 @@ handle_core_connect (void *cls,
5144 if (GNUNET_YES == 5196 if (GNUNET_YES ==
5145 GNUNET_CONTAINER_multihashmap_contains (all_known_peers, 5197 GNUNET_CONTAINER_multihashmap_contains (all_known_peers,
5146 &peer->hashPubKey)) 5198 &peer->hashPubKey))
5147 { 5199 {
5148#if DEBUG_DHT 5200#if DEBUG_DHT
5149 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 5201 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5150 "%s:%s Received %s message for peer %s, but already have peer in RT!", 5202 "%s:%s Received %s message for peer %s, but already have peer in RT!",
5151 my_short_id, "DHT", "CORE CONNECT", GNUNET_i2s (peer)); 5203 my_short_id, "DHT", "CORE CONNECT", GNUNET_i2s (peer));
5152#endif 5204#endif
5153 GNUNET_break (0); 5205 GNUNET_break (0);
5154 return; 5206 return;
5155 } 5207 }
5156 5208
5157 if ((datacache != NULL) && (GNUNET_YES == put_peer_identities)) 5209 if ((datacache != NULL) && (GNUNET_YES == put_peer_identities))
5158 { 5210 {
5159 put_entry = GNUNET_malloc(sizeof(struct DHTPutEntry) + sizeof (struct GNUNET_PeerIdentity)); 5211 put_entry =
5160 put_entry->path_length = 0; 5212 GNUNET_malloc (sizeof (struct DHTPutEntry) +
5161 put_entry->data_size = sizeof (struct GNUNET_PeerIdentity); 5213 sizeof (struct GNUNET_PeerIdentity));
5162 memcpy(&put_entry[1], peer, sizeof (struct GNUNET_PeerIdentity)); 5214 put_entry->path_length = 0;
5163 GNUNET_DATACACHE_put (datacache, &peer->hashPubKey, 5215 put_entry->data_size = sizeof (struct GNUNET_PeerIdentity);
5164 sizeof(struct DHTPutEntry) + sizeof (struct GNUNET_PeerIdentity), 5216 memcpy (&put_entry[1], peer, sizeof (struct GNUNET_PeerIdentity));
5165 (char *)put_entry, GNUNET_BLOCK_TYPE_DHT_HELLO, 5217 GNUNET_DATACACHE_put (datacache, &peer->hashPubKey,
5166 GNUNET_TIME_absolute_get_forever ()); 5218 sizeof (struct DHTPutEntry) +
5167 GNUNET_free (put_entry); 5219 sizeof (struct GNUNET_PeerIdentity),
5168 } 5220 (char *) put_entry, GNUNET_BLOCK_TYPE_DHT_HELLO,
5221 GNUNET_TIME_absolute_get_forever ());
5222 GNUNET_free (put_entry);
5223 }
5169 else if (datacache == NULL) 5224 else if (datacache == NULL)
5170 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "DHT has no connection to datacache!\n"); 5225 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
5226 "DHT has no connection to datacache!\n");
5171 5227
5172 peer_bucket = find_current_bucket (&peer->hashPubKey); 5228 peer_bucket = find_current_bucket (&peer->hashPubKey);
5173 GNUNET_assert (peer_bucket >= lowest_bucket); 5229 GNUNET_assert (peer_bucket >= lowest_bucket);
@@ -5180,15 +5236,14 @@ handle_core_connect (void *cls,
5180 ret->id = *peer; 5236 ret->id = *peer;
5181 GNUNET_CONTAINER_DLL_insert_after (k_buckets[peer_bucket].head, 5237 GNUNET_CONTAINER_DLL_insert_after (k_buckets[peer_bucket].head,
5182 k_buckets[peer_bucket].tail, 5238 k_buckets[peer_bucket].tail,
5183 k_buckets[peer_bucket].tail, 5239 k_buckets[peer_bucket].tail, ret);
5184 ret);
5185 k_buckets[peer_bucket].peers_size++; 5240 k_buckets[peer_bucket].peers_size++;
5186#if DO_UPDATE_PREFERENCE 5241#if DO_UPDATE_PREFERENCE
5187 if ( (GNUNET_CRYPTO_hash_matching_bits 5242 if ((GNUNET_CRYPTO_hash_matching_bits
5188 (&my_identity.hashPubKey, &peer->hashPubKey) > 0) && 5243 (&my_identity.hashPubKey, &peer->hashPubKey) > 0) &&
5189 (k_buckets[peer_bucket].peers_size <= bucket_size) ) 5244 (k_buckets[peer_bucket].peers_size <= bucket_size))
5190 ret->preference_task = GNUNET_SCHEDULER_add_now (&update_core_preference, 5245 ret->preference_task = GNUNET_SCHEDULER_add_now (&update_core_preference,
5191 ret); 5246 ret);
5192#endif 5247#endif
5193 if ((k_buckets[lowest_bucket].peers_size) >= bucket_size) 5248 if ((k_buckets[lowest_bucket].peers_size) >= bucket_size)
5194 enable_next_bucket (); 5249 enable_next_bucket ();
@@ -5197,9 +5252,9 @@ handle_core_connect (void *cls,
5197#endif 5252#endif
5198 newly_found_peers++; 5253 newly_found_peers++;
5199 GNUNET_CONTAINER_multihashmap_put (all_known_peers, &peer->hashPubKey, 5254 GNUNET_CONTAINER_multihashmap_put (all_known_peers, &peer->hashPubKey,
5200 ret, 5255 ret,
5201 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); 5256 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
5202 increment_stats (STAT_PEERS_KNOWN); 5257 increment_stats (STAT_PEERS_KNOWN);
5203 5258
5204#if DEBUG_DHT 5259#if DEBUG_DHT
5205 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 5260 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -5222,7 +5277,7 @@ handle_core_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer)
5222 int current_bucket; 5277 int current_bucket;
5223 5278
5224 /* Check for disconnect from self message */ 5279 /* Check for disconnect from self message */
5225 if (0 == memcmp(&my_identity, peer, sizeof(struct GNUNET_PeerIdentity))) 5280 if (0 == memcmp (&my_identity, peer, sizeof (struct GNUNET_PeerIdentity)))
5226 return; 5281 return;
5227#if DEBUG_DHT 5282#if DEBUG_DHT
5228 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 5283 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -5233,26 +5288,26 @@ handle_core_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer)
5233 if (GNUNET_YES != 5288 if (GNUNET_YES !=
5234 GNUNET_CONTAINER_multihashmap_contains (all_known_peers, 5289 GNUNET_CONTAINER_multihashmap_contains (all_known_peers,
5235 &peer->hashPubKey)) 5290 &peer->hashPubKey))
5236 { 5291 {
5237 GNUNET_break (0); 5292 GNUNET_break (0);
5238#if DEBUG_DHT 5293#if DEBUG_DHT
5239 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 5294 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5240 "%s:%s: do not have peer `%s' in RT, can't disconnect!\n", 5295 "%s:%s: do not have peer `%s' in RT, can't disconnect!\n",
5241 my_short_id, "DHT", GNUNET_i2s (peer)); 5296 my_short_id, "DHT", GNUNET_i2s (peer));
5242#endif 5297#endif
5243 return; 5298 return;
5244 } 5299 }
5245 increment_stats (STAT_DISCONNECTS); 5300 increment_stats (STAT_DISCONNECTS);
5246 GNUNET_assert (GNUNET_CONTAINER_multihashmap_contains 5301 GNUNET_assert (GNUNET_CONTAINER_multihashmap_contains
5247 (all_known_peers, &peer->hashPubKey)); 5302 (all_known_peers, &peer->hashPubKey));
5248 to_remove = 5303 to_remove =
5249 GNUNET_CONTAINER_multihashmap_get (all_known_peers, &peer->hashPubKey); 5304 GNUNET_CONTAINER_multihashmap_get (all_known_peers, &peer->hashPubKey);
5250 GNUNET_assert (to_remove != NULL); 5305 GNUNET_assert (to_remove != NULL);
5251 if (NULL != to_remove->info_ctx) 5306 if (NULL != to_remove->info_ctx)
5252 { 5307 {
5253 GNUNET_CORE_peer_change_preference_cancel (to_remove->info_ctx); 5308 GNUNET_CORE_peer_change_preference_cancel (to_remove->info_ctx);
5254 to_remove->info_ctx = NULL; 5309 to_remove->info_ctx = NULL;
5255 } 5310 }
5256 GNUNET_assert (0 == 5311 GNUNET_assert (0 ==
5257 memcmp (peer, &to_remove->id, 5312 memcmp (peer, &to_remove->id,
5258 sizeof (struct GNUNET_PeerIdentity))); 5313 sizeof (struct GNUNET_PeerIdentity)));
@@ -5306,101 +5361,101 @@ run (void *cls,
5306 block_context = GNUNET_BLOCK_context_create (cfg); 5361 block_context = GNUNET_BLOCK_context_create (cfg);
5307 lowest_bucket = MAX_BUCKETS - 1; 5362 lowest_bucket = MAX_BUCKETS - 1;
5308 forward_list.hashmap = 5363 forward_list.hashmap =
5309 GNUNET_CONTAINER_multihashmap_create (MAX_OUTSTANDING_FORWARDS / 10); 5364 GNUNET_CONTAINER_multihashmap_create (MAX_OUTSTANDING_FORWARDS / 10);
5310 forward_list.minHeap = 5365 forward_list.minHeap =
5311 GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); 5366 GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
5312 all_known_peers = GNUNET_CONTAINER_multihashmap_create (MAX_BUCKETS / 8); 5367 all_known_peers = GNUNET_CONTAINER_multihashmap_create (MAX_BUCKETS / 8);
5313 recent_find_peer_requests = 5368 recent_find_peer_requests =
5314 GNUNET_CONTAINER_multihashmap_create (MAX_BUCKETS / 8); 5369 GNUNET_CONTAINER_multihashmap_create (MAX_BUCKETS / 8);
5315 GNUNET_assert (all_known_peers != NULL); 5370 GNUNET_assert (all_known_peers != NULL);
5316 if (GNUNET_YES == 5371 if (GNUNET_YES ==
5317 GNUNET_CONFIGURATION_get_value_yesno (cfg, "dht_testing", 5372 GNUNET_CONFIGURATION_get_value_yesno (cfg, "dht_testing",
5318 "mysql_logging")) 5373 "mysql_logging"))
5319 { 5374 {
5320 debug_routes = GNUNET_YES; 5375 debug_routes = GNUNET_YES;
5321 } 5376 }
5322 5377
5323 if (GNUNET_YES == 5378 if (GNUNET_YES ==
5324 GNUNET_CONFIGURATION_get_value_yesno (cfg, "dht", "strict_kademlia")) 5379 GNUNET_CONFIGURATION_get_value_yesno (cfg, "dht", "strict_kademlia"))
5325 { 5380 {
5326 strict_kademlia = GNUNET_YES; 5381 strict_kademlia = GNUNET_YES;
5327 } 5382 }
5328 5383
5329 if (GNUNET_YES == 5384 if (GNUNET_YES ==
5330 GNUNET_CONFIGURATION_get_value_yesno (cfg, "dht", "stop_on_closest")) 5385 GNUNET_CONFIGURATION_get_value_yesno (cfg, "dht", "stop_on_closest"))
5331 { 5386 {
5332 stop_on_closest = GNUNET_YES; 5387 stop_on_closest = GNUNET_YES;
5333 } 5388 }
5334 5389
5335 if (GNUNET_YES == 5390 if (GNUNET_YES ==
5336 GNUNET_CONFIGURATION_get_value_yesno (cfg, "dht", "stop_found")) 5391 GNUNET_CONFIGURATION_get_value_yesno (cfg, "dht", "stop_found"))
5337 { 5392 {
5338 stop_on_found = GNUNET_YES; 5393 stop_on_found = GNUNET_YES;
5339 } 5394 }
5340 5395
5341 if (GNUNET_YES == 5396 if (GNUNET_YES ==
5342 GNUNET_CONFIGURATION_get_value_yesno (cfg, "dht", "malicious_getter")) 5397 GNUNET_CONFIGURATION_get_value_yesno (cfg, "dht", "malicious_getter"))
5343 { 5398 {
5344 malicious_getter = GNUNET_YES; 5399 malicious_getter = GNUNET_YES;
5345 if (GNUNET_NO == GNUNET_CONFIGURATION_get_value_number (cfg, "DHT", 5400 if (GNUNET_NO == GNUNET_CONFIGURATION_get_value_number (cfg, "DHT",
5346 "MALICIOUS_GET_FREQUENCY", 5401 "MALICIOUS_GET_FREQUENCY",
5347 &malicious_get_frequency)) 5402 &malicious_get_frequency))
5348 malicious_get_frequency = DEFAULT_MALICIOUS_GET_FREQUENCY; 5403 malicious_get_frequency = DEFAULT_MALICIOUS_GET_FREQUENCY;
5349 } 5404 }
5350 5405
5351 if (GNUNET_YES != GNUNET_CONFIGURATION_get_value_number (cfg, "DHT", 5406 if (GNUNET_YES != GNUNET_CONFIGURATION_get_value_number (cfg, "DHT",
5352 "MAX_HOPS", 5407 "MAX_HOPS",
5353 &max_hops)) 5408 &max_hops))
5354 { 5409 {
5355 max_hops = DEFAULT_MAX_HOPS; 5410 max_hops = DEFAULT_MAX_HOPS;
5356 } 5411 }
5357 5412
5358 if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (cfg, "DHT", 5413 if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (cfg, "DHT",
5359 "USE_MAX_HOPS")) 5414 "USE_MAX_HOPS"))
5360 { 5415 {
5361 use_max_hops = GNUNET_YES; 5416 use_max_hops = GNUNET_YES;
5362 } 5417 }
5363 5418
5364 if (GNUNET_YES == 5419 if (GNUNET_YES ==
5365 GNUNET_CONFIGURATION_get_value_yesno (cfg, "dht", "malicious_putter")) 5420 GNUNET_CONFIGURATION_get_value_yesno (cfg, "dht", "malicious_putter"))
5366 { 5421 {
5367 malicious_putter = GNUNET_YES; 5422 malicious_putter = GNUNET_YES;
5368 if (GNUNET_NO == GNUNET_CONFIGURATION_get_value_number (cfg, "DHT", 5423 if (GNUNET_NO == GNUNET_CONFIGURATION_get_value_number (cfg, "DHT",
5369 "MALICIOUS_PUT_FREQUENCY", 5424 "MALICIOUS_PUT_FREQUENCY",
5370 &malicious_put_frequency)) 5425 &malicious_put_frequency))
5371 malicious_put_frequency = DEFAULT_MALICIOUS_PUT_FREQUENCY; 5426 malicious_put_frequency = DEFAULT_MALICIOUS_PUT_FREQUENCY;
5372 } 5427 }
5373 5428
5374 dht_republish_frequency = GNUNET_DHT_DEFAULT_REPUBLISH_FREQUENCY; 5429 dht_republish_frequency = GNUNET_DHT_DEFAULT_REPUBLISH_FREQUENCY;
5375 if (GNUNET_OK == 5430 if (GNUNET_OK ==
5376 GNUNET_CONFIGURATION_get_value_number (cfg, "DHT", 5431 GNUNET_CONFIGURATION_get_value_number (cfg, "DHT",
5377 "REPLICATION_FREQUENCY", 5432 "REPLICATION_FREQUENCY",
5378 &temp_config_num)) 5433 &temp_config_num))
5379 { 5434 {
5380 dht_republish_frequency = 5435 dht_republish_frequency =
5381 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5436 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES,
5382 temp_config_num); 5437 temp_config_num);
5383 } 5438 }
5384 5439
5385 if (GNUNET_OK == 5440 if (GNUNET_OK ==
5386 GNUNET_CONFIGURATION_get_value_number (cfg, "DHT", "bucket_size", 5441 GNUNET_CONFIGURATION_get_value_number (cfg, "DHT", "bucket_size",
5387 &temp_config_num)) 5442 &temp_config_num))
5388 { 5443 {
5389 bucket_size = (unsigned int) temp_config_num; 5444 bucket_size = (unsigned int) temp_config_num;
5390 } 5445 }
5391 5446
5392 if (GNUNET_OK != 5447 if (GNUNET_OK !=
5393 GNUNET_CONFIGURATION_get_value_number (cfg, "DHT", "kad_alpha", 5448 GNUNET_CONFIGURATION_get_value_number (cfg, "DHT", "kad_alpha",
5394 &kademlia_replication)) 5449 &kademlia_replication))
5395 { 5450 {
5396 kademlia_replication = DEFAULT_KADEMLIA_REPLICATION; 5451 kademlia_replication = DEFAULT_KADEMLIA_REPLICATION;
5397 } 5452 }
5398 5453
5399 if (GNUNET_YES == 5454 if (GNUNET_YES ==
5400 GNUNET_CONFIGURATION_get_value_yesno (cfg, "dht", "malicious_dropper")) 5455 GNUNET_CONFIGURATION_get_value_yesno (cfg, "dht", "malicious_dropper"))
5401 { 5456 {
5402 malicious_dropper = GNUNET_YES; 5457 malicious_dropper = GNUNET_YES;
5403 } 5458 }
5404 5459
5405 if (GNUNET_YES == 5460 if (GNUNET_YES ==
5406 GNUNET_CONFIGURATION_get_value_yesno (cfg, "dht", "republish")) 5461 GNUNET_CONFIGURATION_get_value_yesno (cfg, "dht", "republish"))
@@ -5408,9 +5463,9 @@ run (void *cls,
5408 5463
5409 if (GNUNET_NO == 5464 if (GNUNET_NO ==
5410 GNUNET_CONFIGURATION_get_value_yesno (cfg, "dht", "do_find_peer")) 5465 GNUNET_CONFIGURATION_get_value_yesno (cfg, "dht", "do_find_peer"))
5411 { 5466 {
5412 do_find_peer = GNUNET_NO; 5467 do_find_peer = GNUNET_NO;
5413 } 5468 }
5414 else 5469 else
5415 do_find_peer = GNUNET_YES; 5470 do_find_peer = GNUNET_YES;
5416 5471
@@ -5421,113 +5476,109 @@ run (void *cls,
5421 if (GNUNET_YES == 5476 if (GNUNET_YES ==
5422 GNUNET_CONFIGURATION_get_value_yesno (cfg, "dht_testing", 5477 GNUNET_CONFIGURATION_get_value_yesno (cfg, "dht_testing",
5423 "mysql_logging_extended")) 5478 "mysql_logging_extended"))
5424 { 5479 {
5425 debug_routes = GNUNET_YES; 5480 debug_routes = GNUNET_YES;
5426 debug_routes_extended = GNUNET_YES; 5481 debug_routes_extended = GNUNET_YES;
5427 } 5482 }
5428 5483
5429#if DEBUG_DHT_ROUTING 5484#if DEBUG_DHT_ROUTING
5430 if (GNUNET_YES == debug_routes) 5485 if (GNUNET_YES == debug_routes)
5486 {
5487 dhtlog_handle = GNUNET_DHTLOG_connect (cfg);
5488 if (dhtlog_handle == NULL)
5431 { 5489 {
5432 dhtlog_handle = GNUNET_DHTLOG_connect (cfg); 5490 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
5433 if (dhtlog_handle == NULL) 5491 "Could not connect to mysql logging server, logging will not happen!");
5434 {
5435 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
5436 "Could not connect to mysql logging server, logging will not happen!");
5437 }
5438 } 5492 }
5493 }
5439#endif 5494#endif
5440 5495
5441 converge_option = DHT_CONVERGE_BINARY; 5496 converge_option = DHT_CONVERGE_BINARY;
5442 if (GNUNET_YES == 5497 if (GNUNET_YES ==
5443 GNUNET_CONFIGURATION_get_value_yesno (cfg, "dht", "converge_linear")) 5498 GNUNET_CONFIGURATION_get_value_yesno (cfg, "dht", "converge_linear"))
5444 { 5499 {
5445 converge_option = DHT_CONVERGE_LINEAR; 5500 converge_option = DHT_CONVERGE_LINEAR;
5446 } 5501 }
5447 else if (GNUNET_YES == 5502 else if (GNUNET_YES ==
5448 GNUNET_CONFIGURATION_get_value_yesno (cfg, "dht", 5503 GNUNET_CONFIGURATION_get_value_yesno (cfg, "dht",
5449 "converge_exponential")) 5504 "converge_exponential"))
5450 { 5505 {
5451 converge_option = DHT_CONVERGE_EXPONENTIAL; 5506 converge_option = DHT_CONVERGE_EXPONENTIAL;
5452 } 5507 }
5453 else if (GNUNET_YES == 5508 else if (GNUNET_YES ==
5454 GNUNET_CONFIGURATION_get_value_yesno (cfg, "dht", 5509 GNUNET_CONFIGURATION_get_value_yesno (cfg, "dht", "converge_random"))
5455 "converge_random")) 5510 {
5456 { 5511 converge_option = DHT_CONVERGE_RANDOM;
5457 converge_option = DHT_CONVERGE_RANDOM; 5512 }
5458 }
5459 else if (GNUNET_YES == 5513 else if (GNUNET_YES ==
5460 GNUNET_CONFIGURATION_get_value_yesno (cfg, "dht", 5514 GNUNET_CONFIGURATION_get_value_yesno (cfg, "dht", "converge_binary"))
5461 "converge_binary")) 5515 {
5462 { 5516 converge_option = DHT_CONVERGE_BINARY;
5463 converge_option = DHT_CONVERGE_BINARY; 5517 }
5464 }
5465 5518
5466 converge_modifier = 4.0; 5519 converge_modifier = 4.0;
5467 if (GNUNET_OK == 5520 if (GNUNET_OK ==
5468 GNUNET_CONFIGURATION_get_value_string (cfg, "dht", "converge_modifier", 5521 GNUNET_CONFIGURATION_get_value_string (cfg, "dht", "converge_modifier",
5469 &converge_modifier_buf)) 5522 &converge_modifier_buf))
5523 {
5524 if (1 != sscanf (converge_modifier_buf, "%f", &converge_modifier))
5470 { 5525 {
5471 if (1 != sscanf (converge_modifier_buf, "%f", &converge_modifier)) 5526 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
5472 { 5527 "Failed to read decimal value for %s from `%s'\n",
5473 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 5528 "CONVERGE_MODIFIER", converge_modifier_buf);
5474 "Failed to read decimal value for %s from `%s'\n", 5529 converge_modifier = 0.0;
5475 "CONVERGE_MODIFIER", converge_modifier_buf);
5476 converge_modifier = 0.0;
5477 }
5478 GNUNET_free (converge_modifier_buf);
5479 } 5530 }
5531 GNUNET_free (converge_modifier_buf);
5532 }
5480 5533
5481 if (GNUNET_YES == 5534 if (GNUNET_YES ==
5482 GNUNET_CONFIGURATION_get_value_yesno (cfg, "dht", "paper_forwarding")) 5535 GNUNET_CONFIGURATION_get_value_yesno (cfg, "dht", "paper_forwarding"))
5483 paper_forwarding = GNUNET_YES; 5536 paper_forwarding = GNUNET_YES;
5484 5537
5485 if (GNUNET_YES == 5538 if (GNUNET_YES ==
5486 GNUNET_CONFIGURATION_get_value_yesno (cfg, "dht", "put_peer_identities")) 5539 GNUNET_CONFIGURATION_get_value_yesno (cfg, "dht", "put_peer_identities"))
5487 put_peer_identities = GNUNET_YES; 5540 put_peer_identities = GNUNET_YES;
5488 5541
5489 stats = GNUNET_STATISTICS_create ("dht", cfg); 5542 stats = GNUNET_STATISTICS_create ("dht", cfg);
5490 5543
5491 if (stats != NULL) 5544 if (stats != NULL)
5492 { 5545 {
5493 GNUNET_STATISTICS_set (stats, STAT_ROUTES, 0, GNUNET_NO); 5546 GNUNET_STATISTICS_set (stats, STAT_ROUTES, 0, GNUNET_NO);
5494 GNUNET_STATISTICS_set (stats, STAT_ROUTE_FORWARDS, 0, GNUNET_NO); 5547 GNUNET_STATISTICS_set (stats, STAT_ROUTE_FORWARDS, 0, GNUNET_NO);
5495 GNUNET_STATISTICS_set (stats, STAT_ROUTE_FORWARDS_CLOSEST, 0, 5548 GNUNET_STATISTICS_set (stats, STAT_ROUTE_FORWARDS_CLOSEST, 0, GNUNET_NO);
5496 GNUNET_NO); 5549 GNUNET_STATISTICS_set (stats, STAT_RESULTS, 0, GNUNET_NO);
5497 GNUNET_STATISTICS_set (stats, STAT_RESULTS, 0, GNUNET_NO); 5550 GNUNET_STATISTICS_set (stats, STAT_RESULTS_TO_CLIENT, 0, GNUNET_NO);
5498 GNUNET_STATISTICS_set (stats, STAT_RESULTS_TO_CLIENT, 0, GNUNET_NO); 5551 GNUNET_STATISTICS_set (stats, STAT_RESULT_FORWARDS, 0, GNUNET_NO);
5499 GNUNET_STATISTICS_set (stats, STAT_RESULT_FORWARDS, 0, GNUNET_NO); 5552 GNUNET_STATISTICS_set (stats, STAT_GETS, 0, GNUNET_NO);
5500 GNUNET_STATISTICS_set (stats, STAT_GETS, 0, GNUNET_NO); 5553 GNUNET_STATISTICS_set (stats, STAT_PUTS, 0, GNUNET_NO);
5501 GNUNET_STATISTICS_set (stats, STAT_PUTS, 0, GNUNET_NO); 5554 GNUNET_STATISTICS_set (stats, STAT_PUTS_INSERTED, 0, GNUNET_NO);
5502 GNUNET_STATISTICS_set (stats, STAT_PUTS_INSERTED, 0, GNUNET_NO); 5555 GNUNET_STATISTICS_set (stats, STAT_FIND_PEER, 0, GNUNET_NO);
5503 GNUNET_STATISTICS_set (stats, STAT_FIND_PEER, 0, GNUNET_NO); 5556 GNUNET_STATISTICS_set (stats, STAT_FIND_PEER_START, 0, GNUNET_NO);
5504 GNUNET_STATISTICS_set (stats, STAT_FIND_PEER_START, 0, GNUNET_NO); 5557 GNUNET_STATISTICS_set (stats, STAT_GET_START, 0, GNUNET_NO);
5505 GNUNET_STATISTICS_set (stats, STAT_GET_START, 0, GNUNET_NO); 5558 GNUNET_STATISTICS_set (stats, STAT_PUT_START, 0, GNUNET_NO);
5506 GNUNET_STATISTICS_set (stats, STAT_PUT_START, 0, GNUNET_NO); 5559 GNUNET_STATISTICS_set (stats, STAT_FIND_PEER_REPLY, 0, GNUNET_NO);
5507 GNUNET_STATISTICS_set (stats, STAT_FIND_PEER_REPLY, 0, GNUNET_NO); 5560 GNUNET_STATISTICS_set (stats, STAT_FIND_PEER_ANSWER, 0, GNUNET_NO);
5508 GNUNET_STATISTICS_set (stats, STAT_FIND_PEER_ANSWER, 0, GNUNET_NO); 5561 GNUNET_STATISTICS_set (stats, STAT_BLOOM_FIND_PEER, 0, GNUNET_NO);
5509 GNUNET_STATISTICS_set (stats, STAT_BLOOM_FIND_PEER, 0, GNUNET_NO); 5562 GNUNET_STATISTICS_set (stats, STAT_GET_REPLY, 0, GNUNET_NO);
5510 GNUNET_STATISTICS_set (stats, STAT_GET_REPLY, 0, GNUNET_NO); 5563 GNUNET_STATISTICS_set (stats, STAT_GET_RESPONSE_START, 0, GNUNET_NO);
5511 GNUNET_STATISTICS_set (stats, STAT_GET_RESPONSE_START, 0, GNUNET_NO); 5564 GNUNET_STATISTICS_set (stats, STAT_HELLOS_PROVIDED, 0, GNUNET_NO);
5512 GNUNET_STATISTICS_set (stats, STAT_HELLOS_PROVIDED, 0, GNUNET_NO); 5565 GNUNET_STATISTICS_set (stats, STAT_DISCONNECTS, 0, GNUNET_NO);
5513 GNUNET_STATISTICS_set (stats, STAT_DISCONNECTS, 0, GNUNET_NO); 5566 }
5514 }
5515 /* FIXME: if there are no recent requests then these never get freed, but alternative is _annoying_! */ 5567 /* FIXME: if there are no recent requests then these never get freed, but alternative is _annoying_! */
5516 recent.hashmap = GNUNET_CONTAINER_multihashmap_create (DHT_MAX_RECENT / 2); 5568 recent.hashmap = GNUNET_CONTAINER_multihashmap_create (DHT_MAX_RECENT / 2);
5517 recent.minHeap = 5569 recent.minHeap =
5518 GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); 5570 GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
5519 if (GNUNET_YES == do_find_peer) 5571 if (GNUNET_YES == do_find_peer)
5520 { 5572 {
5521 next_send_time.rel_value = DHT_MINIMUM_FIND_PEER_INTERVAL.rel_value + 5573 next_send_time.rel_value = DHT_MINIMUM_FIND_PEER_INTERVAL.rel_value +
5522 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, 5574 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG,
5523 (DHT_MAXIMUM_FIND_PEER_INTERVAL.rel_value / 5575 (DHT_MAXIMUM_FIND_PEER_INTERVAL.rel_value /
5524 2) - 5576 2) -
5525 DHT_MINIMUM_FIND_PEER_INTERVAL.rel_value); 5577 DHT_MINIMUM_FIND_PEER_INTERVAL.rel_value);
5526 find_peer_context.start = GNUNET_TIME_absolute_get (); 5578 find_peer_context.start = GNUNET_TIME_absolute_get ();
5527 GNUNET_SCHEDULER_add_delayed (next_send_time, 5579 GNUNET_SCHEDULER_add_delayed (next_send_time,
5528 &send_find_peer_message, 5580 &send_find_peer_message, &find_peer_context);
5529 &find_peer_context); 5581 }
5530 }
5531 5582
5532 /* Scheduled the task to clean up when shutdown is called */ 5583 /* Scheduled the task to clean up when shutdown is called */
5533 cleanup_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, 5584 cleanup_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
@@ -5552,21 +5603,21 @@ main (int argc, char *const *argv)
5552 "dht", 5603 "dht",
5553 GNUNET_SERVICE_OPTION_NONE, &run, NULL)) ? 0 : 1; 5604 GNUNET_SERVICE_OPTION_NONE, &run, NULL)) ? 0 : 1;
5554 if (NULL != recent.hashmap) 5605 if (NULL != recent.hashmap)
5555 { 5606 {
5556 GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap_size (recent.hashmap)); 5607 GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap_size (recent.hashmap));
5557 GNUNET_CONTAINER_multihashmap_destroy (recent.hashmap); 5608 GNUNET_CONTAINER_multihashmap_destroy (recent.hashmap);
5558 recent.hashmap = NULL; 5609 recent.hashmap = NULL;
5559 } 5610 }
5560 if (NULL != recent.minHeap) 5611 if (NULL != recent.minHeap)
5561 { 5612 {
5562 GNUNET_assert (0 == GNUNET_CONTAINER_heap_get_size (recent.minHeap)); 5613 GNUNET_assert (0 == GNUNET_CONTAINER_heap_get_size (recent.minHeap));
5563 GNUNET_CONTAINER_heap_destroy (recent.minHeap); 5614 GNUNET_CONTAINER_heap_destroy (recent.minHeap);
5564 recent.minHeap = NULL; 5615 recent.minHeap = NULL;
5565 } 5616 }
5566 if (NULL != recent_find_peer_requests) 5617 if (NULL != recent_find_peer_requests)
5567 { 5618 {
5568 GNUNET_CONTAINER_multihashmap_destroy (recent_find_peer_requests); 5619 GNUNET_CONTAINER_multihashmap_destroy (recent_find_peer_requests);
5569 recent_find_peer_requests = NULL; 5620 recent_find_peer_requests = NULL;
5570 } 5621 }
5571 return ret; 5622 return ret;
5572} 5623}