diff options
author | Christian Grothoff <christian@grothoff.org> | 2017-02-26 22:30:15 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2017-02-26 22:30:15 +0100 |
commit | e87663cf00dd102e8bb60f400db4bad6d82b3b6c (patch) | |
tree | 1bb6c6fbf6e8826bb063c880c1d064f2bb1dd422 /src/dht/gnunet-service-dht_neighbours.c | |
parent | fc44a16d5a5761fcc14c1de29daa3451be251edd (diff) | |
download | gnunet-e87663cf00dd102e8bb60f400db4bad6d82b3b6c.tar.gz gnunet-e87663cf00dd102e8bb60f400db4bad6d82b3b6c.zip |
make sure DHT does not pass around cyclic paths
Diffstat (limited to 'src/dht/gnunet-service-dht_neighbours.c')
-rw-r--r-- | src/dht/gnunet-service-dht_neighbours.c | 168 |
1 files changed, 105 insertions, 63 deletions
diff --git a/src/dht/gnunet-service-dht_neighbours.c b/src/dht/gnunet-service-dht_neighbours.c index 1b4082830..15071edca 100644 --- a/src/dht/gnunet-service-dht_neighbours.c +++ b/src/dht/gnunet-service-dht_neighbours.c | |||
@@ -2225,6 +2225,81 @@ check_dht_p2p_result (void *cls, | |||
2225 | 2225 | ||
2226 | 2226 | ||
2227 | /** | 2227 | /** |
2228 | * Process a reply, after the @a get_path has been updated. | ||
2229 | * | ||
2230 | * @param expiration_time when does the reply expire | ||
2231 | * @param key key matching the query | ||
2232 | * @param get_path_length number of entries in @a get_path | ||
2233 | * @param get_path path the reply has taken | ||
2234 | * @param put_path_length number of entries in @a put_path | ||
2235 | * @param put_path path the PUT has taken | ||
2236 | * @param type type of the block | ||
2237 | * @param data_size number of bytes in @a data | ||
2238 | * @param data payload of the reply | ||
2239 | */ | ||
2240 | static void | ||
2241 | process_reply_with_path (struct GNUNET_TIME_Absolute expiration_time, | ||
2242 | const struct GNUNET_HashCode *key, | ||
2243 | unsigned int get_path_length, | ||
2244 | const struct GNUNET_PeerIdentity *get_path, | ||
2245 | unsigned int put_path_length, | ||
2246 | const struct GNUNET_PeerIdentity *put_path, | ||
2247 | enum GNUNET_BLOCK_Type type, | ||
2248 | size_t data_size, | ||
2249 | const void *data) | ||
2250 | { | ||
2251 | /* forward to local clients */ | ||
2252 | GDS_CLIENTS_handle_reply (expiration_time, | ||
2253 | key, | ||
2254 | get_path_length, | ||
2255 | get_path, | ||
2256 | put_path_length, | ||
2257 | put_path, | ||
2258 | type, | ||
2259 | data_size, | ||
2260 | data); | ||
2261 | GDS_CLIENTS_process_get_resp (type, | ||
2262 | get_path, | ||
2263 | get_path_length, | ||
2264 | put_path, | ||
2265 | put_path_length, | ||
2266 | expiration_time, | ||
2267 | key, | ||
2268 | data, | ||
2269 | data_size); | ||
2270 | if (GNUNET_YES == cache_results) | ||
2271 | { | ||
2272 | struct GNUNET_PeerIdentity xput_path[get_path_length + 1 + put_path_length]; | ||
2273 | |||
2274 | GNUNET_memcpy (xput_path, | ||
2275 | put_path, | ||
2276 | put_path_length * sizeof (struct GNUNET_PeerIdentity)); | ||
2277 | GNUNET_memcpy (&xput_path[put_path_length], | ||
2278 | get_path, | ||
2279 | get_path_length * sizeof (struct GNUNET_PeerIdentity)); | ||
2280 | |||
2281 | GDS_DATACACHE_handle_put (expiration_time, | ||
2282 | key, | ||
2283 | get_path_length + put_path_length, | ||
2284 | xput_path, | ||
2285 | type, | ||
2286 | data_size, | ||
2287 | data); | ||
2288 | } | ||
2289 | /* forward to other peers */ | ||
2290 | GDS_ROUTING_process (type, | ||
2291 | expiration_time, | ||
2292 | key, | ||
2293 | put_path_length, | ||
2294 | put_path, | ||
2295 | get_path_length, | ||
2296 | get_path, | ||
2297 | data, | ||
2298 | data_size); | ||
2299 | } | ||
2300 | |||
2301 | |||
2302 | /** | ||
2228 | * Core handler for p2p result messages. | 2303 | * Core handler for p2p result messages. |
2229 | * | 2304 | * |
2230 | * @param cls closure | 2305 | * @param cls closure |
@@ -2318,77 +2393,44 @@ handle_dht_p2p_result (void *cls, | |||
2318 | h); | 2393 | h); |
2319 | } | 2394 | } |
2320 | 2395 | ||
2321 | /* append 'peer' to 'get_path' */ | ||
2322 | { | ||
2323 | struct GNUNET_PeerIdentity xget_path[get_path_length + 1]; | ||
2324 | 2396 | ||
2325 | #if SANITY_CHECKS | 2397 | /* First, check if 'peer' is already on the path, and if |
2326 | for (unsigned int i=0;i<=get_path_length;i++) | 2398 | so, truncate it instead of expanding. */ |
2399 | for (unsigned int i=0;i<=get_path_length;i++) | ||
2400 | if (0 == memcmp (&get_path[i], | ||
2401 | peer->id, | ||
2402 | sizeof (struct GNUNET_PeerIdentity))) | ||
2327 | { | 2403 | { |
2328 | for (unsigned int j=0;j<i;j++) | 2404 | process_reply_with_path (GNUNET_TIME_absolute_ntoh (prm->expiration_time), |
2329 | { | 2405 | &prm->key, |
2330 | GNUNET_break (0 != memcmp (&get_path[i], | 2406 | i, |
2331 | &get_path[j], | 2407 | get_path, |
2332 | sizeof (struct GNUNET_PeerIdentity))); | 2408 | put_path_length, |
2333 | } | 2409 | put_path, |
2334 | GNUNET_break (0 != memcmp (&get_path[i], | 2410 | type, |
2335 | peer->id, | 2411 | data_size, |
2336 | sizeof (struct GNUNET_PeerIdentity))); | 2412 | data); |
2413 | return; | ||
2337 | } | 2414 | } |
2338 | #endif | 2415 | |
2416 | /* Need to append 'peer' to 'get_path' (normal case) */ | ||
2417 | { | ||
2418 | struct GNUNET_PeerIdentity xget_path[get_path_length + 1]; | ||
2419 | |||
2339 | GNUNET_memcpy (xget_path, | 2420 | GNUNET_memcpy (xget_path, |
2340 | get_path, | 2421 | get_path, |
2341 | get_path_length * sizeof (struct GNUNET_PeerIdentity)); | 2422 | get_path_length * sizeof (struct GNUNET_PeerIdentity)); |
2342 | xget_path[get_path_length] = *peer->id; | 2423 | xget_path[get_path_length] = *peer->id; |
2343 | get_path_length++; | ||
2344 | |||
2345 | /* forward to local clients */ | ||
2346 | GDS_CLIENTS_handle_reply (GNUNET_TIME_absolute_ntoh (prm->expiration_time), | ||
2347 | &prm->key, | ||
2348 | get_path_length, | ||
2349 | xget_path, | ||
2350 | put_path_length, | ||
2351 | put_path, | ||
2352 | type, | ||
2353 | data_size, | ||
2354 | data); | ||
2355 | GDS_CLIENTS_process_get_resp (type, | ||
2356 | xget_path, | ||
2357 | get_path_length, | ||
2358 | put_path, put_path_length, | ||
2359 | GNUNET_TIME_absolute_ntoh (prm->expiration_time), | ||
2360 | &prm->key, | ||
2361 | data, | ||
2362 | data_size); | ||
2363 | if (GNUNET_YES == cache_results) | ||
2364 | { | ||
2365 | struct GNUNET_PeerIdentity xput_path[get_path_length + 1 + put_path_length]; | ||
2366 | 2424 | ||
2367 | GNUNET_memcpy (xput_path, | 2425 | process_reply_with_path (GNUNET_TIME_absolute_ntoh (prm->expiration_time), |
2368 | put_path, | 2426 | &prm->key, |
2369 | put_path_length * sizeof (struct GNUNET_PeerIdentity)); | 2427 | get_path_length + 1, |
2370 | GNUNET_memcpy (&xput_path[put_path_length], | 2428 | xget_path, |
2371 | xget_path, | 2429 | put_path_length, |
2372 | get_path_length * sizeof (struct GNUNET_PeerIdentity)); | 2430 | put_path, |
2373 | 2431 | type, | |
2374 | GDS_DATACACHE_handle_put (GNUNET_TIME_absolute_ntoh (prm->expiration_time), | 2432 | data_size, |
2375 | &prm->key, | 2433 | data); |
2376 | get_path_length + put_path_length, | ||
2377 | xput_path, | ||
2378 | type, | ||
2379 | data_size, | ||
2380 | data); | ||
2381 | } | ||
2382 | /* forward to other peers */ | ||
2383 | GDS_ROUTING_process (type, | ||
2384 | GNUNET_TIME_absolute_ntoh (prm->expiration_time), | ||
2385 | &prm->key, | ||
2386 | put_path_length, | ||
2387 | put_path, | ||
2388 | get_path_length, | ||
2389 | xget_path, | ||
2390 | data, | ||
2391 | data_size); | ||
2392 | } | 2434 | } |
2393 | } | 2435 | } |
2394 | 2436 | ||