diff options
Diffstat (limited to 'src/transport/gnunet-service-transport_blacklist.c')
-rw-r--r-- | src/transport/gnunet-service-transport_blacklist.c | 611 |
1 files changed, 290 insertions, 321 deletions
diff --git a/src/transport/gnunet-service-transport_blacklist.c b/src/transport/gnunet-service-transport_blacklist.c index 4738cdc0f..7720e467f 100644 --- a/src/transport/gnunet-service-transport_blacklist.c +++ b/src/transport/gnunet-service-transport_blacklist.c | |||
@@ -162,8 +162,7 @@ static struct GNUNET_CONTAINER_MultiHashMap *blacklist; | |||
162 | * @param tc unused | 162 | * @param tc unused |
163 | */ | 163 | */ |
164 | static void | 164 | static void |
165 | do_blacklist_check (void *cls, | 165 | do_blacklist_check (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); |
166 | const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
167 | 166 | ||
168 | 167 | ||
169 | /** | 168 | /** |
@@ -174,8 +173,7 @@ do_blacklist_check (void *cls, | |||
174 | * @param client identification of the client | 173 | * @param client identification of the client |
175 | */ | 174 | */ |
176 | static void | 175 | static void |
177 | client_disconnect_notification (void *cls, | 176 | client_disconnect_notification (void *cls, struct GNUNET_SERVER_Client *client) |
178 | struct GNUNET_SERVER_Client *client) | ||
179 | { | 177 | { |
180 | struct Blacklisters *bl; | 178 | struct Blacklisters *bl; |
181 | struct GST_BlacklistCheck *bc; | 179 | struct GST_BlacklistCheck *bc; |
@@ -183,31 +181,28 @@ client_disconnect_notification (void *cls, | |||
183 | if (client == NULL) | 181 | if (client == NULL) |
184 | return; | 182 | return; |
185 | for (bl = bl_head; bl != NULL; bl = bl->next) | 183 | for (bl = bl_head; bl != NULL; bl = bl->next) |
184 | { | ||
185 | if (bl->client != client) | ||
186 | continue; | ||
187 | for (bc = bc_head; bc != NULL; bc = bc->next) | ||
186 | { | 188 | { |
187 | if (bl->client != client) | 189 | if (bc->bl_pos != bl) |
188 | continue; | 190 | continue; |
189 | for (bc = bc_head; bc != NULL; bc = bc->next) | 191 | bc->bl_pos = bl->next; |
190 | { | 192 | if (bc->th != NULL) |
191 | if (bc->bl_pos != bl) | 193 | { |
192 | continue; | 194 | GNUNET_CONNECTION_notify_transmit_ready_cancel (bc->th); |
193 | bc->bl_pos = bl->next; | 195 | bc->th = NULL; |
194 | if (bc->th != NULL) | 196 | } |
195 | { | 197 | if (bc->task == GNUNET_SCHEDULER_NO_TASK) |
196 | GNUNET_CONNECTION_notify_transmit_ready_cancel (bc->th); | 198 | bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, bc); |
197 | bc->th = NULL; | ||
198 | } | ||
199 | if (bc->task == GNUNET_SCHEDULER_NO_TASK) | ||
200 | bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, | ||
201 | bc); | ||
202 | break; | ||
203 | } | ||
204 | GNUNET_CONTAINER_DLL_remove (bl_head, | ||
205 | bl_tail, | ||
206 | bl); | ||
207 | GNUNET_SERVER_client_drop (bl->client); | ||
208 | GNUNET_free (bl); | ||
209 | break; | 199 | break; |
210 | } | 200 | } |
201 | GNUNET_CONTAINER_DLL_remove (bl_head, bl_tail, bl); | ||
202 | GNUNET_SERVER_client_drop (bl->client); | ||
203 | GNUNET_free (bl); | ||
204 | break; | ||
205 | } | ||
211 | } | 206 | } |
212 | 207 | ||
213 | 208 | ||
@@ -234,153 +229,152 @@ read_blacklist_file () | |||
234 | if (GNUNET_OK != | 229 | if (GNUNET_OK != |
235 | GNUNET_CONFIGURATION_get_value_filename (GST_cfg, | 230 | GNUNET_CONFIGURATION_get_value_filename (GST_cfg, |
236 | "TRANSPORT", | 231 | "TRANSPORT", |
237 | "BLACKLIST_FILE", | 232 | "BLACKLIST_FILE", &fn)) |
238 | &fn)) | 233 | { |
239 | { | ||
240 | #if DEBUG_TRANSPORT | 234 | #if DEBUG_TRANSPORT |
241 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 235 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
242 | "Option `%s' in section `%s' not specified!\n", | 236 | "Option `%s' in section `%s' not specified!\n", |
243 | "BLACKLIST_FILE", | 237 | "BLACKLIST_FILE", "TRANSPORT"); |
244 | "TRANSPORT"); | ||
245 | #endif | 238 | #endif |
246 | return; | 239 | return; |
247 | } | 240 | } |
248 | if (GNUNET_OK != GNUNET_DISK_file_test (fn)) | 241 | if (GNUNET_OK != GNUNET_DISK_file_test (fn)) |
249 | GNUNET_DISK_fn_write (fn, NULL, 0, | 242 | GNUNET_DISK_fn_write (fn, NULL, 0, |
250 | GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); | 243 | GNUNET_DISK_PERM_USER_READ | |
244 | GNUNET_DISK_PERM_USER_WRITE); | ||
251 | if (0 != STAT (fn, &frstat)) | 245 | if (0 != STAT (fn, &frstat)) |
252 | { | 246 | { |
253 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 247 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
254 | _("Could not read blacklist file `%s'\n"), | 248 | _("Could not read blacklist file `%s'\n"), fn); |
255 | fn); | 249 | GNUNET_free (fn); |
256 | GNUNET_free (fn); | 250 | return; |
257 | return; | 251 | } |
258 | } | ||
259 | if (frstat.st_size == 0) | 252 | if (frstat.st_size == 0) |
260 | { | 253 | { |
261 | #if DEBUG_TRANSPORT | 254 | #if DEBUG_TRANSPORT |
262 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 255 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
263 | _("Blacklist file `%s' is empty.\n"), | 256 | _("Blacklist file `%s' is empty.\n"), fn); |
264 | fn); | ||
265 | #endif | 257 | #endif |
266 | GNUNET_free (fn); | 258 | GNUNET_free (fn); |
267 | return; | 259 | return; |
268 | } | 260 | } |
269 | /* FIXME: use mmap */ | 261 | /* FIXME: use mmap */ |
270 | data = GNUNET_malloc_large (frstat.st_size); | 262 | data = GNUNET_malloc_large (frstat.st_size); |
271 | GNUNET_assert(data != NULL); | 263 | GNUNET_assert (data != NULL); |
272 | if (frstat.st_size != | 264 | if (frstat.st_size != GNUNET_DISK_fn_read (fn, data, frstat.st_size)) |
273 | GNUNET_DISK_fn_read (fn, data, frstat.st_size)) | 265 | { |
266 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
267 | _("Failed to read blacklist from `%s'\n"), fn); | ||
268 | GNUNET_free (fn); | ||
269 | GNUNET_free (data); | ||
270 | return; | ||
271 | } | ||
272 | entries_found = 0; | ||
273 | pos = 0; | ||
274 | while ((pos < frstat.st_size) && isspace ((unsigned char) data[pos])) | ||
275 | pos++; | ||
276 | while ((frstat.st_size >= sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)) && | ||
277 | (pos <= | ||
278 | frstat.st_size - sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded))) | ||
279 | { | ||
280 | colon_pos = pos; | ||
281 | while ((colon_pos < frstat.st_size) && | ||
282 | (data[colon_pos] != ':') && | ||
283 | (!isspace ((unsigned char) data[colon_pos]))) | ||
284 | colon_pos++; | ||
285 | if (colon_pos >= frstat.st_size) | ||
274 | { | 286 | { |
275 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 287 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
276 | _("Failed to read blacklist from `%s'\n"), | 288 | _ |
277 | fn); | 289 | ("Syntax error in blacklist file at offset %llu, giving up!\n"), |
290 | (unsigned long long) colon_pos); | ||
278 | GNUNET_free (fn); | 291 | GNUNET_free (fn); |
279 | GNUNET_free (data); | 292 | GNUNET_free (data); |
280 | return; | 293 | return; |
281 | } | 294 | } |
282 | entries_found = 0; | 295 | |
283 | pos = 0; | 296 | if (isspace ((unsigned char) data[colon_pos])) |
284 | while ((pos < frstat.st_size) && isspace ( (unsigned char) data[pos])) | ||
285 | pos++; | ||
286 | while ((frstat.st_size >= sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)) && | ||
287 | (pos <= frstat.st_size - sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded))) | ||
288 | { | 297 | { |
289 | colon_pos = pos; | 298 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
290 | while ( (colon_pos < frstat.st_size) && | 299 | _ |
291 | (data[colon_pos] != ':') && | 300 | ("Syntax error in blacklist file at offset %llu, skipping bytes.\n"), |
292 | (! isspace ( (unsigned char) data[colon_pos])) ) | 301 | (unsigned long long) colon_pos); |
293 | colon_pos++; | 302 | pos = colon_pos; |
294 | if (colon_pos >= frstat.st_size) | 303 | while ((pos < frstat.st_size) && isspace ((unsigned char) data[pos])) |
295 | { | 304 | pos++; |
296 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 305 | continue; |
297 | _("Syntax error in blacklist file at offset %llu, giving up!\n"), | 306 | } |
298 | (unsigned long long) colon_pos); | 307 | tsize = colon_pos - pos; |
299 | GNUNET_free (fn); | 308 | if ((pos >= frstat.st_size) || (pos + tsize >= frstat.st_size) || |
300 | GNUNET_free (data); | 309 | (tsize == 0)) |
301 | return; | 310 | { |
302 | } | 311 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
303 | 312 | _ | |
304 | if (isspace( (unsigned char) data[colon_pos])) | 313 | ("Syntax error in blacklist file at offset %llu, giving up!\n"), |
305 | { | 314 | (unsigned long long) colon_pos); |
306 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 315 | GNUNET_free (fn); |
307 | _("Syntax error in blacklist file at offset %llu, skipping bytes.\n"), | 316 | GNUNET_free (data); |
308 | (unsigned long long) colon_pos); | 317 | return; |
309 | pos = colon_pos; | 318 | } |
310 | while ((pos < frstat.st_size) && isspace ( (unsigned char) data[pos])) | ||
311 | pos++; | ||
312 | continue; | ||
313 | } | ||
314 | tsize = colon_pos - pos; | ||
315 | if ((pos >= frstat.st_size) || (pos + tsize >= frstat.st_size) || (tsize == 0)) | ||
316 | { | ||
317 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
318 | _("Syntax error in blacklist file at offset %llu, giving up!\n"), | ||
319 | (unsigned long long) colon_pos); | ||
320 | GNUNET_free (fn); | ||
321 | GNUNET_free (data); | ||
322 | return; | ||
323 | } | ||
324 | |||
325 | if (tsize < 1) | ||
326 | continue; | ||
327 | 319 | ||
328 | transport_name = GNUNET_malloc(tsize + 1); | 320 | if (tsize < 1) |
329 | memcpy(transport_name, &data[pos], tsize); | 321 | continue; |
330 | pos = colon_pos + 1; | 322 | |
323 | transport_name = GNUNET_malloc (tsize + 1); | ||
324 | memcpy (transport_name, &data[pos], tsize); | ||
325 | pos = colon_pos + 1; | ||
331 | #if DEBUG_TRANSPORT | 326 | #if DEBUG_TRANSPORT |
332 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 327 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
333 | "Read transport name `%s' in blacklist file.\n", | 328 | "Read transport name `%s' in blacklist file.\n", |
334 | transport_name); | 329 | transport_name); |
335 | #endif | 330 | #endif |
336 | memcpy (&enc, | 331 | memcpy (&enc, &data[pos], sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)); |
337 | &data[pos], | 332 | if (!isspace |
338 | sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)); | 333 | ((unsigned char) |
339 | if (! isspace ( (unsigned char) enc.encoding[sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1])) | 334 | enc.encoding[sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1])) |
340 | { | 335 | { |
341 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 336 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
342 | _("Syntax error in blacklist file at offset %llu, skipping bytes.\n"), | 337 | _ |
343 | (unsigned long long) pos); | 338 | ("Syntax error in blacklist file at offset %llu, skipping bytes.\n"), |
344 | pos++; | 339 | (unsigned long long) pos); |
345 | while ((pos < frstat.st_size) && (!isspace ( (unsigned char) data[pos]))) | 340 | pos++; |
346 | pos++; | 341 | while ((pos < frstat.st_size) && (!isspace ((unsigned char) data[pos]))) |
347 | GNUNET_free_non_null(transport_name); | ||
348 | continue; | ||
349 | } | ||
350 | enc.encoding[sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1] = '\0'; | ||
351 | if (GNUNET_OK != GNUNET_CRYPTO_hash_from_string ((char *) &enc, &pid.hashPubKey)) | ||
352 | { | ||
353 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
354 | _("Syntax error in blacklist file at offset %llu, skipping bytes `%s'.\n"), | ||
355 | (unsigned long long) pos, | ||
356 | &enc); | ||
357 | } | ||
358 | else | ||
359 | { | ||
360 | if (0 != memcmp (&pid, | ||
361 | &GST_my_identity, | ||
362 | sizeof (struct GNUNET_PeerIdentity))) | ||
363 | { | ||
364 | entries_found++; | ||
365 | GST_blacklist_add_peer (&pid, | ||
366 | transport_name); | ||
367 | } | ||
368 | else | ||
369 | { | ||
370 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
371 | _("Found myself `%s' in blacklist (useless, ignored)\n"), | ||
372 | GNUNET_i2s (&pid)); | ||
373 | } | ||
374 | } | ||
375 | pos = pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded); | ||
376 | GNUNET_free_non_null(transport_name); | ||
377 | while ((pos < frstat.st_size) && isspace ( (unsigned char) data[pos])) | ||
378 | pos++; | 342 | pos++; |
343 | GNUNET_free_non_null (transport_name); | ||
344 | continue; | ||
345 | } | ||
346 | enc.encoding[sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1] = '\0'; | ||
347 | if (GNUNET_OK != | ||
348 | GNUNET_CRYPTO_hash_from_string ((char *) &enc, &pid.hashPubKey)) | ||
349 | { | ||
350 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
351 | _ | ||
352 | ("Syntax error in blacklist file at offset %llu, skipping bytes `%s'.\n"), | ||
353 | (unsigned long long) pos, &enc); | ||
379 | } | 354 | } |
380 | GNUNET_STATISTICS_update (GST_stats, | 355 | else |
381 | "# Transport entries blacklisted", | 356 | { |
382 | entries_found, | 357 | if (0 != memcmp (&pid, |
383 | GNUNET_NO); | 358 | &GST_my_identity, sizeof (struct GNUNET_PeerIdentity))) |
359 | { | ||
360 | entries_found++; | ||
361 | GST_blacklist_add_peer (&pid, transport_name); | ||
362 | } | ||
363 | else | ||
364 | { | ||
365 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
366 | _("Found myself `%s' in blacklist (useless, ignored)\n"), | ||
367 | GNUNET_i2s (&pid)); | ||
368 | } | ||
369 | } | ||
370 | pos = pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded); | ||
371 | GNUNET_free_non_null (transport_name); | ||
372 | while ((pos < frstat.st_size) && isspace ((unsigned char) data[pos])) | ||
373 | pos++; | ||
374 | } | ||
375 | GNUNET_STATISTICS_update (GST_stats, | ||
376 | "# Transport entries blacklisted", | ||
377 | entries_found, GNUNET_NO); | ||
384 | GNUNET_free (data); | 378 | GNUNET_free (data); |
385 | GNUNET_free (fn); | 379 | GNUNET_free (fn); |
386 | } | 380 | } |
@@ -396,8 +390,7 @@ GST_blacklist_start (struct GNUNET_SERVER_Handle *server) | |||
396 | { | 390 | { |
397 | read_blacklist_file (); | 391 | read_blacklist_file (); |
398 | GNUNET_SERVER_disconnect_notify (server, | 392 | GNUNET_SERVER_disconnect_notify (server, |
399 | &client_disconnect_notification, | 393 | &client_disconnect_notification, NULL); |
400 | NULL); | ||
401 | } | 394 | } |
402 | 395 | ||
403 | 396 | ||
@@ -410,9 +403,7 @@ GST_blacklist_start (struct GNUNET_SERVER_Handle *server) | |||
410 | * @return GNUNET_OK (continue to iterate) | 403 | * @return GNUNET_OK (continue to iterate) |
411 | */ | 404 | */ |
412 | static int | 405 | static int |
413 | free_blacklist_entry (void *cls, | 406 | free_blacklist_entry (void *cls, const GNUNET_HashCode * key, void *value) |
414 | const GNUNET_HashCode *key, | ||
415 | void *value) | ||
416 | { | 407 | { |
417 | char *be = value; | 408 | char *be = value; |
418 | 409 | ||
@@ -428,13 +419,12 @@ void | |||
428 | GST_blacklist_stop () | 419 | GST_blacklist_stop () |
429 | { | 420 | { |
430 | if (NULL != blacklist) | 421 | if (NULL != blacklist) |
431 | { | 422 | { |
432 | GNUNET_CONTAINER_multihashmap_iterate (blacklist, | 423 | GNUNET_CONTAINER_multihashmap_iterate (blacklist, |
433 | &free_blacklist_entry, | 424 | &free_blacklist_entry, NULL); |
434 | NULL); | 425 | GNUNET_CONTAINER_multihashmap_destroy (blacklist); |
435 | GNUNET_CONTAINER_multihashmap_destroy (blacklist); | 426 | blacklist = NULL; |
436 | blacklist = NULL; | 427 | } |
437 | } | ||
438 | } | 428 | } |
439 | 429 | ||
440 | 430 | ||
@@ -447,9 +437,7 @@ GST_blacklist_stop () | |||
447 | * @return number of bytes copied to buf | 437 | * @return number of bytes copied to buf |
448 | */ | 438 | */ |
449 | static size_t | 439 | static size_t |
450 | transmit_blacklist_message (void *cls, | 440 | transmit_blacklist_message (void *cls, size_t size, void *buf) |
451 | size_t size, | ||
452 | void *buf) | ||
453 | { | 441 | { |
454 | struct GST_BlacklistCheck *bc = cls; | 442 | struct GST_BlacklistCheck *bc = cls; |
455 | struct Blacklisters *bl; | 443 | struct Blacklisters *bl; |
@@ -457,19 +445,18 @@ transmit_blacklist_message (void *cls, | |||
457 | 445 | ||
458 | bc->th = NULL; | 446 | bc->th = NULL; |
459 | if (size == 0) | 447 | if (size == 0) |
460 | { | 448 | { |
461 | GNUNET_assert (bc->task == GNUNET_SCHEDULER_NO_TASK); | 449 | GNUNET_assert (bc->task == GNUNET_SCHEDULER_NO_TASK); |
462 | bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, | 450 | bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, bc); |
463 | bc); | 451 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
464 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 452 | "Failed to send blacklist test for peer `%s' to client\n", |
465 | "Failed to send blacklist test for peer `%s' to client\n", | 453 | GNUNET_i2s (&bc->peer)); |
466 | GNUNET_i2s (&bc->peer)); | 454 | return 0; |
467 | return 0; | 455 | } |
468 | } | ||
469 | #if DEBUG_TRANSPORT | 456 | #if DEBUG_TRANSPORT |
470 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 457 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
471 | "Sending blacklist test for peer `%s' to client\n", | 458 | "Sending blacklist test for peer `%s' to client\n", |
472 | GNUNET_i2s (&bc->peer)); | 459 | GNUNET_i2s (&bc->peer)); |
473 | #endif | 460 | #endif |
474 | bl = bc->bl_pos; | 461 | bl = bc->bl_pos; |
475 | bm.header.size = htons (sizeof (struct BlacklistMessage)); | 462 | bm.header.size = htons (sizeof (struct BlacklistMessage)); |
@@ -490,8 +477,7 @@ transmit_blacklist_message (void *cls, | |||
490 | * @param tc unused | 477 | * @param tc unused |
491 | */ | 478 | */ |
492 | static void | 479 | static void |
493 | do_blacklist_check (void *cls, | 480 | do_blacklist_check (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
494 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
495 | { | 481 | { |
496 | struct GST_BlacklistCheck *bc = cls; | 482 | struct GST_BlacklistCheck *bc = cls; |
497 | struct Blacklisters *bl; | 483 | struct Blacklisters *bl; |
@@ -499,27 +485,25 @@ do_blacklist_check (void *cls, | |||
499 | bc->task = GNUNET_SCHEDULER_NO_TASK; | 485 | bc->task = GNUNET_SCHEDULER_NO_TASK; |
500 | bl = bc->bl_pos; | 486 | bl = bc->bl_pos; |
501 | if (bl == NULL) | 487 | if (bl == NULL) |
502 | { | 488 | { |
503 | #if DEBUG_TRANSPORT | 489 | #if DEBUG_TRANSPORT |
504 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 490 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
505 | "No other blacklist clients active, will allow neighbour `%s'\n", | 491 | "No other blacklist clients active, will allow neighbour `%s'\n", |
506 | GNUNET_i2s (&bc->peer)); | 492 | GNUNET_i2s (&bc->peer)); |
507 | #endif | 493 | #endif |
508 | bc->cont (bc->cont_cls, | 494 | bc->cont (bc->cont_cls, &bc->peer, GNUNET_OK); |
509 | &bc->peer, | 495 | GNUNET_free (bc); |
510 | GNUNET_OK); | 496 | return; |
511 | GNUNET_free (bc); | 497 | } |
512 | return; | 498 | if ((bl->bc != NULL) || (bl->waiting_for_reply != GNUNET_NO)) |
513 | } | 499 | return; /* someone else busy with this client */ |
514 | if ( (bl->bc != NULL) || | ||
515 | (bl->waiting_for_reply != GNUNET_NO) ) | ||
516 | return; /* someone else busy with this client */ | ||
517 | bl->bc = bc; | 500 | bl->bc = bc; |
518 | bc->th = GNUNET_SERVER_notify_transmit_ready (bl->client, | 501 | bc->th = GNUNET_SERVER_notify_transmit_ready (bl->client, |
519 | sizeof (struct BlacklistMessage), | 502 | sizeof (struct |
520 | GNUNET_TIME_UNIT_FOREVER_REL, | 503 | BlacklistMessage), |
521 | &transmit_blacklist_message, | 504 | GNUNET_TIME_UNIT_FOREVER_REL, |
522 | bc); | 505 | &transmit_blacklist_message, |
506 | bc); | ||
523 | } | 507 | } |
524 | 508 | ||
525 | 509 | ||
@@ -534,15 +518,13 @@ do_blacklist_check (void *cls, | |||
534 | */ | 518 | */ |
535 | static void | 519 | static void |
536 | confirm_or_drop_neighbour (void *cls, | 520 | confirm_or_drop_neighbour (void *cls, |
537 | const struct GNUNET_PeerIdentity *peer, | 521 | const struct GNUNET_PeerIdentity *peer, int allowed) |
538 | int allowed) | ||
539 | { | 522 | { |
540 | if (GNUNET_OK == allowed) | 523 | if (GNUNET_OK == allowed) |
541 | return; /* we're done */ | 524 | return; /* we're done */ |
542 | GNUNET_STATISTICS_update (GST_stats, | 525 | GNUNET_STATISTICS_update (GST_stats, |
543 | gettext_noop ("# disconnects due to blacklist"), | 526 | gettext_noop ("# disconnects due to blacklist"), |
544 | 1, | 527 | 1, GNUNET_NO); |
545 | GNUNET_NO); | ||
546 | GST_neighbours_force_disconnect (peer); | 528 | GST_neighbours_force_disconnect (peer); |
547 | } | 529 | } |
548 | 530 | ||
@@ -554,7 +536,7 @@ struct TestConnectionContext | |||
554 | { | 536 | { |
555 | /** | 537 | /** |
556 | * Is this the first neighbour we're checking? | 538 | * Is this the first neighbour we're checking? |
557 | */ | 539 | */ |
558 | int first; | 540 | int first; |
559 | 541 | ||
560 | /** | 542 | /** |
@@ -575,9 +557,9 @@ struct TestConnectionContext | |||
575 | */ | 557 | */ |
576 | static void | 558 | static void |
577 | test_connection_ok (void *cls, | 559 | test_connection_ok (void *cls, |
578 | const struct GNUNET_PeerIdentity *neighbour, | 560 | const struct GNUNET_PeerIdentity *neighbour, |
579 | const struct GNUNET_TRANSPORT_ATS_Information *ats, | 561 | const struct GNUNET_TRANSPORT_ATS_Information *ats, |
580 | uint32_t ats_count) | 562 | uint32_t ats_count) |
581 | { | 563 | { |
582 | struct TestConnectionContext *tcc = cls; | 564 | struct TestConnectionContext *tcc = cls; |
583 | struct GST_BlacklistCheck *bc; | 565 | struct GST_BlacklistCheck *bc; |
@@ -589,13 +571,12 @@ test_connection_ok (void *cls, | |||
589 | bc->cont_cls = NULL; | 571 | bc->cont_cls = NULL; |
590 | bc->bl_pos = tcc->bl; | 572 | bc->bl_pos = tcc->bl; |
591 | if (GNUNET_YES == tcc->first) | 573 | if (GNUNET_YES == tcc->first) |
592 | { | 574 | { |
593 | /* all would wait for the same client, no need to | 575 | /* all would wait for the same client, no need to |
594 | create more than just the first task right now */ | 576 | * create more than just the first task right now */ |
595 | bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, | 577 | bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, bc); |
596 | bc); | 578 | tcc->first = GNUNET_NO; |
597 | tcc->first = GNUNET_NO; | 579 | } |
598 | } | ||
599 | } | 580 | } |
600 | 581 | ||
601 | 582 | ||
@@ -611,23 +592,23 @@ test_connection_ok (void *cls, | |||
611 | */ | 592 | */ |
612 | void | 593 | void |
613 | GST_blacklist_handle_init (void *cls, | 594 | GST_blacklist_handle_init (void *cls, |
614 | struct GNUNET_SERVER_Client *client, | 595 | struct GNUNET_SERVER_Client *client, |
615 | const struct GNUNET_MessageHeader *message) | 596 | const struct GNUNET_MessageHeader *message) |
616 | { | 597 | { |
617 | struct Blacklisters *bl; | 598 | struct Blacklisters *bl; |
618 | struct TestConnectionContext tcc; | 599 | struct TestConnectionContext tcc; |
619 | 600 | ||
620 | bl = bl_head; | 601 | bl = bl_head; |
621 | while (bl != NULL) | 602 | while (bl != NULL) |
603 | { | ||
604 | if (bl->client == client) | ||
622 | { | 605 | { |
623 | if (bl->client == client) | 606 | GNUNET_break (0); |
624 | { | 607 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |
625 | GNUNET_break (0); | 608 | return; |
626 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
627 | return; | ||
628 | } | ||
629 | bl = bl->next; | ||
630 | } | 609 | } |
610 | bl = bl->next; | ||
611 | } | ||
631 | bl = GNUNET_malloc (sizeof (struct Blacklisters)); | 612 | bl = GNUNET_malloc (sizeof (struct Blacklisters)); |
632 | bl->client = client; | 613 | bl->client = client; |
633 | GNUNET_SERVER_client_keep (client); | 614 | GNUNET_SERVER_client_keep (client); |
@@ -636,8 +617,7 @@ GST_blacklist_handle_init (void *cls, | |||
636 | /* confirm that all existing connections are OK! */ | 617 | /* confirm that all existing connections are OK! */ |
637 | tcc.bl = bl; | 618 | tcc.bl = bl; |
638 | tcc.first = GNUNET_YES; | 619 | tcc.first = GNUNET_YES; |
639 | GST_neighbours_iterate (&test_connection_ok, | 620 | GST_neighbours_iterate (&test_connection_ok, &tcc); |
640 | &tcc); | ||
641 | } | 621 | } |
642 | 622 | ||
643 | 623 | ||
@@ -650,65 +630,61 @@ GST_blacklist_handle_init (void *cls, | |||
650 | */ | 630 | */ |
651 | void | 631 | void |
652 | GST_blacklist_handle_reply (void *cls, | 632 | GST_blacklist_handle_reply (void *cls, |
653 | struct GNUNET_SERVER_Client *client, | 633 | struct GNUNET_SERVER_Client *client, |
654 | const struct GNUNET_MessageHeader *message) | 634 | const struct GNUNET_MessageHeader *message) |
655 | { | 635 | { |
656 | const struct BlacklistMessage *msg = (const struct BlacklistMessage*) message; | 636 | const struct BlacklistMessage *msg = |
637 | (const struct BlacklistMessage *) message; | ||
657 | struct Blacklisters *bl; | 638 | struct Blacklisters *bl; |
658 | struct GST_BlacklistCheck *bc; | 639 | struct GST_BlacklistCheck *bc; |
659 | 640 | ||
660 | bl = bl_head; | 641 | bl = bl_head; |
661 | while ( (bl != NULL) && | 642 | while ((bl != NULL) && (bl->client != client)) |
662 | (bl->client != client) ) | ||
663 | bl = bl->next; | 643 | bl = bl->next; |
664 | if (bl == NULL) | 644 | if (bl == NULL) |
665 | { | 645 | { |
666 | #if DEBUG_TRANSPORT | 646 | #if DEBUG_TRANSPORT |
667 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 647 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Blacklist client disconnected\n"); |
668 | "Blacklist client disconnected\n"); | ||
669 | #endif | 648 | #endif |
670 | /* FIXME: other error handling here!? */ | 649 | /* FIXME: other error handling here!? */ |
671 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 650 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |
672 | return; | 651 | return; |
673 | } | 652 | } |
674 | bc = bl->bc; | 653 | bc = bl->bc; |
675 | bl->bc = NULL; | 654 | bl->bc = NULL; |
676 | bl->waiting_for_reply = GNUNET_NO; | 655 | bl->waiting_for_reply = GNUNET_NO; |
677 | if (NULL != bc) | 656 | if (NULL != bc) |
657 | { | ||
658 | /* only run this if the blacklist check has not been | ||
659 | * cancelled in the meantime... */ | ||
660 | if (ntohl (msg->is_allowed) == GNUNET_SYSERR) | ||
678 | { | 661 | { |
679 | /* only run this if the blacklist check has not been | ||
680 | cancelled in the meantime... */ | ||
681 | if (ntohl (msg->is_allowed) == GNUNET_SYSERR) | ||
682 | { | ||
683 | #if DEBUG_TRANSPORT | 662 | #if DEBUG_TRANSPORT |
684 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 663 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
685 | "Blacklist check failed, peer not allowed\n"); | 664 | "Blacklist check failed, peer not allowed\n"); |
686 | #endif | 665 | #endif |
687 | bc->cont (bc->cont_cls, &bc->peer, GNUNET_NO); | 666 | bc->cont (bc->cont_cls, &bc->peer, GNUNET_NO); |
688 | GNUNET_CONTAINER_DLL_remove (bc_head, bc_tail, bc); | 667 | GNUNET_CONTAINER_DLL_remove (bc_head, bc_tail, bc); |
689 | GNUNET_free (bc); | 668 | GNUNET_free (bc); |
690 | } | 669 | } |
691 | else | 670 | else |
692 | { | 671 | { |
693 | #if DEBUG_TRANSPORT | 672 | #if DEBUG_TRANSPORT |
694 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 673 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
695 | "Blacklist check succeeded, continuing with checks\n"); | 674 | "Blacklist check succeeded, continuing with checks\n"); |
696 | #endif | 675 | #endif |
697 | bc->bl_pos = bc->bl_pos->next; | 676 | bc->bl_pos = bc->bl_pos->next; |
698 | bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, | 677 | bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, bc); |
699 | bc); | ||
700 | } | ||
701 | } | 678 | } |
679 | } | ||
702 | /* check if any other bc's are waiting for this blacklister */ | 680 | /* check if any other bc's are waiting for this blacklister */ |
703 | bc = bc_head; | 681 | bc = bc_head; |
704 | for (bc = bc_head; bc != NULL; bc = bc->next) | 682 | for (bc = bc_head; bc != NULL; bc = bc->next) |
705 | if ( (bc->bl_pos == bl) && | 683 | if ((bc->bl_pos == bl) && (GNUNET_SCHEDULER_NO_TASK == bc->task)) |
706 | (GNUNET_SCHEDULER_NO_TASK == bc->task) ) | 684 | { |
707 | { | 685 | bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, bc); |
708 | bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, | 686 | break; |
709 | bc); | 687 | } |
710 | break; | ||
711 | } | ||
712 | } | 688 | } |
713 | 689 | ||
714 | 690 | ||
@@ -720,20 +696,19 @@ GST_blacklist_handle_reply (void *cls, | |||
720 | */ | 696 | */ |
721 | void | 697 | void |
722 | GST_blacklist_add_peer (const struct GNUNET_PeerIdentity *peer, | 698 | GST_blacklist_add_peer (const struct GNUNET_PeerIdentity *peer, |
723 | const char *transport_name) | 699 | const char *transport_name) |
724 | { | 700 | { |
725 | #if DEBUG_TRANSPORT | 701 | #if DEBUG_TRANSPORT |
726 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 702 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
727 | "Adding peer `%s' with plugin `%s' to blacklist\n", | 703 | "Adding peer `%s' with plugin `%s' to blacklist\n", |
728 | GNUNET_i2s (peer), | 704 | GNUNET_i2s (peer), transport_name); |
729 | transport_name); | ||
730 | #endif | 705 | #endif |
731 | if (blacklist == NULL) | 706 | if (blacklist == NULL) |
732 | blacklist = GNUNET_CONTAINER_multihashmap_create(TRANSPORT_BLACKLIST_HT_SIZE); | 707 | blacklist = |
733 | GNUNET_CONTAINER_multihashmap_put (blacklist, | 708 | GNUNET_CONTAINER_multihashmap_create (TRANSPORT_BLACKLIST_HT_SIZE); |
734 | &peer->hashPubKey, | 709 | GNUNET_CONTAINER_multihashmap_put (blacklist, &peer->hashPubKey, |
735 | GNUNET_strdup (transport_name), | 710 | GNUNET_strdup (transport_name), |
736 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | 711 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); |
737 | } | 712 | } |
738 | 713 | ||
739 | 714 | ||
@@ -747,16 +722,13 @@ GST_blacklist_add_peer (const struct GNUNET_PeerIdentity *peer, | |||
747 | * @return GNUNET_OK if the entry does not match, GNUNET_NO if it matches | 722 | * @return GNUNET_OK if the entry does not match, GNUNET_NO if it matches |
748 | */ | 723 | */ |
749 | static int | 724 | static int |
750 | test_blacklisted (void *cls, | 725 | test_blacklisted (void *cls, const GNUNET_HashCode * key, void *value) |
751 | const GNUNET_HashCode *key, | ||
752 | void *value) | ||
753 | { | 726 | { |
754 | const char *transport_name = cls; | 727 | const char *transport_name = cls; |
755 | char *be = value; | 728 | char *be = value; |
756 | 729 | ||
757 | if (0 == strcmp (transport_name, | 730 | if (0 == strcmp (transport_name, be)) |
758 | be)) | 731 | return GNUNET_NO; /* abort iteration! */ |
759 | return GNUNET_NO; /* abort iteration! */ | ||
760 | return GNUNET_OK; | 732 | return GNUNET_OK; |
761 | } | 733 | } |
762 | 734 | ||
@@ -773,36 +745,34 @@ test_blacklisted (void *cls, | |||
773 | */ | 745 | */ |
774 | struct GST_BlacklistCheck * | 746 | struct GST_BlacklistCheck * |
775 | GST_blacklist_test_allowed (const struct GNUNET_PeerIdentity *peer, | 747 | GST_blacklist_test_allowed (const struct GNUNET_PeerIdentity *peer, |
776 | const char *transport_name, | 748 | const char *transport_name, |
777 | GST_BlacklistTestContinuation cont, | 749 | GST_BlacklistTestContinuation cont, void *cont_cls) |
778 | void *cont_cls) | ||
779 | { | 750 | { |
780 | struct GST_BlacklistCheck *bc; | 751 | struct GST_BlacklistCheck *bc; |
781 | 752 | ||
782 | if ( (blacklist != NULL) && | 753 | if ((blacklist != NULL) && |
783 | (GNUNET_SYSERR == | 754 | (GNUNET_SYSERR == |
784 | GNUNET_CONTAINER_multihashmap_get_multiple (blacklist, | 755 | GNUNET_CONTAINER_multihashmap_get_multiple (blacklist, |
785 | &peer->hashPubKey, | 756 | &peer->hashPubKey, |
786 | &test_blacklisted, | 757 | &test_blacklisted, |
787 | (void*) transport_name)) ) | 758 | (void *) transport_name))) |
788 | { | 759 | { |
789 | /* disallowed by config, disapprove instantly */ | 760 | /* disallowed by config, disapprove instantly */ |
790 | GNUNET_STATISTICS_update (GST_stats, | 761 | GNUNET_STATISTICS_update (GST_stats, |
791 | gettext_noop ("# disconnects due to blacklist"), | 762 | gettext_noop ("# disconnects due to blacklist"), |
792 | 1, | 763 | 1, GNUNET_NO); |
793 | GNUNET_NO); | 764 | if (cont != NULL) |
794 | if (cont != NULL) | 765 | cont (cont_cls, peer, GNUNET_NO); |
795 | cont (cont_cls, peer, GNUNET_NO); | 766 | return NULL; |
796 | return NULL; | 767 | } |
797 | } | ||
798 | 768 | ||
799 | if (bl_head == NULL) | 769 | if (bl_head == NULL) |
800 | { | 770 | { |
801 | /* no blacklist clients, approve instantly */ | 771 | /* no blacklist clients, approve instantly */ |
802 | if (cont != NULL) | 772 | if (cont != NULL) |
803 | cont (cont_cls, peer, GNUNET_OK); | 773 | cont (cont_cls, peer, GNUNET_OK); |
804 | return NULL; | 774 | return NULL; |
805 | } | 775 | } |
806 | 776 | ||
807 | /* need to query blacklist clients */ | 777 | /* need to query blacklist clients */ |
808 | bc = GNUNET_malloc (sizeof (struct GST_BlacklistCheck)); | 778 | bc = GNUNET_malloc (sizeof (struct GST_BlacklistCheck)); |
@@ -811,11 +781,10 @@ GST_blacklist_test_allowed (const struct GNUNET_PeerIdentity *peer, | |||
811 | bc->cont = cont; | 781 | bc->cont = cont; |
812 | bc->cont_cls = cont_cls; | 782 | bc->cont_cls = cont_cls; |
813 | bc->bl_pos = bl_head; | 783 | bc->bl_pos = bl_head; |
814 | bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, | 784 | bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, bc); |
815 | bc); | ||
816 | return bc; | 785 | return bc; |
817 | } | 786 | } |
818 | 787 | ||
819 | 788 | ||
820 | /** | 789 | /** |
821 | * Cancel a blacklist check. | 790 | * Cancel a blacklist check. |
@@ -827,25 +796,25 @@ GST_blacklist_test_cancel (struct GST_BlacklistCheck *bc) | |||
827 | { | 796 | { |
828 | GNUNET_CONTAINER_DLL_remove (bc_head, bc_tail, bc); | 797 | GNUNET_CONTAINER_DLL_remove (bc_head, bc_tail, bc); |
829 | if (bc->bl_pos != NULL) | 798 | if (bc->bl_pos != NULL) |
799 | { | ||
800 | if (bc->bl_pos->bc == bc) | ||
830 | { | 801 | { |
831 | if (bc->bl_pos->bc == bc) | 802 | /* we're at the head of the queue, remove us! */ |
832 | { | 803 | bc->bl_pos->bc = NULL; |
833 | /* we're at the head of the queue, remove us! */ | ||
834 | bc->bl_pos->bc = NULL; | ||
835 | } | ||
836 | } | 804 | } |
805 | } | ||
837 | if (GNUNET_SCHEDULER_NO_TASK != bc->task) | 806 | if (GNUNET_SCHEDULER_NO_TASK != bc->task) |
838 | { | 807 | { |
839 | GNUNET_SCHEDULER_cancel (bc->task); | 808 | GNUNET_SCHEDULER_cancel (bc->task); |
840 | bc->task = GNUNET_SCHEDULER_NO_TASK; | 809 | bc->task = GNUNET_SCHEDULER_NO_TASK; |
841 | } | 810 | } |
842 | if (NULL != bc->th) | 811 | if (NULL != bc->th) |
843 | { | 812 | { |
844 | GNUNET_CONNECTION_notify_transmit_ready_cancel (bc->th); | 813 | GNUNET_CONNECTION_notify_transmit_ready_cancel (bc->th); |
845 | bc->th = NULL; | 814 | bc->th = NULL; |
846 | } | 815 | } |
847 | GNUNET_free (bc); | 816 | GNUNET_free (bc); |
848 | } | 817 | } |
849 | 818 | ||
850 | 819 | ||
851 | /* end of file gnunet-service-transport_blacklist.c */ | 820 | /* end of file gnunet-service-transport_blacklist.c */ |