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