diff options
Diffstat (limited to 'src/dht/gnunet-service-dht_neighbours.c')
-rw-r--r-- | src/dht/gnunet-service-dht_neighbours.c | 177 |
1 files changed, 115 insertions, 62 deletions
diff --git a/src/dht/gnunet-service-dht_neighbours.c b/src/dht/gnunet-service-dht_neighbours.c index 284380647..f542dd6af 100644 --- a/src/dht/gnunet-service-dht_neighbours.c +++ b/src/dht/gnunet-service-dht_neighbours.c | |||
@@ -519,22 +519,60 @@ do_send (struct PeerInfo *pi, | |||
519 | * @param pred predecessor peer ID | 519 | * @param pred predecessor peer ID |
520 | * @param succ successor peer ID | 520 | * @param succ successor peer ID |
521 | * @param[out] sig where to write the signature | 521 | * @param[out] sig where to write the signature |
522 | * (of purpose #GNUNET_SIGNATURE_PURPOSE_DHT_PUT_HOP) | ||
523 | */ | ||
524 | static void | ||
525 | sign_put_path (const void *data, | ||
526 | size_t data_size, | ||
527 | struct GNUNET_TIME_Absolute exp_time, | ||
528 | const struct GNUNET_PeerIdentity *pred, | ||
529 | const struct GNUNET_PeerIdentity *succ, | ||
530 | struct GNUNET_CRYPTO_EddsaSignature *sig) | ||
531 | { | ||
532 | struct GNUNET_DHT_PutHopSignature hs = { | ||
533 | .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DHT_PUT_HOP), | ||
534 | .purpose.size = htonl (sizeof (hs)), | ||
535 | .expiration_time = GNUNET_TIME_absolute_hton (exp_time), | ||
536 | .pred = *pred, | ||
537 | .succ = *succ | ||
538 | }; | ||
539 | |||
540 | GNUNET_CRYPTO_hash (data, | ||
541 | data_size, | ||
542 | &hs.h_data); | ||
543 | GNUNET_CRYPTO_eddsa_sign (&GDS_my_private_key, | ||
544 | &hs, | ||
545 | sig); | ||
546 | } | ||
547 | |||
548 | |||
549 | /** | ||
550 | * Sign that we are routing a message from @a pred to @a succ. | ||
551 | * (So the route is $PRED->us->$SUCC). | ||
552 | * | ||
553 | * @param query_hash query being answered | ||
554 | * @param data payload (the block) | ||
555 | * @param data_size number of bytes in @a data | ||
556 | * @param exp_time expiration time of @a data | ||
557 | * @param pred predecessor peer ID | ||
558 | * @param succ successor peer ID | ||
559 | * @param[out] sig where to write the signature | ||
522 | * (of purpose #GNUNET_SIGNATURE_PURPOSE_DHT_HOP) | 560 | * (of purpose #GNUNET_SIGNATURE_PURPOSE_DHT_HOP) |
523 | */ | 561 | */ |
524 | static void | 562 | static void |
525 | sign_path (const struct GNUNET_HashCode *key, | 563 | sign_result_path (const struct GNUNET_HashCode *query_hash, |
526 | const void *data, | 564 | const void *data, |
527 | size_t data_size, | 565 | size_t data_size, |
528 | struct GNUNET_TIME_Absolute exp_time, | 566 | struct GNUNET_TIME_Absolute exp_time, |
529 | const struct GNUNET_PeerIdentity *pred, | 567 | const struct GNUNET_PeerIdentity *pred, |
530 | const struct GNUNET_PeerIdentity *succ, | 568 | const struct GNUNET_PeerIdentity *succ, |
531 | struct GNUNET_CRYPTO_EddsaSignature *sig) | 569 | struct GNUNET_CRYPTO_EddsaSignature *sig) |
532 | { | 570 | { |
533 | struct GNUNET_DHT_HopSignature hs = { | 571 | struct GNUNET_DHT_ResultHopSignature hs = { |
534 | .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DHT_HOP), | 572 | .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DHT_RESULT_HOP), |
535 | .purpose.size = htonl (sizeof (hs)), | 573 | .purpose.size = htonl (sizeof (hs)), |
536 | .expiration_time = GNUNET_TIME_absolute_hton (exp_time), | 574 | .expiration_time = GNUNET_TIME_absolute_hton (exp_time), |
537 | .key = *key, | 575 | .query_hash = *query_hash, |
538 | .pred = *pred, | 576 | .pred = *pred, |
539 | .succ = *succ | 577 | .succ = *succ |
540 | }; | 578 | }; |
@@ -1299,7 +1337,7 @@ GDS_NEIGHBOURS_handle_put (const struct GDS_DATACACHE_BlockData *bd, | |||
1299 | GNUNET_assert (NULL != bf); | 1337 | GNUNET_assert (NULL != bf); |
1300 | #if SANITY_CHECKS | 1338 | #if SANITY_CHECKS |
1301 | if (0 != | 1339 | if (0 != |
1302 | GNUNET_DHT_verify_path (&bd->key, | 1340 | GNUNET_DHT_verify_path (NULL, |
1303 | bd->data, | 1341 | bd->data, |
1304 | bd->data_size, | 1342 | bd->data_size, |
1305 | bd->expiration_time, | 1343 | bd->expiration_time, |
@@ -1393,13 +1431,12 @@ GDS_NEIGHBOURS_handle_put (const struct GDS_DATACACHE_BlockData *bd, | |||
1393 | { | 1431 | { |
1394 | /* Note that the signature in 'put_path' was not initialized before, | 1432 | /* Note that the signature in 'put_path' was not initialized before, |
1395 | so this is crucial to avoid sending garbage. */ | 1433 | so this is crucial to avoid sending garbage. */ |
1396 | sign_path (&bd->key, | 1434 | sign_put_path (bd->data, |
1397 | bd->data, | 1435 | bd->data_size, |
1398 | bd->data_size, | 1436 | bd->expiration_time, |
1399 | bd->expiration_time, | 1437 | &pp[put_path_length - 1].pred, |
1400 | &pp[put_path_length - 1].pred, | 1438 | &target->id, |
1401 | &target->id, | 1439 | &pp[put_path_length - 1].sig); |
1402 | &pp[put_path_length - 1].sig); | ||
1403 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1440 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1404 | "Signing PUT PATH %u => %s\n", | 1441 | "Signing PUT PATH %u => %s\n", |
1405 | put_path_length, | 1442 | put_path_length, |
@@ -1546,7 +1583,7 @@ GDS_NEIGHBOURS_lookup_peer (const struct GNUNET_PeerIdentity *target) | |||
1546 | } | 1583 | } |
1547 | 1584 | ||
1548 | 1585 | ||
1549 | void | 1586 | bool |
1550 | GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi, | 1587 | GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi, |
1551 | const struct GDS_DATACACHE_BlockData *bd, | 1588 | const struct GDS_DATACACHE_BlockData *bd, |
1552 | const struct GNUNET_HashCode *query_hash, | 1589 | const struct GNUNET_HashCode *query_hash, |
@@ -1559,7 +1596,7 @@ GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi, | |||
1559 | 1596 | ||
1560 | #if SANITY_CHECKS | 1597 | #if SANITY_CHECKS |
1561 | if (0 != | 1598 | if (0 != |
1562 | GNUNET_DHT_verify_path (&bd->key, | 1599 | GNUNET_DHT_verify_path (query_hash, |
1563 | bd->data, | 1600 | bd->data, |
1564 | bd->data_size, | 1601 | bd->data_size, |
1565 | bd->expiration_time, | 1602 | bd->expiration_time, |
@@ -1570,8 +1607,7 @@ GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi, | |||
1570 | &GDS_my_identity)) | 1607 | &GDS_my_identity)) |
1571 | { | 1608 | { |
1572 | GNUNET_break_op (0); | 1609 | GNUNET_break_op (0); |
1573 | get_path_length = 0; | 1610 | return false; |
1574 | ppl = 0; | ||
1575 | } | 1611 | } |
1576 | #endif | 1612 | #endif |
1577 | msize = bd->data_size + (get_path_length + ppl) | 1613 | msize = bd->data_size + (get_path_length + ppl) |
@@ -1596,7 +1632,7 @@ GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi, | |||
1596 | (bd->data_size > GNUNET_MAX_MESSAGE_SIZE)) | 1632 | (bd->data_size > GNUNET_MAX_MESSAGE_SIZE)) |
1597 | { | 1633 | { |
1598 | GNUNET_break (0); | 1634 | GNUNET_break (0); |
1599 | return; | 1635 | return false; |
1600 | } | 1636 | } |
1601 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 1637 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
1602 | "Forwarding reply for key %s to peer %s\n", | 1638 | "Forwarding reply for key %s to peer %s\n", |
@@ -1645,13 +1681,13 @@ GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi, | |||
1645 | { | 1681 | { |
1646 | /* Note that the last signature in 'paths' was not initialized before, | 1682 | /* Note that the last signature in 'paths' was not initialized before, |
1647 | so this is crucial to avoid sending garbage. */ | 1683 | so this is crucial to avoid sending garbage. */ |
1648 | sign_path (query_hash, | 1684 | sign_result_path (query_hash, |
1649 | bd->data, | 1685 | bd->data, |
1650 | bd->data_size, | 1686 | bd->data_size, |
1651 | bd->expiration_time, | 1687 | bd->expiration_time, |
1652 | &paths[ppl + get_path_length - 1].pred, | 1688 | &paths[ppl + get_path_length - 1].pred, |
1653 | &pi->id, | 1689 | &pi->id, |
1654 | &paths[ppl + get_path_length - 1].sig); | 1690 | &paths[ppl + get_path_length - 1].sig); |
1655 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1691 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1656 | "Signing GET PATH %u/%u of %s => %s\n", | 1692 | "Signing GET PATH %u/%u of %s => %s\n", |
1657 | ppl, | 1693 | ppl, |
@@ -1683,7 +1719,7 @@ GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi, | |||
1683 | &pi->id)) | 1719 | &pi->id)) |
1684 | { | 1720 | { |
1685 | GNUNET_break (0); | 1721 | GNUNET_break (0); |
1686 | return; | 1722 | return false; |
1687 | } | 1723 | } |
1688 | } | 1724 | } |
1689 | #endif | 1725 | #endif |
@@ -1692,6 +1728,7 @@ GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi, | |||
1692 | do_send (pi, | 1728 | do_send (pi, |
1693 | &prm->header); | 1729 | &prm->header); |
1694 | } | 1730 | } |
1731 | return true; | ||
1695 | } | 1732 | } |
1696 | 1733 | ||
1697 | 1734 | ||
@@ -1870,9 +1907,9 @@ handle_dht_p2p_put (void *cls, | |||
1870 | } | 1907 | } |
1871 | 1908 | ||
1872 | /* give to local clients */ | 1909 | /* give to local clients */ |
1873 | GDS_CLIENTS_handle_reply (&bd, | 1910 | GNUNET_break (GDS_CLIENTS_handle_reply (&bd, |
1874 | &bd.key, | 1911 | &bd.key, |
1875 | 0, NULL /* get path */); | 1912 | 0, NULL /* get path */)); |
1876 | 1913 | ||
1877 | /* store locally */ | 1914 | /* store locally */ |
1878 | if ( (0 != (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) || | 1915 | if ( (0 != (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) || |
@@ -1958,10 +1995,10 @@ handle_find_my_hello (struct PeerInfo *pi, | |||
1958 | .data_size = block_size | 1995 | .data_size = block_size |
1959 | }; | 1996 | }; |
1960 | 1997 | ||
1961 | GDS_NEIGHBOURS_handle_reply (pi, | 1998 | GNUNET_break (GDS_NEIGHBOURS_handle_reply (pi, |
1962 | &bd, | 1999 | &bd, |
1963 | query_hash, | 2000 | query_hash, |
1964 | 0, NULL /* get path */); | 2001 | 0, NULL /* get path */)); |
1965 | } | 2002 | } |
1966 | else | 2003 | else |
1967 | { | 2004 | { |
@@ -2013,10 +2050,10 @@ handle_find_local_hello (struct PeerInfo *pi, | |||
2013 | .data_size = peer->hello_size | 2050 | .data_size = peer->hello_size |
2014 | }; | 2051 | }; |
2015 | 2052 | ||
2016 | GDS_NEIGHBOURS_handle_reply (pi, | 2053 | GNUNET_break (GDS_NEIGHBOURS_handle_reply (pi, |
2017 | &bd, | 2054 | &bd, |
2018 | query_hash, | 2055 | query_hash, |
2019 | 0, NULL /* get path */); | 2056 | 0, NULL /* get path */)); |
2020 | } | 2057 | } |
2021 | } | 2058 | } |
2022 | 2059 | ||
@@ -2033,10 +2070,10 @@ handle_local_result (void *cls, | |||
2033 | { | 2070 | { |
2034 | struct PeerInfo *peer = cls; | 2071 | struct PeerInfo *peer = cls; |
2035 | 2072 | ||
2036 | GDS_NEIGHBOURS_handle_reply (peer, | 2073 | GNUNET_break (GDS_NEIGHBOURS_handle_reply (peer, |
2037 | bd, | 2074 | bd, |
2038 | &bd->key, | 2075 | &bd->key, |
2039 | 0, NULL /* get path */); | 2076 | 0, NULL /* get path */)); |
2040 | } | 2077 | } |
2041 | 2078 | ||
2042 | 2079 | ||
@@ -2230,8 +2267,9 @@ handle_dht_p2p_get (void *cls, | |||
2230 | * @param query_hash hash of the original query, might not match key in @a bd | 2267 | * @param query_hash hash of the original query, might not match key in @a bd |
2231 | * @param get_path_length number of entries in @a get_path | 2268 | * @param get_path_length number of entries in @a get_path |
2232 | * @param get_path path the reply has taken | 2269 | * @param get_path path the reply has taken |
2270 | * @return true on success | ||
2233 | */ | 2271 | */ |
2234 | static void | 2272 | static bool |
2235 | process_reply_with_path (const struct GDS_DATACACHE_BlockData *bd, | 2273 | process_reply_with_path (const struct GDS_DATACACHE_BlockData *bd, |
2236 | const struct GNUNET_HashCode *query_hash, | 2274 | const struct GNUNET_HashCode *query_hash, |
2237 | unsigned int get_path_length, | 2275 | unsigned int get_path_length, |
@@ -2240,10 +2278,14 @@ process_reply_with_path (const struct GDS_DATACACHE_BlockData *bd, | |||
2240 | /* forward to local clients */ | 2278 | /* forward to local clients */ |
2241 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2279 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2242 | "Forwarding reply to local clients\n"); | 2280 | "Forwarding reply to local clients\n"); |
2243 | GDS_CLIENTS_handle_reply (bd, | 2281 | if (! GDS_CLIENTS_handle_reply (bd, |
2244 | query_hash, | 2282 | query_hash, |
2245 | get_path_length, | 2283 | get_path_length, |
2246 | get_path); | 2284 | get_path)) |
2285 | { | ||
2286 | GNUNET_break (0); | ||
2287 | return false; | ||
2288 | } | ||
2247 | GDS_CLIENTS_process_get_resp (bd, | 2289 | GDS_CLIENTS_process_get_resp (bd, |
2248 | get_path, | 2290 | get_path, |
2249 | get_path_length); | 2291 | get_path_length); |
@@ -2268,6 +2310,7 @@ process_reply_with_path (const struct GDS_DATACACHE_BlockData *bd, | |||
2268 | query_hash, | 2310 | query_hash, |
2269 | get_path_length, | 2311 | get_path_length, |
2270 | get_path); | 2312 | get_path); |
2313 | return true; | ||
2271 | } | 2314 | } |
2272 | 2315 | ||
2273 | 2316 | ||
@@ -2282,6 +2325,8 @@ static enum GNUNET_GenericReturnValue | |||
2282 | check_dht_p2p_result (void *cls, | 2325 | check_dht_p2p_result (void *cls, |
2283 | const struct PeerResultMessage *prm) | 2326 | const struct PeerResultMessage *prm) |
2284 | { | 2327 | { |
2328 | struct Target *t = cls; | ||
2329 | struct PeerInfo *peer = t->pi; | ||
2285 | uint16_t get_path_length = ntohs (prm->get_path_length); | 2330 | uint16_t get_path_length = ntohs (prm->get_path_length); |
2286 | uint16_t put_path_length = ntohs (prm->put_path_length); | 2331 | uint16_t put_path_length = ntohs (prm->put_path_length); |
2287 | uint16_t msize = ntohs (prm->header.size); | 2332 | uint16_t msize = ntohs (prm->header.size); |
@@ -2289,8 +2334,8 @@ check_dht_p2p_result (void *cls, | |||
2289 | = (const struct GNUNET_DHT_PathElement *) &prm[1]; | 2334 | = (const struct GNUNET_DHT_PathElement *) &prm[1]; |
2290 | const struct GNUNET_DHT_PathElement *gp | 2335 | const struct GNUNET_DHT_PathElement *gp |
2291 | = &pp[put_path_length]; | 2336 | = &pp[put_path_length]; |
2337 | struct GNUNET_DHT_PathElement gpx[get_path_length + 1]; | ||
2292 | 2338 | ||
2293 | (void) cls; | ||
2294 | if ( (msize < | 2339 | if ( (msize < |
2295 | sizeof(struct PeerResultMessage) | 2340 | sizeof(struct PeerResultMessage) |
2296 | + (get_path_length + put_path_length) | 2341 | + (get_path_length + put_path_length) |
@@ -2305,6 +2350,14 @@ check_dht_p2p_result (void *cls, | |||
2305 | } | 2350 | } |
2306 | 2351 | ||
2307 | #if SANITY_CHECKS | 2352 | #if SANITY_CHECKS |
2353 | memcpy (gpx, | ||
2354 | gp, | ||
2355 | get_path_length | ||
2356 | * sizeof (struct GNUNET_DHT_PathElement)); | ||
2357 | gpx[get_path_length].pred = peer->id; | ||
2358 | memset (&gpx[get_path_length].sig, | ||
2359 | 0, | ||
2360 | sizeof (gpx[get_path_length].sig)); | ||
2308 | if (0 != | 2361 | if (0 != |
2309 | GNUNET_DHT_verify_path (&prm->key, | 2362 | GNUNET_DHT_verify_path (&prm->key, |
2310 | &gp[get_path_length], | 2363 | &gp[get_path_length], |
@@ -2314,8 +2367,8 @@ check_dht_p2p_result (void *cls, | |||
2314 | GNUNET_TIME_absolute_ntoh (prm->expiration_time), | 2367 | GNUNET_TIME_absolute_ntoh (prm->expiration_time), |
2315 | pp, | 2368 | pp, |
2316 | put_path_length, | 2369 | put_path_length, |
2317 | gp, | 2370 | gpx, |
2318 | get_path_length, | 2371 | get_path_length + 1, |
2319 | &GDS_my_identity)) | 2372 | &GDS_my_identity)) |
2320 | { | 2373 | { |
2321 | GNUNET_break_op (0); | 2374 | GNUNET_break_op (0); |
@@ -2483,10 +2536,10 @@ handle_dht_p2p_result (void *cls, | |||
2483 | "Truncating path at %u/%u\n", | 2536 | "Truncating path at %u/%u\n", |
2484 | i, | 2537 | i, |
2485 | get_path_length); | 2538 | get_path_length); |
2486 | process_reply_with_path (&bd, | 2539 | GNUNET_break (process_reply_with_path (&bd, |
2487 | &prm->key, | 2540 | &prm->key, |
2488 | i, | 2541 | i, |
2489 | get_path); | 2542 | get_path)); |
2490 | return; | 2543 | return; |
2491 | } | 2544 | } |
2492 | 2545 | ||
@@ -2505,10 +2558,10 @@ handle_dht_p2p_result (void *cls, | |||
2505 | "Extending GET path of length %u with %s\n", | 2558 | "Extending GET path of length %u with %s\n", |
2506 | get_path_length, | 2559 | get_path_length, |
2507 | GNUNET_i2s (&peer->id)); | 2560 | GNUNET_i2s (&peer->id)); |
2508 | process_reply_with_path (&bd, | 2561 | GNUNET_break (process_reply_with_path (&bd, |
2509 | &prm->key, | 2562 | &prm->key, |
2510 | get_path_length + 1, | 2563 | get_path_length + 1, |
2511 | xget_path); | 2564 | xget_path)); |
2512 | } | 2565 | } |
2513 | } | 2566 | } |
2514 | 2567 | ||