diff options
Diffstat (limited to 'src/dht')
-rw-r--r-- | src/dht/gnunet-service-dht.h | 68 | ||||
-rw-r--r-- | src/dht/gnunet-service-dht_clients.c | 340 | ||||
-rw-r--r-- | src/dht/gnunet-service-dht_datacache.c | 200 | ||||
-rw-r--r-- | src/dht/gnunet-service-dht_datacache.h | 124 | ||||
-rw-r--r-- | src/dht/gnunet-service-dht_hello.c | 18 | ||||
-rw-r--r-- | src/dht/gnunet-service-dht_neighbours.c | 695 | ||||
-rw-r--r-- | src/dht/gnunet-service-dht_neighbours.h | 47 | ||||
-rw-r--r-- | src/dht/gnunet-service-dht_nse.c | 30 | ||||
-rw-r--r-- | src/dht/gnunet-service-dht_routing.c | 200 | ||||
-rw-r--r-- | src/dht/gnunet-service-dht_routing.h | 24 |
10 files changed, 626 insertions, 1120 deletions
diff --git a/src/dht/gnunet-service-dht.h b/src/dht/gnunet-service-dht.h index 2854131c5..d520cc905 100644 --- a/src/dht/gnunet-service-dht.h +++ b/src/dht/gnunet-service-dht.h | |||
@@ -26,10 +26,10 @@ | |||
26 | #ifndef GNUNET_SERVICE_DHT_H | 26 | #ifndef GNUNET_SERVICE_DHT_H |
27 | #define GNUNET_SERVICE_DHT_H | 27 | #define GNUNET_SERVICE_DHT_H |
28 | 28 | ||
29 | #include "gnunet_util_lib.h" | 29 | #include "gnunet-service-dht_datacache.h" |
30 | #include "gnunet_statistics_service.h" | 30 | #include "gnunet_statistics_service.h" |
31 | #include "gnunet_transport_service.h" | 31 | #include "gnunet_transport_service.h" |
32 | #include "gnunet_block_lib.h" | 32 | |
33 | 33 | ||
34 | #define DEBUG_DHT GNUNET_EXTRA_LOGGING | 34 | #define DEBUG_DHT GNUNET_EXTRA_LOGGING |
35 | 35 | ||
@@ -64,28 +64,16 @@ extern struct GNUNET_MessageHeader *GDS_my_hello; | |||
64 | * matches any of our pending queries, forward it to the respective | 64 | * matches any of our pending queries, forward it to the respective |
65 | * client(s). | 65 | * client(s). |
66 | * | 66 | * |
67 | * @param expiration when will the reply expire | 67 | * @param bd block details |
68 | * @param key the key of the query that triggered the reply | 68 | * @param query_hash hash of the original query, might not match key in @a bd |
69 | * @param query_hash the query hash of the response | 69 | * @param get_path_length number of entries in @a get_path |
70 | * @param get_path_length number of peers in @a get_path | 70 | * @param get_path path the reply has taken |
71 | * @param get_path path the reply took on get | ||
72 | * @param put_path_length number of peers in @a put_path | ||
73 | * @param put_path path the reply took on put | ||
74 | * @param type type of the reply | ||
75 | * @param data_size number of bytes in @a data | ||
76 | * @param data application payload data | ||
77 | */ | 71 | */ |
78 | void | 72 | void |
79 | GDS_CLIENTS_handle_reply (struct GNUNET_TIME_Absolute expiration, | 73 | GDS_CLIENTS_handle_reply (const struct GDS_DATACACHE_BlockData *bd, |
80 | const struct GNUNET_HashCode *key, | ||
81 | const struct GNUNET_HashCode *query_hash, | 74 | const struct GNUNET_HashCode *query_hash, |
82 | unsigned int get_path_length, | 75 | unsigned int get_path_length, |
83 | const struct GNUNET_PeerIdentity *get_path, | 76 | const struct GNUNET_PeerIdentity *get_path); |
84 | unsigned int put_path_length, | ||
85 | const struct GNUNET_PeerIdentity *put_path, | ||
86 | enum GNUNET_BLOCK_Type type, | ||
87 | size_t data_size, | ||
88 | const void *data); | ||
89 | 77 | ||
90 | 78 | ||
91 | /** | 79 | /** |
@@ -114,26 +102,14 @@ GDS_CLIENTS_process_get (uint32_t options, | |||
114 | * Check if some client is monitoring GET RESP messages and notify | 102 | * Check if some client is monitoring GET RESP messages and notify |
115 | * them in that case. | 103 | * them in that case. |
116 | * | 104 | * |
117 | * @param type The type of data in the result. | 105 | * @param bd block details |
118 | * @param get_path Peers on GET path (or NULL if not recorded). | 106 | * @param get_path Peers on GET path (or NULL if not recorded). |
119 | * @param get_path_length number of entries in @a get_path. | 107 | * @param get_path_length number of entries in @a get_path. |
120 | * @param put_path peers on the PUT path (or NULL if not recorded). | ||
121 | * @param put_path_length number of entries in @a get_path. | ||
122 | * @param exp Expiration time of the data. | ||
123 | * @param key Key of the @a data. | ||
124 | * @param data Pointer to the result data. | ||
125 | * @param size Number of bytes in @a data. | ||
126 | */ | 108 | */ |
127 | void | 109 | void |
128 | GDS_CLIENTS_process_get_resp (enum GNUNET_BLOCK_Type type, | 110 | GDS_CLIENTS_process_get_resp (const struct GDS_DATACACHE_BlockData *bd, |
129 | const struct GNUNET_PeerIdentity *get_path, | 111 | const struct GNUNET_PeerIdentity *get_path, |
130 | unsigned int get_path_length, | 112 | unsigned int get_path_length); |
131 | const struct GNUNET_PeerIdentity *put_path, | ||
132 | unsigned int put_path_length, | ||
133 | struct GNUNET_TIME_Absolute exp, | ||
134 | const struct GNUNET_HashCode *key, | ||
135 | const void *data, | ||
136 | size_t size); | ||
137 | 113 | ||
138 | 114 | ||
139 | /** | 115 | /** |
@@ -141,27 +117,15 @@ GDS_CLIENTS_process_get_resp (enum GNUNET_BLOCK_Type type, | |||
141 | * them in that case. The @a path should include our own | 117 | * them in that case. The @a path should include our own |
142 | * peer ID (if recorded). | 118 | * peer ID (if recorded). |
143 | * | 119 | * |
144 | * @param options Options, for instance RecordRoute, DemultiplexEverywhere. | 120 | * @param options routing options to apply |
145 | * @param type The type of data in the request. | 121 | * @param bd details about the block |
146 | * @param hop_count Hop count so far. | 122 | * @param hop_count Hop count so far. |
147 | * @param path_length number of entries in path (or 0 if not recorded). | ||
148 | * @param path peers on the PUT path (or NULL if not recorded). | ||
149 | * @param desired_replication_level Desired replication level. | 123 | * @param desired_replication_level Desired replication level. |
150 | * @param exp Expiration time of the data. | ||
151 | * @param key Key under which data is to be stored. | ||
152 | * @param data Pointer to the data carried. | ||
153 | * @param size Number of bytes in data. | ||
154 | */ | 124 | */ |
155 | void | 125 | void |
156 | GDS_CLIENTS_process_put (uint32_t options, | 126 | GDS_CLIENTS_process_put (enum GNUNET_DHT_RouteOption options, |
157 | enum GNUNET_BLOCK_Type type, | 127 | const struct GDS_DATACACHE_BlockData *bd, |
158 | uint32_t hop_count, | 128 | uint32_t hop_count, |
159 | uint32_t desired_replication_level, | 129 | uint32_t desired_replication_level); |
160 | unsigned int path_length, | ||
161 | const struct GNUNET_PeerIdentity *path, | ||
162 | struct GNUNET_TIME_Absolute exp, | ||
163 | const struct GNUNET_HashCode *key, | ||
164 | const void *data, | ||
165 | size_t size); | ||
166 | 130 | ||
167 | #endif | 131 | #endif |
diff --git a/src/dht/gnunet-service-dht_clients.c b/src/dht/gnunet-service-dht_clients.c index aa41f519c..b520cda41 100644 --- a/src/dht/gnunet-service-dht_clients.c +++ b/src/dht/gnunet-service-dht_clients.c | |||
@@ -425,6 +425,7 @@ transmit_next_request_task (void *cls) | |||
425 | { | 425 | { |
426 | struct ClientQueryRecord *cqr; | 426 | struct ClientQueryRecord *cqr; |
427 | 427 | ||
428 | (void) cls; | ||
428 | retry_task = NULL; | 429 | retry_task = NULL; |
429 | while (NULL != (cqr = GNUNET_CONTAINER_heap_remove_root (retry_heap))) | 430 | while (NULL != (cqr = GNUNET_CONTAINER_heap_remove_root (retry_heap))) |
430 | { | 431 | { |
@@ -486,19 +487,23 @@ handle_dht_local_put (void *cls, | |||
486 | { | 487 | { |
487 | struct ClientHandle *ch = cls; | 488 | struct ClientHandle *ch = cls; |
488 | uint16_t size = ntohs (dht_msg->header.size); | 489 | uint16_t size = ntohs (dht_msg->header.size); |
489 | uint32_t type = ntohl (dht_msg->type); | ||
490 | struct GNUNET_TIME_Absolute expiration | ||
491 | = GNUNET_TIME_absolute_ntoh (dht_msg->expiration); | ||
492 | enum GNUNET_DHT_RouteOption options | 490 | enum GNUNET_DHT_RouteOption options |
493 | = (enum GNUNET_DHT_RouteOption) ntohl (dht_msg->options); | 491 | = (enum GNUNET_DHT_RouteOption) ntohl (dht_msg->options); |
494 | uint32_t replication_level | 492 | uint32_t replication_level |
495 | = ntohl (dht_msg->desired_replication_level); | 493 | = ntohl (dht_msg->desired_replication_level); |
494 | struct GDS_DATACACHE_BlockData bd = { | ||
495 | .key = dht_msg->key, | ||
496 | .expiration_time = GNUNET_TIME_absolute_ntoh (dht_msg->expiration), | ||
497 | .data = &dht_msg[1], | ||
498 | .data_size = size - sizeof (*dht_msg), | ||
499 | .type = ntohl (dht_msg->type) | ||
500 | }; | ||
496 | 501 | ||
497 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 502 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
498 | "Handling local PUT of %lu-bytes for query %s of type %u\n", | 503 | "Handling local PUT of %lu-bytes for query %s of type %u\n", |
499 | (unsigned long) (size - sizeof(struct GNUNET_DHT_ClientPutMessage)), | 504 | (unsigned long) (size - sizeof(struct GNUNET_DHT_ClientPutMessage)), |
500 | GNUNET_h2s (&dht_msg->key), | 505 | GNUNET_h2s (&dht_msg->key), |
501 | (unsigned int) type); | 506 | (unsigned int) bd.type); |
502 | GNUNET_STATISTICS_update (GDS_stats, | 507 | GNUNET_STATISTICS_update (GDS_stats, |
503 | "# PUT requests received from clients", | 508 | "# PUT requests received from clients", |
504 | 1, | 509 | 1, |
@@ -507,14 +512,10 @@ handle_dht_local_put (void *cls, | |||
507 | "CLIENT-PUT %s\n", | 512 | "CLIENT-PUT %s\n", |
508 | GNUNET_h2s_full (&dht_msg->key)); | 513 | GNUNET_h2s_full (&dht_msg->key)); |
509 | /* give to local clients */ | 514 | /* give to local clients */ |
510 | GDS_CLIENTS_handle_reply (expiration, | 515 | GDS_CLIENTS_handle_reply (&bd, |
511 | &dht_msg->key, | 516 | &bd.key, |
512 | &dht_msg->key, | 517 | 0, NULL /* get path */); |
513 | 0, NULL, /* get path */ | 518 | |
514 | 0, NULL, /* put path */ | ||
515 | type, | ||
516 | size - sizeof(struct GNUNET_DHT_ClientPutMessage), | ||
517 | &dht_msg[1]); | ||
518 | { | 519 | { |
519 | struct GNUNET_CONTAINER_BloomFilter *peer_bf; | 520 | struct GNUNET_CONTAINER_BloomFilter *peer_bf; |
520 | 521 | ||
@@ -526,26 +527,14 @@ handle_dht_local_put (void *cls, | |||
526 | if ( (0 != (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) || | 527 | if ( (0 != (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) || |
527 | (GDS_am_closest_peer (&dht_msg->key, | 528 | (GDS_am_closest_peer (&dht_msg->key, |
528 | peer_bf))) | 529 | peer_bf))) |
529 | GDS_DATACACHE_handle_put ( | 530 | GDS_DATACACHE_handle_put (&bd); |
530 | expiration, | ||
531 | &dht_msg->key, | ||
532 | 0, NULL, /* put path */ | ||
533 | type, | ||
534 | size - sizeof(struct GNUNET_DHT_ClientPutMessage), | ||
535 | &dht_msg[1]); | ||
536 | /* route to other peers */ | 531 | /* route to other peers */ |
537 | if (GNUNET_OK != | 532 | if (GNUNET_OK != |
538 | GDS_NEIGHBOURS_handle_put ( | 533 | GDS_NEIGHBOURS_handle_put (&bd, |
539 | type, | 534 | options, |
540 | options, | 535 | replication_level, |
541 | replication_level, | 536 | 0 /* hop count */, |
542 | expiration, | 537 | peer_bf)) |
543 | 0 /* hop count */, | ||
544 | peer_bf, | ||
545 | &dht_msg->key, | ||
546 | 0, NULL, /* put path */ | ||
547 | &dht_msg[1], | ||
548 | size - sizeof(struct GNUNET_DHT_ClientPutMessage))) | ||
549 | { | 538 | { |
550 | GNUNET_STATISTICS_update (GDS_stats, | 539 | GNUNET_STATISTICS_update (GDS_stats, |
551 | "# Local PUT requests not routed", | 540 | "# Local PUT requests not routed", |
@@ -556,15 +545,9 @@ handle_dht_local_put (void *cls, | |||
556 | } | 545 | } |
557 | GDS_CLIENTS_process_put ( | 546 | GDS_CLIENTS_process_put ( |
558 | options, | 547 | options, |
559 | type, | 548 | &bd, |
560 | 0, /* hop count */ | 549 | 0, /* hop count */ |
561 | replication_level, | 550 | replication_level); |
562 | 1, /* path length */ | ||
563 | GDS_NEIGHBOURS_get_id (), | ||
564 | expiration, | ||
565 | &dht_msg->key, | ||
566 | &dht_msg[1], | ||
567 | size - sizeof(struct GNUNET_DHT_ClientPutMessage)); | ||
568 | GNUNET_SERVICE_client_continue (ch->client); | 551 | GNUNET_SERVICE_client_continue (ch->client); |
569 | } | 552 | } |
570 | 553 | ||
@@ -573,37 +556,16 @@ handle_dht_local_put (void *cls, | |||
573 | * Handle a result from local datacache for a GET operation. | 556 | * Handle a result from local datacache for a GET operation. |
574 | * | 557 | * |
575 | * @param cls the `struct ClientHandle` of the client doing the query | 558 | * @param cls the `struct ClientHandle` of the client doing the query |
576 | * @param type type of the block | 559 | * @param bd details about the block that was found |
577 | * @param expiration_time when does the content expire | ||
578 | * @param key key for the content | ||
579 | * @param put_path_length number of entries in @a put_path | ||
580 | * @param put_path peers the original PUT traversed (if tracked) | ||
581 | * @param get_path_length number of entries in @a get_path | ||
582 | * @param get_path peers this reply has traversed so far (if tracked) | ||
583 | * @param data payload of the reply | ||
584 | * @param data_size number of bytes in @a data | ||
585 | */ | 560 | */ |
586 | static void | 561 | static void |
587 | handle_local_result (void *cls, | 562 | handle_local_result (void *cls, |
588 | enum GNUNET_BLOCK_Type type, | 563 | const struct GDS_DATACACHE_BlockData *bd) |
589 | struct GNUNET_TIME_Absolute expiration_time, | ||
590 | const struct GNUNET_HashCode *key, | ||
591 | unsigned int put_path_length, | ||
592 | const struct GNUNET_PeerIdentity *put_path, | ||
593 | unsigned int get_path_length, | ||
594 | const struct GNUNET_PeerIdentity *get_path, | ||
595 | const void *data, | ||
596 | size_t data_size) | ||
597 | { | 564 | { |
598 | // FIXME: this may deserve some clean up: inline the function, | 565 | /* FIXME: use 'cls' instead of looking up the client? */ |
599 | // possibly avoid even looking up the client! | 566 | GDS_CLIENTS_handle_reply (bd, |
600 | GDS_CLIENTS_handle_reply (expiration_time, | 567 | &bd->key, |
601 | key, | 568 | 0, NULL /* get_path */); |
602 | key, | ||
603 | 0, NULL, | ||
604 | put_path_length, put_path, | ||
605 | type, | ||
606 | data_size, data); | ||
607 | } | 569 | } |
608 | 570 | ||
609 | 571 | ||
@@ -713,6 +675,9 @@ struct FindByUniqueIdContext | |||
713 | */ | 675 | */ |
714 | struct ClientQueryRecord *cqr; | 676 | struct ClientQueryRecord *cqr; |
715 | 677 | ||
678 | /** | ||
679 | * Unique ID to look for. | ||
680 | */ | ||
716 | uint64_t unique_id; | 681 | uint64_t unique_id; |
717 | }; | 682 | }; |
718 | 683 | ||
@@ -968,9 +933,9 @@ handle_dht_local_monitor_stop ( | |||
968 | struct ForwardReplyContext | 933 | struct ForwardReplyContext |
969 | { | 934 | { |
970 | /** | 935 | /** |
971 | * Expiration time of the reply. | 936 | * Block details. |
972 | */ | 937 | */ |
973 | struct GNUNET_TIME_Absolute expiration; | 938 | const struct GDS_DATACACHE_BlockData *bd; |
974 | 939 | ||
975 | /** | 940 | /** |
976 | * GET path taken. | 941 | * GET path taken. |
@@ -978,39 +943,10 @@ struct ForwardReplyContext | |||
978 | const struct GNUNET_PeerIdentity *get_path; | 943 | const struct GNUNET_PeerIdentity *get_path; |
979 | 944 | ||
980 | /** | 945 | /** |
981 | * PUT path taken. | ||
982 | */ | ||
983 | const struct GNUNET_PeerIdentity *put_path; | ||
984 | |||
985 | /** | ||
986 | * Hash under which the payload is stored. | ||
987 | */ | ||
988 | const struct GNUNET_HashCode *query_hash; | ||
989 | |||
990 | /** | ||
991 | * Embedded payload. | ||
992 | */ | ||
993 | const void *data; | ||
994 | |||
995 | /** | ||
996 | * Number of bytes in data. | ||
997 | */ | ||
998 | size_t data_size; | ||
999 | |||
1000 | /** | ||
1001 | * Number of entries in @e get_path. | 946 | * Number of entries in @e get_path. |
1002 | */ | 947 | */ |
1003 | unsigned int get_path_length; | 948 | unsigned int get_path_length; |
1004 | 949 | ||
1005 | /** | ||
1006 | * Number of entries in @e put_path. | ||
1007 | */ | ||
1008 | unsigned int put_path_length; | ||
1009 | |||
1010 | /** | ||
1011 | * Type of the data. | ||
1012 | */ | ||
1013 | enum GNUNET_BLOCK_Type type; | ||
1014 | }; | 950 | }; |
1015 | 951 | ||
1016 | 952 | ||
@@ -1019,15 +955,15 @@ struct ForwardReplyContext | |||
1019 | * each of the matching clients. With some tricky recycling | 955 | * each of the matching clients. With some tricky recycling |
1020 | * of the buffer. | 956 | * of the buffer. |
1021 | * | 957 | * |
1022 | * @param cls the 'struct ForwardReplyContext' | 958 | * @param cls the `struct ForwardReplyContext` |
1023 | * @param key current key | 959 | * @param query_hash hash of the query for which this may be a reply |
1024 | * @param value value in the hash map, a ClientQueryRecord | 960 | * @param value value in the hash map, a ClientQueryRecord |
1025 | * @return #GNUNET_YES (we should continue to iterate), | 961 | * @return #GNUNET_YES (we should continue to iterate), |
1026 | * if the result is mal-formed, #GNUNET_NO | 962 | * if the result is mal-formed, #GNUNET_NO |
1027 | */ | 963 | */ |
1028 | static enum GNUNET_GenericReturnValue | 964 | static enum GNUNET_GenericReturnValue |
1029 | forward_reply (void *cls, | 965 | forward_reply (void *cls, |
1030 | const struct GNUNET_HashCode *key, | 966 | const struct GNUNET_HashCode *query_hash, |
1031 | void *value) | 967 | void *value) |
1032 | { | 968 | { |
1033 | struct ForwardReplyContext *frc = cls; | 969 | struct ForwardReplyContext *frc = cls; |
@@ -1041,13 +977,13 @@ forward_reply (void *cls, | |||
1041 | 977 | ||
1042 | LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG, | 978 | LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG, |
1043 | "CLIENT-RESULT %s\n", | 979 | "CLIENT-RESULT %s\n", |
1044 | GNUNET_h2s_full (frc->query_hash)); | 980 | GNUNET_h2s_full (&frc->bd->key)); |
1045 | if ((record->type != GNUNET_BLOCK_TYPE_ANY) && | 981 | if ( (record->type != GNUNET_BLOCK_TYPE_ANY) && |
1046 | (record->type != frc->type)) | 982 | (record->type != frc->bd->type) ) |
1047 | { | 983 | { |
1048 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 984 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1049 | "Record type mismatch, not passing request for key %s to local client\n", | 985 | "Record type mismatch, not passing request for key %s to local client\n", |
1050 | GNUNET_h2s (key)); | 986 | GNUNET_h2s (&frc->bd->key)); |
1051 | GNUNET_STATISTICS_update (GDS_stats, | 987 | GNUNET_STATISTICS_update (GDS_stats, |
1052 | "# Key match, type mismatches in REPLY to CLIENT", | 988 | "# Key match, type mismatches in REPLY to CLIENT", |
1053 | 1, | 989 | 1, |
@@ -1055,8 +991,8 @@ forward_reply (void *cls, | |||
1055 | return GNUNET_YES; /* type mismatch */ | 991 | return GNUNET_YES; /* type mismatch */ |
1056 | } | 992 | } |
1057 | if ( (0 == (record->msg_options & GNUNET_DHT_RO_FIND_PEER)) && | 993 | if ( (0 == (record->msg_options & GNUNET_DHT_RO_FIND_PEER)) && |
1058 | (0 != GNUNET_memcmp (key, | 994 | (0 != GNUNET_memcmp (&frc->bd->key, |
1059 | frc->query_hash)) ) | 995 | query_hash)) ) |
1060 | { | 996 | { |
1061 | GNUNET_STATISTICS_update (GDS_stats, | 997 | GNUNET_STATISTICS_update (GDS_stats, |
1062 | "# Inexact key match, but exact match required", | 998 | "# Inexact key match, but exact match required", |
@@ -1064,37 +1000,36 @@ forward_reply (void *cls, | |||
1064 | GNUNET_NO); | 1000 | GNUNET_NO); |
1065 | return GNUNET_YES; /* type mismatch */ | 1001 | return GNUNET_YES; /* type mismatch */ |
1066 | } | 1002 | } |
1067 | GNUNET_CRYPTO_hash (frc->data, | 1003 | GNUNET_CRYPTO_hash (frc->bd->data, |
1068 | frc->data_size, | 1004 | frc->bd->data_size, |
1069 | &ch); | 1005 | &ch); |
1070 | for (unsigned int i = 0; i < record->seen_replies_count; i++) | 1006 | for (unsigned int i = 0; i < record->seen_replies_count; i++) |
1071 | if (0 == memcmp (&record->seen_replies[i], | 1007 | if (0 == |
1072 | &ch, | 1008 | GNUNET_memcmp (&record->seen_replies[i], |
1073 | sizeof(struct GNUNET_HashCode))) | 1009 | &ch)) |
1074 | { | 1010 | { |
1075 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1011 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1076 | "Duplicate reply, not passing request for key %s to local client\n", | 1012 | "Duplicate reply, not passing request for key %s to local client\n", |
1077 | GNUNET_h2s (key)); | 1013 | GNUNET_h2s (&frc->bd->key)); |
1078 | GNUNET_STATISTICS_update (GDS_stats, | 1014 | GNUNET_STATISTICS_update (GDS_stats, |
1079 | gettext_noop | 1015 | "# Duplicate REPLIES to CLIENT request dropped", |
1080 | ( | 1016 | 1, |
1081 | "# Duplicate REPLIES to CLIENT request dropped"), | 1017 | GNUNET_NO); |
1082 | 1, GNUNET_NO); | ||
1083 | return GNUNET_YES; /* duplicate */ | 1018 | return GNUNET_YES; /* duplicate */ |
1084 | } | 1019 | } |
1085 | eval | 1020 | eval |
1086 | = GNUNET_BLOCK_check_reply (GDS_block_context, | 1021 | = GNUNET_BLOCK_check_reply (GDS_block_context, |
1087 | record->type, | 1022 | record->type, |
1088 | NULL, | 1023 | NULL, |
1089 | key, | 1024 | &frc->bd->key, |
1090 | record->xquery, | 1025 | record->xquery, |
1091 | record->xquery_size, | 1026 | record->xquery_size, |
1092 | frc->data, | 1027 | frc->bd->data, |
1093 | frc->data_size); | 1028 | frc->bd->data_size); |
1094 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1029 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1095 | "Evaluation result is %d for key %s for local client's query\n", | 1030 | "Evaluation result is %d for key %s for local client's query\n", |
1096 | (int) eval, | 1031 | (int) eval, |
1097 | GNUNET_h2s (key)); | 1032 | GNUNET_h2s (&frc->bd->key)); |
1098 | switch (eval) | 1033 | switch (eval) |
1099 | { | 1034 | { |
1100 | case GNUNET_BLOCK_REPLY_OK_LAST: | 1035 | case GNUNET_BLOCK_REPLY_OK_LAST: |
@@ -1125,29 +1060,29 @@ forward_reply (void *cls, | |||
1125 | 1, | 1060 | 1, |
1126 | GNUNET_NO); | 1061 | GNUNET_NO); |
1127 | env = GNUNET_MQ_msg_extra (reply, | 1062 | env = GNUNET_MQ_msg_extra (reply, |
1128 | frc->data_size | 1063 | frc->bd->data_size |
1129 | + (frc->get_path_length + frc->put_path_length) | 1064 | + (frc->get_path_length + frc->bd->put_path_length) |
1130 | * sizeof(struct GNUNET_PeerIdentity), | 1065 | * sizeof(struct GNUNET_PeerIdentity), |
1131 | GNUNET_MESSAGE_TYPE_DHT_CLIENT_RESULT); | 1066 | GNUNET_MESSAGE_TYPE_DHT_CLIENT_RESULT); |
1132 | reply->type = htonl (frc->type); | 1067 | reply->type = htonl (frc->bd->type); |
1133 | reply->get_path_length = htonl (frc->get_path_length); | 1068 | reply->get_path_length = htonl (frc->get_path_length); |
1134 | reply->put_path_length = htonl (frc->put_path_length); | 1069 | reply->put_path_length = htonl (frc->bd->put_path_length); |
1135 | reply->unique_id = record->unique_id; | 1070 | reply->unique_id = record->unique_id; |
1136 | reply->expiration = GNUNET_TIME_absolute_hton (frc->expiration); | 1071 | reply->expiration = GNUNET_TIME_absolute_hton (frc->bd->expiration_time); |
1137 | reply->key = *key; | 1072 | reply->key = frc->bd->key; |
1138 | paths = (struct GNUNET_PeerIdentity *) &reply[1]; | 1073 | paths = (struct GNUNET_PeerIdentity *) &reply[1]; |
1139 | GNUNET_memcpy (paths, | 1074 | GNUNET_memcpy (paths, |
1140 | frc->put_path, | 1075 | frc->bd->put_path, |
1141 | sizeof(struct GNUNET_PeerIdentity) * frc->put_path_length); | 1076 | sizeof(struct GNUNET_PeerIdentity) * frc->bd->put_path_length); |
1142 | GNUNET_memcpy (&paths[frc->put_path_length], | 1077 | GNUNET_memcpy (&paths[frc->bd->put_path_length], |
1143 | frc->get_path, | 1078 | frc->get_path, |
1144 | sizeof(struct GNUNET_PeerIdentity) * frc->get_path_length); | 1079 | sizeof(struct GNUNET_PeerIdentity) * frc->get_path_length); |
1145 | GNUNET_memcpy (&paths[frc->get_path_length + frc->put_path_length], | 1080 | GNUNET_memcpy (&paths[frc->get_path_length + frc->bd->put_path_length], |
1146 | frc->data, | 1081 | frc->bd->data, |
1147 | frc->data_size); | 1082 | frc->bd->data_size); |
1148 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1083 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1149 | "Sending reply to query %s for client %p\n", | 1084 | "Sending reply to query %s for client %p\n", |
1150 | GNUNET_h2s (key), | 1085 | GNUNET_h2s (query_hash), |
1151 | record->ch->client); | 1086 | record->ch->client); |
1152 | GNUNET_MQ_send (record->ch->mq, | 1087 | GNUNET_MQ_send (record->ch->mq, |
1153 | env); | 1088 | env); |
@@ -1157,66 +1092,38 @@ forward_reply (void *cls, | |||
1157 | } | 1092 | } |
1158 | 1093 | ||
1159 | 1094 | ||
1160 | /** | ||
1161 | * Handle a reply we've received from another peer. If the reply | ||
1162 | * matches any of our pending queries, forward it to the respective | ||
1163 | * client(s). | ||
1164 | * | ||
1165 | * @param expiration when will the reply expire | ||
1166 | * @param key the key of the query that triggered the reply | ||
1167 | * @param query_hash the query hash of the response | ||
1168 | * @param get_path_length number of peers in @a get_path | ||
1169 | * @param get_path path the reply took on get | ||
1170 | * @param put_path_length number of peers in @a put_path | ||
1171 | * @param put_path path the reply took on put | ||
1172 | * @param type type of the reply | ||
1173 | * @param data_size number of bytes in @a data | ||
1174 | * @param data application payload data | ||
1175 | */ | ||
1176 | void | 1095 | void |
1177 | GDS_CLIENTS_handle_reply (struct GNUNET_TIME_Absolute expiration, | 1096 | GDS_CLIENTS_handle_reply (const struct GDS_DATACACHE_BlockData *bd, |
1178 | const struct GNUNET_HashCode *key, | ||
1179 | const struct GNUNET_HashCode *query_hash, | 1097 | const struct GNUNET_HashCode *query_hash, |
1180 | unsigned int get_path_length, | 1098 | unsigned int get_path_length, |
1181 | const struct GNUNET_PeerIdentity *get_path, | 1099 | const struct GNUNET_PeerIdentity *get_path) |
1182 | unsigned int put_path_length, | ||
1183 | const struct GNUNET_PeerIdentity *put_path, | ||
1184 | enum GNUNET_BLOCK_Type type, | ||
1185 | size_t data_size, | ||
1186 | const void *data) | ||
1187 | { | 1100 | { |
1188 | struct ForwardReplyContext frc; | 1101 | struct ForwardReplyContext frc; |
1189 | size_t msize; | 1102 | size_t msize = sizeof (struct GNUNET_DHT_ClientResultMessage) |
1103 | + bd->data_size | ||
1104 | + (get_path_length + bd->put_path_length) | ||
1105 | * sizeof(struct GNUNET_PeerIdentity); | ||
1190 | 1106 | ||
1191 | msize = sizeof(struct GNUNET_DHT_ClientResultMessage) + data_size | ||
1192 | + (get_path_length + put_path_length) | ||
1193 | * sizeof(struct GNUNET_PeerIdentity); | ||
1194 | if (msize >= GNUNET_MAX_MESSAGE_SIZE) | 1107 | if (msize >= GNUNET_MAX_MESSAGE_SIZE) |
1195 | { | 1108 | { |
1196 | GNUNET_break (0); | 1109 | GNUNET_break (0); |
1197 | return; | 1110 | return; |
1198 | } | 1111 | } |
1199 | frc.expiration = expiration; | 1112 | frc.bd = bd; |
1200 | frc.query_hash = query_hash; | ||
1201 | frc.get_path = get_path; | 1113 | frc.get_path = get_path; |
1202 | frc.put_path = put_path; | ||
1203 | frc.data = data; | ||
1204 | frc.data_size = data_size; | ||
1205 | frc.get_path_length = get_path_length; | 1114 | frc.get_path_length = get_path_length; |
1206 | frc.put_path_length = put_path_length; | ||
1207 | frc.type = type; | ||
1208 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1115 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1209 | "Forwarding reply for key %s to client\n", | 1116 | "Forwarding reply for query hash %s to client\n", |
1210 | GNUNET_h2s (key)); | 1117 | GNUNET_h2s (query_hash)); |
1211 | if (0 == | 1118 | if (0 == |
1212 | GNUNET_CONTAINER_multihashmap_get_multiple (forward_map, | 1119 | GNUNET_CONTAINER_multihashmap_get_multiple (forward_map, |
1213 | key, | 1120 | query_hash, |
1214 | &forward_reply, | 1121 | &forward_reply, |
1215 | &frc)) | 1122 | &frc)) |
1216 | { | 1123 | { |
1217 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1124 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1218 | "No matching client for reply for key %s\n", | 1125 | "No matching client for reply for query %s\n", |
1219 | GNUNET_h2s (key)); | 1126 | GNUNET_h2s (query_hash)); |
1220 | GNUNET_STATISTICS_update (GDS_stats, | 1127 | GNUNET_STATISTICS_update (GDS_stats, |
1221 | "# REPLIES ignored for CLIENTS (no match)", | 1128 | "# REPLIES ignored for CLIENTS (no match)", |
1222 | 1, | 1129 | 1, |
@@ -1298,15 +1205,9 @@ GDS_CLIENTS_process_get (uint32_t options, | |||
1298 | 1205 | ||
1299 | 1206 | ||
1300 | void | 1207 | void |
1301 | GDS_CLIENTS_process_get_resp (enum GNUNET_BLOCK_Type type, | 1208 | GDS_CLIENTS_process_get_resp (const struct GDS_DATACACHE_BlockData *bd, |
1302 | const struct GNUNET_PeerIdentity *get_path, | 1209 | const struct GNUNET_PeerIdentity *get_path, |
1303 | unsigned int get_path_length, | 1210 | unsigned int get_path_length) |
1304 | const struct GNUNET_PeerIdentity *put_path, | ||
1305 | unsigned int put_path_length, | ||
1306 | struct GNUNET_TIME_Absolute exp, | ||
1307 | const struct GNUNET_HashCode *key, | ||
1308 | const void *data, | ||
1309 | size_t size) | ||
1310 | { | 1211 | { |
1311 | struct ClientHandle **cl = NULL; | 1212 | struct ClientHandle **cl = NULL; |
1312 | unsigned int cl_size = 0; | 1213 | unsigned int cl_size = 0; |
@@ -1316,9 +1217,9 @@ GDS_CLIENTS_process_get_resp (enum GNUNET_BLOCK_Type type, | |||
1316 | m = m->next) | 1217 | m = m->next) |
1317 | { | 1218 | { |
1318 | if ( ( (GNUNET_BLOCK_TYPE_ANY == m->type) || | 1219 | if ( ( (GNUNET_BLOCK_TYPE_ANY == m->type) || |
1319 | (m->type == type) ) && | 1220 | (m->type == bd->type) ) && |
1320 | ( (GNUNET_is_zero (&m->key)) || | 1221 | ( (GNUNET_is_zero (&m->key)) || |
1321 | (0 == GNUNET_memcmp (key, | 1222 | (0 == GNUNET_memcmp (&bd->key, |
1322 | &m->key)) ) ) | 1223 | &m->key)) ) ) |
1323 | { | 1224 | { |
1324 | struct GNUNET_MQ_Envelope *env; | 1225 | struct GNUNET_MQ_Envelope *env; |
@@ -1336,27 +1237,27 @@ GDS_CLIENTS_process_get_resp (enum GNUNET_BLOCK_Type type, | |||
1336 | GNUNET_array_append (cl, | 1237 | GNUNET_array_append (cl, |
1337 | cl_size, | 1238 | cl_size, |
1338 | m->ch); | 1239 | m->ch); |
1339 | msize = size; | 1240 | msize = bd->data_size; |
1340 | msize += (get_path_length + put_path_length) | 1241 | msize += (get_path_length + bd->put_path_length) |
1341 | * sizeof(struct GNUNET_PeerIdentity); | 1242 | * sizeof(struct GNUNET_PeerIdentity); |
1342 | env = GNUNET_MQ_msg_extra (mmsg, | 1243 | env = GNUNET_MQ_msg_extra (mmsg, |
1343 | msize, | 1244 | msize, |
1344 | GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET_RESP); | 1245 | GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET_RESP); |
1345 | mmsg->type = htonl (type); | 1246 | mmsg->type = htonl (bd->type); |
1346 | mmsg->put_path_length = htonl (put_path_length); | 1247 | mmsg->put_path_length = htonl (bd->put_path_length); |
1347 | mmsg->get_path_length = htonl (get_path_length); | 1248 | mmsg->get_path_length = htonl (get_path_length); |
1348 | mmsg->expiration_time = GNUNET_TIME_absolute_hton (exp); | 1249 | mmsg->expiration_time = GNUNET_TIME_absolute_hton (bd->expiration_time); |
1349 | mmsg->key = *key; | 1250 | mmsg->key = bd->key; |
1350 | path = (struct GNUNET_PeerIdentity *) &mmsg[1]; | 1251 | path = (struct GNUNET_PeerIdentity *) &mmsg[1]; |
1351 | GNUNET_memcpy (path, | 1252 | GNUNET_memcpy (path, |
1352 | put_path, | 1253 | bd->put_path, |
1353 | put_path_length * sizeof(struct GNUNET_PeerIdentity)); | 1254 | bd->put_path_length * sizeof(struct GNUNET_PeerIdentity)); |
1354 | GNUNET_memcpy (path, | 1255 | GNUNET_memcpy (path, |
1355 | get_path, | 1256 | get_path, |
1356 | get_path_length * sizeof(struct GNUNET_PeerIdentity)); | 1257 | get_path_length * sizeof(struct GNUNET_PeerIdentity)); |
1357 | GNUNET_memcpy (&path[get_path_length], | 1258 | GNUNET_memcpy (&path[get_path_length], |
1358 | data, | 1259 | bd->data, |
1359 | size); | 1260 | bd->data_size); |
1360 | GNUNET_MQ_send (m->ch->mq, | 1261 | GNUNET_MQ_send (m->ch->mq, |
1361 | env); | 1262 | env); |
1362 | } | 1263 | } |
@@ -1365,32 +1266,11 @@ GDS_CLIENTS_process_get_resp (enum GNUNET_BLOCK_Type type, | |||
1365 | } | 1266 | } |
1366 | 1267 | ||
1367 | 1268 | ||
1368 | /** | ||
1369 | * Check if some client is monitoring PUT messages and notify | ||
1370 | * them in that case. The @a path should include our own peer ID. | ||
1371 | * | ||
1372 | * @param options Options, for instance RecordRoute, DemultiplexEverywhere. | ||
1373 | * @param type The type of data in the request. | ||
1374 | * @param hop_count Hop count so far. | ||
1375 | * @param path_length number of entries in path (or 0 if not recorded). | ||
1376 | * @param path peers on the PUT path (or NULL if not recorded). | ||
1377 | * @param desired_replication_level Desired replication level. | ||
1378 | * @param exp Expiration time of the data. | ||
1379 | * @param key Key under which data is to be stored. | ||
1380 | * @param data Pointer to the data carried. | ||
1381 | * @param size Number of bytes in data. | ||
1382 | */ | ||
1383 | void | 1269 | void |
1384 | GDS_CLIENTS_process_put (uint32_t options, | 1270 | GDS_CLIENTS_process_put (enum GNUNET_DHT_RouteOption options, |
1385 | enum GNUNET_BLOCK_Type type, | 1271 | const struct GDS_DATACACHE_BlockData *bd, |
1386 | uint32_t hop_count, | 1272 | uint32_t hop_count, |
1387 | uint32_t desired_replication_level, | 1273 | uint32_t desired_replication_level) |
1388 | unsigned int path_length, | ||
1389 | const struct GNUNET_PeerIdentity *path, | ||
1390 | struct GNUNET_TIME_Absolute exp, | ||
1391 | const struct GNUNET_HashCode *key, | ||
1392 | const void *data, | ||
1393 | size_t size) | ||
1394 | { | 1274 | { |
1395 | struct ClientHandle **cl = NULL; | 1275 | struct ClientHandle **cl = NULL; |
1396 | unsigned int cl_size = 0; | 1276 | unsigned int cl_size = 0; |
@@ -1400,10 +1280,10 @@ GDS_CLIENTS_process_put (uint32_t options, | |||
1400 | m = m->next) | 1280 | m = m->next) |
1401 | { | 1281 | { |
1402 | if ( ( (GNUNET_BLOCK_TYPE_ANY == m->type) || | 1282 | if ( ( (GNUNET_BLOCK_TYPE_ANY == m->type) || |
1403 | (m->type == type) ) && | 1283 | (m->type == bd->type) ) && |
1404 | ( (GNUNET_is_zero (&m->key)) || | 1284 | ( (GNUNET_is_zero (&m->key)) || |
1405 | (0 == | 1285 | (0 == |
1406 | GNUNET_memcmp (key, | 1286 | GNUNET_memcmp (&bd->key, |
1407 | &m->key)) ) ) | 1287 | &m->key)) ) ) |
1408 | { | 1288 | { |
1409 | struct GNUNET_MQ_Envelope *env; | 1289 | struct GNUNET_MQ_Envelope *env; |
@@ -1421,25 +1301,25 @@ GDS_CLIENTS_process_put (uint32_t options, | |||
1421 | GNUNET_array_append (cl, | 1301 | GNUNET_array_append (cl, |
1422 | cl_size, | 1302 | cl_size, |
1423 | m->ch); | 1303 | m->ch); |
1424 | msize = size; | 1304 | msize = bd->data_size; |
1425 | msize += path_length * sizeof(struct GNUNET_PeerIdentity); | 1305 | msize += bd->put_path_length * sizeof(struct GNUNET_PeerIdentity); |
1426 | env = GNUNET_MQ_msg_extra (mmsg, | 1306 | env = GNUNET_MQ_msg_extra (mmsg, |
1427 | msize, | 1307 | msize, |
1428 | GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT); | 1308 | GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT); |
1429 | mmsg->options = htonl (options); | 1309 | mmsg->options = htonl (options); |
1430 | mmsg->type = htonl (type); | 1310 | mmsg->type = htonl (bd->type); |
1431 | mmsg->hop_count = htonl (hop_count); | 1311 | mmsg->hop_count = htonl (hop_count); |
1432 | mmsg->desired_replication_level = htonl (desired_replication_level); | 1312 | mmsg->desired_replication_level = htonl (desired_replication_level); |
1433 | mmsg->put_path_length = htonl (path_length); | 1313 | mmsg->put_path_length = htonl (bd->put_path_length); |
1434 | mmsg->key = *key; | 1314 | mmsg->key = bd->key; |
1435 | mmsg->expiration_time = GNUNET_TIME_absolute_hton (exp); | 1315 | mmsg->expiration_time = GNUNET_TIME_absolute_hton (bd->expiration_time); |
1436 | msg_path = (struct GNUNET_PeerIdentity *) &mmsg[1]; | 1316 | msg_path = (struct GNUNET_PeerIdentity *) &mmsg[1]; |
1437 | GNUNET_memcpy (msg_path, | 1317 | GNUNET_memcpy (msg_path, |
1438 | path, | 1318 | bd->put_path, |
1439 | path_length * sizeof(struct GNUNET_PeerIdentity)); | 1319 | bd->put_path_length * sizeof(struct GNUNET_PeerIdentity)); |
1440 | GNUNET_memcpy (&msg_path[path_length], | 1320 | GNUNET_memcpy (&msg_path[bd->put_path_length], |
1441 | data, | 1321 | bd->data, |
1442 | size); | 1322 | bd->data_size); |
1443 | GNUNET_MQ_send (m->ch->mq, | 1323 | GNUNET_MQ_send (m->ch->mq, |
1444 | env); | 1324 | env); |
1445 | } | 1325 | } |
diff --git a/src/dht/gnunet-service-dht_datacache.c b/src/dht/gnunet-service-dht_datacache.c index d80889635..a60f49a51 100644 --- a/src/dht/gnunet-service-dht_datacache.c +++ b/src/dht/gnunet-service-dht_datacache.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2009, 2010, 2011, 2015, 2017 GNUnet e.V. | 3 | Copyright (C) 2009, 2010, 2011, 2015, 2017, 2022 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software: you can redistribute it and/or modify it | 5 | GNUnet is free software: you can redistribute it and/or modify it |
6 | under the terms of the GNU Affero General Public License as published | 6 | under the terms of the GNU Affero General Public License as published |
@@ -38,35 +38,18 @@ | |||
38 | */ | 38 | */ |
39 | #define NUM_CLOSEST 42 | 39 | #define NUM_CLOSEST 42 |
40 | 40 | ||
41 | |||
41 | /** | 42 | /** |
42 | * Handle to the datacache service (for inserting/retrieving data) | 43 | * Handle to the datacache service (for inserting/retrieving data) |
43 | */ | 44 | */ |
44 | static struct GNUNET_DATACACHE_Handle *datacache; | 45 | static struct GNUNET_DATACACHE_Handle *datacache; |
45 | 46 | ||
46 | 47 | ||
47 | /** | ||
48 | * Handle a datum we've received from another peer. Cache if | ||
49 | * possible. | ||
50 | * | ||
51 | * @param expiration when will the reply expire | ||
52 | * @param key the query this reply is for | ||
53 | * @param put_path_length number of peers in @a put_path | ||
54 | * @param put_path path the reply took on put | ||
55 | * @param type type of the reply | ||
56 | * @param data_size number of bytes in @a data | ||
57 | * @param data application payload data | ||
58 | */ | ||
59 | void | 48 | void |
60 | GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration, | 49 | GDS_DATACACHE_handle_put (const struct GDS_DATACACHE_BlockData *bd) |
61 | const struct GNUNET_HashCode *key, | ||
62 | unsigned int put_path_length, | ||
63 | const struct GNUNET_PeerIdentity *put_path, | ||
64 | enum GNUNET_BLOCK_Type type, | ||
65 | size_t data_size, | ||
66 | const void *data) | ||
67 | { | 50 | { |
68 | struct GNUNET_HashCode xor; | 51 | struct GNUNET_HashCode xor; |
69 | int r; | 52 | enum GNUNET_GenericReturnValue r; |
70 | 53 | ||
71 | if (NULL == datacache) | 54 | if (NULL == datacache) |
72 | { | 55 | { |
@@ -74,7 +57,7 @@ GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration, | |||
74 | "PUT request received, but have no datacache!\n"); | 57 | "PUT request received, but have no datacache!\n"); |
75 | return; | 58 | return; |
76 | } | 59 | } |
77 | if (data_size >= GNUNET_MAX_MESSAGE_SIZE) | 60 | if (bd->data_size >= GNUNET_MAX_MESSAGE_SIZE) |
78 | { | 61 | { |
79 | GNUNET_break (0); | 62 | GNUNET_break (0); |
80 | return; | 63 | return; |
@@ -84,24 +67,24 @@ GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration, | |||
84 | "# ITEMS stored in datacache", | 67 | "# ITEMS stored in datacache", |
85 | 1, | 68 | 1, |
86 | GNUNET_NO); | 69 | GNUNET_NO); |
87 | GNUNET_CRYPTO_hash_xor (key, | 70 | GNUNET_CRYPTO_hash_xor (&bd->key, |
88 | &my_identity_hash, | 71 | &my_identity_hash, |
89 | &xor); | 72 | &xor); |
90 | r = GNUNET_DATACACHE_put (datacache, | 73 | r = GNUNET_DATACACHE_put (datacache, |
91 | key, | 74 | &bd->key, |
92 | GNUNET_CRYPTO_hash_count_leading_zeros (&xor), | 75 | GNUNET_CRYPTO_hash_count_leading_zeros (&xor), |
93 | data_size, | 76 | bd->data_size, |
94 | data, | 77 | bd->data, |
95 | type, | 78 | bd->type, |
96 | expiration, | 79 | bd->expiration_time, |
97 | put_path_length, | 80 | bd->put_path_length, |
98 | put_path); | 81 | bd->put_path); |
99 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 82 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
100 | "DATACACHE PUT for key %s [%lu] completed (%d) after %u hops\n", | 83 | "DATACACHE PUT for key %s [%lu] completed (%d) after %u hops\n", |
101 | GNUNET_h2s (key), | 84 | GNUNET_h2s (&bd->key), |
102 | (unsigned long) data_size, | 85 | (unsigned long) bd->data_size, |
103 | r, | 86 | r, |
104 | put_path_length); | 87 | bd->put_path_length); |
105 | } | 88 | } |
106 | 89 | ||
107 | 90 | ||
@@ -171,30 +154,34 @@ datacache_get_iterator (void *cls, | |||
171 | unsigned int put_path_length, | 154 | unsigned int put_path_length, |
172 | const struct GNUNET_PeerIdentity *put_path) | 155 | const struct GNUNET_PeerIdentity *put_path) |
173 | { | 156 | { |
174 | static char non_null; | ||
175 | struct GetRequestContext *ctx = cls; | 157 | struct GetRequestContext *ctx = cls; |
176 | enum GNUNET_BLOCK_ReplyEvaluationResult eval; | 158 | enum GNUNET_BLOCK_ReplyEvaluationResult eval; |
177 | 159 | struct GDS_DATACACHE_BlockData bd = { | |
178 | if (0 == GNUNET_TIME_absolute_get_remaining (exp).rel_value_us) | 160 | .key = *key, |
161 | .expiration_time = exp, | ||
162 | .put_path = put_path, | ||
163 | .data = data, | ||
164 | .data_size = data_size, | ||
165 | .put_path_length = put_path_length, | ||
166 | .type = type | ||
167 | }; | ||
168 | |||
169 | if (GNUNET_TIME_absolute_is_past (exp)) | ||
179 | { | 170 | { |
180 | GNUNET_break (0); /* why does datacache return expired values? */ | 171 | GNUNET_break (0); /* why does datacache return expired values? */ |
181 | return GNUNET_OK; /* skip expired record */ | 172 | return GNUNET_OK; /* skip expired record */ |
182 | } | 173 | } |
183 | if ((NULL == data) && | ||
184 | (0 == data_size)) | ||
185 | data = &non_null; /* point anywhere, but not to NULL */ | ||
186 | |||
187 | eval | 174 | eval |
188 | = GNUNET_BLOCK_check_reply (GDS_block_context, | 175 | = GNUNET_BLOCK_check_reply (GDS_block_context, |
189 | type, | 176 | bd.type, |
190 | ctx->bg, | 177 | ctx->bg, |
191 | key, | 178 | &bd.key, |
192 | ctx->xquery, | 179 | ctx->xquery, |
193 | ctx->xquery_size, | 180 | ctx->xquery_size, |
194 | data, | 181 | bd.data, |
195 | data_size); | 182 | bd.data_size); |
196 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 183 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
197 | "Found reply for query %s in datacache, evaluation result is %d\n", | 184 | "Evaluated reply for query %s in datacache, result is %d\n", |
198 | GNUNET_h2s (key), | 185 | GNUNET_h2s (key), |
199 | (int) eval); | 186 | (int) eval); |
200 | ctx->eval = eval; | 187 | ctx->eval = eval; |
@@ -209,12 +196,7 @@ datacache_get_iterator (void *cls, | |||
209 | 1, | 196 | 1, |
210 | GNUNET_NO); | 197 | GNUNET_NO); |
211 | ctx->gc (ctx->gc_cls, | 198 | ctx->gc (ctx->gc_cls, |
212 | type, | 199 | &bd); |
213 | exp, | ||
214 | key, | ||
215 | put_path_length, put_path, | ||
216 | 0, NULL, | ||
217 | data, data_size); | ||
218 | break; | 200 | break; |
219 | case GNUNET_BLOCK_REPLY_OK_DUPLICATE: | 201 | case GNUNET_BLOCK_REPLY_OK_DUPLICATE: |
220 | GNUNET_STATISTICS_update (GDS_stats, | 202 | GNUNET_STATISTICS_update (GDS_stats, |
@@ -240,18 +222,6 @@ datacache_get_iterator (void *cls, | |||
240 | } | 222 | } |
241 | 223 | ||
242 | 224 | ||
243 | /** | ||
244 | * Handle a GET request we've received from another peer. | ||
245 | * | ||
246 | * @param key the query | ||
247 | * @param type requested data type | ||
248 | * @param xquery extended query | ||
249 | * @param xquery_size number of bytes in @a xquery | ||
250 | * @param bg block group to use for reply evaluation | ||
251 | * @param gc function to call on the results | ||
252 | * @param gc_cls closure for @a gc | ||
253 | * @return evaluation result for the local replies | ||
254 | */ | ||
255 | enum GNUNET_BLOCK_EvaluationResult | 225 | enum GNUNET_BLOCK_EvaluationResult |
256 | GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *key, | 226 | GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *key, |
257 | enum GNUNET_BLOCK_Type type, | 227 | enum GNUNET_BLOCK_Type type, |
@@ -292,62 +262,6 @@ GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *key, | |||
292 | 262 | ||
293 | 263 | ||
294 | /** | 264 | /** |
295 | * Function called with a random element from the datacache. | ||
296 | * Stores the key in the closure. | ||
297 | * | ||
298 | * @param cls a `struct GNUNET_HashCode *`, where to store the @a key | ||
299 | * @param key key for the content | ||
300 | * @param data_size number of bytes in @a data | ||
301 | * @param data content stored | ||
302 | * @param type type of the content | ||
303 | * @param exp when will the content expire? | ||
304 | * @param path_info_len number of entries in @a path_info | ||
305 | * @param path_info a path through the network | ||
306 | * @return #GNUNET_OK to continue iterating, #GNUNET_SYSERR to abort | ||
307 | */ | ||
308 | static int | ||
309 | datacache_random_iterator (void *cls, | ||
310 | const struct GNUNET_HashCode *key, | ||
311 | size_t data_size, | ||
312 | const char *data, | ||
313 | enum GNUNET_BLOCK_Type type, | ||
314 | struct GNUNET_TIME_Absolute exp, | ||
315 | unsigned int path_info_len, | ||
316 | const struct GNUNET_PeerIdentity *path_info) | ||
317 | { | ||
318 | struct GNUNET_HashCode *dest = cls; | ||
319 | |||
320 | *dest = *key; | ||
321 | return GNUNET_OK; /* should actually not matter which we return */ | ||
322 | } | ||
323 | |||
324 | |||
325 | /** | ||
326 | * Obtain a random key from the datacache. | ||
327 | * Used by Whanau for load-balancing. | ||
328 | * | ||
329 | * @param[out] key where to store the key of a random element, | ||
330 | * randomized by PRNG if datacache is empty | ||
331 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if the datacache is empty | ||
332 | */ | ||
333 | int | ||
334 | GDS_DATACACHE_get_random_key (struct GNUNET_HashCode *key) | ||
335 | { | ||
336 | if (0 == | ||
337 | GNUNET_DATACACHE_get_random (datacache, | ||
338 | &datacache_random_iterator, | ||
339 | key)) | ||
340 | { | ||
341 | /* randomize key in this case */ | ||
342 | GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_NONCE, | ||
343 | key); | ||
344 | return GNUNET_SYSERR; | ||
345 | } | ||
346 | return GNUNET_OK; | ||
347 | } | ||
348 | |||
349 | |||
350 | /** | ||
351 | * Closure for #datacache_get_successors_iterator(). | 265 | * Closure for #datacache_get_successors_iterator(). |
352 | */ | 266 | */ |
353 | struct SuccContext | 267 | struct SuccContext |
@@ -355,12 +269,13 @@ struct SuccContext | |||
355 | /** | 269 | /** |
356 | * Function to call on the result | 270 | * Function to call on the result |
357 | */ | 271 | */ |
358 | GDS_DATACACHE_SuccessorCallback cb; | 272 | GDS_DATACACHE_GetCallback cb; |
359 | 273 | ||
360 | /** | 274 | /** |
361 | * Closure for @e cb. | 275 | * Closure for @e cb. |
362 | */ | 276 | */ |
363 | void *cb_cls; | 277 | void *cb_cls; |
278 | |||
364 | }; | 279 | }; |
365 | 280 | ||
366 | 281 | ||
@@ -378,7 +293,7 @@ struct SuccContext | |||
378 | * @return #GNUNET_OK to continue iteration, anything else | 293 | * @return #GNUNET_OK to continue iteration, anything else |
379 | * to stop iteration. | 294 | * to stop iteration. |
380 | */ | 295 | */ |
381 | static int | 296 | static enum GNUNET_GenericReturnValue |
382 | datacache_get_successors_iterator (void *cls, | 297 | datacache_get_successors_iterator (void *cls, |
383 | const struct GNUNET_HashCode *key, | 298 | const struct GNUNET_HashCode *key, |
384 | size_t size, | 299 | size_t size, |
@@ -389,40 +304,36 @@ datacache_get_successors_iterator (void *cls, | |||
389 | const struct GNUNET_PeerIdentity *put_path) | 304 | const struct GNUNET_PeerIdentity *put_path) |
390 | { | 305 | { |
391 | const struct SuccContext *sc = cls; | 306 | const struct SuccContext *sc = cls; |
307 | struct GDS_DATACACHE_BlockData bd = { | ||
308 | .key = *key, | ||
309 | .expiration_time = exp, | ||
310 | .put_path = put_path, | ||
311 | .data = data, | ||
312 | .data_size = size, | ||
313 | .put_path_length = put_path_length, | ||
314 | .type = type | ||
315 | }; | ||
392 | 316 | ||
393 | /* NOTE: The datacache currently does not store the RO from | 317 | /* NOTE: The datacache currently does not store the RO from |
394 | the original 'put', so we don't know the 'correct' option | 318 | the original 'put', so we don't know the 'correct' option |
395 | at this point anymore. Thus, we conservatively assume | 319 | at this point anymore. Thus, we conservatively assume |
396 | that recording is desired (for now). */ | 320 | that recording is desired (for now). */ |
397 | sc->cb (sc->cb_cls, | 321 | sc->cb (sc->cb_cls, |
398 | GNUNET_DHT_RO_RECORD_ROUTE, | 322 | &bd); |
399 | key, | ||
400 | type, | ||
401 | put_path_length, put_path, | ||
402 | exp, | ||
403 | data, | ||
404 | size); | ||
405 | return GNUNET_OK; | 323 | return GNUNET_OK; |
406 | } | 324 | } |
407 | 325 | ||
408 | 326 | ||
409 | /** | ||
410 | * Handle a request for data close to a key that we have received from | ||
411 | * another peer. | ||
412 | * | ||
413 | * @param key the location at which the peer is looking for data that is close | ||
414 | * @param cb function to call with the result | ||
415 | * @param cb_cls closure for @a cb | ||
416 | */ | ||
417 | void | 327 | void |
418 | GDS_DATACACHE_get_successors (const struct GNUNET_HashCode *key, | 328 | GDS_DATACACHE_get_successors (const struct GNUNET_HashCode *key, |
419 | GDS_DATACACHE_SuccessorCallback cb, | 329 | GDS_DATACACHE_GetCallback cb, |
420 | void *cb_cls) | 330 | void *cb_cls) |
421 | { | 331 | { |
422 | struct SuccContext sc; | 332 | struct SuccContext sc = { |
333 | .cb = cb, | ||
334 | .cb_cls = cb_cls | ||
335 | }; | ||
423 | 336 | ||
424 | sc.cb = cb; | ||
425 | sc.cb_cls = cb_cls; | ||
426 | (void) GNUNET_DATACACHE_get_closest (datacache, | 337 | (void) GNUNET_DATACACHE_get_closest (datacache, |
427 | key, | 338 | key, |
428 | NUM_CLOSEST, | 339 | NUM_CLOSEST, |
@@ -431,19 +342,14 @@ GDS_DATACACHE_get_successors (const struct GNUNET_HashCode *key, | |||
431 | } | 342 | } |
432 | 343 | ||
433 | 344 | ||
434 | /** | ||
435 | * Initialize datacache subsystem. | ||
436 | */ | ||
437 | void | 345 | void |
438 | GDS_DATACACHE_init () | 346 | GDS_DATACACHE_init () |
439 | { | 347 | { |
440 | datacache = GNUNET_DATACACHE_create (GDS_cfg, "dhtcache"); | 348 | datacache = GNUNET_DATACACHE_create (GDS_cfg, |
349 | "dhtcache"); | ||
441 | } | 350 | } |
442 | 351 | ||
443 | 352 | ||
444 | /** | ||
445 | * Shutdown datacache subsystem. | ||
446 | */ | ||
447 | void | 353 | void |
448 | GDS_DATACACHE_done () | 354 | GDS_DATACACHE_done () |
449 | { | 355 | { |
diff --git a/src/dht/gnunet-service-dht_datacache.h b/src/dht/gnunet-service-dht_datacache.h index 5be59c90e..249bb8ee3 100644 --- a/src/dht/gnunet-service-dht_datacache.h +++ b/src/dht/gnunet-service-dht_datacache.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2009, 2010, 2011 GNUnet e.V. | 3 | Copyright (C) 2009, 2010, 2011, 2022 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software: you can redistribute it and/or modify it | 5 | GNUnet is free software: you can redistribute it and/or modify it |
6 | under the terms of the GNU Affero General Public License as published | 6 | under the terms of the GNU Affero General Public License as published |
@@ -31,53 +31,68 @@ | |||
31 | #include "gnunet_block_lib.h" | 31 | #include "gnunet_block_lib.h" |
32 | #include "gnunet_dht_service.h" | 32 | #include "gnunet_dht_service.h" |
33 | 33 | ||
34 | |||
35 | /** | ||
36 | * Information about a block stored in the datacache. | ||
37 | */ | ||
38 | struct GDS_DATACACHE_BlockData | ||
39 | { | ||
40 | /** | ||
41 | * Key of the block. | ||
42 | */ | ||
43 | struct GNUNET_HashCode key; | ||
44 | |||
45 | /** | ||
46 | * When does the block expire? | ||
47 | */ | ||
48 | struct GNUNET_TIME_Absolute expiration_time; | ||
49 | |||
50 | /** | ||
51 | * PUT path taken by the block, array of peer identities. | ||
52 | */ | ||
53 | const struct GNUNET_PeerIdentity *put_path; | ||
54 | |||
55 | /** | ||
56 | * Actual block data. | ||
57 | */ | ||
58 | const void *data; | ||
59 | |||
60 | /** | ||
61 | * Number of bytes in @a data. | ||
62 | */ | ||
63 | size_t data_size; | ||
64 | |||
65 | /** | ||
66 | * Length of the @e put_path array. | ||
67 | */ | ||
68 | unsigned int put_path_length; | ||
69 | |||
70 | /** | ||
71 | * Type of the block. | ||
72 | */ | ||
73 | enum GNUNET_BLOCK_Type type; | ||
74 | }; | ||
75 | |||
76 | |||
34 | /** | 77 | /** |
35 | * Handle a datum we've received from another peer. Cache if | 78 | * Handle a datum we've received from another peer. Cache if |
36 | * possible. | 79 | * possible. |
37 | * | 80 | * |
38 | * @param expiration when will the reply expire | 81 | * @param bd block data to cache |
39 | * @param key the query this reply is for | ||
40 | * @param put_path_length number of peers in 'put_path' | ||
41 | * @param put_path path the reply took on put | ||
42 | * @param type type of the reply | ||
43 | * @param data_size number of bytes in 'data' | ||
44 | * @param data application payload data | ||
45 | */ | 82 | */ |
46 | void | 83 | void |
47 | GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration, | 84 | GDS_DATACACHE_handle_put (const struct GDS_DATACACHE_BlockData *bd); |
48 | const struct GNUNET_HashCode *key, | ||
49 | unsigned int put_path_length, | ||
50 | const struct GNUNET_PeerIdentity *put_path, | ||
51 | enum GNUNET_BLOCK_Type type, | ||
52 | size_t data_size, | ||
53 | const void *data); | ||
54 | 85 | ||
55 | 86 | ||
56 | /** | 87 | /** |
57 | * Handle a result for a GET operation. | 88 | * Handle a result for a GET operation. |
58 | * | 89 | * |
59 | * @param cls closure | 90 | * @param cls closure |
60 | * @param type type of the block | 91 | * @param bd block details |
61 | * @param expiration_time when does the content expire | ||
62 | * @param key key for the content | ||
63 | * @param put_path_length number of entries in @a put_path | ||
64 | * @param put_path peers the original PUT traversed (if tracked) | ||
65 | * @param get_path_length number of entries in @a get_path | ||
66 | * @param get_path peers this reply has traversed so far (if tracked) | ||
67 | * @param data payload of the reply | ||
68 | * @param data_size number of bytes in @a data | ||
69 | */ | 92 | */ |
70 | typedef void | 93 | typedef void |
71 | (*GDS_DATACACHE_GetCallback)(void *cls, | 94 | (*GDS_DATACACHE_GetCallback)(void *cls, |
72 | enum GNUNET_BLOCK_Type type, | 95 | const struct GDS_DATACACHE_BlockData *bd); |
73 | struct GNUNET_TIME_Absolute expiration_time, | ||
74 | const struct GNUNET_HashCode *key, | ||
75 | unsigned int put_path_length, | ||
76 | const struct GNUNET_PeerIdentity *put_path, | ||
77 | unsigned int get_path_length, | ||
78 | const struct GNUNET_PeerIdentity *get_path, | ||
79 | const void *data, | ||
80 | size_t data_size); | ||
81 | 96 | ||
82 | 97 | ||
83 | /** | 98 | /** |
@@ -103,43 +118,6 @@ GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *key, | |||
103 | 118 | ||
104 | 119 | ||
105 | /** | 120 | /** |
106 | * Obtain a random key from the datacache. | ||
107 | * Used by Whanau for load-balancing. | ||
108 | * | ||
109 | * @param[out] key where to store the key of a random element, | ||
110 | * randomized by PRNG if datacache is empty | ||
111 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if the datacache is empty | ||
112 | */ | ||
113 | int | ||
114 | GDS_DATACACHE_get_random_key (struct GNUNET_HashCode *key); | ||
115 | |||
116 | |||
117 | /** | ||
118 | * Send the get result to requesting client. | ||
119 | * | ||
120 | * @param cls closure | ||
121 | * @param options routing options (from GET request) | ||
122 | * @param key key of the requested data. | ||
123 | * @param type block type | ||
124 | * @param put_path_length number of peers in @a put_path | ||
125 | * @param put_path path taken to put the data at its stored location. | ||
126 | * @param expiration when will this result expire? | ||
127 | * @param data payload to store | ||
128 | * @param data_size size of the @a data | ||
129 | */ | ||
130 | typedef void | ||
131 | (*GDS_DATACACHE_SuccessorCallback)(void *cls, | ||
132 | enum GNUNET_DHT_RouteOption options, | ||
133 | const struct GNUNET_HashCode *key, | ||
134 | enum GNUNET_BLOCK_Type type, | ||
135 | unsigned int put_path_length, | ||
136 | const struct GNUNET_PeerIdentity *put_path, | ||
137 | struct GNUNET_TIME_Absolute expiration, | ||
138 | const void *data, | ||
139 | size_t data_size); | ||
140 | |||
141 | |||
142 | /** | ||
143 | * Handle a request for data close to a key that we have received from | 121 | * Handle a request for data close to a key that we have received from |
144 | * another peer. | 122 | * another peer. |
145 | * | 123 | * |
@@ -148,9 +126,9 @@ typedef void | |||
148 | * @param cb_cls closure for @a cb | 126 | * @param cb_cls closure for @a cb |
149 | */ | 127 | */ |
150 | void | 128 | void |
151 | GDS_DATACACHE_get_successors (const struct GNUNET_HashCode *key, | 129 | GDS_DATACACHE_get_closest (const struct GNUNET_HashCode *key, |
152 | GDS_DATACACHE_SuccessorCallback cb, | 130 | GDS_DATACACHE_GetCallback cb, |
153 | void *cb_cls); | 131 | void *cb_cls); |
154 | 132 | ||
155 | 133 | ||
156 | /** | 134 | /** |
diff --git a/src/dht/gnunet-service-dht_hello.c b/src/dht/gnunet-service-dht_hello.c index 906391334..949456575 100644 --- a/src/dht/gnunet-service-dht_hello.c +++ b/src/dht/gnunet-service-dht_hello.c | |||
@@ -54,7 +54,8 @@ GDS_HELLO_get (const struct GNUNET_PeerIdentity *peer) | |||
54 | { | 54 | { |
55 | if (NULL == peer_to_hello) | 55 | if (NULL == peer_to_hello) |
56 | return NULL; | 56 | return NULL; |
57 | return GNUNET_CONTAINER_multipeermap_get (peer_to_hello, peer); | 57 | return GNUNET_CONTAINER_multipeermap_get (peer_to_hello, |
58 | peer); | ||
58 | } | 59 | } |
59 | 60 | ||
60 | 61 | ||
@@ -83,15 +84,20 @@ process_hello (void *cls, | |||
83 | if (0 == GNUNET_TIME_absolute_get_remaining (ex).rel_value_us) | 84 | if (0 == GNUNET_TIME_absolute_get_remaining (ex).rel_value_us) |
84 | return; | 85 | return; |
85 | GNUNET_STATISTICS_update (GDS_stats, | 86 | GNUNET_STATISTICS_update (GDS_stats, |
86 | gettext_noop ("# HELLOs obtained from peerinfo"), 1, | 87 | "# HELLOs obtained from peerinfo", |
88 | 1, | ||
87 | GNUNET_NO); | 89 | GNUNET_NO); |
88 | hm = GNUNET_CONTAINER_multipeermap_get (peer_to_hello, peer); | 90 | hm = GNUNET_CONTAINER_multipeermap_get (peer_to_hello, |
91 | peer); | ||
89 | GNUNET_free (hm); | 92 | GNUNET_free (hm); |
90 | hm = GNUNET_malloc (GNUNET_HELLO_size (hello)); | 93 | hm = GNUNET_malloc (GNUNET_HELLO_size (hello)); |
91 | GNUNET_memcpy (hm, hello, GNUNET_HELLO_size (hello)); | 94 | GNUNET_memcpy (hm, |
95 | hello, | ||
96 | GNUNET_HELLO_size (hello)); | ||
92 | GNUNET_assert (GNUNET_SYSERR != | 97 | GNUNET_assert (GNUNET_SYSERR != |
93 | GNUNET_CONTAINER_multipeermap_put (peer_to_hello, | 98 | GNUNET_CONTAINER_multipeermap_put (peer_to_hello, |
94 | peer, hm, | 99 | peer, |
100 | hm, | ||
95 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE)); | 101 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE)); |
96 | } | 102 | } |
97 | 103 | ||
@@ -114,7 +120,7 @@ GDS_HELLO_init () | |||
114 | /** | 120 | /** |
115 | * Free memory occopied by the HELLO. | 121 | * Free memory occopied by the HELLO. |
116 | */ | 122 | */ |
117 | static int | 123 | static enum GNUNET_GenericReturnValue |
118 | free_hello (void *cls, | 124 | free_hello (void *cls, |
119 | const struct GNUNET_PeerIdentity *key, | 125 | const struct GNUNET_PeerIdentity *key, |
120 | void *hello) | 126 | void *hello) |
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 | ||
diff --git a/src/dht/gnunet-service-dht_neighbours.h b/src/dht/gnunet-service-dht_neighbours.h index 55cc5b135..ba7cc6055 100644 --- a/src/dht/gnunet-service-dht_neighbours.h +++ b/src/dht/gnunet-service-dht_neighbours.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2009, 2010, 2011 GNUnet e.V. | 3 | Copyright (C) 2009, 2010, 2011, 2022 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software: you can redistribute it and/or modify it | 5 | GNUnet is free software: you can redistribute it and/or modify it |
6 | under the terms of the GNU Affero General Public License as published | 6 | under the terms of the GNU Affero General Public License as published |
@@ -30,6 +30,7 @@ | |||
30 | #include "gnunet_util_lib.h" | 30 | #include "gnunet_util_lib.h" |
31 | #include "gnunet_block_lib.h" | 31 | #include "gnunet_block_lib.h" |
32 | #include "gnunet_dht_service.h" | 32 | #include "gnunet_dht_service.h" |
33 | #include "gnunet-service-dht_datacache.h" | ||
33 | 34 | ||
34 | /** | 35 | /** |
35 | * Hash of the identity of this peer. | 36 | * Hash of the identity of this peer. |
@@ -44,30 +45,19 @@ extern struct GNUNET_HashCode my_identity_hash; | |||
44 | * peer in the network (or if we are the closest peer in the | 45 | * peer in the network (or if we are the closest peer in the |
45 | * network). | 46 | * network). |
46 | * | 47 | * |
47 | * @param type type of the block | 48 | * @param bd data about the block |
48 | * @param options routing options | 49 | * @param options routing options |
49 | * @param desired_replication_level desired replication level | 50 | * @param desired_replication_level desired replication level |
50 | * @param expiration_time when does the content expire | ||
51 | * @param hop_count how many hops has this message traversed so far | 51 | * @param hop_count how many hops has this message traversed so far |
52 | * @param bf Bloom filter of peers this PUT has already traversed | 52 | * @param bf Bloom filter of peers this PUT has already traversed |
53 | * @param key key for the content | ||
54 | * @param put_path_length number of entries in put_path | ||
55 | * @param put_path peers this request has traversed so far (if tracked) | ||
56 | * @param data payload to store | ||
57 | * @param data_size number of bytes in data | ||
58 | * @return #GNUNET_OK if the request was forwarded, #GNUNET_NO if not | 53 | * @return #GNUNET_OK if the request was forwarded, #GNUNET_NO if not |
59 | */ | 54 | */ |
60 | int | 55 | enum GNUNET_GenericReturnValue |
61 | GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type, | 56 | GDS_NEIGHBOURS_handle_put (const struct GDS_DATACACHE_BlockData *bd, |
62 | enum GNUNET_DHT_RouteOption options, | 57 | enum GNUNET_DHT_RouteOption options, |
63 | uint32_t desired_replication_level, | 58 | uint32_t desired_replication_level, |
64 | struct GNUNET_TIME_Absolute expiration_time, | ||
65 | uint32_t hop_count, | 59 | uint32_t hop_count, |
66 | struct GNUNET_CONTAINER_BloomFilter *bf, | 60 | struct GNUNET_CONTAINER_BloomFilter *bf); |
67 | const struct GNUNET_HashCode *key, | ||
68 | unsigned int put_path_length, | ||
69 | struct GNUNET_PeerIdentity *put_path, | ||
70 | const void *data, size_t data_size); | ||
71 | 61 | ||
72 | 62 | ||
73 | /** | 63 | /** |
@@ -87,7 +77,7 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type, | |||
87 | * @param peer_bf filter for peers not to select (again, updated) | 77 | * @param peer_bf filter for peers not to select (again, updated) |
88 | * @return #GNUNET_OK if the request was forwarded, #GNUNET_NO if not | 78 | * @return #GNUNET_OK if the request was forwarded, #GNUNET_NO if not |
89 | */ | 79 | */ |
90 | int | 80 | enum GNUNET_GenericReturnValue |
91 | GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type, | 81 | GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type, |
92 | enum GNUNET_DHT_RouteOption options, | 82 | enum GNUNET_DHT_RouteOption options, |
93 | uint32_t desired_replication_level, | 83 | uint32_t desired_replication_level, |
@@ -106,26 +96,17 @@ GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type, | |||
106 | * | 96 | * |
107 | * @param target neighbour that should receive the block (if still connected) | 97 | * @param target neighbour that should receive the block (if still connected) |
108 | * @param type type of the block | 98 | * @param type type of the block |
109 | * @param expiration_time when does the content expire | 99 | * @param bd details about the reply |
110 | * @param key key for the content | 100 | * @param query_hash query that was used for the request |
111 | * @param put_path_length number of entries in put_path | ||
112 | * @param put_path peers the original PUT traversed (if tracked) | ||
113 | * @param get_path_length number of entries in put_path | 101 | * @param get_path_length number of entries in put_path |
114 | * @param get_path peers this reply has traversed so far (if tracked) | 102 | * @param get_path peers this reply has traversed so far (if tracked) |
115 | * @param data payload of the reply | ||
116 | * @param data_size number of bytes in data | ||
117 | */ | 103 | */ |
118 | void | 104 | void |
119 | GDS_NEIGHBOURS_handle_reply (const struct GNUNET_PeerIdentity *target, | 105 | GDS_NEIGHBOURS_handle_reply (const struct GNUNET_PeerIdentity *target, |
120 | enum GNUNET_BLOCK_Type type, | 106 | const struct GDS_DATACACHE_BlockData *bd, |
121 | struct GNUNET_TIME_Absolute expiration_time, | 107 | const struct GNUNET_HashCode *query_hash, |
122 | const struct GNUNET_HashCode *key, | ||
123 | unsigned int put_path_length, | ||
124 | const struct GNUNET_PeerIdentity *put_path, | ||
125 | unsigned int get_path_length, | 108 | unsigned int get_path_length, |
126 | const struct GNUNET_PeerIdentity *get_path, | 109 | const struct GNUNET_PeerIdentity *get_path); |
127 | const void *data, | ||
128 | size_t data_size); | ||
129 | 110 | ||
130 | 111 | ||
131 | /** | 112 | /** |
@@ -138,7 +119,7 @@ GDS_NEIGHBOURS_handle_reply (const struct GNUNET_PeerIdentity *target, | |||
138 | * @return #GNUNET_YES if node location is closest, | 119 | * @return #GNUNET_YES if node location is closest, |
139 | * #GNUNET_NO otherwise. | 120 | * #GNUNET_NO otherwise. |
140 | */ | 121 | */ |
141 | int | 122 | enum GNUNET_GenericReturnValue |
142 | GDS_am_closest_peer (const struct GNUNET_HashCode *key, | 123 | GDS_am_closest_peer (const struct GNUNET_HashCode *key, |
143 | const struct GNUNET_CONTAINER_BloomFilter *bloom); | 124 | const struct GNUNET_CONTAINER_BloomFilter *bloom); |
144 | 125 | ||
@@ -148,7 +129,7 @@ GDS_am_closest_peer (const struct GNUNET_HashCode *key, | |||
148 | * | 129 | * |
149 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | 130 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error |
150 | */ | 131 | */ |
151 | int | 132 | enum GNUNET_GenericReturnValue |
152 | GDS_NEIGHBOURS_init (void); | 133 | GDS_NEIGHBOURS_init (void); |
153 | 134 | ||
154 | 135 | ||
diff --git a/src/dht/gnunet-service-dht_nse.c b/src/dht/gnunet-service-dht_nse.c index 7f411cf71..58f18816a 100644 --- a/src/dht/gnunet-service-dht_nse.c +++ b/src/dht/gnunet-service-dht_nse.c | |||
@@ -52,11 +52,13 @@ static struct GNUNET_NSE_Handle *nse; | |||
52 | * | 52 | * |
53 | */ | 53 | */ |
54 | static void | 54 | static void |
55 | update_network_size_estimate (void *cls, struct GNUNET_TIME_Absolute timestamp, | 55 | update_network_size_estimate (void *cls, |
56 | double logestimate, double std_dev) | 56 | struct GNUNET_TIME_Absolute timestamp, |
57 | double logestimate, | ||
58 | double std_dev) | ||
57 | { | 59 | { |
58 | GNUNET_STATISTICS_update (GDS_stats, | 60 | GNUNET_STATISTICS_update (GDS_stats, |
59 | gettext_noop ("# Network size estimates received"), | 61 | "# Network size estimates received", |
60 | 1, GNUNET_NO); | 62 | 1, GNUNET_NO); |
61 | /* do not allow estimates < 0.5 */ | 63 | /* do not allow estimates < 0.5 */ |
62 | log_of_network_size_estimate = GNUNET_MAX (0.5, logestimate); | 64 | log_of_network_size_estimate = GNUNET_MAX (0.5, logestimate); |
@@ -83,20 +85,22 @@ GDS_NSE_init () | |||
83 | { | 85 | { |
84 | unsigned long long hops; | 86 | unsigned long long hops; |
85 | 87 | ||
86 | if ((GNUNET_YES == | 88 | if ( (GNUNET_YES == |
87 | GNUNET_CONFIGURATION_have_value (GDS_cfg, | 89 | GNUNET_CONFIGURATION_have_value (GDS_cfg, |
88 | "dht", | 90 | "dht", |
89 | "FORCE_NSE")) && | 91 | "FORCE_NSE")) && |
90 | (GNUNET_OK == | 92 | (GNUNET_OK == |
91 | GNUNET_CONFIGURATION_get_value_number (GDS_cfg, | 93 | GNUNET_CONFIGURATION_get_value_number (GDS_cfg, |
92 | "dht", | 94 | "dht", |
93 | "FORCE_NSE", | 95 | "FORCE_NSE", |
94 | &hops))) | 96 | &hops)) ) |
95 | { | 97 | { |
96 | log_of_network_size_estimate = (double) hops; | 98 | log_of_network_size_estimate = (double) hops; |
97 | return; | 99 | return; |
98 | } | 100 | } |
99 | nse = GNUNET_NSE_connect (GDS_cfg, &update_network_size_estimate, NULL); | 101 | nse = GNUNET_NSE_connect (GDS_cfg, |
102 | &update_network_size_estimate, | ||
103 | NULL); | ||
100 | } | 104 | } |
101 | 105 | ||
102 | 106 | ||
diff --git a/src/dht/gnunet-service-dht_routing.c b/src/dht/gnunet-service-dht_routing.c index ef3aded77..8ba0c70ad 100644 --- a/src/dht/gnunet-service-dht_routing.c +++ b/src/dht/gnunet-service-dht_routing.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2011 GNUnet e.V. | 3 | Copyright (C) 2011, 2022 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software: you can redistribute it and/or modify it | 5 | GNUnet is free software: you can redistribute it and/or modify it |
6 | under the terms of the GNU Affero General Public License as published | 6 | under the terms of the GNU Affero General Public License as published |
@@ -31,8 +31,9 @@ | |||
31 | 31 | ||
32 | /** | 32 | /** |
33 | * Number of requests we track at most (for routing replies). | 33 | * Number of requests we track at most (for routing replies). |
34 | * TODO: make configurable! | ||
34 | */ | 35 | */ |
35 | #define DHT_MAX_RECENT (1024 * 16) | 36 | #define DHT_MAX_RECENT (1024 * 128) |
36 | 37 | ||
37 | 38 | ||
38 | /** | 39 | /** |
@@ -96,14 +97,14 @@ static struct GNUNET_CONTAINER_MultiHashMap *recent_map; | |||
96 | 97 | ||
97 | 98 | ||
98 | /** | 99 | /** |
99 | * Closure for the 'process' function. | 100 | * Closure for the process() function. |
100 | */ | 101 | */ |
101 | struct ProcessContext | 102 | struct ProcessContext |
102 | { | 103 | { |
103 | /** | 104 | /** |
104 | * Path of the original PUT | 105 | * Block data. |
105 | */ | 106 | */ |
106 | const struct GNUNET_PeerIdentity *put_path; | 107 | const struct GDS_DATACACHE_BlockData *bd; |
107 | 108 | ||
108 | /** | 109 | /** |
109 | * Path of the reply. | 110 | * Path of the reply. |
@@ -111,34 +112,10 @@ struct ProcessContext | |||
111 | const struct GNUNET_PeerIdentity *get_path; | 112 | const struct GNUNET_PeerIdentity *get_path; |
112 | 113 | ||
113 | /** | 114 | /** |
114 | * Payload of the reply. | ||
115 | */ | ||
116 | const void *data; | ||
117 | |||
118 | /** | ||
119 | * Expiration time of the result. | ||
120 | */ | ||
121 | struct GNUNET_TIME_Absolute expiration_time; | ||
122 | |||
123 | /** | ||
124 | * Number of entries in @e put_path. | ||
125 | */ | ||
126 | unsigned int put_path_length; | ||
127 | |||
128 | /** | ||
129 | * Number of entries in @e get_path. | 115 | * Number of entries in @e get_path. |
130 | */ | 116 | */ |
131 | unsigned int get_path_length; | 117 | unsigned int get_path_length; |
132 | 118 | ||
133 | /** | ||
134 | * Number of bytes in @e data. | ||
135 | */ | ||
136 | size_t data_size; | ||
137 | |||
138 | /** | ||
139 | * Type of the reply. | ||
140 | */ | ||
141 | enum GNUNET_BLOCK_Type type; | ||
142 | }; | 119 | }; |
143 | 120 | ||
144 | 121 | ||
@@ -146,71 +123,56 @@ struct ProcessContext | |||
146 | * Forward the result to the given peer if it matches the request. | 123 | * Forward the result to the given peer if it matches the request. |
147 | * | 124 | * |
148 | * @param cls the `struct ProcessContext` with the result | 125 | * @param cls the `struct ProcessContext` with the result |
149 | * @param key the query | 126 | * @param query_hash the hash from the original query |
150 | * @param value the `struct RecentRequest` with the request | 127 | * @param value the `struct RecentRequest` with the request |
151 | * @return #GNUNET_OK (continue to iterate) | 128 | * @return #GNUNET_OK (continue to iterate) |
152 | */ | 129 | */ |
153 | static enum GNUNET_GenericReturnValue | 130 | static enum GNUNET_GenericReturnValue |
154 | process (void *cls, | 131 | process (void *cls, |
155 | const struct GNUNET_HashCode *key, | 132 | const struct GNUNET_HashCode *query_hash, |
156 | void *value) | 133 | void *value) |
157 | { | 134 | { |
158 | struct ProcessContext *pc = cls; | 135 | struct ProcessContext *pc = cls; |
159 | struct RecentRequest *rr = value; | 136 | struct RecentRequest *rr = value; |
160 | enum GNUNET_BLOCK_ReplyEvaluationResult eval; | 137 | enum GNUNET_BLOCK_ReplyEvaluationResult eval; |
161 | unsigned int gpl; | 138 | unsigned int get_path_length; |
162 | unsigned int ppl; | 139 | struct GDS_DATACACHE_BlockData bdx = *pc->bd; |
163 | struct GNUNET_HashCode hc; | ||
164 | const struct GNUNET_HashCode *eval_key; | ||
165 | 140 | ||
166 | if ((rr->type != GNUNET_BLOCK_TYPE_ANY) && | 141 | if ( (rr->type != GNUNET_BLOCK_TYPE_ANY) && |
167 | (rr->type != pc->type)) | 142 | (rr->type != pc->bd->type) ) |
168 | return GNUNET_OK; /* type mismatch */ | 143 | return GNUNET_OK; /* type mismatch */ |
169 | |||
170 | if (0 != (rr->options & GNUNET_DHT_RO_RECORD_ROUTE)) | 144 | if (0 != (rr->options & GNUNET_DHT_RO_RECORD_ROUTE)) |
171 | { | 145 | { |
172 | gpl = pc->get_path_length; | 146 | get_path_length = pc->get_path_length; |
173 | ppl = pc->put_path_length; | ||
174 | } | 147 | } |
175 | else | 148 | else |
176 | { | 149 | { |
177 | gpl = 0; | 150 | get_path_length = 0; |
178 | ppl = 0; | 151 | bdx.put_path_length = 0; |
152 | bdx.put_path = NULL; | ||
179 | } | 153 | } |
180 | /* FIXME-SCHANZEN: should we modify FIND_PEER to | 154 | if ( (0 == (rr->options & GNUNET_DHT_RO_FIND_PEER)) && |
181 | be a generic approximate search and not check | 155 | (0 != GNUNET_memcmp (query_hash, |
182 | for the DHT_HELLO type here? */ | 156 | &bdx.key)) ) |
183 | if ( (0 != (rr->options & GNUNET_DHT_RO_FIND_PEER)) && | ||
184 | (pc->type == GNUNET_BLOCK_TYPE_DHT_HELLO) ) | ||
185 | { | 157 | { |
186 | /* key may not match HELLO, which is OK since | 158 | GNUNET_STATISTICS_update (GDS_stats, |
187 | * the search is approximate. Still, the evaluation | 159 | "# Inexact matches discarded in exact search", |
188 | * would fail since the match is not exact. So | 160 | 1, |
189 | * we fake it by changing the key to the actual PID ... */ | 161 | GNUNET_NO); |
190 | GNUNET_BLOCK_get_key (GDS_block_context, | 162 | return GNUNET_OK; /* exact search, but inexact match */ |
191 | GNUNET_BLOCK_TYPE_DHT_HELLO, | ||
192 | pc->data, | ||
193 | pc->data_size, | ||
194 | &hc); | ||
195 | eval_key = &hc; | ||
196 | } | ||
197 | else | ||
198 | { | ||
199 | eval_key = key; | ||
200 | } | 163 | } |
201 | eval | 164 | eval = GNUNET_BLOCK_check_reply (GDS_block_context, |
202 | = GNUNET_BLOCK_check_reply (GDS_block_context, | 165 | bdx.type, |
203 | pc->type, | 166 | rr->bg, |
204 | rr->bg, | 167 | &bdx.key, |
205 | eval_key, | 168 | rr->xquery, |
206 | rr->xquery, | 169 | rr->xquery_size, |
207 | rr->xquery_size, | 170 | bdx.data, |
208 | pc->data, | 171 | bdx.data_size); |
209 | pc->data_size); | ||
210 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 172 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
211 | "Result for %s of type %d was evaluated as %d\n", | 173 | "Result for %s of type %d was evaluated as %d\n", |
212 | GNUNET_h2s (key), | 174 | GNUNET_h2s (&bdx.key), |
213 | pc->type, | 175 | bdx.type, |
214 | eval); | 176 | eval); |
215 | switch (eval) | 177 | switch (eval) |
216 | { | 178 | { |
@@ -222,13 +184,9 @@ process (void *cls, | |||
222 | 1, | 184 | 1, |
223 | GNUNET_NO); | 185 | GNUNET_NO); |
224 | GDS_NEIGHBOURS_handle_reply (&rr->peer, | 186 | GDS_NEIGHBOURS_handle_reply (&rr->peer, |
225 | pc->type, | 187 | &bdx, |
226 | pc->expiration_time, | 188 | query_hash, |
227 | key, | 189 | get_path_length, pc->get_path); |
228 | ppl, pc->put_path, | ||
229 | gpl, pc->get_path, | ||
230 | pc->data, | ||
231 | pc->data_size); | ||
232 | break; | 190 | break; |
233 | case GNUNET_BLOCK_REPLY_OK_DUPLICATE: | 191 | case GNUNET_BLOCK_REPLY_OK_DUPLICATE: |
234 | GNUNET_STATISTICS_update (GDS_stats, | 192 | GNUNET_STATISTICS_update (GDS_stats, |
@@ -264,39 +222,25 @@ process (void *cls, | |||
264 | * GDS_NEIGHBOURS_handle_reply() for all peers that sent us a matching | 222 | * GDS_NEIGHBOURS_handle_reply() for all peers that sent us a matching |
265 | * request recently. | 223 | * request recently. |
266 | * | 224 | * |
267 | * @param type type of the block | 225 | * @param bd block details |
268 | * @param expiration_time when does the content expire | 226 | * @param query_hash query used in the inquiry |
269 | * @param key key for the content | ||
270 | * @param put_path_length number of entries in @a put_path | ||
271 | * @param put_path peers the original PUT traversed (if tracked) | ||
272 | * @param get_path_length number of entries in @a get_path | 227 | * @param get_path_length number of entries in @a get_path |
273 | * @param get_path peers this reply has traversed so far (if tracked) | 228 | * @param get_path peers this reply has traversed so far (if tracked) |
274 | * @param data payload of the reply | ||
275 | * @param data_size number of bytes in data | ||
276 | */ | 229 | */ |
277 | void | 230 | void |
278 | GDS_ROUTING_process (enum GNUNET_BLOCK_Type type, | 231 | GDS_ROUTING_process (const struct GDS_DATACACHE_BlockData *bd, |
279 | struct GNUNET_TIME_Absolute expiration_time, | 232 | const struct GNUNET_HashCode *query_hash, |
280 | const struct GNUNET_HashCode *key, | ||
281 | unsigned int put_path_length, | ||
282 | const struct GNUNET_PeerIdentity *put_path, | ||
283 | unsigned int get_path_length, | 233 | unsigned int get_path_length, |
284 | const struct GNUNET_PeerIdentity *get_path, | 234 | const struct GNUNET_PeerIdentity *get_path) |
285 | const void *data, | ||
286 | size_t data_size) | ||
287 | { | 235 | { |
288 | struct ProcessContext pc; | 236 | struct ProcessContext pc = { |
289 | 237 | .bd = bd, | |
290 | pc.type = type; | 238 | .get_path = get_path, |
291 | pc.expiration_time = expiration_time; | 239 | .get_path_length = get_path_length |
292 | pc.put_path_length = put_path_length; | 240 | }; |
293 | pc.put_path = put_path; | 241 | |
294 | pc.get_path_length = get_path_length; | ||
295 | pc.get_path = get_path; | ||
296 | pc.data = data; | ||
297 | pc.data_size = data_size; | ||
298 | GNUNET_CONTAINER_multihashmap_get_multiple (recent_map, | 242 | GNUNET_CONTAINER_multihashmap_get_multiple (recent_map, |
299 | key, | 243 | query_hash, |
300 | &process, | 244 | &process, |
301 | &pc); | 245 | &pc); |
302 | } | 246 | } |
@@ -313,7 +257,7 @@ expire_oldest_entry (void) | |||
313 | struct RecentRequest *recent_req; | 257 | struct RecentRequest *recent_req; |
314 | 258 | ||
315 | GNUNET_STATISTICS_update (GDS_stats, | 259 | GNUNET_STATISTICS_update (GDS_stats, |
316 | "# Entries removed from routing table", | 260 | "# Old entries removed from routing table", |
317 | 1, | 261 | 1, |
318 | GNUNET_NO); | 262 | GNUNET_NO); |
319 | recent_req = GNUNET_CONTAINER_heap_peek (recent_heap); | 263 | recent_req = GNUNET_CONTAINER_heap_peek (recent_heap); |
@@ -334,7 +278,7 @@ expire_oldest_entry (void) | |||
334 | * | 278 | * |
335 | * @param cls the new `struct RecentRequest` (to discard upon successful combination) | 279 | * @param cls the new `struct RecentRequest` (to discard upon successful combination) |
336 | * @param key the query | 280 | * @param key the query |
337 | * @param value the existing 'struct RecentRequest' (to update upon successful combination) | 281 | * @param value the existing `struct RecentRequest` (to update upon successful combination) |
338 | * @return #GNUNET_OK (continue to iterate), | 282 | * @return #GNUNET_OK (continue to iterate), |
339 | * #GNUNET_SYSERR if the request was successfully combined | 283 | * #GNUNET_SYSERR if the request was successfully combined |
340 | */ | 284 | */ |
@@ -346,13 +290,13 @@ try_combine_recent (void *cls, | |||
346 | struct RecentRequest *in = cls; | 290 | struct RecentRequest *in = cls; |
347 | struct RecentRequest *rr = value; | 291 | struct RecentRequest *rr = value; |
348 | 292 | ||
349 | if ((0 != GNUNET_memcmp (&in->peer, | 293 | if ( (0 != GNUNET_memcmp (&in->peer, |
350 | &rr->peer)) || | 294 | &rr->peer)) || |
351 | (in->type != rr->type) || | 295 | (in->type != rr->type) || |
352 | (in->xquery_size != rr->xquery_size) || | 296 | (in->xquery_size != rr->xquery_size) || |
353 | (0 != memcmp (in->xquery, | 297 | (0 != memcmp (in->xquery, |
354 | rr->xquery, | 298 | rr->xquery, |
355 | in->xquery_size))) | 299 | in->xquery_size) ) ) |
356 | return GNUNET_OK; | 300 | return GNUNET_OK; |
357 | GNUNET_break (GNUNET_SYSERR != | 301 | GNUNET_break (GNUNET_SYSERR != |
358 | GNUNET_BLOCK_group_merge (in->bg, | 302 | GNUNET_BLOCK_group_merge (in->bg, |
@@ -410,19 +354,21 @@ GDS_ROUTING_add (const struct GNUNET_PeerIdentity *sender, | |||
410 | recent_req)) | 354 | recent_req)) |
411 | { | 355 | { |
412 | GNUNET_STATISTICS_update (GDS_stats, | 356 | GNUNET_STATISTICS_update (GDS_stats, |
413 | gettext_noop | 357 | "# DHT requests combined", |
414 | ("# DHT requests combined"), | 358 | 1, |
415 | 1, GNUNET_NO); | 359 | GNUNET_NO); |
416 | return; | 360 | return; |
417 | } | 361 | } |
418 | recent_req->heap_node | 362 | recent_req->heap_node |
419 | = GNUNET_CONTAINER_heap_insert (recent_heap, | 363 | = GNUNET_CONTAINER_heap_insert ( |
420 | recent_req, | 364 | recent_heap, |
421 | GNUNET_TIME_absolute_get ().abs_value_us); | 365 | recent_req, |
422 | GNUNET_CONTAINER_multihashmap_put (recent_map, | 366 | GNUNET_TIME_absolute_get ().abs_value_us); |
423 | key, | 367 | (void) GNUNET_CONTAINER_multihashmap_put ( |
424 | recent_req, | 368 | recent_map, |
425 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | 369 | key, |
370 | recent_req, | ||
371 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
426 | } | 372 | } |
427 | 373 | ||
428 | 374 | ||
@@ -446,10 +392,12 @@ GDS_ROUTING_done () | |||
446 | { | 392 | { |
447 | while (GNUNET_CONTAINER_heap_get_size (recent_heap) > 0) | 393 | while (GNUNET_CONTAINER_heap_get_size (recent_heap) > 0) |
448 | expire_oldest_entry (); | 394 | expire_oldest_entry (); |
449 | GNUNET_assert (0 == GNUNET_CONTAINER_heap_get_size (recent_heap)); | 395 | GNUNET_assert (0 == |
396 | GNUNET_CONTAINER_heap_get_size (recent_heap)); | ||
450 | GNUNET_CONTAINER_heap_destroy (recent_heap); | 397 | GNUNET_CONTAINER_heap_destroy (recent_heap); |
451 | recent_heap = NULL; | 398 | recent_heap = NULL; |
452 | GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap_size (recent_map)); | 399 | GNUNET_assert (0 == |
400 | GNUNET_CONTAINER_multihashmap_size (recent_map)); | ||
453 | GNUNET_CONTAINER_multihashmap_destroy (recent_map); | 401 | GNUNET_CONTAINER_multihashmap_destroy (recent_map); |
454 | recent_map = NULL; | 402 | recent_map = NULL; |
455 | } | 403 | } |
diff --git a/src/dht/gnunet-service-dht_routing.h b/src/dht/gnunet-service-dht_routing.h index 7fea01bae..1a1514cc5 100644 --- a/src/dht/gnunet-service-dht_routing.h +++ b/src/dht/gnunet-service-dht_routing.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2011 GNUnet e.V. | 3 | Copyright (C) 2011, 2022 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software: you can redistribute it and/or modify it | 5 | GNUnet is free software: you can redistribute it and/or modify it |
6 | under the terms of the GNU Affero General Public License as published | 6 | under the terms of the GNU Affero General Public License as published |
@@ -35,29 +35,19 @@ | |||
35 | * Handle a reply (route to origin). Only forwards the reply back to | 35 | * Handle a reply (route to origin). Only forwards the reply back to |
36 | * other peers waiting for it. Does not do local caching or | 36 | * other peers waiting for it. Does not do local caching or |
37 | * forwarding to local clients. Essentially calls | 37 | * forwarding to local clients. Essentially calls |
38 | * #GDS_NEIGHBOURS_handle_reply() for all peers that sent us a matching | 38 | * GDS_NEIGHBOURS_handle_reply() for all peers that sent us a matching |
39 | * request recently. | 39 | * request recently. |
40 | * | 40 | * |
41 | * @param type type of the block | 41 | * @param bd block details |
42 | * @param expiration_time when does the content expire | 42 | * @param query_hash query used in the inquiry |
43 | * @param key key for the content | ||
44 | * @param put_path_length number of entries in @a put_path | ||
45 | * @param put_path peers the original PUT traversed (if tracked) | ||
46 | * @param get_path_length number of entries in @a get_path | 43 | * @param get_path_length number of entries in @a get_path |
47 | * @param get_path peers this reply has traversed so far (if tracked) | 44 | * @param get_path peers this reply has traversed so far (if tracked) |
48 | * @param data payload of the reply | ||
49 | * @param data_size number of bytes in @a data | ||
50 | */ | 45 | */ |
51 | void | 46 | void |
52 | GDS_ROUTING_process (enum GNUNET_BLOCK_Type type, | 47 | GDS_ROUTING_process (const struct GDS_DATACACHE_BlockData *bd, |
53 | struct GNUNET_TIME_Absolute expiration_time, | 48 | const struct GNUNET_HashCode *query_hash, |
54 | const struct GNUNET_HashCode *key, | ||
55 | unsigned int put_path_length, | ||
56 | const struct GNUNET_PeerIdentity *put_path, | ||
57 | unsigned int get_path_length, | 49 | unsigned int get_path_length, |
58 | const struct GNUNET_PeerIdentity *get_path, | 50 | const struct GNUNET_PeerIdentity *get_path); |
59 | const void *data, | ||
60 | size_t data_size); | ||
61 | 51 | ||
62 | 52 | ||
63 | /** | 53 | /** |