diff options
Diffstat (limited to 'src/util/server.c')
-rw-r--r-- | src/util/server.c | 769 |
1 files changed, 378 insertions, 391 deletions
diff --git a/src/util/server.c b/src/util/server.c index f792e5a67..6f1b8cdb4 100644 --- a/src/util/server.c +++ b/src/util/server.c | |||
@@ -264,8 +264,7 @@ struct GNUNET_SERVER_Client | |||
264 | * @param tc reason why we are running right now | 264 | * @param tc reason why we are running right now |
265 | */ | 265 | */ |
266 | static void | 266 | static void |
267 | process_listen_socket (void *cls, | 267 | process_listen_socket (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
268 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
269 | { | 268 | { |
270 | struct GNUNET_SERVER_Handle *server = cls; | 269 | struct GNUNET_SERVER_Handle *server = cls; |
271 | struct GNUNET_CONNECTION_Handle *sock; | 270 | struct GNUNET_CONNECTION_Handle *sock; |
@@ -279,47 +278,45 @@ process_listen_socket (void *cls, | |||
279 | while (NULL != server->listen_sockets[i]) | 278 | while (NULL != server->listen_sockets[i]) |
280 | GNUNET_NETWORK_fdset_set (r, server->listen_sockets[i++]); | 279 | GNUNET_NETWORK_fdset_set (r, server->listen_sockets[i++]); |
281 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | 280 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) |
282 | { | 281 | { |
283 | /* ignore shutdown, someone else will take care of it! */ | 282 | /* ignore shutdown, someone else will take care of it! */ |
284 | server->listen_task = | 283 | server->listen_task = |
285 | GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH, | 284 | GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH, |
286 | GNUNET_SCHEDULER_NO_TASK, | 285 | GNUNET_SCHEDULER_NO_TASK, |
287 | GNUNET_TIME_UNIT_FOREVER_REL, r, NULL, | 286 | GNUNET_TIME_UNIT_FOREVER_REL, r, NULL, |
288 | &process_listen_socket, server); | 287 | &process_listen_socket, server); |
289 | GNUNET_NETWORK_fdset_destroy (r); | 288 | GNUNET_NETWORK_fdset_destroy (r); |
290 | return; | 289 | return; |
291 | } | 290 | } |
292 | i = 0; | 291 | i = 0; |
293 | while (NULL != server->listen_sockets[i]) | 292 | while (NULL != server->listen_sockets[i]) |
293 | { | ||
294 | if (GNUNET_NETWORK_fdset_isset (tc->read_ready, server->listen_sockets[i])) | ||
294 | { | 295 | { |
295 | if (GNUNET_NETWORK_fdset_isset | 296 | sock = |
296 | (tc->read_ready, server->listen_sockets[i])) | 297 | GNUNET_CONNECTION_create_from_accept (server->access, |
297 | { | 298 | server->access_cls, |
298 | sock = | 299 | server->listen_sockets[i]); |
299 | GNUNET_CONNECTION_create_from_accept (server->access, | 300 | if (sock != NULL) |
300 | server->access_cls, | 301 | { |
301 | server->listen_sockets[i]); | ||
302 | if (sock != NULL) | ||
303 | { | ||
304 | #if DEBUG_SERVER | 302 | #if DEBUG_SERVER |
305 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 303 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Server accepted incoming connection.\n"); |
306 | "Server accepted incoming connection.\n"); | ||
307 | #endif | 304 | #endif |
308 | client = GNUNET_SERVER_connect_socket (server, sock); | 305 | client = GNUNET_SERVER_connect_socket (server, sock); |
309 | GNUNET_CONNECTION_ignore_shutdown (sock, | 306 | GNUNET_CONNECTION_ignore_shutdown (sock, |
310 | server->clients_ignore_shutdown); | 307 | server->clients_ignore_shutdown); |
311 | /* decrement reference count, we don't keep "client" alive */ | 308 | /* decrement reference count, we don't keep "client" alive */ |
312 | GNUNET_SERVER_client_drop (client); | 309 | GNUNET_SERVER_client_drop (client); |
313 | } | 310 | } |
314 | } | ||
315 | i++; | ||
316 | } | 311 | } |
312 | i++; | ||
313 | } | ||
317 | /* listen for more! */ | 314 | /* listen for more! */ |
318 | server->listen_task = | 315 | server->listen_task = |
319 | GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH, | 316 | GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH, |
320 | GNUNET_SCHEDULER_NO_TASK, | 317 | GNUNET_SCHEDULER_NO_TASK, |
321 | GNUNET_TIME_UNIT_FOREVER_REL, r, NULL, | 318 | GNUNET_TIME_UNIT_FOREVER_REL, r, NULL, |
322 | &process_listen_socket, server); | 319 | &process_listen_socket, server); |
323 | GNUNET_NETWORK_fdset_destroy (r); | 320 | GNUNET_NETWORK_fdset_destroy (r); |
324 | } | 321 | } |
325 | 322 | ||
@@ -340,87 +337,87 @@ open_listen_socket (const struct sockaddr *serverAddr, socklen_t socklen) | |||
340 | int eno; | 337 | int eno; |
341 | 338 | ||
342 | switch (serverAddr->sa_family) | 339 | switch (serverAddr->sa_family) |
343 | { | 340 | { |
344 | case AF_INET: | 341 | case AF_INET: |
345 | port = ntohs (((const struct sockaddr_in *) serverAddr)->sin_port); | 342 | port = ntohs (((const struct sockaddr_in *) serverAddr)->sin_port); |
346 | break; | 343 | break; |
347 | case AF_INET6: | 344 | case AF_INET6: |
348 | port = ntohs (((const struct sockaddr_in6 *) serverAddr)->sin6_port); | 345 | port = ntohs (((const struct sockaddr_in6 *) serverAddr)->sin6_port); |
349 | break; | 346 | break; |
350 | case AF_UNIX: | 347 | case AF_UNIX: |
351 | port = 0; | 348 | port = 0; |
352 | break; | 349 | break; |
353 | default: | 350 | default: |
354 | GNUNET_break (0); | 351 | GNUNET_break (0); |
355 | port = 0; | 352 | port = 0; |
356 | break; | 353 | break; |
357 | } | 354 | } |
358 | sock = GNUNET_NETWORK_socket_create (serverAddr->sa_family, SOCK_STREAM, 0); | 355 | sock = GNUNET_NETWORK_socket_create (serverAddr->sa_family, SOCK_STREAM, 0); |
359 | if (NULL == sock) | 356 | if (NULL == sock) |
360 | { | 357 | { |
361 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket"); | 358 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket"); |
362 | errno = 0; | 359 | errno = 0; |
363 | return NULL; | 360 | return NULL; |
364 | } | 361 | } |
365 | if (port != 0) | 362 | if (port != 0) |
366 | { | 363 | { |
367 | if (GNUNET_NETWORK_socket_setsockopt | 364 | if (GNUNET_NETWORK_socket_setsockopt |
368 | (sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) != GNUNET_OK) | 365 | (sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) != GNUNET_OK) |
369 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | 366 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, |
370 | "setsockopt"); | 367 | "setsockopt"); |
371 | #ifdef IPV6_V6ONLY | 368 | #ifdef IPV6_V6ONLY |
372 | if ((serverAddr->sa_family == AF_INET6) && | 369 | if ((serverAddr->sa_family == AF_INET6) && |
373 | (GNUNET_NETWORK_socket_setsockopt | 370 | (GNUNET_NETWORK_socket_setsockopt |
374 | (sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof (on)) != GNUNET_OK)) | 371 | (sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof (on)) != GNUNET_OK)) |
375 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | 372 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, |
376 | "setsockopt"); | 373 | "setsockopt"); |
377 | #endif | 374 | #endif |
378 | } | 375 | } |
379 | /* bind the socket */ | 376 | /* bind the socket */ |
380 | if (GNUNET_NETWORK_socket_bind (sock, serverAddr, socklen) != GNUNET_OK) | 377 | if (GNUNET_NETWORK_socket_bind (sock, serverAddr, socklen) != GNUNET_OK) |
378 | { | ||
379 | eno = errno; | ||
380 | if (errno != EADDRINUSE) | ||
381 | { | 381 | { |
382 | eno = errno; | 382 | /* we don't log 'EADDRINUSE' here since an IPv4 bind may |
383 | if (errno != EADDRINUSE) | 383 | * fail if we already took the port on IPv6; if both IPv4 and |
384 | { | 384 | * IPv6 binds fail, then our caller will log using the |
385 | /* we don't log 'EADDRINUSE' here since an IPv4 bind may | 385 | * errno preserved in 'eno' */ |
386 | * fail if we already took the port on IPv6; if both IPv4 and | 386 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "bind"); |
387 | * IPv6 binds fail, then our caller will log using the | 387 | if (port != 0) |
388 | * errno preserved in 'eno' */ | 388 | LOG (GNUNET_ERROR_TYPE_ERROR, _("`%s' failed for port %d (%s).\n"), |
389 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "bind"); | 389 | "bind", port, |
390 | if (port != 0) | 390 | (serverAddr->sa_family == AF_INET) ? "IPv4" : "IPv6"); |
391 | LOG (GNUNET_ERROR_TYPE_ERROR, | 391 | eno = 0; |
392 | _("`%s' failed for port %d (%s).\n"), "bind", port, | ||
393 | (serverAddr->sa_family == AF_INET) ? "IPv4" : "IPv6"); | ||
394 | eno = 0; | ||
395 | } | ||
396 | else | ||
397 | { | ||
398 | if (port != 0) | ||
399 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
400 | _("`%s' failed for port %d (%s): address already in use\n"), | ||
401 | "bind", port, | ||
402 | (serverAddr->sa_family == AF_INET) ? "IPv4" : "IPv6"); | ||
403 | else if (serverAddr->sa_family == AF_UNIX) | ||
404 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
405 | _("`%s' failed for `%s': address already in use\n"), "bind", | ||
406 | ((const struct sockaddr_un *) serverAddr)->sun_path); | ||
407 | |||
408 | } | ||
409 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); | ||
410 | errno = eno; | ||
411 | return NULL; | ||
412 | } | 392 | } |
413 | if (GNUNET_OK != GNUNET_NETWORK_socket_listen (sock, 5)) | 393 | else |
414 | { | 394 | { |
415 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "listen"); | 395 | if (port != 0) |
416 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); | 396 | LOG (GNUNET_ERROR_TYPE_WARNING, |
417 | errno = 0; | 397 | _("`%s' failed for port %d (%s): address already in use\n"), |
418 | return NULL; | 398 | "bind", port, |
399 | (serverAddr->sa_family == AF_INET) ? "IPv4" : "IPv6"); | ||
400 | else if (serverAddr->sa_family == AF_UNIX) | ||
401 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
402 | _("`%s' failed for `%s': address already in use\n"), "bind", | ||
403 | ((const struct sockaddr_un *) serverAddr)->sun_path); | ||
404 | |||
419 | } | 405 | } |
406 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); | ||
407 | errno = eno; | ||
408 | return NULL; | ||
409 | } | ||
410 | if (GNUNET_OK != GNUNET_NETWORK_socket_listen (sock, 5)) | ||
411 | { | ||
412 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "listen"); | ||
413 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); | ||
414 | errno = 0; | ||
415 | return NULL; | ||
416 | } | ||
420 | #if DEBUG_SERVER | 417 | #if DEBUG_SERVER |
421 | if (port != 0) | 418 | if (port != 0) |
422 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 419 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Server starts to listen on port %u.\n", |
423 | "Server starts to listen on port %u.\n", port); | 420 | port); |
424 | #endif | 421 | #endif |
425 | return sock; | 422 | return sock; |
426 | } | 423 | } |
@@ -440,10 +437,10 @@ open_listen_socket (const struct sockaddr *serverAddr, socklen_t socklen) | |||
440 | */ | 437 | */ |
441 | struct GNUNET_SERVER_Handle * | 438 | struct GNUNET_SERVER_Handle * |
442 | GNUNET_SERVER_create_with_sockets (GNUNET_CONNECTION_AccessCheck access, | 439 | GNUNET_SERVER_create_with_sockets (GNUNET_CONNECTION_AccessCheck access, |
443 | void *access_cls, | 440 | void *access_cls, |
444 | struct GNUNET_NETWORK_Handle **lsocks, | 441 | struct GNUNET_NETWORK_Handle **lsocks, |
445 | struct GNUNET_TIME_Relative idle_timeout, | 442 | struct GNUNET_TIME_Relative idle_timeout, |
446 | int require_found) | 443 | int require_found) |
447 | { | 444 | { |
448 | struct GNUNET_SERVER_Handle *ret; | 445 | struct GNUNET_SERVER_Handle *ret; |
449 | struct GNUNET_NETWORK_FDSet *r; | 446 | struct GNUNET_NETWORK_FDSet *r; |
@@ -456,18 +453,18 @@ GNUNET_SERVER_create_with_sockets (GNUNET_CONNECTION_AccessCheck access, | |||
456 | ret->access_cls = access_cls; | 453 | ret->access_cls = access_cls; |
457 | ret->require_found = require_found; | 454 | ret->require_found = require_found; |
458 | if (lsocks != NULL) | 455 | if (lsocks != NULL) |
459 | { | 456 | { |
460 | r = GNUNET_NETWORK_fdset_create (); | 457 | r = GNUNET_NETWORK_fdset_create (); |
461 | i = 0; | 458 | i = 0; |
462 | while (NULL != ret->listen_sockets[i]) | 459 | while (NULL != ret->listen_sockets[i]) |
463 | GNUNET_NETWORK_fdset_set (r, ret->listen_sockets[i++]); | 460 | GNUNET_NETWORK_fdset_set (r, ret->listen_sockets[i++]); |
464 | ret->listen_task = | 461 | ret->listen_task = |
465 | GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH, | 462 | GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH, |
466 | GNUNET_SCHEDULER_NO_TASK, | 463 | GNUNET_SCHEDULER_NO_TASK, |
467 | GNUNET_TIME_UNIT_FOREVER_REL, r, NULL, | 464 | GNUNET_TIME_UNIT_FOREVER_REL, r, NULL, |
468 | &process_listen_socket, ret); | 465 | &process_listen_socket, ret); |
469 | GNUNET_NETWORK_fdset_destroy (r); | 466 | GNUNET_NETWORK_fdset_destroy (r); |
470 | } | 467 | } |
471 | return ret; | 468 | return ret; |
472 | } | 469 | } |
473 | 470 | ||
@@ -487,10 +484,10 @@ GNUNET_SERVER_create_with_sockets (GNUNET_CONNECTION_AccessCheck access, | |||
487 | */ | 484 | */ |
488 | struct GNUNET_SERVER_Handle * | 485 | struct GNUNET_SERVER_Handle * |
489 | GNUNET_SERVER_create (GNUNET_CONNECTION_AccessCheck access, void *access_cls, | 486 | GNUNET_SERVER_create (GNUNET_CONNECTION_AccessCheck access, void *access_cls, |
490 | struct sockaddr *const *serverAddr, | 487 | struct sockaddr *const *serverAddr, |
491 | const socklen_t * socklen, | 488 | const socklen_t * socklen, |
492 | struct GNUNET_TIME_Relative idle_timeout, | 489 | struct GNUNET_TIME_Relative idle_timeout, |
493 | int require_found) | 490 | int require_found) |
494 | { | 491 | { |
495 | struct GNUNET_NETWORK_Handle **lsocks; | 492 | struct GNUNET_NETWORK_Handle **lsocks; |
496 | unsigned int i; | 493 | unsigned int i; |
@@ -500,32 +497,31 @@ GNUNET_SERVER_create (GNUNET_CONNECTION_AccessCheck access, void *access_cls, | |||
500 | while (serverAddr[i] != NULL) | 497 | while (serverAddr[i] != NULL) |
501 | i++; | 498 | i++; |
502 | if (i > 0) | 499 | if (i > 0) |
500 | { | ||
501 | lsocks = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle *) * (i + 1)); | ||
502 | i = 0; | ||
503 | j = 0; | ||
504 | while (serverAddr[i] != NULL) | ||
503 | { | 505 | { |
504 | lsocks = | 506 | lsocks[j] = open_listen_socket (serverAddr[i], socklen[i]); |
505 | GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle *) * (i + 1)); | 507 | if (lsocks[j] != NULL) |
506 | i = 0; | 508 | j++; |
507 | j = 0; | 509 | i++; |
508 | while (serverAddr[i] != NULL) | ||
509 | { | ||
510 | lsocks[j] = open_listen_socket (serverAddr[i], socklen[i]); | ||
511 | if (lsocks[j] != NULL) | ||
512 | j++; | ||
513 | i++; | ||
514 | } | ||
515 | if (j == 0) | ||
516 | { | ||
517 | if (errno != 0) | ||
518 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "bind"); | ||
519 | GNUNET_free (lsocks); | ||
520 | lsocks = NULL; | ||
521 | } | ||
522 | } | 510 | } |
523 | else | 511 | if (j == 0) |
524 | { | 512 | { |
513 | if (errno != 0) | ||
514 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "bind"); | ||
515 | GNUNET_free (lsocks); | ||
525 | lsocks = NULL; | 516 | lsocks = NULL; |
526 | } | 517 | } |
518 | } | ||
519 | else | ||
520 | { | ||
521 | lsocks = NULL; | ||
522 | } | ||
527 | return GNUNET_SERVER_create_with_sockets (access, access_cls, lsocks, | 523 | return GNUNET_SERVER_create_with_sockets (access, access_cls, lsocks, |
528 | idle_timeout, require_found); | 524 | idle_timeout, require_found); |
529 | } | 525 | } |
530 | 526 | ||
531 | 527 | ||
@@ -545,32 +541,32 @@ GNUNET_SERVER_destroy (struct GNUNET_SERVER_Handle *s) | |||
545 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Server shutting down.\n"); | 541 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Server shutting down.\n"); |
546 | #endif | 542 | #endif |
547 | if (GNUNET_SCHEDULER_NO_TASK != s->listen_task) | 543 | if (GNUNET_SCHEDULER_NO_TASK != s->listen_task) |
548 | { | 544 | { |
549 | GNUNET_SCHEDULER_cancel (s->listen_task); | 545 | GNUNET_SCHEDULER_cancel (s->listen_task); |
550 | s->listen_task = GNUNET_SCHEDULER_NO_TASK; | 546 | s->listen_task = GNUNET_SCHEDULER_NO_TASK; |
551 | } | 547 | } |
552 | if (s->listen_sockets != NULL) | 548 | if (s->listen_sockets != NULL) |
553 | { | 549 | { |
554 | i = 0; | 550 | i = 0; |
555 | while (s->listen_sockets[i] != NULL) | 551 | while (s->listen_sockets[i] != NULL) |
556 | GNUNET_break (GNUNET_OK == | 552 | GNUNET_break (GNUNET_OK == |
557 | GNUNET_NETWORK_socket_close (s->listen_sockets[i++])); | 553 | GNUNET_NETWORK_socket_close (s->listen_sockets[i++])); |
558 | GNUNET_free (s->listen_sockets); | 554 | GNUNET_free (s->listen_sockets); |
559 | s->listen_sockets = NULL; | 555 | s->listen_sockets = NULL; |
560 | } | 556 | } |
561 | while (s->clients != NULL) | 557 | while (s->clients != NULL) |
562 | GNUNET_SERVER_client_disconnect (s->clients); | 558 | GNUNET_SERVER_client_disconnect (s->clients); |
563 | while (NULL != (hpos = s->handlers)) | 559 | while (NULL != (hpos = s->handlers)) |
564 | { | 560 | { |
565 | s->handlers = hpos->next; | 561 | s->handlers = hpos->next; |
566 | GNUNET_free (hpos); | 562 | GNUNET_free (hpos); |
567 | } | 563 | } |
568 | while (NULL != (npos = s->disconnect_notify_list)) | 564 | while (NULL != (npos = s->disconnect_notify_list)) |
569 | { | 565 | { |
570 | npos->callback (npos->callback_cls, NULL); | 566 | npos->callback (npos->callback_cls, NULL); |
571 | s->disconnect_notify_list = npos->next; | 567 | s->disconnect_notify_list = npos->next; |
572 | GNUNET_free (npos); | 568 | GNUNET_free (npos); |
573 | } | 569 | } |
574 | GNUNET_free (s); | 570 | GNUNET_free (s); |
575 | } | 571 | } |
576 | 572 | ||
@@ -590,8 +586,7 @@ GNUNET_SERVER_destroy (struct GNUNET_SERVER_Handle *s) | |||
590 | */ | 586 | */ |
591 | void | 587 | void |
592 | GNUNET_SERVER_add_handlers (struct GNUNET_SERVER_Handle *server, | 588 | GNUNET_SERVER_add_handlers (struct GNUNET_SERVER_Handle *server, |
593 | const struct GNUNET_SERVER_MessageHandler | 589 | const struct GNUNET_SERVER_MessageHandler *handlers) |
594 | *handlers) | ||
595 | { | 590 | { |
596 | struct HandlerList *p; | 591 | struct HandlerList *p; |
597 | 592 | ||
@@ -609,21 +604,20 @@ GNUNET_SERVER_add_handlers (struct GNUNET_SERVER_Handle *server, | |||
609 | * @param tc scheduler context (unused) | 604 | * @param tc scheduler context (unused) |
610 | */ | 605 | */ |
611 | static void | 606 | static void |
612 | warn_no_receive_done (void *cls, | 607 | warn_no_receive_done (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
613 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
614 | { | 608 | { |
615 | struct GNUNET_SERVER_Client *client = cls; | 609 | struct GNUNET_SERVER_Client *client = cls; |
616 | 610 | ||
617 | client->warn_task = | 611 | client->warn_task = |
618 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, | 612 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, |
619 | &warn_no_receive_done, client); | 613 | &warn_no_receive_done, client); |
620 | if (0 == (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason)) | 614 | if (0 == (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason)) |
621 | LOG (GNUNET_ERROR_TYPE_WARNING, | 615 | LOG (GNUNET_ERROR_TYPE_WARNING, |
622 | _ | 616 | _ |
623 | ("Processing code for message of type %u did not call GNUNET_SERVER_receive_done after %llums\n"), | 617 | ("Processing code for message of type %u did not call GNUNET_SERVER_receive_done after %llums\n"), |
624 | (unsigned int) client->warn_type, | 618 | (unsigned int) client->warn_type, |
625 | (unsigned long long) | 619 | (unsigned long long) |
626 | GNUNET_TIME_absolute_get_duration (client->warn_start).rel_value); | 620 | GNUNET_TIME_absolute_get_duration (client->warn_start).rel_value); |
627 | } | 621 | } |
628 | 622 | ||
629 | 623 | ||
@@ -635,14 +629,13 @@ warn_no_receive_done (void *cls, | |||
635 | * @param client client for which to disable the warning | 629 | * @param client client for which to disable the warning |
636 | */ | 630 | */ |
637 | void | 631 | void |
638 | GNUNET_SERVER_disable_receive_done_warning (struct GNUNET_SERVER_Client | 632 | GNUNET_SERVER_disable_receive_done_warning (struct GNUNET_SERVER_Client *client) |
639 | *client) | ||
640 | { | 633 | { |
641 | if (GNUNET_SCHEDULER_NO_TASK != client->warn_task) | 634 | if (GNUNET_SCHEDULER_NO_TASK != client->warn_task) |
642 | { | 635 | { |
643 | GNUNET_SCHEDULER_cancel (client->warn_task); | 636 | GNUNET_SCHEDULER_cancel (client->warn_task); |
644 | client->warn_task = GNUNET_SCHEDULER_NO_TASK; | 637 | client->warn_task = GNUNET_SCHEDULER_NO_TASK; |
645 | } | 638 | } |
646 | } | 639 | } |
647 | 640 | ||
648 | 641 | ||
@@ -663,8 +656,8 @@ GNUNET_SERVER_disable_receive_done_warning (struct GNUNET_SERVER_Client | |||
663 | */ | 656 | */ |
664 | int | 657 | int |
665 | GNUNET_SERVER_inject (struct GNUNET_SERVER_Handle *server, | 658 | GNUNET_SERVER_inject (struct GNUNET_SERVER_Handle *server, |
666 | struct GNUNET_SERVER_Client *sender, | 659 | struct GNUNET_SERVER_Client *sender, |
667 | const struct GNUNET_MessageHeader *message) | 660 | const struct GNUNET_MessageHeader *message) |
668 | { | 661 | { |
669 | struct HandlerList *pos; | 662 | struct HandlerList *pos; |
670 | const struct GNUNET_SERVER_MessageHandler *mh; | 663 | const struct GNUNET_SERVER_MessageHandler *mh; |
@@ -684,50 +677,49 @@ GNUNET_SERVER_inject (struct GNUNET_SERVER_Handle *server, | |||
684 | pos = server->handlers; | 677 | pos = server->handlers; |
685 | found = GNUNET_NO; | 678 | found = GNUNET_NO; |
686 | while (pos != NULL) | 679 | while (pos != NULL) |
680 | { | ||
681 | i = 0; | ||
682 | while (pos->handlers[i].callback != NULL) | ||
687 | { | 683 | { |
688 | i = 0; | 684 | mh = &pos->handlers[i]; |
689 | while (pos->handlers[i].callback != NULL) | 685 | if ((mh->type == type) || (mh->type == GNUNET_MESSAGE_TYPE_ALL)) |
690 | { | 686 | { |
691 | mh = &pos->handlers[i]; | 687 | if ((mh->expected_size != 0) && (mh->expected_size != size)) |
692 | if ((mh->type == type) || (mh->type == GNUNET_MESSAGE_TYPE_ALL)) | 688 | { |
693 | { | ||
694 | if ((mh->expected_size != 0) && (mh->expected_size != size)) | ||
695 | { | ||
696 | #if GNUNET8_NETWORK_IS_DEAD | 689 | #if GNUNET8_NETWORK_IS_DEAD |
697 | LOG (GNUNET_ERROR_TYPE_WARNING, | 690 | LOG (GNUNET_ERROR_TYPE_WARNING, |
698 | "Expected %u bytes for message of type %u, got %u\n", | 691 | "Expected %u bytes for message of type %u, got %u\n", |
699 | mh->expected_size, mh->type, size); | 692 | mh->expected_size, mh->type, size); |
700 | GNUNET_break_op (0); | 693 | GNUNET_break_op (0); |
701 | #endif | 694 | #endif |
702 | return GNUNET_SYSERR; | 695 | return GNUNET_SYSERR; |
703 | } | 696 | } |
704 | if (sender != NULL) | 697 | if (sender != NULL) |
705 | { | 698 | { |
706 | if (0 == sender->suspended) | 699 | if (0 == sender->suspended) |
707 | { | 700 | { |
708 | sender->warn_start = GNUNET_TIME_absolute_get (); | 701 | sender->warn_start = GNUNET_TIME_absolute_get (); |
709 | sender->warn_task = | 702 | sender->warn_task = |
710 | GNUNET_SCHEDULER_add_delayed | 703 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, |
711 | (GNUNET_TIME_UNIT_MINUTES, &warn_no_receive_done, | 704 | &warn_no_receive_done, sender); |
712 | sender); | 705 | sender->warn_type = type; |
713 | sender->warn_type = type; | 706 | } |
714 | } | 707 | sender->suspended++; |
715 | sender->suspended++; | 708 | } |
716 | } | 709 | mh->callback (mh->callback_cls, sender, message); |
717 | mh->callback (mh->callback_cls, sender, message); | 710 | found = GNUNET_YES; |
718 | found = GNUNET_YES; | 711 | } |
719 | } | 712 | i++; |
720 | i++; | ||
721 | } | ||
722 | pos = pos->next; | ||
723 | } | 713 | } |
714 | pos = pos->next; | ||
715 | } | ||
724 | if (found == GNUNET_NO) | 716 | if (found == GNUNET_NO) |
725 | { | 717 | { |
726 | LOG (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, | 718 | LOG (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, |
727 | "Received message of unknown type %d\n", type); | 719 | "Received message of unknown type %d\n", type); |
728 | if (server->require_found == GNUNET_YES) | 720 | if (server->require_found == GNUNET_YES) |
729 | return GNUNET_SYSERR; | 721 | return GNUNET_SYSERR; |
730 | } | 722 | } |
731 | return GNUNET_OK; | 723 | return GNUNET_OK; |
732 | } | 724 | } |
733 | 725 | ||
@@ -744,8 +736,7 @@ GNUNET_SERVER_inject (struct GNUNET_SERVER_Handle *server, | |||
744 | */ | 736 | */ |
745 | static void | 737 | static void |
746 | process_incoming (void *cls, const void *buf, size_t available, | 738 | process_incoming (void *cls, const void *buf, size_t available, |
747 | const struct sockaddr *addr, socklen_t addrlen, | 739 | const struct sockaddr *addr, socklen_t addrlen, int errCode); |
748 | int errCode); | ||
749 | 740 | ||
750 | 741 | ||
751 | /** | 742 | /** |
@@ -765,44 +756,44 @@ static void | |||
765 | process_mst (struct GNUNET_SERVER_Client *client, int ret) | 756 | process_mst (struct GNUNET_SERVER_Client *client, int ret) |
766 | { | 757 | { |
767 | while ((ret != GNUNET_SYSERR) && (client->server != NULL) && | 758 | while ((ret != GNUNET_SYSERR) && (client->server != NULL) && |
768 | (GNUNET_YES != client->shutdown_now) && (0 == client->suspended)) | 759 | (GNUNET_YES != client->shutdown_now) && (0 == client->suspended)) |
760 | { | ||
761 | if (ret == GNUNET_OK) | ||
769 | { | 762 | { |
770 | if (ret == GNUNET_OK) | 763 | client->receive_pending = GNUNET_YES; |
771 | { | ||
772 | client->receive_pending = GNUNET_YES; | ||
773 | #if DEBUG_SERVER | ||
774 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
775 | "Server re-enters receive loop, timeout: %llu.\n", | ||
776 | client->idle_timeout.rel_value); | ||
777 | #endif | ||
778 | GNUNET_CONNECTION_receive (client->connection, | ||
779 | GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, | ||
780 | client->idle_timeout, &process_incoming, | ||
781 | client); | ||
782 | break; | ||
783 | } | ||
784 | #if DEBUG_SERVER | 764 | #if DEBUG_SERVER |
785 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 765 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
786 | "Server processes additional messages instantly.\n"); | 766 | "Server re-enters receive loop, timeout: %llu.\n", |
767 | client->idle_timeout.rel_value); | ||
787 | #endif | 768 | #endif |
788 | ret = | 769 | GNUNET_CONNECTION_receive (client->connection, |
789 | GNUNET_SERVER_mst_receive (client->mst, client, NULL, 0, GNUNET_NO, | 770 | GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, |
790 | GNUNET_YES); | 771 | client->idle_timeout, &process_incoming, |
772 | client); | ||
773 | break; | ||
791 | } | 774 | } |
792 | #if DEBUG_SERVER | 775 | #if DEBUG_SERVER |
776 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
777 | "Server processes additional messages instantly.\n"); | ||
778 | #endif | ||
779 | ret = | ||
780 | GNUNET_SERVER_mst_receive (client->mst, client, NULL, 0, GNUNET_NO, | ||
781 | GNUNET_YES); | ||
782 | } | ||
783 | #if DEBUG_SERVER | ||
793 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 784 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
794 | "Server leaves instant processing loop: ret = %d, server = %p, shutdown = %d, suspended = %u\n", | 785 | "Server leaves instant processing loop: ret = %d, server = %p, shutdown = %d, suspended = %u\n", |
795 | ret, client->server, client->shutdown_now, client->suspended); | 786 | ret, client->server, client->shutdown_now, client->suspended); |
796 | #endif | 787 | #endif |
797 | 788 | ||
798 | if (ret == GNUNET_NO) | 789 | if (ret == GNUNET_NO) |
799 | { | 790 | { |
800 | #if DEBUG_SERVER | 791 | #if DEBUG_SERVER |
801 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 792 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
802 | "Server has more data pending but is suspended.\n"); | 793 | "Server has more data pending but is suspended.\n"); |
803 | #endif | 794 | #endif |
804 | client->receive_pending = GNUNET_SYSERR; /* data pending */ | 795 | client->receive_pending = GNUNET_SYSERR; /* data pending */ |
805 | } | 796 | } |
806 | if ((ret == GNUNET_SYSERR) || (GNUNET_YES == client->shutdown_now)) | 797 | if ((ret == GNUNET_SYSERR) || (GNUNET_YES == client->shutdown_now)) |
807 | GNUNET_SERVER_client_disconnect (client); | 798 | GNUNET_SERVER_client_disconnect (client); |
808 | GNUNET_SERVER_client_drop (client); | 799 | GNUNET_SERVER_client_drop (client); |
@@ -821,7 +812,7 @@ process_mst (struct GNUNET_SERVER_Client *client, int ret) | |||
821 | */ | 812 | */ |
822 | static void | 813 | static void |
823 | process_incoming (void *cls, const void *buf, size_t available, | 814 | process_incoming (void *cls, const void *buf, size_t available, |
824 | const struct sockaddr *addr, socklen_t addrlen, int errCode) | 815 | const struct sockaddr *addr, socklen_t addrlen, int errCode) |
825 | { | 816 | { |
826 | struct GNUNET_SERVER_Client *client = cls; | 817 | struct GNUNET_SERVER_Client *client = cls; |
827 | struct GNUNET_SERVER_Handle *server = client->server; | 818 | struct GNUNET_SERVER_Handle *server = client->server; |
@@ -832,35 +823,34 @@ process_incoming (void *cls, const void *buf, size_t available, | |||
832 | GNUNET_assert (client->receive_pending == GNUNET_YES); | 823 | GNUNET_assert (client->receive_pending == GNUNET_YES); |
833 | client->receive_pending = GNUNET_NO; | 824 | client->receive_pending = GNUNET_NO; |
834 | now = GNUNET_TIME_absolute_get (); | 825 | now = GNUNET_TIME_absolute_get (); |
835 | end = | 826 | end = GNUNET_TIME_absolute_add (client->last_activity, client->idle_timeout); |
836 | GNUNET_TIME_absolute_add (client->last_activity, client->idle_timeout); | ||
837 | 827 | ||
838 | if ((buf == NULL) && (available == 0) && (addr == NULL) && (errCode == 0) && | 828 | if ((buf == NULL) && (available == 0) && (addr == NULL) && (errCode == 0) && |
839 | (client->shutdown_now != GNUNET_YES) && (server != NULL) && | 829 | (client->shutdown_now != GNUNET_YES) && (server != NULL) && |
840 | (GNUNET_YES == GNUNET_CONNECTION_check (client->connection)) && | 830 | (GNUNET_YES == GNUNET_CONNECTION_check (client->connection)) && |
841 | (end.abs_value > now.abs_value)) | 831 | (end.abs_value > now.abs_value)) |
842 | { | 832 | { |
843 | /* wait longer, timeout changed (i.e. due to us sending) */ | 833 | /* wait longer, timeout changed (i.e. due to us sending) */ |
844 | #if DEBUG_SERVER | 834 | #if DEBUG_SERVER |
845 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 835 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
846 | "Receive time out, but no disconnect due to sending (%p)\n", | 836 | "Receive time out, but no disconnect due to sending (%p)\n", |
847 | GNUNET_a2s (addr, addrlen)); | 837 | GNUNET_a2s (addr, addrlen)); |
848 | #endif | 838 | #endif |
849 | client->receive_pending = GNUNET_YES; | 839 | client->receive_pending = GNUNET_YES; |
850 | GNUNET_CONNECTION_receive (client->connection, | 840 | GNUNET_CONNECTION_receive (client->connection, |
851 | GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, | 841 | GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, |
852 | GNUNET_TIME_absolute_get_remaining (end), | 842 | GNUNET_TIME_absolute_get_remaining (end), |
853 | &process_incoming, client); | 843 | &process_incoming, client); |
854 | return; | 844 | return; |
855 | } | 845 | } |
856 | if ((buf == NULL) || (available == 0) || (errCode != 0) || (server == NULL) | 846 | if ((buf == NULL) || (available == 0) || (errCode != 0) || (server == NULL) || |
857 | || (client->shutdown_now == GNUNET_YES) | 847 | (client->shutdown_now == GNUNET_YES) || |
858 | || (GNUNET_YES != GNUNET_CONNECTION_check (client->connection))) | 848 | (GNUNET_YES != GNUNET_CONNECTION_check (client->connection))) |
859 | { | 849 | { |
860 | /* other side closed connection, error connecting, etc. */ | 850 | /* other side closed connection, error connecting, etc. */ |
861 | GNUNET_SERVER_client_disconnect (client); | 851 | GNUNET_SERVER_client_disconnect (client); |
862 | return; | 852 | return; |
863 | } | 853 | } |
864 | #if DEBUG_SERVER | 854 | #if DEBUG_SERVER |
865 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Server receives %u bytes from `%s'.\n", | 855 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Server receives %u bytes from `%s'.\n", |
866 | (unsigned int) available, GNUNET_a2s (addr, addrlen)); | 856 | (unsigned int) available, GNUNET_a2s (addr, addrlen)); |
@@ -868,8 +858,8 @@ process_incoming (void *cls, const void *buf, size_t available, | |||
868 | GNUNET_SERVER_client_keep (client); | 858 | GNUNET_SERVER_client_keep (client); |
869 | client->last_activity = now; | 859 | client->last_activity = now; |
870 | ret = | 860 | ret = |
871 | GNUNET_SERVER_mst_receive (client->mst, client, buf, available, GNUNET_NO, | 861 | GNUNET_SERVER_mst_receive (client->mst, client, buf, available, GNUNET_NO, |
872 | GNUNET_YES); | 862 | GNUNET_YES); |
873 | process_mst (client, ret); | 863 | process_mst (client, ret); |
874 | } | 864 | } |
875 | 865 | ||
@@ -890,23 +880,21 @@ restart_processing (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
890 | client->restart_task = GNUNET_SCHEDULER_NO_TASK; | 880 | client->restart_task = GNUNET_SCHEDULER_NO_TASK; |
891 | if ((0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) && | 881 | if ((0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) && |
892 | (GNUNET_NO == server->clients_ignore_shutdown)) | 882 | (GNUNET_NO == server->clients_ignore_shutdown)) |
893 | { | 883 | { |
894 | GNUNET_SERVER_client_disconnect (client); | 884 | GNUNET_SERVER_client_disconnect (client); |
895 | return; | 885 | return; |
896 | } | 886 | } |
897 | if (client->receive_pending == GNUNET_NO) | 887 | if (client->receive_pending == GNUNET_NO) |
898 | { | 888 | { |
899 | #if DEBUG_SERVER | 889 | #if DEBUG_SERVER |
900 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 890 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Server begins to read again from client.\n"); |
901 | "Server begins to read again from client.\n"); | ||
902 | #endif | 891 | #endif |
903 | client->receive_pending = GNUNET_YES; | 892 | client->receive_pending = GNUNET_YES; |
904 | GNUNET_CONNECTION_receive (client->connection, | 893 | GNUNET_CONNECTION_receive (client->connection, |
905 | GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, | 894 | GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, |
906 | client->idle_timeout, &process_incoming, | 895 | client->idle_timeout, &process_incoming, client); |
907 | client); | 896 | return; |
908 | return; | 897 | } |
909 | } | ||
910 | #if DEBUG_SERVER | 898 | #if DEBUG_SERVER |
911 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 899 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
912 | "Server continues processing messages still in the buffer.\n"); | 900 | "Server continues processing messages still in the buffer.\n"); |
@@ -927,7 +915,7 @@ restart_processing (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
927 | */ | 915 | */ |
928 | static void | 916 | static void |
929 | client_message_tokenizer_callback (void *cls, void *client, | 917 | client_message_tokenizer_callback (void *cls, void *client, |
930 | const struct GNUNET_MessageHeader *message) | 918 | const struct GNUNET_MessageHeader *message) |
931 | { | 919 | { |
932 | struct GNUNET_SERVER_Handle *server = cls; | 920 | struct GNUNET_SERVER_Handle *server = cls; |
933 | struct GNUNET_SERVER_Client *sender = client; | 921 | struct GNUNET_SERVER_Client *sender = client; |
@@ -961,14 +949,14 @@ client_message_tokenizer_callback (void *cls, void *client, | |||
961 | */ | 949 | */ |
962 | struct GNUNET_SERVER_Client * | 950 | struct GNUNET_SERVER_Client * |
963 | GNUNET_SERVER_connect_socket (struct GNUNET_SERVER_Handle *server, | 951 | GNUNET_SERVER_connect_socket (struct GNUNET_SERVER_Handle *server, |
964 | struct GNUNET_CONNECTION_Handle *connection) | 952 | struct GNUNET_CONNECTION_Handle *connection) |
965 | { | 953 | { |
966 | struct GNUNET_SERVER_Client *client; | 954 | struct GNUNET_SERVER_Client *client; |
967 | 955 | ||
968 | client = GNUNET_malloc (sizeof (struct GNUNET_SERVER_Client)); | 956 | client = GNUNET_malloc (sizeof (struct GNUNET_SERVER_Client)); |
969 | client->connection = connection; | 957 | client->connection = connection; |
970 | client->mst = | 958 | client->mst = |
971 | GNUNET_SERVER_mst_create (&client_message_tokenizer_callback, server); | 959 | GNUNET_SERVER_mst_create (&client_message_tokenizer_callback, server); |
972 | client->reference_count = 1; | 960 | client->reference_count = 1; |
973 | client->server = server; | 961 | client->server = server; |
974 | client->last_activity = GNUNET_TIME_absolute_get (); | 962 | client->last_activity = GNUNET_TIME_absolute_get (); |
@@ -979,8 +967,8 @@ GNUNET_SERVER_connect_socket (struct GNUNET_SERVER_Handle *server, | |||
979 | client->callback = NULL; | 967 | client->callback = NULL; |
980 | client->callback_cls = NULL; | 968 | client->callback_cls = NULL; |
981 | GNUNET_CONNECTION_receive (client->connection, | 969 | GNUNET_CONNECTION_receive (client->connection, |
982 | GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, | 970 | GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, |
983 | client->idle_timeout, &process_incoming, client); | 971 | client->idle_timeout, &process_incoming, client); |
984 | return client; | 972 | return client; |
985 | } | 973 | } |
986 | 974 | ||
@@ -995,7 +983,7 @@ GNUNET_SERVER_connect_socket (struct GNUNET_SERVER_Handle *server, | |||
995 | */ | 983 | */ |
996 | void | 984 | void |
997 | GNUNET_SERVER_client_set_timeout (struct GNUNET_SERVER_Client *client, | 985 | GNUNET_SERVER_client_set_timeout (struct GNUNET_SERVER_Client *client, |
998 | struct GNUNET_TIME_Relative timeout) | 986 | struct GNUNET_TIME_Relative timeout) |
999 | { | 987 | { |
1000 | client->idle_timeout = timeout; | 988 | client->idle_timeout = timeout; |
1001 | } | 989 | } |
@@ -1043,7 +1031,7 @@ GNUNET_SERVER_client_drop (struct GNUNET_SERVER_Client *client) | |||
1043 | */ | 1031 | */ |
1044 | int | 1032 | int |
1045 | GNUNET_SERVER_client_get_address (struct GNUNET_SERVER_Client *client, | 1033 | GNUNET_SERVER_client_get_address (struct GNUNET_SERVER_Client *client, |
1046 | void **addr, size_t * addrlen) | 1034 | void **addr, size_t * addrlen) |
1047 | { | 1035 | { |
1048 | return GNUNET_CONNECTION_get_address (client->connection, addr, addrlen); | 1036 | return GNUNET_CONNECTION_get_address (client->connection, addr, addrlen); |
1049 | } | 1037 | } |
@@ -1061,8 +1049,8 @@ GNUNET_SERVER_client_get_address (struct GNUNET_SERVER_Client *client, | |||
1061 | */ | 1049 | */ |
1062 | void | 1050 | void |
1063 | GNUNET_SERVER_disconnect_notify (struct GNUNET_SERVER_Handle *server, | 1051 | GNUNET_SERVER_disconnect_notify (struct GNUNET_SERVER_Handle *server, |
1064 | GNUNET_SERVER_DisconnectCallback callback, | 1052 | GNUNET_SERVER_DisconnectCallback callback, |
1065 | void *callback_cls) | 1053 | void *callback_cls) |
1066 | { | 1054 | { |
1067 | struct NotifyList *n; | 1055 | struct NotifyList *n; |
1068 | 1056 | ||
@@ -1083,8 +1071,8 @@ GNUNET_SERVER_disconnect_notify (struct GNUNET_SERVER_Handle *server, | |||
1083 | */ | 1071 | */ |
1084 | void | 1072 | void |
1085 | GNUNET_SERVER_disconnect_notify_cancel (struct GNUNET_SERVER_Handle *server, | 1073 | GNUNET_SERVER_disconnect_notify_cancel (struct GNUNET_SERVER_Handle *server, |
1086 | GNUNET_SERVER_DisconnectCallback | 1074 | GNUNET_SERVER_DisconnectCallback |
1087 | callback, void *callback_cls) | 1075 | callback, void *callback_cls) |
1088 | { | 1076 | { |
1089 | struct NotifyList *pos; | 1077 | struct NotifyList *pos; |
1090 | struct NotifyList *prev; | 1078 | struct NotifyList *prev; |
@@ -1092,17 +1080,17 @@ GNUNET_SERVER_disconnect_notify_cancel (struct GNUNET_SERVER_Handle *server, | |||
1092 | prev = NULL; | 1080 | prev = NULL; |
1093 | pos = server->disconnect_notify_list; | 1081 | pos = server->disconnect_notify_list; |
1094 | while (pos != NULL) | 1082 | while (pos != NULL) |
1095 | { | 1083 | { |
1096 | if ((pos->callback == callback) && (pos->callback_cls == callback_cls)) | 1084 | if ((pos->callback == callback) && (pos->callback_cls == callback_cls)) |
1097 | break; | 1085 | break; |
1098 | prev = pos; | 1086 | prev = pos; |
1099 | pos = pos->next; | 1087 | pos = pos->next; |
1100 | } | 1088 | } |
1101 | if (pos == NULL) | 1089 | if (pos == NULL) |
1102 | { | 1090 | { |
1103 | GNUNET_break (0); | 1091 | GNUNET_break (0); |
1104 | return; | 1092 | return; |
1105 | } | 1093 | } |
1106 | if (prev == NULL) | 1094 | if (prev == NULL) |
1107 | server->disconnect_notify_list = pos->next; | 1095 | server->disconnect_notify_list = pos->next; |
1108 | else | 1096 | else |
@@ -1133,72 +1121,72 @@ GNUNET_SERVER_client_disconnect (struct GNUNET_SERVER_Client *client) | |||
1133 | "Client is being disconnected from the server.\n"); | 1121 | "Client is being disconnected from the server.\n"); |
1134 | #endif | 1122 | #endif |
1135 | if (client->restart_task != GNUNET_SCHEDULER_NO_TASK) | 1123 | if (client->restart_task != GNUNET_SCHEDULER_NO_TASK) |
1124 | { | ||
1125 | GNUNET_SCHEDULER_cancel (client->restart_task); | ||
1126 | client->restart_task = GNUNET_SCHEDULER_NO_TASK; | ||
1127 | } | ||
1128 | if (client->warn_task != GNUNET_SCHEDULER_NO_TASK) | ||
1129 | { | ||
1130 | GNUNET_SCHEDULER_cancel (client->warn_task); | ||
1131 | client->warn_task = GNUNET_SCHEDULER_NO_TASK; | ||
1132 | } | ||
1133 | if (GNUNET_YES == client->receive_pending) | ||
1134 | { | ||
1135 | GNUNET_CONNECTION_receive_cancel (client->connection); | ||
1136 | client->receive_pending = GNUNET_NO; | ||
1137 | } | ||
1138 | |||
1139 | rc = client->reference_count; | ||
1140 | if (client->server != NULL) | ||
1141 | { | ||
1142 | server = client->server; | ||
1143 | client->server = NULL; | ||
1144 | client->shutdown_now = GNUNET_YES; | ||
1145 | prev = NULL; | ||
1146 | pos = server->clients; | ||
1147 | while ((pos != NULL) && (pos != client)) | ||
1148 | { | ||
1149 | prev = pos; | ||
1150 | pos = pos->next; | ||
1151 | } | ||
1152 | GNUNET_assert (pos != NULL); | ||
1153 | if (prev == NULL) | ||
1154 | server->clients = pos->next; | ||
1155 | else | ||
1156 | prev->next = pos->next; | ||
1157 | if (client->restart_task != GNUNET_SCHEDULER_NO_TASK) | ||
1136 | { | 1158 | { |
1137 | GNUNET_SCHEDULER_cancel (client->restart_task); | 1159 | GNUNET_SCHEDULER_cancel (client->restart_task); |
1138 | client->restart_task = GNUNET_SCHEDULER_NO_TASK; | 1160 | client->restart_task = GNUNET_SCHEDULER_NO_TASK; |
1139 | } | 1161 | } |
1140 | if (client->warn_task != GNUNET_SCHEDULER_NO_TASK) | 1162 | if (client->warn_task != GNUNET_SCHEDULER_NO_TASK) |
1141 | { | 1163 | { |
1142 | GNUNET_SCHEDULER_cancel (client->warn_task); | 1164 | GNUNET_SCHEDULER_cancel (client->warn_task); |
1143 | client->warn_task = GNUNET_SCHEDULER_NO_TASK; | 1165 | client->warn_task = GNUNET_SCHEDULER_NO_TASK; |
1144 | } | 1166 | } |
1145 | if (GNUNET_YES == client->receive_pending) | 1167 | n = server->disconnect_notify_list; |
1146 | { | 1168 | while (n != NULL) |
1147 | GNUNET_CONNECTION_receive_cancel (client->connection); | ||
1148 | client->receive_pending = GNUNET_NO; | ||
1149 | } | ||
1150 | |||
1151 | rc = client->reference_count; | ||
1152 | if (client->server != NULL) | ||
1153 | { | 1169 | { |
1154 | server = client->server; | 1170 | n->callback (n->callback_cls, client); |
1155 | client->server = NULL; | 1171 | n = n->next; |
1156 | client->shutdown_now = GNUNET_YES; | ||
1157 | prev = NULL; | ||
1158 | pos = server->clients; | ||
1159 | while ((pos != NULL) && (pos != client)) | ||
1160 | { | ||
1161 | prev = pos; | ||
1162 | pos = pos->next; | ||
1163 | } | ||
1164 | GNUNET_assert (pos != NULL); | ||
1165 | if (prev == NULL) | ||
1166 | server->clients = pos->next; | ||
1167 | else | ||
1168 | prev->next = pos->next; | ||
1169 | if (client->restart_task != GNUNET_SCHEDULER_NO_TASK) | ||
1170 | { | ||
1171 | GNUNET_SCHEDULER_cancel (client->restart_task); | ||
1172 | client->restart_task = GNUNET_SCHEDULER_NO_TASK; | ||
1173 | } | ||
1174 | if (client->warn_task != GNUNET_SCHEDULER_NO_TASK) | ||
1175 | { | ||
1176 | GNUNET_SCHEDULER_cancel (client->warn_task); | ||
1177 | client->warn_task = GNUNET_SCHEDULER_NO_TASK; | ||
1178 | } | ||
1179 | n = server->disconnect_notify_list; | ||
1180 | while (n != NULL) | ||
1181 | { | ||
1182 | n->callback (n->callback_cls, client); | ||
1183 | n = n->next; | ||
1184 | } | ||
1185 | } | 1172 | } |
1173 | } | ||
1186 | if (rc > 0) | 1174 | if (rc > 0) |
1187 | { | 1175 | { |
1188 | #if DEBUG_SERVER | 1176 | #if DEBUG_SERVER |
1189 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1177 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1190 | "RC still positive, not destroying everything.\n"); | 1178 | "RC still positive, not destroying everything.\n"); |
1191 | #endif | 1179 | #endif |
1192 | return; | 1180 | return; |
1193 | } | 1181 | } |
1194 | if (client->in_process_client_buffer == GNUNET_YES) | 1182 | if (client->in_process_client_buffer == GNUNET_YES) |
1195 | { | 1183 | { |
1196 | #if DEBUG_SERVER | 1184 | #if DEBUG_SERVER |
1197 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1185 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1198 | "Still processing inputs, not destroying everything.\n"); | 1186 | "Still processing inputs, not destroying everything.\n"); |
1199 | #endif | 1187 | #endif |
1200 | return; | 1188 | return; |
1201 | } | 1189 | } |
1202 | 1190 | ||
1203 | if (client->persist == GNUNET_YES) | 1191 | if (client->persist == GNUNET_YES) |
1204 | GNUNET_CONNECTION_persist_ (client->connection); | 1192 | GNUNET_CONNECTION_persist_ (client->connection); |
@@ -1262,17 +1250,17 @@ transmit_ready_callback_wrapper (void *cls, size_t size, void *buf) | |||
1262 | */ | 1250 | */ |
1263 | struct GNUNET_CONNECTION_TransmitHandle * | 1251 | struct GNUNET_CONNECTION_TransmitHandle * |
1264 | GNUNET_SERVER_notify_transmit_ready (struct GNUNET_SERVER_Client *client, | 1252 | GNUNET_SERVER_notify_transmit_ready (struct GNUNET_SERVER_Client *client, |
1265 | size_t size, | 1253 | size_t size, |
1266 | struct GNUNET_TIME_Relative timeout, | 1254 | struct GNUNET_TIME_Relative timeout, |
1267 | GNUNET_CONNECTION_TransmitReadyNotify | 1255 | GNUNET_CONNECTION_TransmitReadyNotify |
1268 | callback, void *callback_cls) | 1256 | callback, void *callback_cls) |
1269 | { | 1257 | { |
1270 | client->callback_cls = callback_cls; | 1258 | client->callback_cls = callback_cls; |
1271 | client->callback = callback; | 1259 | client->callback = callback; |
1272 | return GNUNET_CONNECTION_notify_transmit_ready (client->connection, size, | 1260 | return GNUNET_CONNECTION_notify_transmit_ready (client->connection, size, |
1273 | timeout, | 1261 | timeout, |
1274 | &transmit_ready_callback_wrapper, | 1262 | &transmit_ready_callback_wrapper, |
1275 | client); | 1263 | client); |
1276 | } | 1264 | } |
1277 | 1265 | ||
1278 | 1266 | ||
@@ -1309,47 +1297,46 @@ GNUNET_SERVER_receive_done (struct GNUNET_SERVER_Client *client, int success) | |||
1309 | GNUNET_assert (client->suspended > 0); | 1297 | GNUNET_assert (client->suspended > 0); |
1310 | client->suspended--; | 1298 | client->suspended--; |
1311 | if (success != GNUNET_OK) | 1299 | if (success != GNUNET_OK) |
1312 | { | 1300 | { |
1313 | #if DEBUG_SERVER | 1301 | #if DEBUG_SERVER |
1314 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1302 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1315 | "GNUNET_SERVER_receive_done called with failure indication\n"); | 1303 | "GNUNET_SERVER_receive_done called with failure indication\n"); |
1316 | #endif | 1304 | #endif |
1317 | GNUNET_SERVER_client_disconnect (client); | 1305 | GNUNET_SERVER_client_disconnect (client); |
1318 | return; | 1306 | return; |
1319 | } | 1307 | } |
1320 | if (client->suspended > 0) | 1308 | if (client->suspended > 0) |
1321 | { | 1309 | { |
1322 | #if DEBUG_SERVER | 1310 | #if DEBUG_SERVER |
1323 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1311 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1324 | "GNUNET_SERVER_receive_done called, but more clients pending\n"); | 1312 | "GNUNET_SERVER_receive_done called, but more clients pending\n"); |
1325 | #endif | 1313 | #endif |
1326 | return; | 1314 | return; |
1327 | } | 1315 | } |
1328 | if (GNUNET_SCHEDULER_NO_TASK != client->warn_task) | 1316 | if (GNUNET_SCHEDULER_NO_TASK != client->warn_task) |
1329 | { | 1317 | { |
1330 | GNUNET_SCHEDULER_cancel (client->warn_task); | 1318 | GNUNET_SCHEDULER_cancel (client->warn_task); |
1331 | client->warn_task = GNUNET_SCHEDULER_NO_TASK; | 1319 | client->warn_task = GNUNET_SCHEDULER_NO_TASK; |
1332 | } | 1320 | } |
1333 | if (client->in_process_client_buffer == GNUNET_YES) | 1321 | if (client->in_process_client_buffer == GNUNET_YES) |
1334 | { | 1322 | { |
1335 | #if DEBUG_SERVER | 1323 | #if DEBUG_SERVER |
1336 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1324 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1337 | "GNUNET_SERVER_receive_done called while still in processing loop\n"); | 1325 | "GNUNET_SERVER_receive_done called while still in processing loop\n"); |
1338 | #endif | 1326 | #endif |
1339 | return; | 1327 | return; |
1340 | } | 1328 | } |
1341 | if (client->server == NULL) | 1329 | if (client->server == NULL) |
1342 | { | 1330 | { |
1343 | GNUNET_SERVER_client_disconnect (client); | 1331 | GNUNET_SERVER_client_disconnect (client); |
1344 | return; | 1332 | return; |
1345 | } | 1333 | } |
1346 | #if DEBUG_SERVER | 1334 | #if DEBUG_SERVER |
1347 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1335 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1348 | "GNUNET_SERVER_receive_done causes restart in reading from the socket\n"); | 1336 | "GNUNET_SERVER_receive_done causes restart in reading from the socket\n"); |
1349 | #endif | 1337 | #endif |
1350 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == client->restart_task); | 1338 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == client->restart_task); |
1351 | client->restart_task = | 1339 | client->restart_task = GNUNET_SCHEDULER_add_now (&restart_processing, client); |
1352 | GNUNET_SCHEDULER_add_now (&restart_processing, client); | ||
1353 | } | 1340 | } |
1354 | 1341 | ||
1355 | 1342 | ||