aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2021-12-29 20:16:01 +0100
committerChristian Grothoff <christian@grothoff.org>2021-12-29 20:16:01 +0100
commit9859314207ad10e37b73eacd5dfccac59ec8153e (patch)
tree4c32f5d5b5d00cf69855f29b1b9e26e51e787123 /src
parentdaa9284567865177279a692eb722e257ed06923e (diff)
downloadgnunet-9859314207ad10e37b73eacd5dfccac59ec8153e.tar.gz
gnunet-9859314207ad10e37b73eacd5dfccac59ec8153e.zip
-start to use new block API in DHT
Diffstat (limited to 'src')
-rw-r--r--src/dht/dht_api.c3
-rw-r--r--src/dht/gnunet-service-dht.h4
-rw-r--r--src/dht/gnunet-service-dht_clients.c144
-rw-r--r--src/dht/gnunet-service-dht_datacache.c72
-rw-r--r--src/dht/gnunet-service-dht_neighbours.c253
-rw-r--r--src/dht/gnunet-service-dht_routing.c128
-rw-r--r--src/include/gnunet_block_lib.h12
7 files changed, 271 insertions, 345 deletions
diff --git a/src/dht/dht_api.c b/src/dht/dht_api.c
index 96399cb5a..727f1a1f6 100644
--- a/src/dht/dht_api.c
+++ b/src/dht/dht_api.c
@@ -1048,8 +1048,7 @@ GNUNET_DHT_put_cancel (struct GNUNET_DHT_PutHandle *ph)
1048 1048
1049 1049
1050/** 1050/**
1051 * Perform an asynchronous GET operation on the DHT identified. See 1051 * Perform an asynchronous GET operation on the DHT identified.
1052 * also #GNUNET_BLOCK_evaluate.
1053 * 1052 *
1054 * @param handle handle to the DHT service 1053 * @param handle handle to the DHT service
1055 * @param type expected type of the response object 1054 * @param type expected type of the response object
diff --git a/src/dht/gnunet-service-dht.h b/src/dht/gnunet-service-dht.h
index 6741efb4e..a366367ca 100644
--- a/src/dht/gnunet-service-dht.h
+++ b/src/dht/gnunet-service-dht.h
@@ -65,7 +65,8 @@ extern struct GNUNET_MessageHeader *GDS_my_hello;
65 * client(s). 65 * client(s).
66 * 66 *
67 * @param expiration when will the reply expire 67 * @param expiration when will the reply expire
68 * @param key the query this reply is for 68 * @param key the key of the query that triggered the reply
69 * @param query_hash the query hash of the response
69 * @param get_path_length number of peers in @a get_path 70 * @param get_path_length number of peers in @a get_path
70 * @param get_path path the reply took on get 71 * @param get_path path the reply took on get
71 * @param put_path_length number of peers in @a put_path 72 * @param put_path_length number of peers in @a put_path
@@ -77,6 +78,7 @@ extern struct GNUNET_MessageHeader *GDS_my_hello;
77void 78void
78GDS_CLIENTS_handle_reply (struct GNUNET_TIME_Absolute expiration, 79GDS_CLIENTS_handle_reply (struct GNUNET_TIME_Absolute expiration,
79 const struct GNUNET_HashCode *key, 80 const struct GNUNET_HashCode *key,
81 const struct GNUNET_HashCode *query_hash,
80 unsigned int get_path_length, 82 unsigned int get_path_length,
81 const struct GNUNET_PeerIdentity *get_path, 83 const struct GNUNET_PeerIdentity *get_path,
82 unsigned int put_path_length, 84 unsigned int put_path_length,
diff --git a/src/dht/gnunet-service-dht_clients.c b/src/dht/gnunet-service-dht_clients.c
index cfcb25336..feccde8a8 100644
--- a/src/dht/gnunet-service-dht_clients.c
+++ b/src/dht/gnunet-service-dht_clients.c
@@ -125,6 +125,8 @@ struct ClientQueryRecord
125 125
126 /** 126 /**
127 * Any message options for this request 127 * Any message options for this request
128 *
129 * FIXME: why uint32_t instead of enum?
128 */ 130 */
129 uint32_t msg_options; 131 uint32_t msg_options;
130 132
@@ -493,6 +495,7 @@ handle_dht_local_put (void *cls,
493 GNUNET_h2s (&dht_msg->key)); 495 GNUNET_h2s (&dht_msg->key));
494 GDS_CLIENTS_handle_reply (GNUNET_TIME_absolute_ntoh (dht_msg->expiration), 496 GDS_CLIENTS_handle_reply (GNUNET_TIME_absolute_ntoh (dht_msg->expiration),
495 &dht_msg->key, 497 &dht_msg->key,
498 &dht_msg->key,
496 0, 499 0,
497 NULL, 500 NULL,
498 0, 501 0,
@@ -585,6 +588,7 @@ handle_local_result (void *cls,
585 // possibly avoid even looking up the client! 588 // possibly avoid even looking up the client!
586 GDS_CLIENTS_handle_reply (expiration_time, 589 GDS_CLIENTS_handle_reply (expiration_time,
587 key, 590 key,
591 key,
588 0, NULL, 592 0, NULL,
589 put_path_length, put_path, 593 put_path_length, put_path,
590 type, 594 type,
@@ -967,6 +971,11 @@ struct ForwardReplyContext
967 const struct GNUNET_PeerIdentity *put_path; 971 const struct GNUNET_PeerIdentity *put_path;
968 972
969 /** 973 /**
974 * Hash under which the payload is stored.
975 */
976 const struct GNUNET_HashCode *query_hash;
977
978 /**
970 * Embedded payload. 979 * Embedded payload.
971 */ 980 */
972 const void *data; 981 const void *data;
@@ -1004,7 +1013,7 @@ struct ForwardReplyContext
1004 * @return #GNUNET_YES (we should continue to iterate), 1013 * @return #GNUNET_YES (we should continue to iterate),
1005 * if the result is mal-formed, #GNUNET_NO 1014 * if the result is mal-formed, #GNUNET_NO
1006 */ 1015 */
1007static int 1016static enum GNUNET_GenericReturnValue
1008forward_reply (void *cls, 1017forward_reply (void *cls,
1009 const struct GNUNET_HashCode *key, 1018 const struct GNUNET_HashCode *key,
1010 void *value) 1019 void *value)
@@ -1013,14 +1022,14 @@ forward_reply (void *cls,
1013 struct ClientQueryRecord *record = value; 1022 struct ClientQueryRecord *record = value;
1014 struct GNUNET_MQ_Envelope *env; 1023 struct GNUNET_MQ_Envelope *env;
1015 struct GNUNET_DHT_ClientResultMessage *reply; 1024 struct GNUNET_DHT_ClientResultMessage *reply;
1016 enum GNUNET_BLOCK_EvaluationResult eval; 1025 enum GNUNET_BLOCK_ReplyEvaluationResult eval;
1017 int do_free; 1026 bool do_free;
1018 struct GNUNET_HashCode ch; 1027 struct GNUNET_HashCode ch;
1019 struct GNUNET_PeerIdentity *paths; 1028 struct GNUNET_PeerIdentity *paths;
1020 1029
1021 LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG, 1030 LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG,
1022 "CLIENT-RESULT %s\n", 1031 "CLIENT-RESULT %s\n",
1023 GNUNET_h2s_full (key)); 1032 GNUNET_h2s_full (frc->query_hash));
1024 if ((record->type != GNUNET_BLOCK_TYPE_ANY) && 1033 if ((record->type != GNUNET_BLOCK_TYPE_ANY) &&
1025 (record->type != frc->type)) 1034 (record->type != frc->type))
1026 { 1035 {
@@ -1028,13 +1037,24 @@ forward_reply (void *cls,
1028 "Record type mismatch, not passing request for key %s to local client\n", 1037 "Record type mismatch, not passing request for key %s to local client\n",
1029 GNUNET_h2s (key)); 1038 GNUNET_h2s (key));
1030 GNUNET_STATISTICS_update (GDS_stats, 1039 GNUNET_STATISTICS_update (GDS_stats,
1031 gettext_noop 1040 "# Key match, type mismatches in REPLY to CLIENT",
1032 ( 1041 1,
1033 "# Key match, type mismatches in REPLY to CLIENT"), 1042 GNUNET_NO);
1034 1, GNUNET_NO);
1035 return GNUNET_YES; /* type mismatch */ 1043 return GNUNET_YES; /* type mismatch */
1036 } 1044 }
1037 GNUNET_CRYPTO_hash (frc->data, frc->data_size, &ch); 1045 if ( (0 == (record->msg_options & GNUNET_DHT_RO_FIND_PEER)) &&
1046 (0 != GNUNET_memcmp (key,
1047 frc->query_hash)) )
1048 {
1049 GNUNET_STATISTICS_update (GDS_stats,
1050 "# Inexact key match, but exact match required",
1051 1,
1052 GNUNET_NO);
1053 return GNUNET_YES; /* type mismatch */
1054 }
1055 GNUNET_CRYPTO_hash (frc->data,
1056 frc->data_size,
1057 &ch);
1038 for (unsigned int i = 0; i < record->seen_replies_count; i++) 1058 for (unsigned int i = 0; i < record->seen_replies_count; i++)
1039 if (0 == memcmp (&record->seen_replies[i], 1059 if (0 == memcmp (&record->seen_replies[i],
1040 &ch, 1060 &ch,
@@ -1051,63 +1071,45 @@ forward_reply (void *cls,
1051 return GNUNET_YES; /* duplicate */ 1071 return GNUNET_YES; /* duplicate */
1052 } 1072 }
1053 eval 1073 eval
1054 = GNUNET_BLOCK_evaluate (GDS_block_context, 1074 = GNUNET_BLOCK_check_reply (GDS_block_context,
1055 record->type, 1075 record->type,
1056 NULL, 1076 NULL,
1057 GNUNET_BLOCK_EO_NONE, 1077 key,
1058 key, 1078 record->xquery,
1059 record->xquery, 1079 record->xquery_size,
1060 record->xquery_size, 1080 frc->data,
1061 frc->data, 1081 frc->data_size);
1062 frc->data_size);
1063 LOG (GNUNET_ERROR_TYPE_DEBUG, 1082 LOG (GNUNET_ERROR_TYPE_DEBUG,
1064 "Evaluation result is %d for key %s for local client's query\n", 1083 "Evaluation result is %d for key %s for local client's query\n",
1065 (int) eval, 1084 (int) eval,
1066 GNUNET_h2s (key)); 1085 GNUNET_h2s (key));
1067 switch (eval) 1086 switch (eval)
1068 { 1087 {
1069 case GNUNET_BLOCK_EVALUATION_OK_LAST: 1088 case GNUNET_BLOCK_REPLY_OK_LAST:
1070 do_free = GNUNET_YES; 1089 do_free = true;
1071 break; 1090 break;
1072 1091 case GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED:
1073 case GNUNET_BLOCK_EVALUATION_OK_MORE: 1092 case GNUNET_BLOCK_REPLY_OK_MORE:
1074 GNUNET_array_append (record->seen_replies, 1093 GNUNET_array_append (record->seen_replies,
1075 record->seen_replies_count, 1094 record->seen_replies_count,
1076 ch); 1095 ch);
1077 do_free = GNUNET_NO; 1096 do_free = false;
1078 break; 1097 break;
1079 1098 case GNUNET_BLOCK_REPLY_OK_DUPLICATE:
1080 case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE:
1081 /* should be impossible to encounter here */ 1099 /* should be impossible to encounter here */
1082 GNUNET_break (0); 1100 GNUNET_break (0);
1083 return GNUNET_YES; 1101 return GNUNET_YES;
1084 1102 case GNUNET_BLOCK_REPLY_INVALID:
1085 case GNUNET_BLOCK_EVALUATION_RESULT_INVALID:
1086 GNUNET_break_op (0); 1103 GNUNET_break_op (0);
1087 return GNUNET_NO; 1104 return GNUNET_NO;
1088 1105 case GNUNET_BLOCK_REPLY_IRRELEVANT:
1089 case GNUNET_BLOCK_EVALUATION_REQUEST_VALID:
1090 GNUNET_break (0);
1091 return GNUNET_NO;
1092
1093 case GNUNET_BLOCK_EVALUATION_REQUEST_INVALID:
1094 GNUNET_break (0);
1095 return GNUNET_NO;
1096
1097 case GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT:
1098 return GNUNET_YES; 1106 return GNUNET_YES;
1099
1100 case GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED:
1101 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1102 _ ("Unsupported block type (%u) in request!\n"), record->type);
1103 return GNUNET_NO;
1104
1105 default: 1107 default:
1106 GNUNET_break (0); 1108 GNUNET_break (0);
1107 return GNUNET_NO; 1109 return GNUNET_NO;
1108 } 1110 }
1109 GNUNET_STATISTICS_update (GDS_stats, 1111 GNUNET_STATISTICS_update (GDS_stats,
1110 gettext_noop ("# RESULTS queued for clients"), 1112 "# RESULTS queued for clients",
1111 1, 1113 1,
1112 GNUNET_NO); 1114 GNUNET_NO);
1113 env = GNUNET_MQ_msg_extra (reply, 1115 env = GNUNET_MQ_msg_extra (reply,
@@ -1149,7 +1151,8 @@ forward_reply (void *cls,
1149 * client(s). 1151 * client(s).
1150 * 1152 *
1151 * @param expiration when will the reply expire 1153 * @param expiration when will the reply expire
1152 * @param key the query this reply is for 1154 * @param key the key of the query that triggered the reply
1155 * @param query_hash the query hash of the response
1153 * @param get_path_length number of peers in @a get_path 1156 * @param get_path_length number of peers in @a get_path
1154 * @param get_path path the reply took on get 1157 * @param get_path path the reply took on get
1155 * @param put_path_length number of peers in @a put_path 1158 * @param put_path_length number of peers in @a put_path
@@ -1161,6 +1164,7 @@ forward_reply (void *cls,
1161void 1164void
1162GDS_CLIENTS_handle_reply (struct GNUNET_TIME_Absolute expiration, 1165GDS_CLIENTS_handle_reply (struct GNUNET_TIME_Absolute expiration,
1163 const struct GNUNET_HashCode *key, 1166 const struct GNUNET_HashCode *key,
1167 const struct GNUNET_HashCode *query_hash,
1164 unsigned int get_path_length, 1168 unsigned int get_path_length,
1165 const struct GNUNET_PeerIdentity *get_path, 1169 const struct GNUNET_PeerIdentity *get_path,
1166 unsigned int put_path_length, 1170 unsigned int put_path_length,
@@ -1173,27 +1177,15 @@ GDS_CLIENTS_handle_reply (struct GNUNET_TIME_Absolute expiration,
1173 size_t msize; 1177 size_t msize;
1174 1178
1175 msize = sizeof(struct GNUNET_DHT_ClientResultMessage) + data_size 1179 msize = sizeof(struct GNUNET_DHT_ClientResultMessage) + data_size
1176 + (get_path_length + put_path_length) * sizeof(struct 1180 + (get_path_length + put_path_length)
1177 GNUNET_PeerIdentity); 1181 * sizeof(struct GNUNET_PeerIdentity);
1178 if (msize >= GNUNET_MAX_MESSAGE_SIZE) 1182 if (msize >= GNUNET_MAX_MESSAGE_SIZE)
1179 { 1183 {
1180 GNUNET_break (0); 1184 GNUNET_break (0);
1181 return; 1185 return;
1182 } 1186 }
1183 if (NULL == GNUNET_CONTAINER_multihashmap_get (forward_map,
1184 key))
1185 {
1186 LOG (GNUNET_ERROR_TYPE_DEBUG,
1187 "No matching client for reply for key %s\n",
1188 GNUNET_h2s (key));
1189 GNUNET_STATISTICS_update (GDS_stats,
1190 gettext_noop (
1191 "# REPLIES ignored for CLIENTS (no match)"),
1192 1,
1193 GNUNET_NO);
1194 return; /* no matching request, fast exit! */
1195 }
1196 frc.expiration = expiration; 1187 frc.expiration = expiration;
1188 frc.query_hash = query_hash;
1197 frc.get_path = get_path; 1189 frc.get_path = get_path;
1198 frc.put_path = put_path; 1190 frc.put_path = put_path;
1199 frc.data = data; 1191 frc.data = data;
@@ -1204,10 +1196,20 @@ GDS_CLIENTS_handle_reply (struct GNUNET_TIME_Absolute expiration,
1204 LOG (GNUNET_ERROR_TYPE_DEBUG, 1196 LOG (GNUNET_ERROR_TYPE_DEBUG,
1205 "Forwarding reply for key %s to client\n", 1197 "Forwarding reply for key %s to client\n",
1206 GNUNET_h2s (key)); 1198 GNUNET_h2s (key));
1207 GNUNET_CONTAINER_multihashmap_get_multiple (forward_map, 1199 if (0 ==
1208 key, 1200 GNUNET_CONTAINER_multihashmap_get_multiple (forward_map,
1209 &forward_reply, 1201 key,
1210 &frc); 1202 &forward_reply,
1203 &frc))
1204 {
1205 LOG (GNUNET_ERROR_TYPE_DEBUG,
1206 "No matching client for reply for key %s\n",
1207 GNUNET_h2s (key));
1208 GNUNET_STATISTICS_update (GDS_stats,
1209 "# REPLIES ignored for CLIENTS (no match)",
1210 1,
1211 GNUNET_NO);
1212 }
1211} 1213}
1212 1214
1213 1215
@@ -1285,20 +1287,6 @@ GDS_CLIENTS_process_get (uint32_t options,
1285} 1287}
1286 1288
1287 1289
1288/**
1289 * Check if some client is monitoring GET RESP messages and notify
1290 * them in that case.
1291 *
1292 * @param type The type of data in the result.
1293 * @param get_path Peers on GET path (or NULL if not recorded).
1294 * @param get_path_length number of entries in get_path.
1295 * @param put_path peers on the PUT path (or NULL if not recorded).
1296 * @param put_path_length number of entries in get_path.
1297 * @param exp Expiration time of the data.
1298 * @param key Key of the data.
1299 * @param data Pointer to the result data.
1300 * @param size Number of bytes in @a data.
1301 */
1302void 1290void
1303GDS_CLIENTS_process_get_resp (enum GNUNET_BLOCK_Type type, 1291GDS_CLIENTS_process_get_resp (enum GNUNET_BLOCK_Type type,
1304 const struct GNUNET_PeerIdentity *get_path, 1292 const struct GNUNET_PeerIdentity *get_path,
diff --git a/src/dht/gnunet-service-dht_datacache.c b/src/dht/gnunet-service-dht_datacache.c
index 7eded2152..8645ea069 100644
--- a/src/dht/gnunet-service-dht_datacache.c
+++ b/src/dht/gnunet-service-dht_datacache.c
@@ -158,7 +158,7 @@ struct GetRequestContext
158 * @return #GNUNET_OK to continue iteration, anything else 158 * @return #GNUNET_OK to continue iteration, anything else
159 * to stop iteration. 159 * to stop iteration.
160 */ 160 */
161static int 161static enum GNUNET_GenericReturnValue
162datacache_get_iterator (void *cls, 162datacache_get_iterator (void *cls,
163 const struct GNUNET_HashCode *key, 163 const struct GNUNET_HashCode *key,
164 size_t data_size, 164 size_t data_size,
@@ -170,7 +170,7 @@ datacache_get_iterator (void *cls,
170{ 170{
171 static char non_null; 171 static char non_null;
172 struct GetRequestContext *ctx = cls; 172 struct GetRequestContext *ctx = cls;
173 enum GNUNET_BLOCK_EvaluationResult eval; 173 enum GNUNET_BLOCK_ReplyEvaluationResult eval;
174 174
175 if (0 == GNUNET_TIME_absolute_get_remaining (exp).rel_value_us) 175 if (0 == GNUNET_TIME_absolute_get_remaining (exp).rel_value_us)
176 { 176 {
@@ -182,15 +182,14 @@ datacache_get_iterator (void *cls,
182 data = &non_null; /* point anywhere, but not to NULL */ 182 data = &non_null; /* point anywhere, but not to NULL */
183 183
184 eval 184 eval
185 = GNUNET_BLOCK_evaluate (GDS_block_context, 185 = GNUNET_BLOCK_check_reply (GDS_block_context,
186 type, 186 type,
187 ctx->bg, 187 ctx->bg,
188 GNUNET_BLOCK_EO_LOCAL_SKIP_CRYPTO, 188 key,
189 key, 189 ctx->xquery,
190 ctx->xquery, 190 ctx->xquery_size,
191 ctx->xquery_size, 191 data,
192 data, 192 data_size);
193 data_size);
194 LOG (GNUNET_ERROR_TYPE_DEBUG, 193 LOG (GNUNET_ERROR_TYPE_DEBUG,
195 "Found reply for query %s in datacache, evaluation result is %d\n", 194 "Found reply for query %s in datacache, evaluation result is %d\n",
196 GNUNET_h2s (key), 195 GNUNET_h2s (key),
@@ -198,12 +197,13 @@ datacache_get_iterator (void *cls,
198 ctx->eval = eval; 197 ctx->eval = eval;
199 switch (eval) 198 switch (eval)
200 { 199 {
201 case GNUNET_BLOCK_EVALUATION_OK_MORE: 200 case GNUNET_BLOCK_REPLY_OK_MORE:
202 case GNUNET_BLOCK_EVALUATION_OK_LAST: 201 case GNUNET_BLOCK_REPLY_OK_LAST:
203 /* forward to local clients */ 202 case GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED:
203 /* forward to initiator */
204 GNUNET_STATISTICS_update (GDS_stats, 204 GNUNET_STATISTICS_update (GDS_stats,
205 gettext_noop 205 "# Good RESULTS found in datacache",
206 ("# Good RESULTS found in datacache"), 1, 206 1,
207 GNUNET_NO); 207 GNUNET_NO);
208 ctx->gc (ctx->gc_cls, 208 ctx->gc (ctx->gc_cls,
209 type, 209 type,
@@ -213,51 +213,27 @@ datacache_get_iterator (void *cls,
213 0, NULL, 213 0, NULL,
214 data, data_size); 214 data, data_size);
215 break; 215 break;
216 216 case GNUNET_BLOCK_REPLY_OK_DUPLICATE:
217 case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE:
218 GNUNET_STATISTICS_update (GDS_stats, 217 GNUNET_STATISTICS_update (GDS_stats,
219 gettext_noop ( 218 "# Duplicate RESULTS found in datacache",
220 "# Duplicate RESULTS found in datacache"),
221 1, 219 1,
222 GNUNET_NO); 220 GNUNET_NO);
223 break; 221 break;
224 222 case GNUNET_BLOCK_REPLY_INVALID:
225 case GNUNET_BLOCK_EVALUATION_RESULT_INVALID: 223 /* maybe it expired? */
226 GNUNET_STATISTICS_update (GDS_stats, 224 GNUNET_STATISTICS_update (GDS_stats,
227 gettext_noop ( 225 "# Invalid RESULTS found in datacache",
228 "# Invalid RESULTS found in datacache"),
229 1, 226 1,
230 GNUNET_NO); 227 GNUNET_NO);
231 break; 228 break;
232 229 case GNUNET_BLOCK_REPLY_IRRELEVANT:
233 case GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT:
234 GNUNET_STATISTICS_update (GDS_stats, 230 GNUNET_STATISTICS_update (GDS_stats,
235 gettext_noop ( 231 "# Irrelevant RESULTS found in datacache",
236 "# Irrelevant RESULTS found in datacache"),
237 1, 232 1,
238 GNUNET_NO); 233 GNUNET_NO);
239 break; 234 break;
240
241 case GNUNET_BLOCK_EVALUATION_REQUEST_VALID:
242 GNUNET_break (0);
243 break;
244
245 case GNUNET_BLOCK_EVALUATION_REQUEST_INVALID:
246 GNUNET_break_op (0);
247 return GNUNET_SYSERR;
248
249 case GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED:
250 GNUNET_STATISTICS_update (GDS_stats,
251 gettext_noop (
252 "# Unsupported RESULTS found in datacache"),
253 1,
254 GNUNET_NO);
255 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
256 _ ("Unsupported block type (%u) in local response!\n"),
257 type);
258 break;
259 } 235 }
260 return (eval == GNUNET_BLOCK_EVALUATION_OK_LAST) ? GNUNET_NO : GNUNET_OK; 236 return (eval == GNUNET_BLOCK_REPLY_OK_LAST) ? GNUNET_NO : GNUNET_OK;
261} 237}
262 238
263 239
diff --git a/src/dht/gnunet-service-dht_neighbours.c b/src/dht/gnunet-service-dht_neighbours.c
index fb061d5b1..75bdaed53 100644
--- a/src/dht/gnunet-service-dht_neighbours.c
+++ b/src/dht/gnunet-service-dht_neighbours.c
@@ -424,7 +424,7 @@ static struct GNUNET_ATS_ConnectivityHandle *ats_ch;
424 * Find the optimal bucket for this key. 424 * Find the optimal bucket for this key.
425 * 425 *
426 * @param hc the hashcode to compare our identity to 426 * @param hc the hashcode to compare our identity to
427 * @return the proper bucket index, or #GNUNET_SYSERR 427 * @return the proper bucket index, or -1
428 * on error (same hashcode) 428 * on error (same hashcode)
429 */ 429 */
430static int 430static int
@@ -437,7 +437,7 @@ find_bucket (const struct GNUNET_HashCode *hc)
437 { 437 {
438 /* How can all bits match? Got my own ID? */ 438 /* How can all bits match? Got my own ID? */
439 GNUNET_break (0); 439 GNUNET_break (0);
440 return GNUNET_SYSERR; 440 return -1;
441 } 441 }
442 return MAX_BUCKETS - bits - 1; 442 return MAX_BUCKETS - bits - 1;
443} 443}
@@ -466,7 +466,7 @@ offer_hello_done (void *cls)
466 * @param value the value to remove 466 * @param value the value to remove
467 * @return #GNUNET_YES 467 * @return #GNUNET_YES
468 */ 468 */
469static int 469static enum GNUNET_GenericReturnValue
470free_connect_info (void *cls, 470free_connect_info (void *cls,
471 const struct GNUNET_PeerIdentity *peer, 471 const struct GNUNET_PeerIdentity *peer,
472 void *value) 472 void *value)
@@ -580,7 +580,7 @@ try_connect (const struct GNUNET_PeerIdentity *pid,
580 * @param value unused 580 * @param value unused
581 * @return #GNUNET_YES (continue to iterate) 581 * @return #GNUNET_YES (continue to iterate)
582 */ 582 */
583static int 583static enum GNUNET_GenericReturnValue
584update_desire_strength (void *cls, 584update_desire_strength (void *cls,
585 const struct GNUNET_PeerIdentity *pid, 585 const struct GNUNET_PeerIdentity *pid,
586 void *value) 586 void *value)
@@ -600,7 +600,7 @@ update_desire_strength (void *cls,
600 * @param tc scheduler context. 600 * @param tc scheduler context.
601 */ 601 */
602static void 602static void
603update_connect_preferences () 603update_connect_preferences (void)
604{ 604{
605 GNUNET_CONTAINER_multipeermap_iterate (all_desired_peers, 605 GNUNET_CONTAINER_multipeermap_iterate (all_desired_peers,
606 &update_desire_strength, 606 &update_desire_strength,
@@ -617,7 +617,7 @@ update_connect_preferences ()
617 * @param value value the peer information (unused) 617 * @param value value the peer information (unused)
618 * @return #GNUNET_YES (we should continue to iterate) 618 * @return #GNUNET_YES (we should continue to iterate)
619 */ 619 */
620static int 620static enum GNUNET_GenericReturnValue
621add_known_to_bloom (void *cls, 621add_known_to_bloom (void *cls,
622 const struct GNUNET_PeerIdentity *key, 622 const struct GNUNET_PeerIdentity *key,
623 void *value) 623 void *value)
@@ -680,7 +680,7 @@ send_find_peer_message (void *cls)
680 &add_known_to_bloom, 680 &add_known_to_bloom,
681 bg); 681 bg);
682 GNUNET_STATISTICS_update (GDS_stats, 682 GNUNET_STATISTICS_update (GDS_stats,
683 gettext_noop ("# FIND PEER messages initiated"), 683 "# FIND PEER messages initiated",
684 1, 684 1,
685 GNUNET_NO); 685 GNUNET_NO);
686 peer_bf 686 peer_bf
@@ -932,7 +932,7 @@ get_distance (const struct GNUNET_HashCode *target,
932 * @return #GNUNET_YES if node location is closest, 932 * @return #GNUNET_YES if node location is closest,
933 * #GNUNET_NO otherwise. 933 * #GNUNET_NO otherwise.
934 */ 934 */
935int 935enum GNUNET_GenericReturnValue
936GDS_am_closest_peer (const struct GNUNET_HashCode *key, 936GDS_am_closest_peer (const struct GNUNET_HashCode *key,
937 const struct GNUNET_CONTAINER_BloomFilter *bloom) 937 const struct GNUNET_CONTAINER_BloomFilter *bloom)
938{ 938{
@@ -1222,7 +1222,7 @@ get_target_peers (const struct GNUNET_HashCode *key,
1222 * @param data_size number of bytes in @a data 1222 * @param data_size number of bytes in @a data
1223 * @return #GNUNET_OK if the request was forwarded, #GNUNET_NO if not 1223 * @return #GNUNET_OK if the request was forwarded, #GNUNET_NO if not
1224 */ 1224 */
1225int 1225enum GNUNET_GenericReturnValue
1226GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type, 1226GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type,
1227 enum GNUNET_DHT_RouteOption options, 1227 enum GNUNET_DHT_RouteOption options,
1228 uint32_t desired_replication_level, 1228 uint32_t desired_replication_level,
@@ -1359,7 +1359,7 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type,
1359 * @param peer_bf filter for peers not to select (again) 1359 * @param peer_bf filter for peers not to select (again)
1360 * @return #GNUNET_OK if the request was forwarded, #GNUNET_NO if not 1360 * @return #GNUNET_OK if the request was forwarded, #GNUNET_NO if not
1361 */ 1361 */
1362int 1362enum GNUNET_GenericReturnValue
1363GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type, 1363GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type,
1364 enum GNUNET_DHT_RouteOption options, 1364 enum GNUNET_DHT_RouteOption options,
1365 uint32_t desired_replication_level, 1365 uint32_t desired_replication_level,
@@ -1614,7 +1614,7 @@ core_init (void *cls,
1614 * @param message message 1614 * @param message message
1615 * @return #GNUNET_OK if the message is valid 1615 * @return #GNUNET_OK if the message is valid
1616 */ 1616 */
1617static int 1617static enum GNUNET_GenericReturnValue
1618check_dht_p2p_put (void *cls, 1618check_dht_p2p_put (void *cls,
1619 const struct PeerPutMessage *put) 1619 const struct PeerPutMessage *put)
1620{ 1620{
@@ -1655,12 +1655,11 @@ handle_dht_p2p_put (void *cls,
1655 size_t payload_size; 1655 size_t payload_size;
1656 enum GNUNET_DHT_RouteOption options; 1656 enum GNUNET_DHT_RouteOption options;
1657 struct GNUNET_CONTAINER_BloomFilter *bf; 1657 struct GNUNET_CONTAINER_BloomFilter *bf;
1658 struct GNUNET_HashCode test_key;
1659 int forwarded; 1658 int forwarded;
1660 struct GNUNET_TIME_Absolute exp_time; 1659 struct GNUNET_TIME_Absolute exp_time;
1661 1660
1662 exp_time = GNUNET_TIME_absolute_ntoh (put->expiration_time); 1661 exp_time = GNUNET_TIME_absolute_ntoh (put->expiration_time);
1663 if (0 == GNUNET_TIME_absolute_get_remaining (exp_time).rel_value_us) 1662 if (GNUNET_TIME_absolute_is_past (exp_time))
1664 { 1663 {
1665 GNUNET_STATISTICS_update (GDS_stats, 1664 GNUNET_STATISTICS_update (GDS_stats,
1666 gettext_noop ("# Expired PUTs discarded"), 1665 gettext_noop ("# Expired PUTs discarded"),
@@ -1710,63 +1709,44 @@ handle_dht_p2p_put (void *cls,
1710 GNUNET_free (pp); 1709 GNUNET_free (pp);
1711 GNUNET_free (tmp); 1710 GNUNET_free (tmp);
1712 } 1711 }
1713 switch (GNUNET_BLOCK_get_key 1712
1714 (GDS_block_context,
1715 ntohl (put->type),
1716 payload,
1717 payload_size,
1718 &test_key))
1719 { 1713 {
1720 case GNUNET_YES: 1714 struct GNUNET_HashCode test_key;
1721 if (0 != memcmp (&test_key, 1715 enum GNUNET_GenericReturnValue ret;
1722 &put->key,
1723 sizeof(struct GNUNET_HashCode)))
1724 {
1725 char *put_s = GNUNET_strdup (GNUNET_h2s_full (&put->key));
1726 1716
1717 ret = GNUNET_BLOCK_get_key (GDS_block_context,
1718 ntohl (put->type),
1719 payload,
1720 payload_size,
1721 &test_key);
1722 switch (ret)
1723 {
1724 case GNUNET_YES:
1725 if (0 != GNUNET_memcmp (&test_key,
1726 &put->key))
1727 {
1728 GNUNET_break_op (0);
1729 return;
1730 }
1731 break;
1732 case GNUNET_NO:
1727 GNUNET_break_op (0); 1733 GNUNET_break_op (0);
1728 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1729 "PUT with key `%s' for block with key %s\n",
1730 put_s,
1731 GNUNET_h2s_full (&test_key));
1732 GNUNET_free (put_s);
1733 return; 1734 return;
1735 case GNUNET_SYSERR:
1736 /* cannot verify, good luck */
1737 break;
1734 } 1738 }
1735 break; 1739 }
1736 1740
1737 case GNUNET_NO: 1741 if (GNUNET_NO ==
1742 GNUNET_BLOCK_check_block (GDS_block_context,
1743 ntohl (put->type),
1744 &put->key,
1745 payload,
1746 payload_size))
1747 {
1738 GNUNET_break_op (0); 1748 GNUNET_break_op (0);
1739 return; 1749 return;
1740
1741 case GNUNET_SYSERR:
1742 /* cannot verify, good luck */
1743 break;
1744 }
1745 if (ntohl (put->type) == GNUNET_BLOCK_TYPE_REGEX) /* FIXME: do for all tpyes */
1746 {
1747 switch (GNUNET_BLOCK_evaluate (GDS_block_context,
1748 ntohl (put->type),
1749 NULL, /* query group */
1750 GNUNET_BLOCK_EO_NONE,
1751 NULL, /* query */
1752 NULL, 0, /* xquery */
1753 payload,
1754 payload_size))
1755 {
1756 case GNUNET_BLOCK_EVALUATION_OK_MORE:
1757 case GNUNET_BLOCK_EVALUATION_OK_LAST:
1758 break;
1759
1760 case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE:
1761 case GNUNET_BLOCK_EVALUATION_RESULT_INVALID:
1762 case GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT:
1763 case GNUNET_BLOCK_EVALUATION_REQUEST_VALID:
1764 case GNUNET_BLOCK_EVALUATION_REQUEST_INVALID:
1765 case GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED:
1766 default:
1767 GNUNET_break_op (0);
1768 return;
1769 }
1770 } 1750 }
1771 1751
1772 bf = GNUNET_CONTAINER_bloomfilter_init (put->bloomfilter, 1752 bf = GNUNET_CONTAINER_bloomfilter_init (put->bloomfilter,
@@ -1807,6 +1787,7 @@ handle_dht_p2p_put (void *cls,
1807 /* give to local clients */ 1787 /* give to local clients */
1808 GDS_CLIENTS_handle_reply (exp_time, 1788 GDS_CLIENTS_handle_reply (exp_time,
1809 &put->key, 1789 &put->key,
1790 &put->key,
1810 0, 1791 0,
1811 NULL, 1792 NULL,
1812 putlen, 1793 putlen,
@@ -1906,8 +1887,7 @@ handle_find_peer (const struct GNUNET_PeerIdentity *sender,
1906 else 1887 else
1907 { 1888 {
1908 GNUNET_STATISTICS_update (GDS_stats, 1889 GNUNET_STATISTICS_update (GDS_stats,
1909 gettext_noop ( 1890 "# FIND PEER requests ignored due to Bloomfilter",
1910 "# FIND PEER requests ignored due to Bloomfilter"),
1911 1, 1891 1,
1912 GNUNET_NO); 1892 GNUNET_NO);
1913 } 1893 }
@@ -1915,17 +1895,16 @@ handle_find_peer (const struct GNUNET_PeerIdentity *sender,
1915 else 1895 else
1916 { 1896 {
1917 GNUNET_STATISTICS_update (GDS_stats, 1897 GNUNET_STATISTICS_update (GDS_stats,
1918 gettext_noop ( 1898 "# FIND PEER requests ignored due to lack of HELLO",
1919 "# FIND PEER requests ignored due to lack of HELLO"),
1920 1, 1899 1,
1921 GNUNET_NO); 1900 GNUNET_NO);
1922 } 1901 }
1923 1902
1924 /* then, also consider sending a random HELLO from the closest bucket */ 1903 /* then, also consider sending a random HELLO from the closest bucket */
1925 /* FIXME: How can this be true? Shouldnt we just do find_bucket() ? */ 1904 /* FIXME: How can this be true? Shouldnt we just do find_bucket() ? */
1926 if (0 == memcmp (&my_identity_hash, 1905 if (0 ==
1927 key, 1906 GNUNET_memcmp (&my_identity_hash,
1928 sizeof(struct GNUNET_HashCode))) 1907 key))
1929 bucket_idx = closest_bucket; 1908 bucket_idx = closest_bucket;
1930 else 1909 else
1931 bucket_idx = GNUNET_MIN ((int) closest_bucket, 1910 bucket_idx = GNUNET_MIN ((int) closest_bucket,
@@ -2005,15 +1984,17 @@ handle_local_result (void *cls,
2005 size_t data_size) 1984 size_t data_size)
2006{ 1985{
2007 struct PeerInfo *peer = cls; 1986 struct PeerInfo *peer = cls;
2008 char *pp; 1987 {
1988 char *pp;
2009 1989
2010 pp = GNUNET_STRINGS_pp2s (put_path, 1990 pp = GNUNET_STRINGS_pp2s (put_path,
2011 put_path_length); 1991 put_path_length);
2012 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1992 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2013 "Found local result for %s (PP: %s)\n", 1993 "Found local result for %s (PP: %s)\n",
2014 GNUNET_h2s (key), 1994 GNUNET_h2s (key),
2015 pp); 1995 pp);
2016 GNUNET_free (pp); 1996 GNUNET_free (pp);
1997 }
2017 GDS_NEIGHBOURS_handle_reply (peer->id, 1998 GDS_NEIGHBOURS_handle_reply (peer->id,
2018 type, 1999 type,
2019 expiration_time, 2000 expiration_time,
@@ -2031,7 +2012,7 @@ handle_local_result (void *cls,
2031 * @param get the message 2012 * @param get the message
2032 * @return #GNUNET_OK if the message is well-formed 2013 * @return #GNUNET_OK if the message is well-formed
2033 */ 2014 */
2034static int 2015static enum GNUNET_GenericReturnValue
2035check_dht_p2p_get (void *cls, 2016check_dht_p2p_get (void *cls,
2036 const struct PeerGetMessage *get) 2017 const struct PeerGetMessage *get)
2037{ 2018{
@@ -2066,11 +2047,11 @@ handle_dht_p2p_get (void *cls,
2066 uint16_t msize; 2047 uint16_t msize;
2067 enum GNUNET_BLOCK_Type type; 2048 enum GNUNET_BLOCK_Type type;
2068 enum GNUNET_DHT_RouteOption options; 2049 enum GNUNET_DHT_RouteOption options;
2069 enum GNUNET_BLOCK_EvaluationResult eval; 2050 enum GNUNET_BLOCK_ReplyEvaluationResult eval = GNUNET_BLOCK_REPLY_OK_MORE;
2070 struct GNUNET_BLOCK_Group *bg; 2051 struct GNUNET_BLOCK_Group *bg;
2071 struct GNUNET_CONTAINER_BloomFilter *peer_bf; 2052 struct GNUNET_CONTAINER_BloomFilter *peer_bf;
2072 const char *xquery; 2053 const void *xquery;
2073 int forwarded; 2054 enum GNUNET_GenericReturnValue forwarded;
2074 2055
2075 /* parse and validate message */ 2056 /* parse and validate message */
2076 msize = ntohs (get->header.size); 2057 msize = ntohs (get->header.size);
@@ -2078,7 +2059,7 @@ handle_dht_p2p_get (void *cls,
2078 reply_bf_size = msize - (sizeof(struct PeerGetMessage) + xquery_size); 2059 reply_bf_size = msize - (sizeof(struct PeerGetMessage) + xquery_size);
2079 type = ntohl (get->type); 2060 type = ntohl (get->type);
2080 options = ntohl (get->options); 2061 options = ntohl (get->options);
2081 xquery = (const char *) &get[1]; 2062 xquery = (const void *) &get[1];
2082 GNUNET_STATISTICS_update (GDS_stats, 2063 GNUNET_STATISTICS_update (GDS_stats,
2083 gettext_noop ("# P2P GET requests received"), 2064 gettext_noop ("# P2P GET requests received"),
2084 1, 2065 1,
@@ -2103,23 +2084,18 @@ handle_dht_p2p_get (void *cls,
2103 GNUNET_CRYPTO_hash_matching_bits (&my_identity_hash, 2084 GNUNET_CRYPTO_hash_matching_bits (&my_identity_hash,
2104 &get->key), 2085 &get->key),
2105 ntohl (get->xquery_size), 2086 ntohl (get->xquery_size),
2106 xquery); 2087 (const char *) xquery);
2107 GNUNET_free (tmp); 2088 GNUNET_free (tmp);
2108 } 2089 }
2109 eval 2090 if (GNUNET_NO ==
2110 = GNUNET_BLOCK_evaluate (GDS_block_context, 2091 GNUNET_BLOCK_check_query (GDS_block_context,
2111 type, 2092 type,
2112 NULL, 2093 &get->key,
2113 GNUNET_BLOCK_EO_NONE, 2094 xquery,
2114 &get->key, 2095 xquery_size))
2115 xquery,
2116 xquery_size,
2117 NULL,
2118 0);
2119 if (eval != GNUNET_BLOCK_EVALUATION_REQUEST_VALID)
2120 { 2096 {
2121 /* request invalid or block type not supported */ 2097 /* request invalid */
2122 GNUNET_break_op (eval == GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED); 2098 GNUNET_break_op (0);
2123 return; 2099 return;
2124 } 2100 }
2125 peer_bf = GNUNET_CONTAINER_bloomfilter_init (get->bloomfilter, 2101 peer_bf = GNUNET_CONTAINER_bloomfilter_init (get->bloomfilter,
@@ -2131,7 +2107,7 @@ handle_dht_p2p_get (void *cls,
2131 bg = GNUNET_BLOCK_group_create (GDS_block_context, 2107 bg = GNUNET_BLOCK_group_create (GDS_block_context,
2132 type, 2108 type,
2133 get->bf_mutator, 2109 get->bf_mutator,
2134 &xquery[xquery_size], 2110 xquery + xquery_size,
2135 reply_bf_size, 2111 reply_bf_size,
2136 "filter-size", 2112 "filter-size",
2137 reply_bf_size, 2113 reply_bf_size,
@@ -2142,15 +2118,14 @@ handle_dht_p2p_get (void *cls,
2142 GNUNET_i2s (&my_identity), 2118 GNUNET_i2s (&my_identity),
2143 (unsigned int) ntohl (get->hop_count)); 2119 (unsigned int) ntohl (get->hop_count));
2144 /* local lookup (this may update the reply_bf) */ 2120 /* local lookup (this may update the reply_bf) */
2145 if ((0 != (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) || 2121 if ( (0 != (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) ||
2146 (GDS_am_closest_peer (&get->key, 2122 (GDS_am_closest_peer (&get->key,
2147 peer_bf))) 2123 peer_bf)) )
2148 { 2124 {
2149 if ((0 != (options & GNUNET_DHT_RO_FIND_PEER))) 2125 if ((0 != (options & GNUNET_DHT_RO_FIND_PEER)))
2150 { 2126 {
2151 GNUNET_STATISTICS_update (GDS_stats, 2127 GNUNET_STATISTICS_update (GDS_stats,
2152 gettext_noop ( 2128 "# P2P FIND PEER requests processed",
2153 "# P2P FIND PEER requests processed"),
2154 1, 2129 1,
2155 GNUNET_NO); 2130 GNUNET_NO);
2156 handle_find_peer (peer->id, 2131 handle_find_peer (peer->id,
@@ -2171,7 +2146,7 @@ handle_dht_p2p_get (void *cls,
2171 else 2146 else
2172 { 2147 {
2173 GNUNET_STATISTICS_update (GDS_stats, 2148 GNUNET_STATISTICS_update (GDS_stats,
2174 gettext_noop ("# P2P GET requests ONLY routed"), 2149 "# P2P GET requests ONLY routed",
2175 1, 2150 1,
2176 GNUNET_NO); 2151 GNUNET_NO);
2177 } 2152 }
@@ -2187,7 +2162,7 @@ handle_dht_p2p_get (void *cls,
2187 2162
2188 /* P2P forwarding */ 2163 /* P2P forwarding */
2189 forwarded = GNUNET_NO; 2164 forwarded = GNUNET_NO;
2190 if (eval != GNUNET_BLOCK_EVALUATION_OK_LAST) 2165 if (eval != GNUNET_BLOCK_REPLY_OK_LAST)
2191 forwarded = GDS_NEIGHBOURS_handle_get (type, 2166 forwarded = GDS_NEIGHBOURS_handle_get (type,
2192 options, 2167 options,
2193 ntohl ( 2168 ntohl (
@@ -2220,7 +2195,7 @@ handle_dht_p2p_get (void *cls,
2220 * @param message message 2195 * @param message message
2221 * @return #GNUNET_YES if the message is well-formed 2196 * @return #GNUNET_YES if the message is well-formed
2222 */ 2197 */
2223static int 2198static enum GNUNET_GenericReturnValue
2224check_dht_p2p_result (void *cls, 2199check_dht_p2p_result (void *cls,
2225 const struct PeerResultMessage *prm) 2200 const struct PeerResultMessage *prm)
2226{ 2201{
@@ -2252,7 +2227,8 @@ check_dht_p2p_result (void *cls,
2252 * Process a reply, after the @a get_path has been updated. 2227 * Process a reply, after the @a get_path has been updated.
2253 * 2228 *
2254 * @param expiration_time when does the reply expire 2229 * @param expiration_time when does the reply expire
2255 * @param key key matching the query 2230 * @param key key of the original inquiry
2231 * @param query_hash key matching the block
2256 * @param get_path_length number of entries in @a get_path 2232 * @param get_path_length number of entries in @a get_path
2257 * @param get_path path the reply has taken 2233 * @param get_path path the reply has taken
2258 * @param put_path_length number of entries in @a put_path 2234 * @param put_path_length number of entries in @a put_path
@@ -2264,6 +2240,7 @@ check_dht_p2p_result (void *cls,
2264static void 2240static void
2265process_reply_with_path (struct GNUNET_TIME_Absolute expiration_time, 2241process_reply_with_path (struct GNUNET_TIME_Absolute expiration_time,
2266 const struct GNUNET_HashCode *key, 2242 const struct GNUNET_HashCode *key,
2243 const struct GNUNET_HashCode *query_hash,
2267 unsigned int get_path_length, 2244 unsigned int get_path_length,
2268 const struct GNUNET_PeerIdentity *get_path, 2245 const struct GNUNET_PeerIdentity *get_path,
2269 unsigned int put_path_length, 2246 unsigned int put_path_length,
@@ -2275,6 +2252,7 @@ process_reply_with_path (struct GNUNET_TIME_Absolute expiration_time,
2275 /* forward to local clients */ 2252 /* forward to local clients */
2276 GDS_CLIENTS_handle_reply (expiration_time, 2253 GDS_CLIENTS_handle_reply (expiration_time,
2277 key, 2254 key,
2255 query_hash,
2278 get_path_length, 2256 get_path_length,
2279 get_path, 2257 get_path,
2280 put_path_length, 2258 put_path_length,
@@ -2288,7 +2266,7 @@ process_reply_with_path (struct GNUNET_TIME_Absolute expiration_time,
2288 put_path, 2266 put_path,
2289 put_path_length, 2267 put_path_length,
2290 expiration_time, 2268 expiration_time,
2291 key, 2269 query_hash,
2292 data, 2270 data,
2293 data_size); 2271 data_size);
2294 if (GNUNET_YES == cache_results) 2272 if (GNUNET_YES == cache_results)
@@ -2303,7 +2281,7 @@ process_reply_with_path (struct GNUNET_TIME_Absolute expiration_time,
2303 get_path_length * sizeof(struct GNUNET_PeerIdentity)); 2281 get_path_length * sizeof(struct GNUNET_PeerIdentity));
2304 2282
2305 GDS_DATACACHE_handle_put (expiration_time, 2283 GDS_DATACACHE_handle_put (expiration_time,
2306 key, 2284 query_hash,
2307 get_path_length + put_path_length, 2285 get_path_length + put_path_length,
2308 xput_path, 2286 xput_path,
2309 type, 2287 type,
@@ -2343,6 +2321,8 @@ handle_dht_p2p_result (void *cls,
2343 size_t data_size; 2321 size_t data_size;
2344 enum GNUNET_BLOCK_Type type; 2322 enum GNUNET_BLOCK_Type type;
2345 struct GNUNET_TIME_Absolute exp_time; 2323 struct GNUNET_TIME_Absolute exp_time;
2324 const struct GNUNET_HashCode *pquery;
2325 struct GNUNET_HashCode dquery;
2346 2326
2347 /* parse and validate message */ 2327 /* parse and validate message */
2348 exp_time = GNUNET_TIME_absolute_ntoh (prm->expiration_time); 2328 exp_time = GNUNET_TIME_absolute_ntoh (prm->expiration_time);
@@ -2363,8 +2343,8 @@ handle_dht_p2p_result (void *cls,
2363 data = (const void *) &get_path[get_path_length]; 2343 data = (const void *) &get_path[get_path_length];
2364 data_size = msize - (sizeof(struct PeerResultMessage) 2344 data_size = msize - (sizeof(struct PeerResultMessage)
2365 + (get_path_length 2345 + (get_path_length
2366 + put_path_length) * sizeof(struct 2346 + put_path_length)
2367 GNUNET_PeerIdentity)); 2347 * sizeof(struct GNUNET_PeerIdentity));
2368 GNUNET_STATISTICS_update (GDS_stats, 2348 GNUNET_STATISTICS_update (GDS_stats,
2369 gettext_noop ("# P2P RESULTS received"), 2349 gettext_noop ("# P2P RESULTS received"),
2370 1, 2350 1,
@@ -2373,6 +2353,31 @@ handle_dht_p2p_result (void *cls,
2373 gettext_noop ("# P2P RESULT bytes received"), 2353 gettext_noop ("# P2P RESULT bytes received"),
2374 msize, 2354 msize,
2375 GNUNET_NO); 2355 GNUNET_NO);
2356 {
2357 enum GNUNET_GenericReturnValue ret;
2358
2359 ret = GNUNET_BLOCK_get_key (GDS_block_context,
2360 type,
2361 data,
2362 data_size,
2363 &dquery);
2364 if (GNUNET_NO == ret)
2365 {
2366 GNUNET_break_op (0);
2367 return;
2368 }
2369 pquery = (GNUNET_OK == ret) ? &dquery : &prm->key;
2370 if (GNUNET_OK !=
2371 GNUNET_BLOCK_check_block (GDS_block_context,
2372 type,
2373 pquery,
2374 data,
2375 data_size))
2376 {
2377 GNUNET_break_op (0);
2378 return;
2379 }
2380 }
2376 if (GNUNET_YES == log_route_details_stderr) 2381 if (GNUNET_YES == log_route_details_stderr)
2377 { 2382 {
2378 char *tmp; 2383 char *tmp;
@@ -2421,9 +2426,8 @@ handle_dht_p2p_result (void *cls,
2421 return; 2426 return;
2422 } 2427 }
2423 if ((GNUNET_YES != disable_try_connect) && 2428 if ((GNUNET_YES != disable_try_connect) &&
2424 (0 != memcmp (&my_identity, 2429 (0 != GNUNET_memcmp (&my_identity,
2425 &pid, 2430 &pid)))
2426 sizeof(struct GNUNET_PeerIdentity))))
2427 try_connect (&pid, 2431 try_connect (&pid,
2428 h); 2432 h);
2429 } 2433 }
@@ -2431,12 +2435,12 @@ handle_dht_p2p_result (void *cls,
2431 /* First, check if 'peer' is already on the path, and if 2435 /* First, check if 'peer' is already on the path, and if
2432 so, truncate it instead of expanding. */ 2436 so, truncate it instead of expanding. */
2433 for (unsigned int i = 0; i <= get_path_length; i++) 2437 for (unsigned int i = 0; i <= get_path_length; i++)
2434 if (0 == memcmp (&get_path[i], 2438 if (0 == GNUNET_memcmp (&get_path[i],
2435 peer->id, 2439 peer->id))
2436 sizeof(struct GNUNET_PeerIdentity)))
2437 { 2440 {
2438 process_reply_with_path (exp_time, 2441 process_reply_with_path (exp_time,
2439 &prm->key, 2442 &prm->key,
2443 pquery,
2440 i, 2444 i,
2441 get_path, 2445 get_path,
2442 put_path_length, 2446 put_path_length,
@@ -2455,9 +2459,9 @@ handle_dht_p2p_result (void *cls,
2455 get_path, 2459 get_path,
2456 get_path_length * sizeof(struct GNUNET_PeerIdentity)); 2460 get_path_length * sizeof(struct GNUNET_PeerIdentity));
2457 xget_path[get_path_length] = *peer->id; 2461 xget_path[get_path_length] = *peer->id;
2458
2459 process_reply_with_path (exp_time, 2462 process_reply_with_path (exp_time,
2460 &prm->key, 2463 &prm->key,
2464 pquery,
2461 get_path_length + 1, 2465 get_path_length + 1,
2462 xget_path, 2466 xget_path,
2463 put_path_length, 2467 put_path_length,
@@ -2469,12 +2473,7 @@ handle_dht_p2p_result (void *cls,
2469} 2473}
2470 2474
2471 2475
2472/** 2476enum GNUNET_GenericReturnValue
2473 * Initialize neighbours subsystem.
2474 *
2475 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
2476 */
2477int
2478GDS_NEIGHBOURS_init () 2477GDS_NEIGHBOURS_init ()
2479{ 2478{
2480 struct GNUNET_MQ_MessageHandler core_handlers[] = { 2479 struct GNUNET_MQ_MessageHandler core_handlers[] = {
@@ -2528,9 +2527,6 @@ GDS_NEIGHBOURS_init ()
2528} 2527}
2529 2528
2530 2529
2531/**
2532 * Shutdown neighbours subsystem.
2533 */
2534void 2530void
2535GDS_NEIGHBOURS_done () 2531GDS_NEIGHBOURS_done ()
2536{ 2532{
@@ -2553,11 +2549,6 @@ GDS_NEIGHBOURS_done ()
2553} 2549}
2554 2550
2555 2551
2556/**
2557 * Get the ID of the local node.
2558 *
2559 * @return identity of the local node
2560 */
2561struct GNUNET_PeerIdentity * 2552struct GNUNET_PeerIdentity *
2562GDS_NEIGHBOURS_get_id () 2553GDS_NEIGHBOURS_get_id ()
2563{ 2554{
diff --git a/src/dht/gnunet-service-dht_routing.c b/src/dht/gnunet-service-dht_routing.c
index b05fb76d3..ef3aded77 100644
--- a/src/dht/gnunet-service-dht_routing.c
+++ b/src/dht/gnunet-service-dht_routing.c
@@ -62,11 +62,6 @@ struct RecentRequest
62 struct GNUNET_BLOCK_Group *bg; 62 struct GNUNET_BLOCK_Group *bg;
63 63
64 /** 64 /**
65 * Type of the requested block.
66 */
67 enum GNUNET_BLOCK_Type type;
68
69 /**
70 * extended query (see gnunet_block_lib.h). Allocated at the 65 * extended query (see gnunet_block_lib.h). Allocated at the
71 * end of this struct. 66 * end of this struct.
72 */ 67 */
@@ -78,6 +73,11 @@ struct RecentRequest
78 size_t xquery_size; 73 size_t xquery_size;
79 74
80 /** 75 /**
76 * Type of the requested block.
77 */
78 enum GNUNET_BLOCK_Type type;
79
80 /**
81 * Request options. 81 * Request options.
82 */ 82 */
83 enum GNUNET_DHT_RouteOption options; 83 enum GNUNET_DHT_RouteOption options;
@@ -148,17 +148,16 @@ struct ProcessContext
148 * @param cls the `struct ProcessContext` with the result 148 * @param cls the `struct ProcessContext` with the result
149 * @param key the query 149 * @param key the query
150 * @param value the `struct RecentRequest` with the request 150 * @param value the `struct RecentRequest` with the request
151 * @return #GNUNET_OK (continue to iterate), 151 * @return #GNUNET_OK (continue to iterate)
152 * #GNUNET_SYSERR if the result is malformed or type unsupported
153 */ 152 */
154static int 153static enum GNUNET_GenericReturnValue
155process (void *cls, 154process (void *cls,
156 const struct GNUNET_HashCode *key, 155 const struct GNUNET_HashCode *key,
157 void *value) 156 void *value)
158{ 157{
159 struct ProcessContext *pc = cls; 158 struct ProcessContext *pc = cls;
160 struct RecentRequest *rr = value; 159 struct RecentRequest *rr = value;
161 enum GNUNET_BLOCK_EvaluationResult eval; 160 enum GNUNET_BLOCK_ReplyEvaluationResult eval;
162 unsigned int gpl; 161 unsigned int gpl;
163 unsigned int ppl; 162 unsigned int ppl;
164 struct GNUNET_HashCode hc; 163 struct GNUNET_HashCode hc;
@@ -178,8 +177,11 @@ process (void *cls,
178 gpl = 0; 177 gpl = 0;
179 ppl = 0; 178 ppl = 0;
180 } 179 }
181 if ((0 != (rr->options & GNUNET_DHT_RO_FIND_PEER)) && 180 /* FIXME-SCHANZEN: should we modify FIND_PEER to
182 (pc->type == GNUNET_BLOCK_TYPE_DHT_HELLO)) 181 be a generic approximate search and not check
182 for the DHT_HELLO type here? */
183 if ( (0 != (rr->options & GNUNET_DHT_RO_FIND_PEER)) &&
184 (pc->type == GNUNET_BLOCK_TYPE_DHT_HELLO) )
183 { 185 {
184 /* key may not match HELLO, which is OK since 186 /* key may not match HELLO, which is OK since
185 * the search is approximate. Still, the evaluation 187 * the search is approximate. Still, the evaluation
@@ -197,15 +199,14 @@ process (void *cls,
197 eval_key = key; 199 eval_key = key;
198 } 200 }
199 eval 201 eval
200 = GNUNET_BLOCK_evaluate (GDS_block_context, 202 = GNUNET_BLOCK_check_reply (GDS_block_context,
201 pc->type, 203 pc->type,
202 rr->bg, 204 rr->bg,
203 GNUNET_BLOCK_EO_NONE, 205 eval_key,
204 eval_key, 206 rr->xquery,
205 rr->xquery, 207 rr->xquery_size,
206 rr->xquery_size, 208 pc->data,
207 pc->data, 209 pc->data_size);
208 pc->data_size);
209 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 210 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
210 "Result for %s of type %d was evaluated as %d\n", 211 "Result for %s of type %d was evaluated as %d\n",
211 GNUNET_h2s (key), 212 GNUNET_h2s (key),
@@ -213,12 +214,13 @@ process (void *cls,
213 eval); 214 eval);
214 switch (eval) 215 switch (eval)
215 { 216 {
216 case GNUNET_BLOCK_EVALUATION_OK_MORE: 217 case GNUNET_BLOCK_REPLY_OK_MORE:
217 case GNUNET_BLOCK_EVALUATION_OK_LAST: 218 case GNUNET_BLOCK_REPLY_OK_LAST:
219 case GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED:
218 GNUNET_STATISTICS_update (GDS_stats, 220 GNUNET_STATISTICS_update (GDS_stats,
219 gettext_noop 221 "# Good REPLIES matched against routing table",
220 ("# Good REPLIES matched against routing table"), 222 1,
221 1, GNUNET_NO); 223 GNUNET_NO);
222 GDS_NEIGHBOURS_handle_reply (&rr->peer, 224 GDS_NEIGHBOURS_handle_reply (&rr->peer,
223 pc->type, 225 pc->type,
224 pc->expiration_time, 226 pc->expiration_time,
@@ -228,50 +230,28 @@ process (void *cls,
228 pc->data, 230 pc->data,
229 pc->data_size); 231 pc->data_size);
230 break; 232 break;
231 233 case GNUNET_BLOCK_REPLY_OK_DUPLICATE:
232 case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE:
233 GNUNET_STATISTICS_update (GDS_stats, 234 GNUNET_STATISTICS_update (GDS_stats,
234 gettext_noop 235 "# Duplicate REPLIES matched against routing table",
235 ( 236 1,
236 "# Duplicate REPLIES matched against routing table"), 237 GNUNET_NO);
237 1, GNUNET_NO);
238 return GNUNET_OK; 238 return GNUNET_OK;
239 239 case GNUNET_BLOCK_REPLY_INVALID:
240 case GNUNET_BLOCK_EVALUATION_RESULT_INVALID:
241 GNUNET_STATISTICS_update (GDS_stats,
242 gettext_noop
243 (
244 "# Invalid REPLIES matched against routing table"),
245 1, GNUNET_NO);
246 return GNUNET_SYSERR;
247
248 case GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT:
249 GNUNET_STATISTICS_update (GDS_stats,
250 gettext_noop
251 (
252 "# Irrelevant REPLIES matched against routing table"),
253 1, GNUNET_NO);
254 return GNUNET_OK;
255
256 case GNUNET_BLOCK_EVALUATION_REQUEST_VALID:
257 GNUNET_break (0);
258 return GNUNET_OK;
259
260 case GNUNET_BLOCK_EVALUATION_REQUEST_INVALID:
261 GNUNET_break (0); 240 GNUNET_break (0);
241 GNUNET_STATISTICS_update (GDS_stats,
242 "# Invalid REPLIES matched against routing table",
243 1,
244 GNUNET_NO);
262 return GNUNET_OK; 245 return GNUNET_OK;
263 246 case GNUNET_BLOCK_REPLY_IRRELEVANT:
264 case GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED:
265 GNUNET_STATISTICS_update (GDS_stats, 247 GNUNET_STATISTICS_update (GDS_stats,
266 gettext_noop 248 "# Irrelevant REPLIES matched against routing table",
267 ( 249 1,
268 "# Unsupported REPLIES matched against routing table"), 250 GNUNET_NO);
269 1, GNUNET_NO); 251 return GNUNET_OK;
270 return GNUNET_SYSERR;
271
272 default: 252 default:
273 GNUNET_break (0); 253 GNUNET_break (0);
274 return GNUNET_SYSERR; 254 return GNUNET_OK;
275 } 255 }
276 return GNUNET_OK; 256 return GNUNET_OK;
277} 257}
@@ -281,7 +261,7 @@ process (void *cls,
281 * Handle a reply (route to origin). Only forwards the reply back to 261 * Handle a reply (route to origin). Only forwards the reply back to
282 * other peers waiting for it. Does not do local caching or 262 * other peers waiting for it. Does not do local caching or
283 * forwarding to local clients. Essentially calls 263 * forwarding to local clients. Essentially calls
284 * GDS_NEIGHBOURS_handle_reply for all peers that sent us a matching 264 * GDS_NEIGHBOURS_handle_reply() for all peers that sent us a matching
285 * request recently. 265 * request recently.
286 * 266 *
287 * @param type type of the block 267 * @param type type of the block
@@ -315,16 +295,6 @@ GDS_ROUTING_process (enum GNUNET_BLOCK_Type type,
315 pc.get_path = get_path; 295 pc.get_path = get_path;
316 pc.data = data; 296 pc.data = data;
317 pc.data_size = data_size; 297 pc.data_size = data_size;
318 if (NULL == data)
319 {
320 /* Some apps might have an 'empty' reply as a valid reply; however,
321 'process' will call GNUNET_BLOCK_evaluate' which treats a 'NULL'
322 reply as request-validation (but we need response-validation).
323 So we set 'data' to a 0-byte non-NULL value just to be sure */
324 GNUNET_break (0 == data_size);
325 pc.data_size = 0;
326 pc.data = ""; /* something not null */
327 }
328 GNUNET_CONTAINER_multihashmap_get_multiple (recent_map, 298 GNUNET_CONTAINER_multihashmap_get_multiple (recent_map,
329 key, 299 key,
330 &process, 300 &process,
@@ -338,13 +308,13 @@ GDS_ROUTING_process (enum GNUNET_BLOCK_Type type,
338 * in the heap and hashmap. 308 * in the heap and hashmap.
339 */ 309 */
340static void 310static void
341expire_oldest_entry () 311expire_oldest_entry (void)
342{ 312{
343 struct RecentRequest *recent_req; 313 struct RecentRequest *recent_req;
344 314
345 GNUNET_STATISTICS_update (GDS_stats, 315 GNUNET_STATISTICS_update (GDS_stats,
346 gettext_noop 316 "# Entries removed from routing table",
347 ("# Entries removed from routing table"), 1, 317 1,
348 GNUNET_NO); 318 GNUNET_NO);
349 recent_req = GNUNET_CONTAINER_heap_peek (recent_heap); 319 recent_req = GNUNET_CONTAINER_heap_peek (recent_heap);
350 GNUNET_assert (recent_req != NULL); 320 GNUNET_assert (recent_req != NULL);
@@ -362,13 +332,13 @@ expire_oldest_entry ()
362 * Try to combine multiple recent requests for the same value 332 * Try to combine multiple recent requests for the same value
363 * (if they come from the same peer). 333 * (if they come from the same peer).
364 * 334 *
365 * @param cls the new 'struct RecentRequest' (to discard upon successful combination) 335 * @param cls the new `struct RecentRequest` (to discard upon successful combination)
366 * @param key the query 336 * @param key the query
367 * @param value the existing 'struct RecentRequest' (to update upon successful combination) 337 * @param value the existing 'struct RecentRequest' (to update upon successful combination)
368 * @return #GNUNET_OK (continue to iterate), 338 * @return #GNUNET_OK (continue to iterate),
369 * #GNUNET_SYSERR if the request was successfully combined 339 * #GNUNET_SYSERR if the request was successfully combined
370 */ 340 */
371static int 341static enum GNUNET_GenericReturnValue
372try_combine_recent (void *cls, 342try_combine_recent (void *cls,
373 const struct GNUNET_HashCode *key, 343 const struct GNUNET_HashCode *key,
374 void *value) 344 void *value)
@@ -419,7 +389,7 @@ GDS_ROUTING_add (const struct GNUNET_PeerIdentity *sender,
419 while (GNUNET_CONTAINER_heap_get_size (recent_heap) >= DHT_MAX_RECENT) 389 while (GNUNET_CONTAINER_heap_get_size (recent_heap) >= DHT_MAX_RECENT)
420 expire_oldest_entry (); 390 expire_oldest_entry ();
421 GNUNET_STATISTICS_update (GDS_stats, 391 GNUNET_STATISTICS_update (GDS_stats,
422 gettext_noop ("# Entries added to routing table"), 392 "# Entries added to routing table",
423 1, 393 1,
424 GNUNET_NO); 394 GNUNET_NO);
425 recent_req = GNUNET_malloc (sizeof(struct RecentRequest) + xquery_size); 395 recent_req = GNUNET_malloc (sizeof(struct RecentRequest) + xquery_size);
diff --git a/src/include/gnunet_block_lib.h b/src/include/gnunet_block_lib.h
index 25569c59e..5640209a6 100644
--- a/src/include/gnunet_block_lib.h
+++ b/src/include/gnunet_block_lib.h
@@ -339,7 +339,7 @@ GNUNET_BLOCK_group_create (struct GNUNET_BLOCK_Context *ctx,
339 * @return #GNUNET_OK on success, #GNUNET_NO if serialization is not 339 * @return #GNUNET_OK on success, #GNUNET_NO if serialization is not
340 * supported, #GNUNET_SYSERR on error 340 * supported, #GNUNET_SYSERR on error
341 */ 341 */
342int 342enum GNUNET_GenericReturnValue
343GNUNET_BLOCK_group_serialize (struct GNUNET_BLOCK_Group *bg, 343GNUNET_BLOCK_group_serialize (struct GNUNET_BLOCK_Group *bg,
344 uint32_t *nonce, 344 uint32_t *nonce,
345 void **raw_data, 345 void **raw_data,
@@ -424,11 +424,11 @@ GNUNET_BLOCK_check_reply (struct GNUNET_BLOCK_Context *ctx,
424 * #GNUNET_SYSERR if @a type is not supported 424 * #GNUNET_SYSERR if @a type is not supported
425 */ 425 */
426enum GNUNET_GenericReturnValue 426enum GNUNET_GenericReturnValue
427GNUNET_BLOCK_check_request (struct GNUNET_BLOCK_Context *ctx, 427GNUNET_BLOCK_check_query (struct GNUNET_BLOCK_Context *ctx,
428 enum GNUNET_BLOCK_Type type, 428 enum GNUNET_BLOCK_Type type,
429 const struct GNUNET_HashCode *query, 429 const struct GNUNET_HashCode *query,
430 const void *xquery, 430 const void *xquery,
431 size_t xquery_size); 431 size_t xquery_size);
432 432
433 433
434/** 434/**