diff options
Diffstat (limited to 'src/dht/gnunet-service-dht_neighbours.c')
-rw-r--r-- | src/dht/gnunet-service-dht_neighbours.c | 695 |
1 files changed, 272 insertions, 423 deletions
diff --git a/src/dht/gnunet-service-dht_neighbours.c b/src/dht/gnunet-service-dht_neighbours.c index ae3f34dce..0fc42d2ef 100644 --- a/src/dht/gnunet-service-dht_neighbours.c +++ b/src/dht/gnunet-service-dht_neighbours.c | |||
@@ -1163,38 +1163,12 @@ get_target_peers (const struct GNUNET_HashCode *key, | |||
1163 | } | 1163 | } |
1164 | 1164 | ||
1165 | 1165 | ||
1166 | /** | ||
1167 | * Perform a PUT operation. Forwards the given request to other | ||
1168 | * peers. Does not store the data locally. Does not give the | ||
1169 | * data to local clients. May do nothing if this is the only | ||
1170 | * peer in the network (or if we are the closest peer in the | ||
1171 | * network). | ||
1172 | * | ||
1173 | * @param type type of the block | ||
1174 | * @param options routing options | ||
1175 | * @param desired_replication_level desired replication count | ||
1176 | * @param expiration_time when does the content expire | ||
1177 | * @param hop_count how many hops has this message traversed so far | ||
1178 | * @param bf Bloom filter of peers this PUT has already traversed | ||
1179 | * @param key key for the content | ||
1180 | * @param put_path_length number of entries in @a put_path | ||
1181 | * @param put_path peers this request has traversed so far (if tracked) | ||
1182 | * @param data payload to store | ||
1183 | * @param data_size number of bytes in @a data | ||
1184 | * @return #GNUNET_OK if the request was forwarded, #GNUNET_NO if not | ||
1185 | */ | ||
1186 | enum GNUNET_GenericReturnValue | 1166 | enum GNUNET_GenericReturnValue |
1187 | GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type, | 1167 | GDS_NEIGHBOURS_handle_put (const struct GDS_DATACACHE_BlockData *bd, |
1188 | enum GNUNET_DHT_RouteOption options, | 1168 | enum GNUNET_DHT_RouteOption options, |
1189 | uint32_t desired_replication_level, | 1169 | uint32_t desired_replication_level, |
1190 | struct GNUNET_TIME_Absolute expiration_time, | ||
1191 | uint32_t hop_count, | 1170 | uint32_t hop_count, |
1192 | struct GNUNET_CONTAINER_BloomFilter *bf, | 1171 | struct GNUNET_CONTAINER_BloomFilter *bf) |
1193 | const struct GNUNET_HashCode *key, | ||
1194 | unsigned int put_path_length, | ||
1195 | struct GNUNET_PeerIdentity *put_path, | ||
1196 | const void *data, | ||
1197 | size_t data_size) | ||
1198 | { | 1172 | { |
1199 | unsigned int target_count; | 1173 | unsigned int target_count; |
1200 | unsigned int i; | 1174 | unsigned int i; |
@@ -1205,20 +1179,21 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type, | |||
1205 | struct PeerPutMessage *ppm; | 1179 | struct PeerPutMessage *ppm; |
1206 | struct GNUNET_PeerIdentity *pp; | 1180 | struct GNUNET_PeerIdentity *pp; |
1207 | unsigned int skip_count; | 1181 | unsigned int skip_count; |
1182 | unsigned int put_path_length = bd->put_path_length; | ||
1208 | 1183 | ||
1209 | GNUNET_assert (NULL != bf); | 1184 | GNUNET_assert (NULL != bf); |
1210 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1185 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1211 | "Adding myself (%s) to PUT bloomfilter for %s\n", | 1186 | "Adding myself (%s) to PUT bloomfilter for %s\n", |
1212 | GNUNET_i2s (&my_identity), | 1187 | GNUNET_i2s (&my_identity), |
1213 | GNUNET_h2s (key)); | 1188 | GNUNET_h2s (&bd->key)); |
1214 | GNUNET_CONTAINER_bloomfilter_add (bf, | 1189 | GNUNET_CONTAINER_bloomfilter_add (bf, |
1215 | &my_identity_hash); | 1190 | &my_identity_hash); |
1216 | GNUNET_STATISTICS_update (GDS_stats, | 1191 | GNUNET_STATISTICS_update (GDS_stats, |
1217 | gettext_noop ("# PUT requests routed"), | 1192 | "# PUT requests routed", |
1218 | 1, | 1193 | 1, |
1219 | GNUNET_NO); | 1194 | GNUNET_NO); |
1220 | target_count | 1195 | target_count |
1221 | = get_target_peers (key, | 1196 | = get_target_peers (&bd->key, |
1222 | bf, | 1197 | bf, |
1223 | hop_count, | 1198 | hop_count, |
1224 | desired_replication_level, | 1199 | desired_replication_level, |
@@ -1227,17 +1202,18 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type, | |||
1227 | { | 1202 | { |
1228 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1203 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1229 | "Routing PUT for %s terminates after %u hops at %s\n", | 1204 | "Routing PUT for %s terminates after %u hops at %s\n", |
1230 | GNUNET_h2s (key), | 1205 | GNUNET_h2s (&bd->key), |
1231 | (unsigned int) hop_count, | 1206 | (unsigned int) hop_count, |
1232 | GNUNET_i2s (&my_identity)); | 1207 | GNUNET_i2s (&my_identity)); |
1233 | return GNUNET_NO; | 1208 | return GNUNET_NO; |
1234 | } | 1209 | } |
1235 | msize = put_path_length * sizeof(struct GNUNET_PeerIdentity) + data_size; | 1210 | msize = bd->put_path_length * sizeof(struct GNUNET_PeerIdentity) |
1211 | + bd->data_size; | ||
1236 | if (msize + sizeof(struct PeerPutMessage) | 1212 | if (msize + sizeof(struct PeerPutMessage) |
1237 | >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE) | 1213 | >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE) |
1238 | { | 1214 | { |
1239 | put_path_length = 0; | 1215 | put_path_length = 0; |
1240 | msize = data_size; | 1216 | msize = bd->data_size; |
1241 | } | 1217 | } |
1242 | if (msize + sizeof(struct PeerPutMessage) | 1218 | if (msize + sizeof(struct PeerPutMessage) |
1243 | >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE) | 1219 | >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE) |
@@ -1267,18 +1243,18 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type, | |||
1267 | } | 1243 | } |
1268 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1244 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1269 | "Routing PUT for %s after %u hops to %s\n", | 1245 | "Routing PUT for %s after %u hops to %s\n", |
1270 | GNUNET_h2s (key), | 1246 | GNUNET_h2s (&bd->key), |
1271 | (unsigned int) hop_count, | 1247 | (unsigned int) hop_count, |
1272 | GNUNET_i2s (target->id)); | 1248 | GNUNET_i2s (target->id)); |
1273 | env = GNUNET_MQ_msg_extra (ppm, | 1249 | env = GNUNET_MQ_msg_extra (ppm, |
1274 | msize, | 1250 | msize, |
1275 | GNUNET_MESSAGE_TYPE_DHT_P2P_PUT); | 1251 | GNUNET_MESSAGE_TYPE_DHT_P2P_PUT); |
1276 | ppm->options = htonl (options); | 1252 | ppm->options = htonl (options); |
1277 | ppm->type = htonl (type); | 1253 | ppm->type = htonl (bd->type); |
1278 | ppm->hop_count = htonl (hop_count + 1); | 1254 | ppm->hop_count = htonl (hop_count + 1); |
1279 | ppm->desired_replication_level = htonl (desired_replication_level); | 1255 | ppm->desired_replication_level = htonl (desired_replication_level); |
1280 | ppm->put_path_length = htonl (put_path_length); | 1256 | ppm->put_path_length = htonl (put_path_length); |
1281 | ppm->expiration_time = GNUNET_TIME_absolute_hton (expiration_time); | 1257 | ppm->expiration_time = GNUNET_TIME_absolute_hton (bd->expiration_time); |
1282 | GNUNET_break (GNUNET_YES == | 1258 | GNUNET_break (GNUNET_YES == |
1283 | GNUNET_CONTAINER_bloomfilter_test (bf, | 1259 | GNUNET_CONTAINER_bloomfilter_test (bf, |
1284 | &target->phash)); | 1260 | &target->phash)); |
@@ -1286,14 +1262,14 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type, | |||
1286 | GNUNET_CONTAINER_bloomfilter_get_raw_data (bf, | 1262 | GNUNET_CONTAINER_bloomfilter_get_raw_data (bf, |
1287 | ppm->bloomfilter, | 1263 | ppm->bloomfilter, |
1288 | DHT_BLOOM_SIZE)); | 1264 | DHT_BLOOM_SIZE)); |
1289 | ppm->key = *key; | 1265 | ppm->key = bd->key; |
1290 | pp = (struct GNUNET_PeerIdentity *) &ppm[1]; | 1266 | pp = (struct GNUNET_PeerIdentity *) &ppm[1]; |
1291 | GNUNET_memcpy (pp, | 1267 | GNUNET_memcpy (pp, |
1292 | put_path, | 1268 | bd->put_path, |
1293 | sizeof(struct GNUNET_PeerIdentity) * put_path_length); | 1269 | sizeof(struct GNUNET_PeerIdentity) * put_path_length); |
1294 | GNUNET_memcpy (&pp[put_path_length], | 1270 | GNUNET_memcpy (&pp[put_path_length], |
1295 | data, | 1271 | bd->data, |
1296 | data_size); | 1272 | bd->data_size); |
1297 | GNUNET_MQ_send (target->mq, | 1273 | GNUNET_MQ_send (target->mq, |
1298 | env); | 1274 | env); |
1299 | } | 1275 | } |
@@ -1302,23 +1278,6 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type, | |||
1302 | } | 1278 | } |
1303 | 1279 | ||
1304 | 1280 | ||
1305 | /** | ||
1306 | * Perform a GET operation. Forwards the given request to other | ||
1307 | * peers. Does not lookup the key locally. May do nothing if this is | ||
1308 | * the only peer in the network (or if we are the closest peer in the | ||
1309 | * network). | ||
1310 | * | ||
1311 | * @param type type of the block | ||
1312 | * @param options routing options | ||
1313 | * @param desired_replication_level desired replication count | ||
1314 | * @param hop_count how many hops did this request traverse so far? | ||
1315 | * @param key key for the content | ||
1316 | * @param xquery extended query | ||
1317 | * @param xquery_size number of bytes in @a xquery | ||
1318 | * @param bg group to use for filtering replies | ||
1319 | * @param peer_bf filter for peers not to select (again) | ||
1320 | * @return #GNUNET_OK if the request was forwarded, #GNUNET_NO if not | ||
1321 | */ | ||
1322 | enum GNUNET_GenericReturnValue | 1281 | enum GNUNET_GenericReturnValue |
1323 | GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type, | 1282 | GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type, |
1324 | enum GNUNET_DHT_RouteOption options, | 1283 | enum GNUNET_DHT_RouteOption options, |
@@ -1444,48 +1403,27 @@ GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type, | |||
1444 | } | 1403 | } |
1445 | 1404 | ||
1446 | 1405 | ||
1447 | /** | ||
1448 | * Handle a reply (route to origin). Only forwards the reply back to | ||
1449 | * the given peer. Does not do local caching or forwarding to local | ||
1450 | * clients. | ||
1451 | * | ||
1452 | * @param target neighbour that should receive the block (if still connected) | ||
1453 | * @param type type of the block | ||
1454 | * @param expiration_time when does the content expire | ||
1455 | * @param key key for the content | ||
1456 | * @param put_path_length number of entries in @a put_path | ||
1457 | * @param put_path peers the original PUT traversed (if tracked) | ||
1458 | * @param get_path_length number of entries in @a get_path | ||
1459 | * @param get_path peers this reply has traversed so far (if tracked) | ||
1460 | * @param data payload of the reply | ||
1461 | * @param data_size number of bytes in @a data | ||
1462 | */ | ||
1463 | void | 1406 | void |
1464 | GDS_NEIGHBOURS_handle_reply (const struct GNUNET_PeerIdentity *target, | 1407 | GDS_NEIGHBOURS_handle_reply (const struct GNUNET_PeerIdentity *target, |
1465 | enum GNUNET_BLOCK_Type type, | 1408 | const struct GDS_DATACACHE_BlockData *bd, |
1466 | struct GNUNET_TIME_Absolute expiration_time, | 1409 | const struct GNUNET_HashCode *query_hash, |
1467 | const struct GNUNET_HashCode *key, | ||
1468 | unsigned int put_path_length, | ||
1469 | const struct GNUNET_PeerIdentity *put_path, | ||
1470 | unsigned int get_path_length, | 1410 | unsigned int get_path_length, |
1471 | const struct GNUNET_PeerIdentity *get_path, | 1411 | const struct GNUNET_PeerIdentity *get_path) |
1472 | const void *data, | ||
1473 | size_t data_size) | ||
1474 | { | 1412 | { |
1475 | struct PeerInfo *pi; | 1413 | struct PeerInfo *pi; |
1476 | struct GNUNET_MQ_Envelope *env; | 1414 | struct GNUNET_MQ_Envelope *env; |
1477 | size_t msize; | ||
1478 | struct PeerResultMessage *prm; | 1415 | struct PeerResultMessage *prm; |
1479 | struct GNUNET_PeerIdentity *paths; | 1416 | struct GNUNET_PeerIdentity *paths; |
1417 | size_t msize; | ||
1480 | 1418 | ||
1481 | msize = data_size + (get_path_length + put_path_length) | 1419 | msize = bd->data_size + (get_path_length + bd->put_path_length) |
1482 | * sizeof(struct GNUNET_PeerIdentity); | 1420 | * sizeof(struct GNUNET_PeerIdentity); |
1483 | if ((msize + sizeof(struct PeerResultMessage) >= GNUNET_MAX_MESSAGE_SIZE) || | 1421 | if ( (msize + sizeof(struct PeerResultMessage) >= GNUNET_MAX_MESSAGE_SIZE) || |
1484 | (get_path_length > | 1422 | (get_path_length > |
1485 | GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_PeerIdentity)) || | 1423 | GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_PeerIdentity)) || |
1486 | (put_path_length > | 1424 | (bd->put_path_length > |
1487 | GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_PeerIdentity)) || | 1425 | GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_PeerIdentity)) || |
1488 | (data_size > GNUNET_MAX_MESSAGE_SIZE)) | 1426 | (bd->data_size > GNUNET_MAX_MESSAGE_SIZE)) |
1489 | { | 1427 | { |
1490 | GNUNET_break (0); | 1428 | GNUNET_break (0); |
1491 | return; | 1429 | return; |
@@ -1497,49 +1435,48 @@ GDS_NEIGHBOURS_handle_reply (const struct GNUNET_PeerIdentity *target, | |||
1497 | /* peer disconnected in the meantime, drop reply */ | 1435 | /* peer disconnected in the meantime, drop reply */ |
1498 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1436 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1499 | "No matching peer for reply for key %s\n", | 1437 | "No matching peer for reply for key %s\n", |
1500 | GNUNET_h2s (key)); | 1438 | GNUNET_h2s (query_hash)); |
1501 | return; | 1439 | return; |
1502 | } | 1440 | } |
1503 | if (GNUNET_MQ_get_length (pi->mq) >= MAXIMUM_PENDING_PER_PEER) | 1441 | if (GNUNET_MQ_get_length (pi->mq) >= MAXIMUM_PENDING_PER_PEER) |
1504 | { | 1442 | { |
1505 | /* skip */ | 1443 | /* skip */ |
1506 | GNUNET_STATISTICS_update (GDS_stats, | 1444 | GNUNET_STATISTICS_update (GDS_stats, |
1507 | gettext_noop ( | 1445 | "# P2P messages dropped due to full queue", |
1508 | "# P2P messages dropped due to full queue"), | ||
1509 | 1, | 1446 | 1, |
1510 | GNUNET_NO); | 1447 | GNUNET_NO); |
1511 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1448 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1512 | "Peer queue full, ignoring reply for key %s\n", | 1449 | "Peer queue full, ignoring reply for key %s\n", |
1513 | GNUNET_h2s (key)); | 1450 | GNUNET_h2s (&bd->key)); |
1514 | return; | 1451 | return; |
1515 | } | 1452 | } |
1516 | 1453 | ||
1517 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1454 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1518 | "Forwarding reply for key %s to peer %s\n", | 1455 | "Forwarding reply for key %s to peer %s\n", |
1519 | GNUNET_h2s (key), | 1456 | GNUNET_h2s (query_hash), |
1520 | GNUNET_i2s (target)); | 1457 | GNUNET_i2s (target)); |
1521 | GNUNET_STATISTICS_update (GDS_stats, | 1458 | GNUNET_STATISTICS_update (GDS_stats, |
1522 | gettext_noop | 1459 | "# RESULT messages queued for transmission", |
1523 | ("# RESULT messages queued for transmission"), 1, | 1460 | 1, |
1524 | GNUNET_NO); | 1461 | GNUNET_NO); |
1525 | env = GNUNET_MQ_msg_extra (prm, | 1462 | env = GNUNET_MQ_msg_extra (prm, |
1526 | msize, | 1463 | msize, |
1527 | GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT); | 1464 | GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT); |
1528 | prm->type = htonl (type); | 1465 | prm->type = htonl (bd->type); |
1529 | prm->put_path_length = htonl (put_path_length); | 1466 | prm->put_path_length = htonl (bd->put_path_length); |
1530 | prm->get_path_length = htonl (get_path_length); | 1467 | prm->get_path_length = htonl (get_path_length); |
1531 | prm->expiration_time = GNUNET_TIME_absolute_hton (expiration_time); | 1468 | prm->expiration_time = GNUNET_TIME_absolute_hton (bd->expiration_time); |
1532 | prm->key = *key; | 1469 | prm->key = *query_hash; |
1533 | paths = (struct GNUNET_PeerIdentity *) &prm[1]; | 1470 | paths = (struct GNUNET_PeerIdentity *) &prm[1]; |
1534 | GNUNET_memcpy (paths, | 1471 | GNUNET_memcpy (paths, |
1535 | put_path, | 1472 | bd->put_path, |
1536 | put_path_length * sizeof(struct GNUNET_PeerIdentity)); | 1473 | bd->put_path_length * sizeof(struct GNUNET_PeerIdentity)); |
1537 | GNUNET_memcpy (&paths[put_path_length], | 1474 | GNUNET_memcpy (&paths[bd->put_path_length], |
1538 | get_path, | 1475 | get_path, |
1539 | get_path_length * sizeof(struct GNUNET_PeerIdentity)); | 1476 | get_path_length * sizeof(struct GNUNET_PeerIdentity)); |
1540 | GNUNET_memcpy (&paths[put_path_length + get_path_length], | 1477 | GNUNET_memcpy (&paths[bd->put_path_length + get_path_length], |
1541 | data, | 1478 | bd->data, |
1542 | data_size); | 1479 | bd->data_size); |
1543 | GNUNET_MQ_send (pi->mq, | 1480 | GNUNET_MQ_send (pi->mq, |
1544 | env); | 1481 | env); |
1545 | } | 1482 | } |
@@ -1608,18 +1545,27 @@ handle_dht_p2p_put (void *cls, | |||
1608 | const struct PeerPutMessage *put) | 1545 | const struct PeerPutMessage *put) |
1609 | { | 1546 | { |
1610 | struct PeerInfo *peer = cls; | 1547 | struct PeerInfo *peer = cls; |
1611 | const struct GNUNET_PeerIdentity *put_path; | 1548 | uint16_t msize = ntohs (put->header.size); |
1612 | const void *payload; | 1549 | enum GNUNET_DHT_RouteOption options |
1613 | uint32_t putlen; | 1550 | = (enum GNUNET_DHT_RouteOption) ntohl (put->options); |
1614 | uint16_t msize; | 1551 | struct GDS_DATACACHE_BlockData bd = { |
1615 | size_t payload_size; | 1552 | .key = put->key, |
1616 | enum GNUNET_DHT_RouteOption options; | 1553 | .expiration_time = GNUNET_TIME_absolute_ntoh (put->expiration_time), |
1617 | struct GNUNET_CONTAINER_BloomFilter *bf; | 1554 | .type = ntohl (put->type) |
1618 | int forwarded; | 1555 | }; |
1619 | struct GNUNET_TIME_Absolute exp_time; | 1556 | const struct GNUNET_PeerIdentity *put_path |
1557 | = (const struct GNUNET_PeerIdentity *) &put[1]; | ||
1558 | uint32_t putlen | ||
1559 | = ntohl (put->put_path_length); | ||
1620 | 1560 | ||
1621 | exp_time = GNUNET_TIME_absolute_ntoh (put->expiration_time); | 1561 | bd.data_size = msize - (sizeof(*put) |
1622 | if (GNUNET_TIME_absolute_is_past (exp_time)) | 1562 | + putlen * sizeof(struct GNUNET_PeerIdentity)); |
1563 | bd.data = &put_path[putlen]; | ||
1564 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1565 | "PUT for `%s' from %s\n", | ||
1566 | GNUNET_h2s (&put->key), | ||
1567 | GNUNET_i2s (peer->id)); | ||
1568 | if (GNUNET_TIME_absolute_is_past (bd.expiration_time)) | ||
1623 | { | 1569 | { |
1624 | GNUNET_STATISTICS_update (GDS_stats, | 1570 | GNUNET_STATISTICS_update (GDS_stats, |
1625 | gettext_noop ("# Expired PUTs discarded"), | 1571 | gettext_noop ("# Expired PUTs discarded"), |
@@ -1627,26 +1573,14 @@ handle_dht_p2p_put (void *cls, | |||
1627 | GNUNET_NO); | 1573 | GNUNET_NO); |
1628 | return; | 1574 | return; |
1629 | } | 1575 | } |
1630 | msize = ntohs (put->header.size); | ||
1631 | putlen = ntohl (put->put_path_length); | ||
1632 | GNUNET_STATISTICS_update (GDS_stats, | 1576 | GNUNET_STATISTICS_update (GDS_stats, |
1633 | gettext_noop ("# P2P PUT requests received"), | 1577 | "# P2P PUT requests received", |
1634 | 1, | 1578 | 1, |
1635 | GNUNET_NO); | 1579 | GNUNET_NO); |
1636 | GNUNET_STATISTICS_update (GDS_stats, | 1580 | GNUNET_STATISTICS_update (GDS_stats, |
1637 | gettext_noop ("# P2P PUT bytes received"), | 1581 | "# P2P PUT bytes received", |
1638 | msize, | 1582 | msize, |
1639 | GNUNET_NO); | 1583 | GNUNET_NO); |
1640 | put_path = (const struct GNUNET_PeerIdentity *) &put[1]; | ||
1641 | payload = &put_path[putlen]; | ||
1642 | options = ntohl (put->options); | ||
1643 | payload_size = msize - (sizeof(struct PeerPutMessage) | ||
1644 | + putlen * sizeof(struct GNUNET_PeerIdentity)); | ||
1645 | |||
1646 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1647 | "PUT for `%s' from %s\n", | ||
1648 | GNUNET_h2s (&put->key), | ||
1649 | GNUNET_i2s (peer->id)); | ||
1650 | if (GNUNET_YES == log_route_details_stderr) | 1584 | if (GNUNET_YES == log_route_details_stderr) |
1651 | { | 1585 | { |
1652 | char *tmp; | 1586 | char *tmp; |
@@ -1681,15 +1615,15 @@ handle_dht_p2p_put (void *cls, | |||
1681 | enum GNUNET_GenericReturnValue ret; | 1615 | enum GNUNET_GenericReturnValue ret; |
1682 | 1616 | ||
1683 | ret = GNUNET_BLOCK_get_key (GDS_block_context, | 1617 | ret = GNUNET_BLOCK_get_key (GDS_block_context, |
1684 | ntohl (put->type), | 1618 | bd.type, |
1685 | payload, | 1619 | bd.data, |
1686 | payload_size, | 1620 | bd.data_size, |
1687 | &test_key); | 1621 | &test_key); |
1688 | switch (ret) | 1622 | switch (ret) |
1689 | { | 1623 | { |
1690 | case GNUNET_YES: | 1624 | case GNUNET_YES: |
1691 | if (0 != GNUNET_memcmp (&test_key, | 1625 | if (0 != GNUNET_memcmp (&test_key, |
1692 | &put->key)) | 1626 | &bd.key)) |
1693 | { | 1627 | { |
1694 | GNUNET_break_op (0); | 1628 | GNUNET_break_op (0); |
1695 | return; | 1629 | return; |
@@ -1706,25 +1640,28 @@ handle_dht_p2p_put (void *cls, | |||
1706 | 1640 | ||
1707 | if (GNUNET_NO == | 1641 | if (GNUNET_NO == |
1708 | GNUNET_BLOCK_check_block (GDS_block_context, | 1642 | GNUNET_BLOCK_check_block (GDS_block_context, |
1709 | ntohl (put->type), | 1643 | bd.type, |
1710 | &put->key, | 1644 | &bd.key, |
1711 | payload, | 1645 | bd.data, |
1712 | payload_size)) | 1646 | bd.data_size)) |
1713 | { | 1647 | { |
1714 | GNUNET_break_op (0); | 1648 | GNUNET_break_op (0); |
1715 | return; | 1649 | return; |
1716 | } | 1650 | } |
1717 | 1651 | ||
1718 | bf = GNUNET_CONTAINER_bloomfilter_init (put->bloomfilter, | ||
1719 | DHT_BLOOM_SIZE, | ||
1720 | GNUNET_CONSTANTS_BLOOMFILTER_K); | ||
1721 | GNUNET_break_op (GNUNET_YES == | ||
1722 | GNUNET_CONTAINER_bloomfilter_test (bf, | ||
1723 | &peer->phash)); | ||
1724 | { | 1652 | { |
1653 | struct GNUNET_CONTAINER_BloomFilter *bf; | ||
1725 | struct GNUNET_PeerIdentity pp[putlen + 1]; | 1654 | struct GNUNET_PeerIdentity pp[putlen + 1]; |
1726 | 1655 | ||
1656 | bf = GNUNET_CONTAINER_bloomfilter_init (put->bloomfilter, | ||
1657 | DHT_BLOOM_SIZE, | ||
1658 | GNUNET_CONSTANTS_BLOOMFILTER_K); | ||
1659 | GNUNET_break_op (GNUNET_YES == | ||
1660 | GNUNET_CONTAINER_bloomfilter_test (bf, | ||
1661 | &peer->phash)); | ||
1727 | /* extend 'put path' by sender */ | 1662 | /* extend 'put path' by sender */ |
1663 | bd.put_path = (const struct GNUNET_PeerIdentity *) pp; | ||
1664 | bd.put_path_length = putlen + 1; | ||
1728 | if (0 != (options & GNUNET_DHT_RO_RECORD_ROUTE)) | 1665 | if (0 != (options & GNUNET_DHT_RO_RECORD_ROUTE)) |
1729 | { | 1666 | { |
1730 | #if SANITY_CHECKS | 1667 | #if SANITY_CHECKS |
@@ -1732,13 +1669,13 @@ handle_dht_p2p_put (void *cls, | |||
1732 | { | 1669 | { |
1733 | for (unsigned int j = 0; j < i; j++) | 1670 | for (unsigned int j = 0; j < i; j++) |
1734 | { | 1671 | { |
1735 | GNUNET_break (0 != memcmp (&pp[i], | 1672 | GNUNET_break (0 != |
1736 | &pp[j], | 1673 | GNUNET_memcmp (&pp[i], |
1737 | sizeof(struct GNUNET_PeerIdentity))); | 1674 | &pp[j])); |
1738 | } | 1675 | } |
1739 | GNUNET_break (0 != memcmp (&pp[i], | 1676 | GNUNET_break (0 != |
1740 | peer->id, | 1677 | GNUNET_memcmp (&pp[i], |
1741 | sizeof(struct GNUNET_PeerIdentity))); | 1678 | peer->id)); |
1742 | } | 1679 | } |
1743 | #endif | 1680 | #endif |
1744 | GNUNET_memcpy (pp, | 1681 | GNUNET_memcpy (pp, |
@@ -1748,57 +1685,41 @@ handle_dht_p2p_put (void *cls, | |||
1748 | putlen++; | 1685 | putlen++; |
1749 | } | 1686 | } |
1750 | else | 1687 | else |
1751 | putlen = 0; | 1688 | { |
1689 | bd.put_path_length = 0; | ||
1690 | } | ||
1752 | 1691 | ||
1753 | /* give to local clients */ | 1692 | /* give to local clients */ |
1754 | GDS_CLIENTS_handle_reply (exp_time, | 1693 | GDS_CLIENTS_handle_reply (&bd, |
1755 | &put->key, | 1694 | &bd.key, |
1756 | &put->key, | 1695 | 0, NULL /* get path */); |
1757 | 0, | 1696 | |
1758 | NULL, | ||
1759 | putlen, | ||
1760 | pp, | ||
1761 | ntohl (put->type), | ||
1762 | payload_size, | ||
1763 | payload); | ||
1764 | /* store locally */ | 1697 | /* store locally */ |
1765 | if ((0 != (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) || | 1698 | if ((0 != (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) || |
1766 | (GDS_am_closest_peer (&put->key, bf))) | 1699 | (GDS_am_closest_peer (&put->key, |
1767 | GDS_DATACACHE_handle_put (exp_time, | 1700 | bf))) |
1768 | &put->key, | 1701 | GDS_DATACACHE_handle_put (&bd); |
1769 | putlen, | 1702 | { |
1770 | pp, | 1703 | enum GNUNET_GenericReturnValue forwarded; |
1771 | ntohl (put->type), | 1704 | |
1772 | payload_size, | 1705 | /* route to other peers */ |
1773 | payload); | 1706 | forwarded |
1774 | /* route to other peers */ | 1707 | = GDS_NEIGHBOURS_handle_put (&bd, |
1775 | forwarded = GDS_NEIGHBOURS_handle_put (ntohl (put->type), | 1708 | options, |
1776 | options, | 1709 | ntohl (put->desired_replication_level), |
1777 | ntohl ( | 1710 | ntohl (put->hop_count), |
1778 | put->desired_replication_level), | 1711 | bf); |
1779 | exp_time, | 1712 | /* notify monitoring clients */ |
1780 | ntohl (put->hop_count), | 1713 | GDS_CLIENTS_process_put (options |
1781 | bf, | 1714 | | ((GNUNET_OK == forwarded) |
1782 | &put->key, | ||
1783 | putlen, | ||
1784 | pp, | ||
1785 | payload, | ||
1786 | payload_size); | ||
1787 | /* notify monitoring clients */ | ||
1788 | GDS_CLIENTS_process_put (options | ||
1789 | | ((GNUNET_OK == forwarded) | ||
1790 | ? GNUNET_DHT_RO_LAST_HOP | 1715 | ? GNUNET_DHT_RO_LAST_HOP |
1791 | : 0), | 1716 | : 0), |
1792 | ntohl (put->type), | 1717 | &bd, |
1793 | ntohl (put->hop_count), | 1718 | ntohl (put->hop_count), |
1794 | ntohl (put->desired_replication_level), | 1719 | ntohl (put->desired_replication_level)); |
1795 | putlen, pp, | 1720 | } |
1796 | exp_time, | 1721 | GNUNET_CONTAINER_bloomfilter_free (bf); |
1797 | &put->key, | ||
1798 | payload, | ||
1799 | payload_size); | ||
1800 | } | 1722 | } |
1801 | GNUNET_CONTAINER_bloomfilter_free (bf); | ||
1802 | } | 1723 | } |
1803 | 1724 | ||
1804 | 1725 | ||
@@ -1812,42 +1733,40 @@ handle_dht_p2p_put (void *cls, | |||
1812 | */ | 1733 | */ |
1813 | static void | 1734 | static void |
1814 | handle_find_peer (const struct GNUNET_PeerIdentity *sender, | 1735 | handle_find_peer (const struct GNUNET_PeerIdentity *sender, |
1815 | const struct GNUNET_HashCode *key, | 1736 | const struct GNUNET_HashCode *query_hash, |
1816 | struct GNUNET_BLOCK_Group *bg) | 1737 | struct GNUNET_BLOCK_Group *bg) |
1817 | { | 1738 | { |
1818 | int bucket_idx; | 1739 | int bucket_idx; |
1819 | struct PeerBucket *bucket; | 1740 | struct PeerBucket *bucket; |
1820 | struct PeerInfo *peer; | 1741 | struct PeerInfo *peer; |
1821 | unsigned int choice; | 1742 | unsigned int choice; |
1822 | const struct GNUNET_HELLO_Message *hello; | 1743 | struct GDS_DATACACHE_BlockData bd = { |
1823 | size_t hello_size; | 1744 | .type = GNUNET_BLOCK_TYPE_DHT_HELLO |
1745 | }; | ||
1824 | 1746 | ||
1825 | /* first, check about our own HELLO */ | 1747 | /* first, check about our own HELLO */ |
1826 | if (NULL != GDS_my_hello) | 1748 | if (NULL != GDS_my_hello) |
1827 | { | 1749 | { |
1828 | hello_size = GNUNET_HELLO_size ( | 1750 | bd.expiration_time = GNUNET_TIME_relative_to_absolute ( |
1751 | hello_expiration), | ||
1752 | bd.key = my_identity_hash, | ||
1753 | bd.data = GDS_my_hello; | ||
1754 | bd.data_size = GNUNET_HELLO_size ( | ||
1829 | (const struct GNUNET_HELLO_Message *) GDS_my_hello); | 1755 | (const struct GNUNET_HELLO_Message *) GDS_my_hello); |
1830 | GNUNET_break (hello_size >= sizeof(struct GNUNET_MessageHeader)); | 1756 | GNUNET_break (bd.data_size >= sizeof(struct GNUNET_MessageHeader)); |
1831 | if (GNUNET_BLOCK_REPLY_OK_MORE == | 1757 | if (GNUNET_BLOCK_REPLY_OK_MORE == |
1832 | GNUNET_BLOCK_check_reply (GDS_block_context, | 1758 | GNUNET_BLOCK_check_reply (GDS_block_context, |
1833 | GNUNET_BLOCK_TYPE_DHT_HELLO, | 1759 | GNUNET_BLOCK_TYPE_DHT_HELLO, |
1834 | bg, | 1760 | bg, |
1835 | &my_identity_hash, | 1761 | &my_identity_hash, |
1836 | NULL, 0, | 1762 | NULL, 0, |
1837 | GDS_my_hello, | 1763 | bd.data, |
1838 | hello_size)) | 1764 | bd.data_size)) |
1839 | { | 1765 | { |
1840 | GDS_NEIGHBOURS_handle_reply (sender, | 1766 | GDS_NEIGHBOURS_handle_reply (sender, |
1841 | GNUNET_BLOCK_TYPE_DHT_HELLO, | 1767 | &bd, |
1842 | GNUNET_TIME_relative_to_absolute ( | 1768 | query_hash, |
1843 | hello_expiration), | 1769 | 0, NULL /* get path */); |
1844 | key, | ||
1845 | 0, | ||
1846 | NULL, | ||
1847 | 0, | ||
1848 | NULL, | ||
1849 | GDS_my_hello, | ||
1850 | hello_size); | ||
1851 | } | 1770 | } |
1852 | else | 1771 | else |
1853 | { | 1772 | { |
@@ -1869,11 +1788,11 @@ handle_find_peer (const struct GNUNET_PeerIdentity *sender, | |||
1869 | /* FIXME: How can this be true? Shouldnt we just do find_bucket() ? */ | 1788 | /* FIXME: How can this be true? Shouldnt we just do find_bucket() ? */ |
1870 | if (0 == | 1789 | if (0 == |
1871 | GNUNET_memcmp (&my_identity_hash, | 1790 | GNUNET_memcmp (&my_identity_hash, |
1872 | key)) | 1791 | query_hash)) |
1873 | bucket_idx = closest_bucket; | 1792 | bucket_idx = closest_bucket; |
1874 | else | 1793 | else |
1875 | bucket_idx = GNUNET_MIN ((int) closest_bucket, | 1794 | bucket_idx = GNUNET_MIN ((int) closest_bucket, |
1876 | find_bucket (key)); | 1795 | find_bucket (query_hash)); |
1877 | if (bucket_idx < 0) | 1796 | if (bucket_idx < 0) |
1878 | return; | 1797 | return; |
1879 | bucket = &k_buckets[bucket_idx]; | 1798 | bucket = &k_buckets[bucket_idx]; |
@@ -1889,84 +1808,69 @@ handle_find_peer (const struct GNUNET_PeerIdentity *sender, | |||
1889 | choice--; | 1808 | choice--; |
1890 | } | 1809 | } |
1891 | choice = bucket->peers_size; | 1810 | choice = bucket->peers_size; |
1892 | do | 1811 | |
1893 | { | 1812 | { |
1894 | peer = peer->next; | 1813 | const struct GNUNET_HELLO_Message *hello; |
1895 | if (0 == choice--) | 1814 | size_t hello_size; |
1896 | return; /* no non-masked peer available */ | 1815 | |
1897 | if (NULL == peer) | 1816 | do |
1898 | peer = bucket->head; | 1817 | { |
1899 | hello = GDS_HELLO_get (peer->id); | 1818 | peer = peer->next; |
1819 | if (0 == choice--) | ||
1820 | return; /* no non-masked peer available */ | ||
1821 | if (NULL == peer) | ||
1822 | peer = bucket->head; | ||
1823 | hello = GDS_HELLO_get (peer->id); | ||
1824 | } while ( (NULL == hello) || | ||
1825 | (GNUNET_BLOCK_REPLY_OK_MORE != | ||
1826 | GNUNET_BLOCK_check_reply ( | ||
1827 | GDS_block_context, | ||
1828 | GNUNET_BLOCK_TYPE_DHT_HELLO, | ||
1829 | bg, | ||
1830 | &peer->phash, | ||
1831 | NULL, 0, /* xquery */ | ||
1832 | hello, | ||
1833 | (hello_size = GNUNET_HELLO_size (hello))))); | ||
1834 | bd.expiration_time = GNUNET_TIME_relative_to_absolute ( | ||
1835 | GNUNET_CONSTANTS_HELLO_ADDRESS_EXPIRATION); | ||
1836 | bd.key = peer->phash; | ||
1837 | bd.data = hello; | ||
1838 | bd.data_size = hello_size; | ||
1839 | GDS_NEIGHBOURS_handle_reply (sender, | ||
1840 | &bd, | ||
1841 | query_hash, | ||
1842 | 0, NULL /* get path */); | ||
1900 | } | 1843 | } |
1901 | /* FIXME: this logic is strange. extra ';', maybe, but then why a while-loop at all? */ | ||
1902 | while ((NULL == hello) || | ||
1903 | (GNUNET_BLOCK_REPLY_OK_MORE != | ||
1904 | GNUNET_BLOCK_check_reply (GDS_block_context, | ||
1905 | GNUNET_BLOCK_TYPE_DHT_HELLO, | ||
1906 | bg, | ||
1907 | &peer->phash, | ||
1908 | NULL, 0, | ||
1909 | hello, | ||
1910 | (hello_size = GNUNET_HELLO_size (hello))))); | ||
1911 | GDS_NEIGHBOURS_handle_reply (sender, | ||
1912 | GNUNET_BLOCK_TYPE_DHT_HELLO, | ||
1913 | GNUNET_TIME_relative_to_absolute | ||
1914 | (GNUNET_CONSTANTS_HELLO_ADDRESS_EXPIRATION), | ||
1915 | key, | ||
1916 | 0, | ||
1917 | NULL, | ||
1918 | 0, | ||
1919 | NULL, | ||
1920 | hello, | ||
1921 | hello_size); | ||
1922 | } | 1844 | } |
1923 | 1845 | ||
1924 | 1846 | ||
1925 | /** | 1847 | /** |
1926 | * Handle a result from local datacache for a GET operation. | 1848 | * Handle an exact result from local datacache for a GET operation. |
1927 | * | 1849 | * |
1928 | * @param cls the `struct PeerInfo` for which this is a reply | 1850 | * @param cls the `struct PeerInfo` for which this is a reply |
1929 | * @param type type of the block | 1851 | * @param bd details about the block we found locally |
1930 | * @param expiration_time when does the content expire | ||
1931 | * @param key key for the content | ||
1932 | * @param put_path_length number of entries in @a put_path | ||
1933 | * @param put_path peers the original PUT traversed (if tracked) | ||
1934 | * @param get_path_length number of entries in @a get_path | ||
1935 | * @param get_path peers this reply has traversed so far (if tracked) | ||
1936 | * @param data payload of the reply | ||
1937 | * @param data_size number of bytes in @a data | ||
1938 | */ | 1852 | */ |
1939 | static void | 1853 | static void |
1940 | handle_local_result (void *cls, | 1854 | handle_local_result (void *cls, |
1941 | enum GNUNET_BLOCK_Type type, | 1855 | const struct GDS_DATACACHE_BlockData *bd) |
1942 | struct GNUNET_TIME_Absolute expiration_time, | ||
1943 | const struct GNUNET_HashCode *key, | ||
1944 | unsigned int put_path_length, | ||
1945 | const struct GNUNET_PeerIdentity *put_path, | ||
1946 | unsigned int get_path_length, | ||
1947 | const struct GNUNET_PeerIdentity *get_path, | ||
1948 | const void *data, | ||
1949 | size_t data_size) | ||
1950 | { | 1856 | { |
1951 | struct PeerInfo *peer = cls; | 1857 | struct PeerInfo *peer = cls; |
1858 | |||
1952 | { | 1859 | { |
1953 | char *pp; | 1860 | char *pp; |
1954 | 1861 | ||
1955 | pp = GNUNET_STRINGS_pp2s (put_path, | 1862 | pp = GNUNET_STRINGS_pp2s (bd->put_path, |
1956 | put_path_length); | 1863 | bd->put_path_length); |
1957 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1864 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1958 | "Found local result for %s (PP: %s)\n", | 1865 | "Found local result for %s (PP: %s)\n", |
1959 | GNUNET_h2s (key), | 1866 | GNUNET_h2s (&bd->key), |
1960 | pp); | 1867 | pp); |
1961 | GNUNET_free (pp); | 1868 | GNUNET_free (pp); |
1962 | } | 1869 | } |
1963 | GDS_NEIGHBOURS_handle_reply (peer->id, | 1870 | GDS_NEIGHBOURS_handle_reply (peer->id, |
1964 | type, | 1871 | bd, |
1965 | expiration_time, | 1872 | &bd->key, |
1966 | key, | 1873 | 0, NULL /* get path */); |
1967 | put_path_length, put_path, | ||
1968 | get_path_length, get_path, | ||
1969 | data, data_size); | ||
1970 | } | 1874 | } |
1971 | 1875 | ||
1972 | 1876 | ||
@@ -2160,115 +2064,80 @@ handle_dht_p2p_get (void *cls, | |||
2160 | 2064 | ||
2161 | 2065 | ||
2162 | /** | 2066 | /** |
2163 | * Check validity of p2p result message. | ||
2164 | * | ||
2165 | * @param cls closure | ||
2166 | * @param message message | ||
2167 | * @return #GNUNET_YES if the message is well-formed | ||
2168 | */ | ||
2169 | static enum GNUNET_GenericReturnValue | ||
2170 | check_dht_p2p_result (void *cls, | ||
2171 | const struct PeerResultMessage *prm) | ||
2172 | { | ||
2173 | uint32_t get_path_length; | ||
2174 | uint32_t put_path_length; | ||
2175 | uint16_t msize; | ||
2176 | |||
2177 | (void) cls; | ||
2178 | msize = ntohs (prm->header.size); | ||
2179 | put_path_length = ntohl (prm->put_path_length); | ||
2180 | get_path_length = ntohl (prm->get_path_length); | ||
2181 | if ((msize < | ||
2182 | sizeof(struct PeerResultMessage) + (get_path_length | ||
2183 | + put_path_length) | ||
2184 | * sizeof(struct GNUNET_PeerIdentity)) || | ||
2185 | (get_path_length > | ||
2186 | GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_PeerIdentity)) || | ||
2187 | (put_path_length > | ||
2188 | GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_PeerIdentity))) | ||
2189 | { | ||
2190 | GNUNET_break_op (0); | ||
2191 | return GNUNET_SYSERR; | ||
2192 | } | ||
2193 | return GNUNET_OK; | ||
2194 | } | ||
2195 | |||
2196 | |||
2197 | /** | ||
2198 | * Process a reply, after the @a get_path has been updated. | 2067 | * Process a reply, after the @a get_path has been updated. |
2199 | * | 2068 | * |
2200 | * @param expiration_time when does the reply expire | 2069 | * @param bd block details |
2201 | * @param key key of the original inquiry | 2070 | * @param query_hash hash of the original query, might not match key in @a bd |
2202 | * @param query_hash key matching the block | ||
2203 | * @param get_path_length number of entries in @a get_path | 2071 | * @param get_path_length number of entries in @a get_path |
2204 | * @param get_path path the reply has taken | 2072 | * @param get_path path the reply has taken |
2205 | * @param put_path_length number of entries in @a put_path | ||
2206 | * @param put_path path the PUT has taken | ||
2207 | * @param type type of the block | ||
2208 | * @param data_size number of bytes in @a data | ||
2209 | * @param data payload of the reply | ||
2210 | */ | 2073 | */ |
2211 | static void | 2074 | static void |
2212 | process_reply_with_path (struct GNUNET_TIME_Absolute expiration_time, | 2075 | process_reply_with_path (const struct GDS_DATACACHE_BlockData *bd, |
2213 | const struct GNUNET_HashCode *key, | ||
2214 | const struct GNUNET_HashCode *query_hash, | 2076 | const struct GNUNET_HashCode *query_hash, |
2215 | unsigned int get_path_length, | 2077 | unsigned int get_path_length, |
2216 | const struct GNUNET_PeerIdentity *get_path, | 2078 | const struct GNUNET_PeerIdentity *get_path) |
2217 | unsigned int put_path_length, | ||
2218 | const struct GNUNET_PeerIdentity *put_path, | ||
2219 | enum GNUNET_BLOCK_Type type, | ||
2220 | size_t data_size, | ||
2221 | const void *data) | ||
2222 | { | 2079 | { |
2223 | /* forward to local clients */ | 2080 | /* forward to local clients */ |
2224 | GDS_CLIENTS_handle_reply (expiration_time, | 2081 | GDS_CLIENTS_handle_reply (bd, |
2225 | key, | ||
2226 | query_hash, | 2082 | query_hash, |
2227 | get_path_length, | 2083 | get_path_length, |
2228 | get_path, | 2084 | get_path); |
2229 | put_path_length, | 2085 | GDS_CLIENTS_process_get_resp (bd, |
2230 | put_path, | ||
2231 | type, | ||
2232 | data_size, | ||
2233 | data); | ||
2234 | GDS_CLIENTS_process_get_resp (type, | ||
2235 | get_path, | 2086 | get_path, |
2236 | get_path_length, | 2087 | get_path_length); |
2237 | put_path, | ||
2238 | put_path_length, | ||
2239 | expiration_time, | ||
2240 | query_hash, | ||
2241 | data, | ||
2242 | data_size); | ||
2243 | if (GNUNET_YES == cache_results) | 2088 | if (GNUNET_YES == cache_results) |
2244 | { | 2089 | { |
2245 | struct GNUNET_PeerIdentity xput_path[get_path_length + 1 + put_path_length]; | 2090 | struct GNUNET_PeerIdentity xput_path[GNUNET_NZL (get_path_length |
2091 | + bd->put_path_length)]; | ||
2092 | struct GDS_DATACACHE_BlockData bdx = *bd; | ||
2246 | 2093 | ||
2247 | GNUNET_memcpy (xput_path, | 2094 | GNUNET_memcpy (xput_path, |
2248 | put_path, | 2095 | bd->put_path, |
2249 | put_path_length * sizeof(struct GNUNET_PeerIdentity)); | 2096 | bd->put_path_length * sizeof(struct GNUNET_PeerIdentity)); |
2250 | GNUNET_memcpy (&xput_path[put_path_length], | 2097 | GNUNET_memcpy (&xput_path[bd->put_path_length], |
2251 | get_path, | 2098 | get_path, |
2252 | get_path_length * sizeof(struct GNUNET_PeerIdentity)); | 2099 | get_path_length * sizeof(struct GNUNET_PeerIdentity)); |
2253 | 2100 | bdx.put_path = xput_path; | |
2254 | GDS_DATACACHE_handle_put (expiration_time, | 2101 | bdx.put_path_length += get_path_length; |
2255 | query_hash, | 2102 | GDS_DATACACHE_handle_put (&bdx); |
2256 | get_path_length + put_path_length, | ||
2257 | xput_path, | ||
2258 | type, | ||
2259 | data_size, | ||
2260 | data); | ||
2261 | } | 2103 | } |
2262 | /* forward to other peers */ | 2104 | /* forward to other peers */ |
2263 | GDS_ROUTING_process (type, | 2105 | GDS_ROUTING_process (bd, |
2264 | expiration_time, | 2106 | query_hash, |
2265 | key, | ||
2266 | put_path_length, | ||
2267 | put_path, | ||
2268 | get_path_length, | 2107 | get_path_length, |
2269 | get_path, | 2108 | get_path); |
2270 | data, | 2109 | } |
2271 | data_size); | 2110 | |
2111 | |||
2112 | /** | ||
2113 | * Check validity of p2p result message. | ||
2114 | * | ||
2115 | * @param cls closure | ||
2116 | * @param message message | ||
2117 | * @return #GNUNET_YES if the message is well-formed | ||
2118 | */ | ||
2119 | static enum GNUNET_GenericReturnValue | ||
2120 | check_dht_p2p_result (void *cls, | ||
2121 | const struct PeerResultMessage *prm) | ||
2122 | { | ||
2123 | uint32_t get_path_length = ntohl (prm->get_path_length); | ||
2124 | uint32_t put_path_length = ntohl (prm->put_path_length); | ||
2125 | uint16_t msize = ntohs (prm->header.size); | ||
2126 | |||
2127 | (void) cls; | ||
2128 | if ( (msize < | ||
2129 | sizeof(struct PeerResultMessage) | ||
2130 | + (get_path_length + put_path_length) | ||
2131 | * sizeof(struct GNUNET_PeerIdentity)) || | ||
2132 | (get_path_length > | ||
2133 | GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_PeerIdentity)) || | ||
2134 | (put_path_length > | ||
2135 | GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_PeerIdentity)) ) | ||
2136 | { | ||
2137 | GNUNET_break_op (0); | ||
2138 | return GNUNET_SYSERR; | ||
2139 | } | ||
2140 | return GNUNET_OK; | ||
2272 | } | 2141 | } |
2273 | 2142 | ||
2274 | 2143 | ||
@@ -2283,72 +2152,66 @@ handle_dht_p2p_result (void *cls, | |||
2283 | const struct PeerResultMessage *prm) | 2152 | const struct PeerResultMessage *prm) |
2284 | { | 2153 | { |
2285 | struct PeerInfo *peer = cls; | 2154 | struct PeerInfo *peer = cls; |
2286 | const struct GNUNET_PeerIdentity *put_path; | 2155 | uint16_t msize = ntohs (prm->header.size); |
2287 | const struct GNUNET_PeerIdentity *get_path; | 2156 | uint32_t get_path_length = ntohl (prm->get_path_length); |
2288 | const void *data; | 2157 | struct GDS_DATACACHE_BlockData bd = { |
2289 | uint32_t get_path_length; | 2158 | .expiration_time = GNUNET_TIME_absolute_ntoh (prm->expiration_time), |
2290 | uint32_t put_path_length; | 2159 | .put_path = (const struct GNUNET_PeerIdentity *) &prm[1], |
2291 | uint16_t msize; | 2160 | .put_path_length = ntohl (prm->put_path_length), |
2292 | size_t data_size; | 2161 | .type = ntohl (prm->type) |
2293 | enum GNUNET_BLOCK_Type type; | 2162 | }; |
2294 | struct GNUNET_TIME_Absolute exp_time; | 2163 | const struct GNUNET_PeerIdentity *get_path |
2295 | const struct GNUNET_HashCode *pquery; | 2164 | = &bd.put_path[bd.put_path_length]; |
2296 | struct GNUNET_HashCode dquery; | ||
2297 | 2165 | ||
2298 | /* parse and validate message */ | 2166 | /* parse and validate message */ |
2299 | exp_time = GNUNET_TIME_absolute_ntoh (prm->expiration_time); | 2167 | if (GNUNET_TIME_absolute_is_past (bd.expiration_time)) |
2300 | if (0 == GNUNET_TIME_absolute_get_remaining (exp_time).rel_value_us) | ||
2301 | { | 2168 | { |
2302 | GNUNET_STATISTICS_update (GDS_stats, | 2169 | GNUNET_STATISTICS_update (GDS_stats, |
2303 | gettext_noop ("# Expired results discarded"), | 2170 | "# Expired results discarded", |
2304 | 1, | 2171 | 1, |
2305 | GNUNET_NO); | 2172 | GNUNET_NO); |
2306 | return; | 2173 | return; |
2307 | } | 2174 | } |
2308 | msize = ntohs (prm->header.size); | 2175 | get_path = &bd.put_path[bd.put_path_length]; |
2309 | put_path_length = ntohl (prm->put_path_length); | 2176 | bd.data = (const void *) &get_path[get_path_length]; |
2310 | get_path_length = ntohl (prm->get_path_length); | 2177 | bd.data_size = msize - (sizeof(struct PeerResultMessage) |
2311 | put_path = (const struct GNUNET_PeerIdentity *) &prm[1]; | 2178 | + (get_path_length + bd.put_path_length) |
2312 | get_path = &put_path[put_path_length]; | 2179 | * sizeof(struct GNUNET_PeerIdentity)); |
2313 | type = ntohl (prm->type); | ||
2314 | data = (const void *) &get_path[get_path_length]; | ||
2315 | data_size = msize - (sizeof(struct PeerResultMessage) | ||
2316 | + (get_path_length | ||
2317 | + put_path_length) | ||
2318 | * sizeof(struct GNUNET_PeerIdentity)); | ||
2319 | GNUNET_STATISTICS_update (GDS_stats, | 2180 | GNUNET_STATISTICS_update (GDS_stats, |
2320 | gettext_noop ("# P2P RESULTS received"), | 2181 | "# P2P RESULTS received", |
2321 | 1, | 2182 | 1, |
2322 | GNUNET_NO); | 2183 | GNUNET_NO); |
2323 | GNUNET_STATISTICS_update (GDS_stats, | 2184 | GNUNET_STATISTICS_update (GDS_stats, |
2324 | gettext_noop ("# P2P RESULT bytes received"), | 2185 | "# P2P RESULT bytes received", |
2325 | msize, | 2186 | msize, |
2326 | GNUNET_NO); | 2187 | GNUNET_NO); |
2327 | { | 2188 | { |
2328 | enum GNUNET_GenericReturnValue ret; | 2189 | enum GNUNET_GenericReturnValue ret; |
2190 | const struct GNUNET_HashCode *pquery; | ||
2329 | 2191 | ||
2330 | ret = GNUNET_BLOCK_get_key (GDS_block_context, | 2192 | ret = GNUNET_BLOCK_get_key (GDS_block_context, |
2331 | type, | 2193 | bd.type, |
2332 | data, | 2194 | bd.data, |
2333 | data_size, | 2195 | bd.data_size, |
2334 | &dquery); | 2196 | &bd.key); |
2335 | if (GNUNET_NO == ret) | 2197 | if (GNUNET_NO == ret) |
2336 | { | 2198 | { |
2337 | GNUNET_break_op (0); | 2199 | GNUNET_break_op (0); |
2338 | return; | 2200 | return; |
2339 | } | 2201 | } |
2340 | pquery = (GNUNET_OK == ret) ? &dquery : &prm->key; | 2202 | pquery = (GNUNET_OK == ret) ? &bd.key : &prm->key; |
2341 | if (GNUNET_OK != | 2203 | if (GNUNET_OK != |
2342 | GNUNET_BLOCK_check_block (GDS_block_context, | 2204 | GNUNET_BLOCK_check_block (GDS_block_context, |
2343 | type, | 2205 | bd.type, |
2344 | pquery, | 2206 | pquery, |
2345 | data, | 2207 | bd.data, |
2346 | data_size)) | 2208 | bd.data_size)) |
2347 | { | 2209 | { |
2348 | GNUNET_break_op (0); | 2210 | GNUNET_break_op (0); |
2349 | return; | 2211 | return; |
2350 | } | 2212 | } |
2351 | } | 2213 | } |
2214 | |||
2352 | if (GNUNET_YES == log_route_details_stderr) | 2215 | if (GNUNET_YES == log_route_details_stderr) |
2353 | { | 2216 | { |
2354 | char *tmp; | 2217 | char *tmp; |
@@ -2357,8 +2220,8 @@ handle_dht_p2p_result (void *cls, | |||
2357 | 2220 | ||
2358 | gp = GNUNET_STRINGS_pp2s (get_path, | 2221 | gp = GNUNET_STRINGS_pp2s (get_path, |
2359 | get_path_length); | 2222 | get_path_length); |
2360 | pp = GNUNET_STRINGS_pp2s (put_path, | 2223 | pp = GNUNET_STRINGS_pp2s (bd.put_path, |
2361 | put_path_length); | 2224 | bd.put_path_length); |
2362 | tmp = GNUNET_strdup (GNUNET_i2s (&my_identity)); | 2225 | tmp = GNUNET_strdup (GNUNET_i2s (&my_identity)); |
2363 | LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG, | 2226 | LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG, |
2364 | "R5N RESULT %s: %s->%s (GP: %s, PP: %s)\n", | 2227 | "R5N RESULT %s: %s->%s (GP: %s, PP: %s)\n", |
@@ -2371,22 +2234,22 @@ handle_dht_p2p_result (void *cls, | |||
2371 | GNUNET_free (pp); | 2234 | GNUNET_free (pp); |
2372 | GNUNET_free (tmp); | 2235 | GNUNET_free (tmp); |
2373 | } | 2236 | } |
2237 | |||
2374 | /* if we got a HELLO, consider it for our own routing table */ | 2238 | /* if we got a HELLO, consider it for our own routing table */ |
2375 | if (GNUNET_BLOCK_TYPE_DHT_HELLO == type) | 2239 | if (GNUNET_BLOCK_TYPE_DHT_HELLO == bd.type) |
2376 | { | 2240 | { |
2377 | const struct GNUNET_MessageHeader *h; | 2241 | const struct GNUNET_MessageHeader *h = bd.data; |
2378 | struct GNUNET_PeerIdentity pid; | 2242 | struct GNUNET_PeerIdentity pid; |
2379 | 2243 | ||
2380 | /* Should be a HELLO, validate and consider using it! */ | 2244 | /* Should be a HELLO, validate and consider using it! */ |
2381 | if (data_size < sizeof(struct GNUNET_HELLO_Message)) | 2245 | if (bd.data_size < sizeof(struct GNUNET_HELLO_Message)) |
2382 | { | 2246 | { |
2383 | GNUNET_break_op (0); | 2247 | GNUNET_break (0); |
2384 | return; | 2248 | return; |
2385 | } | 2249 | } |
2386 | h = data; | 2250 | if (bd.data_size != ntohs (h->size)) |
2387 | if (data_size != ntohs (h->size)) | ||
2388 | { | 2251 | { |
2389 | GNUNET_break_op (0); | 2252 | GNUNET_break (0); |
2390 | return; | 2253 | return; |
2391 | } | 2254 | } |
2392 | if (GNUNET_OK != | 2255 | if (GNUNET_OK != |
@@ -2396,9 +2259,9 @@ handle_dht_p2p_result (void *cls, | |||
2396 | GNUNET_break_op (0); | 2259 | GNUNET_break_op (0); |
2397 | return; | 2260 | return; |
2398 | } | 2261 | } |
2399 | if ((GNUNET_YES != disable_try_connect) && | 2262 | if ( (GNUNET_YES != disable_try_connect) && |
2400 | (0 != GNUNET_memcmp (&my_identity, | 2263 | (0 != GNUNET_memcmp (&my_identity, |
2401 | &pid))) | 2264 | &pid)) ) |
2402 | try_connect (&pid, | 2265 | try_connect (&pid, |
2403 | h); | 2266 | h); |
2404 | } | 2267 | } |
@@ -2409,16 +2272,9 @@ handle_dht_p2p_result (void *cls, | |||
2409 | if (0 == GNUNET_memcmp (&get_path[i], | 2272 | if (0 == GNUNET_memcmp (&get_path[i], |
2410 | peer->id)) | 2273 | peer->id)) |
2411 | { | 2274 | { |
2412 | process_reply_with_path (exp_time, | 2275 | process_reply_with_path (&bd, |
2413 | &prm->key, | 2276 | &prm->key, |
2414 | pquery, | 2277 | i, get_path); |
2415 | i, | ||
2416 | get_path, | ||
2417 | put_path_length, | ||
2418 | put_path, | ||
2419 | type, | ||
2420 | data_size, | ||
2421 | data); | ||
2422 | return; | 2278 | return; |
2423 | } | 2279 | } |
2424 | 2280 | ||
@@ -2430,16 +2286,9 @@ handle_dht_p2p_result (void *cls, | |||
2430 | get_path, | 2286 | get_path, |
2431 | get_path_length * sizeof(struct GNUNET_PeerIdentity)); | 2287 | get_path_length * sizeof(struct GNUNET_PeerIdentity)); |
2432 | xget_path[get_path_length] = *peer->id; | 2288 | xget_path[get_path_length] = *peer->id; |
2433 | process_reply_with_path (exp_time, | 2289 | process_reply_with_path (&bd, |
2434 | &prm->key, | 2290 | &prm->key, |
2435 | pquery, | 2291 | get_path_length + 1, xget_path); |
2436 | get_path_length + 1, | ||
2437 | xget_path, | ||
2438 | put_path_length, | ||
2439 | put_path, | ||
2440 | type, | ||
2441 | data_size, | ||
2442 | data); | ||
2443 | } | 2292 | } |
2444 | } | 2293 | } |
2445 | 2294 | ||