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.c820
1 files changed, 401 insertions, 419 deletions
diff --git a/src/util/server.c b/src/util/server.c
index 6e2dc32cf..935cf04f8 100644
--- a/src/util/server.c
+++ b/src/util/server.c
@@ -242,7 +242,7 @@ struct GNUNET_SERVER_Client
242 * be used in special cases! 242 * be used in special cases!
243 */ 243 */
244 int persist; 244 int persist;
245 245
246 /** 246 /**
247 * Type of last message processed (for warn_no_receive_done). 247 * Type of last message processed (for warn_no_receive_done).
248 */ 248 */
@@ -258,8 +258,7 @@ struct GNUNET_SERVER_Client
258 * @param tc reason why we are running right now 258 * @param tc reason why we are running right now
259 */ 259 */
260static void 260static void
261process_listen_socket (void *cls, 261process_listen_socket (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
262 const struct GNUNET_SCHEDULER_TaskContext *tc)
263{ 262{
264 struct GNUNET_SERVER_Handle *server = cls; 263 struct GNUNET_SERVER_Handle *server = cls;
265 struct GNUNET_CONNECTION_Handle *sock; 264 struct GNUNET_CONNECTION_Handle *sock;
@@ -273,49 +272,46 @@ process_listen_socket (void *cls,
273 while (NULL != server->listen_sockets[i]) 272 while (NULL != server->listen_sockets[i])
274 GNUNET_NETWORK_fdset_set (r, server->listen_sockets[i++]); 273 GNUNET_NETWORK_fdset_set (r, server->listen_sockets[i++]);
275 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) 274 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
276 { 275 {
277 /* ignore shutdown, someone else will take care of it! */ 276 /* ignore shutdown, someone else will take care of it! */
278 server->listen_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH, 277 server->listen_task =
279 GNUNET_SCHEDULER_NO_TASK, 278 GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH,
280 GNUNET_TIME_UNIT_FOREVER_REL, 279 GNUNET_SCHEDULER_NO_TASK,
281 r, NULL, 280 GNUNET_TIME_UNIT_FOREVER_REL, r, NULL,
282 &process_listen_socket, 281 &process_listen_socket, server);
283 server); 282 GNUNET_NETWORK_fdset_destroy (r);
284 GNUNET_NETWORK_fdset_destroy (r); 283 return;
285 return; 284 }
286 }
287 i = 0; 285 i = 0;
288 while (NULL != server->listen_sockets[i]) 286 while (NULL != server->listen_sockets[i])
287 {
288 if (GNUNET_NETWORK_fdset_isset (tc->read_ready, server->listen_sockets[i]))
289 { 289 {
290 if (GNUNET_NETWORK_fdset_isset 290 sock =
291 (tc->read_ready, server->listen_sockets[i])) 291 GNUNET_CONNECTION_create_from_accept (server->access,
292 { 292 server->access_cls,
293 sock = 293 server->listen_sockets[i]);
294 GNUNET_CONNECTION_create_from_accept (server->access, 294 if (sock != NULL)
295 server->access_cls, 295 {
296 server->listen_sockets[i]);
297 if (sock != NULL)
298 {
299#if DEBUG_SERVER 296#if DEBUG_SERVER
300 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 297 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
301 "Server accepted incoming connection.\n"); 298 "Server accepted incoming connection.\n");
302#endif 299#endif
303 client = GNUNET_SERVER_connect_socket (server, sock); 300 client = GNUNET_SERVER_connect_socket (server, sock);
304 GNUNET_CONNECTION_ignore_shutdown (sock, 301 GNUNET_CONNECTION_ignore_shutdown (sock,
305 server->clients_ignore_shutdown); 302 server->clients_ignore_shutdown);
306 /* decrement reference count, we don't keep "client" alive */ 303 /* decrement reference count, we don't keep "client" alive */
307 GNUNET_SERVER_client_drop (client); 304 GNUNET_SERVER_client_drop (client);
308 } 305 }
309 }
310 i++;
311 } 306 }
307 i++;
308 }
312 /* listen for more! */ 309 /* listen for more! */
313 server->listen_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH, 310 server->listen_task =
314 GNUNET_SCHEDULER_NO_TASK, 311 GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH,
315 GNUNET_TIME_UNIT_FOREVER_REL, 312 GNUNET_SCHEDULER_NO_TASK,
316 r, NULL, 313 GNUNET_TIME_UNIT_FOREVER_REL, r, NULL,
317 &process_listen_socket, 314 &process_listen_socket, server);
318 server);
319 GNUNET_NETWORK_fdset_destroy (r); 315 GNUNET_NETWORK_fdset_destroy (r);
320} 316}
321 317
@@ -336,88 +332,88 @@ open_listen_socket (const struct sockaddr *serverAddr, socklen_t socklen)
336 int eno; 332 int eno;
337 333
338 switch (serverAddr->sa_family) 334 switch (serverAddr->sa_family)
339 { 335 {
340 case AF_INET: 336 case AF_INET:
341 port = ntohs (((const struct sockaddr_in *) serverAddr)->sin_port); 337 port = ntohs (((const struct sockaddr_in *) serverAddr)->sin_port);
342 break; 338 break;
343 case AF_INET6: 339 case AF_INET6:
344 port = ntohs (((const struct sockaddr_in6 *) serverAddr)->sin6_port); 340 port = ntohs (((const struct sockaddr_in6 *) serverAddr)->sin6_port);
345 break; 341 break;
346 case AF_UNIX: 342 case AF_UNIX:
347 port = 0; 343 port = 0;
348 break; 344 break;
349 default: 345 default:
350 GNUNET_break (0); 346 GNUNET_break (0);
351 port = 0; 347 port = 0;
352 break; 348 break;
353 } 349 }
354 sock = GNUNET_NETWORK_socket_create (serverAddr->sa_family, SOCK_STREAM, 0); 350 sock = GNUNET_NETWORK_socket_create (serverAddr->sa_family, SOCK_STREAM, 0);
355 if (NULL == sock) 351 if (NULL == sock)
356 { 352 {
357 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "socket"); 353 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "socket");
358 errno = 0; 354 errno = 0;
359 return NULL; 355 return NULL;
360 } 356 }
361 if (port != 0) 357 if (port != 0)
362 { 358 {
363 if (GNUNET_NETWORK_socket_setsockopt 359 if (GNUNET_NETWORK_socket_setsockopt
364 (sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) != GNUNET_OK) 360 (sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) != GNUNET_OK)
365 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 361 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
366 "setsockopt"); 362 "setsockopt");
367#ifdef IPV6_V6ONLY 363#ifdef IPV6_V6ONLY
368 if ( (serverAddr->sa_family == AF_INET6) && 364 if ((serverAddr->sa_family == AF_INET6) &&
369 (GNUNET_NETWORK_socket_setsockopt 365 (GNUNET_NETWORK_socket_setsockopt
370 (sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof (on)) != GNUNET_OK) ) 366 (sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof (on)) != GNUNET_OK))
371 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 367 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
372 "setsockopt"); 368 "setsockopt");
373#endif 369#endif
374 } 370 }
375 /* bind the socket */ 371 /* bind the socket */
376 if (GNUNET_NETWORK_socket_bind (sock, serverAddr, socklen) != GNUNET_OK) 372 if (GNUNET_NETWORK_socket_bind (sock, serverAddr, socklen) != GNUNET_OK)
373 {
374 eno = errno;
375 if (errno != EADDRINUSE)
377 { 376 {
378 eno = errno; 377 /* we don't log 'EADDRINUSE' here since an IPv4 bind may
379 if (errno != EADDRINUSE) 378 * fail if we already took the port on IPv6; if both IPv4 and
380 { 379 * IPv6 binds fail, then our caller will log using the
381 /* we don't log 'EADDRINUSE' here since an IPv4 bind may 380 * errno preserved in 'eno' */
382 fail if we already took the port on IPv6; if both IPv4 and 381 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "bind");
383 IPv6 binds fail, then our caller will log using the 382 if (port != 0)
384 errno preserved in 'eno' */ 383 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
385 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "bind"); 384 _
386 if (port != 0) 385 ("`%s' failed for port %d (%s).\n"),
387 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 386 "bind", port,
388 _ 387 (serverAddr->sa_family == AF_INET) ? "IPv4" : "IPv6");
389 ("`%s' failed for port %d (%s).\n"), 388 eno = 0;
390 "bind", port,
391 (serverAddr->sa_family == AF_INET) ? "IPv4" : "IPv6");
392 eno = 0;
393 }
394 else
395 {
396 if (port != 0)
397 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
398 _
399 ("`%s' failed for port %d (%s): address already in use\n"),
400 "bind", port,
401 (serverAddr->sa_family == AF_INET) ? "IPv4" : "IPv6");
402 else if (serverAddr->sa_family == AF_UNIX)
403 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
404 _
405 ("`%s' failed for `%s': address already in use\n"),
406 "bind",
407 ((const struct sockaddr_un*) serverAddr)->sun_path);
408
409 }
410 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
411 errno = eno;
412 return NULL;
413 } 389 }
414 if (GNUNET_OK != GNUNET_NETWORK_socket_listen (sock, 5)) 390 else
415 { 391 {
416 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "listen"); 392 if (port != 0)
417 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); 393 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
418 errno = 0; 394 _
419 return NULL; 395 ("`%s' failed for port %d (%s): address already in use\n"),
396 "bind", port,
397 (serverAddr->sa_family == AF_INET) ? "IPv4" : "IPv6");
398 else if (serverAddr->sa_family == AF_UNIX)
399 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
400 _
401 ("`%s' failed for `%s': address already in use\n"),
402 "bind",
403 ((const struct sockaddr_un *) serverAddr)->sun_path);
404
420 } 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 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "listen");
413 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
414 errno = 0;
415 return NULL;
416 }
421#if DEBUG_SERVER 417#if DEBUG_SERVER
422 if (port != 0) 418 if (port != 0)
423 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 419 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -440,11 +436,11 @@ open_listen_socket (const struct sockaddr *serverAddr, socklen_t socklen)
440 * (typically, "port" already in use) 436 * (typically, "port" already in use)
441 */ 437 */
442struct GNUNET_SERVER_Handle * 438struct GNUNET_SERVER_Handle *
443GNUNET_SERVER_create_with_sockets (GNUNET_CONNECTION_AccessCheck access, void *access_cls, 439GNUNET_SERVER_create_with_sockets (GNUNET_CONNECTION_AccessCheck access,
444 struct GNUNET_NETWORK_Handle **lsocks, 440 void *access_cls,
445 struct GNUNET_TIME_Relative 441 struct GNUNET_NETWORK_Handle **lsocks,
446 idle_timeout, 442 struct GNUNET_TIME_Relative idle_timeout,
447 int require_found) 443 int require_found)
448{ 444{
449 struct GNUNET_SERVER_Handle *ret; 445 struct GNUNET_SERVER_Handle *ret;
450 struct GNUNET_NETWORK_FDSet *r; 446 struct GNUNET_NETWORK_FDSet *r;
@@ -457,19 +453,18 @@ GNUNET_SERVER_create_with_sockets (GNUNET_CONNECTION_AccessCheck access, void *a
457 ret->access_cls = access_cls; 453 ret->access_cls = access_cls;
458 ret->require_found = require_found; 454 ret->require_found = require_found;
459 if (lsocks != NULL) 455 if (lsocks != NULL)
460 { 456 {
461 r = GNUNET_NETWORK_fdset_create (); 457 r = GNUNET_NETWORK_fdset_create ();
462 i = 0; 458 i = 0;
463 while (NULL != ret->listen_sockets[i]) 459 while (NULL != ret->listen_sockets[i])
464 GNUNET_NETWORK_fdset_set (r, ret->listen_sockets[i++]); 460 GNUNET_NETWORK_fdset_set (r, ret->listen_sockets[i++]);
465 ret->listen_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH, 461 ret->listen_task =
466 GNUNET_SCHEDULER_NO_TASK, 462 GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH,
467 GNUNET_TIME_UNIT_FOREVER_REL, 463 GNUNET_SCHEDULER_NO_TASK,
468 r, NULL, 464 GNUNET_TIME_UNIT_FOREVER_REL, r, NULL,
469 &process_listen_socket, 465 &process_listen_socket, ret);
470 ret); 466 GNUNET_NETWORK_fdset_destroy (r);
471 GNUNET_NETWORK_fdset_destroy (r); 467 }
472 }
473 return ret; 468 return ret;
474} 469}
475 470
@@ -503,34 +498,32 @@ GNUNET_SERVER_create (GNUNET_CONNECTION_AccessCheck access,
503 while (serverAddr[i] != NULL) 498 while (serverAddr[i] != NULL)
504 i++; 499 i++;
505 if (i > 0) 500 if (i > 0)
501 {
502 lsocks = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle *) * (i + 1));
503 i = 0;
504 j = 0;
505 while (serverAddr[i] != NULL)
506 { 506 {
507 lsocks = 507 lsocks[j] = open_listen_socket (serverAddr[i], socklen[i]);
508 GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle *) * (i + 1)); 508 if (lsocks[j] != NULL)
509 i = 0; 509 j++;
510 j = 0; 510 i++;
511 while (serverAddr[i] != NULL)
512 {
513 lsocks[j] = open_listen_socket (serverAddr[i], socklen[i]);
514 if (lsocks[j] != NULL)
515 j++;
516 i++;
517 }
518 if (j == 0)
519 {
520 if (errno != 0)
521 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "bind");
522 GNUNET_free (lsocks);
523 lsocks = NULL;
524 }
525 } 511 }
526 else 512 if (j == 0)
527 { 513 {
514 if (errno != 0)
515 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "bind");
516 GNUNET_free (lsocks);
528 lsocks = NULL; 517 lsocks = NULL;
529 } 518 }
519 }
520 else
521 {
522 lsocks = NULL;
523 }
530 return GNUNET_SERVER_create_with_sockets (access, access_cls, 524 return GNUNET_SERVER_create_with_sockets (access, access_cls,
531 lsocks, 525 lsocks,
532 idle_timeout, 526 idle_timeout, require_found);
533 require_found);
534} 527}
535 528
536 529
@@ -550,32 +543,32 @@ GNUNET_SERVER_destroy (struct GNUNET_SERVER_Handle *s)
550 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Server shutting down.\n"); 543 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Server shutting down.\n");
551#endif 544#endif
552 if (GNUNET_SCHEDULER_NO_TASK != s->listen_task) 545 if (GNUNET_SCHEDULER_NO_TASK != s->listen_task)
553 { 546 {
554 GNUNET_SCHEDULER_cancel (s->listen_task); 547 GNUNET_SCHEDULER_cancel (s->listen_task);
555 s->listen_task = GNUNET_SCHEDULER_NO_TASK; 548 s->listen_task = GNUNET_SCHEDULER_NO_TASK;
556 } 549 }
557 if (s->listen_sockets != NULL) 550 if (s->listen_sockets != NULL)
558 { 551 {
559 i = 0; 552 i = 0;
560 while (s->listen_sockets[i] != NULL) 553 while (s->listen_sockets[i] != NULL)
561 GNUNET_break (GNUNET_OK == 554 GNUNET_break (GNUNET_OK ==
562 GNUNET_NETWORK_socket_close (s->listen_sockets[i++])); 555 GNUNET_NETWORK_socket_close (s->listen_sockets[i++]));
563 GNUNET_free (s->listen_sockets); 556 GNUNET_free (s->listen_sockets);
564 s->listen_sockets = NULL; 557 s->listen_sockets = NULL;
565 } 558 }
566 while (s->clients != NULL) 559 while (s->clients != NULL)
567 GNUNET_SERVER_client_disconnect (s->clients); 560 GNUNET_SERVER_client_disconnect (s->clients);
568 while (NULL != (hpos = s->handlers)) 561 while (NULL != (hpos = s->handlers))
569 { 562 {
570 s->handlers = hpos->next; 563 s->handlers = hpos->next;
571 GNUNET_free (hpos); 564 GNUNET_free (hpos);
572 } 565 }
573 while (NULL != (npos = s->disconnect_notify_list)) 566 while (NULL != (npos = s->disconnect_notify_list))
574 { 567 {
575 npos->callback (npos->callback_cls, NULL); 568 npos->callback (npos->callback_cls, NULL);
576 s->disconnect_notify_list = npos->next; 569 s->disconnect_notify_list = npos->next;
577 GNUNET_free (npos); 570 GNUNET_free (npos);
578 } 571 }
579 GNUNET_free (s); 572 GNUNET_free (s);
580} 573}
581 574
@@ -595,8 +588,7 @@ GNUNET_SERVER_destroy (struct GNUNET_SERVER_Handle *s)
595 */ 588 */
596void 589void
597GNUNET_SERVER_add_handlers (struct GNUNET_SERVER_Handle *server, 590GNUNET_SERVER_add_handlers (struct GNUNET_SERVER_Handle *server,
598 const struct GNUNET_SERVER_MessageHandler 591 const struct GNUNET_SERVER_MessageHandler *handlers)
599 *handlers)
600{ 592{
601 struct HandlerList *p; 593 struct HandlerList *p;
602 594
@@ -614,19 +606,21 @@ GNUNET_SERVER_add_handlers (struct GNUNET_SERVER_Handle *server,
614 * @param tc scheduler context (unused) 606 * @param tc scheduler context (unused)
615 */ 607 */
616static void 608static void
617warn_no_receive_done (void *cls, 609warn_no_receive_done (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
618 const struct GNUNET_SCHEDULER_TaskContext *tc)
619{ 610{
620 struct GNUNET_SERVER_Client *client = cls; 611 struct GNUNET_SERVER_Client *client = cls;
621 612
622 client->warn_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, 613 client->warn_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
623 &warn_no_receive_done, 614 &warn_no_receive_done,
624 client); 615 client);
625 if (0 == (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason)) 616 if (0 == (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
626 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 617 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
627 _("Processing code for message of type %u did not call GNUNET_SERVER_receive_done after %llums\n"), 618 _
628 (unsigned int) client->warn_type, 619 ("Processing code for message of type %u did not call GNUNET_SERVER_receive_done after %llums\n"),
629 (unsigned long long) GNUNET_TIME_absolute_get_duration (client->warn_start).rel_value); 620 (unsigned int) client->warn_type,
621 (unsigned long long)
622 GNUNET_TIME_absolute_get_duration
623 (client->warn_start).rel_value);
630} 624}
631 625
632 626
@@ -641,10 +635,10 @@ void
641GNUNET_SERVER_disable_receive_done_warning (struct GNUNET_SERVER_Client *client) 635GNUNET_SERVER_disable_receive_done_warning (struct GNUNET_SERVER_Client *client)
642{ 636{
643 if (GNUNET_SCHEDULER_NO_TASK != client->warn_task) 637 if (GNUNET_SCHEDULER_NO_TASK != client->warn_task)
644 { 638 {
645 GNUNET_SCHEDULER_cancel (client->warn_task); 639 GNUNET_SCHEDULER_cancel (client->warn_task);
646 client->warn_task = GNUNET_SCHEDULER_NO_TASK; 640 client->warn_task = GNUNET_SCHEDULER_NO_TASK;
647 } 641 }
648} 642}
649 643
650 644
@@ -686,53 +680,49 @@ GNUNET_SERVER_inject (struct GNUNET_SERVER_Handle *server,
686 pos = server->handlers; 680 pos = server->handlers;
687 found = GNUNET_NO; 681 found = GNUNET_NO;
688 while (pos != NULL) 682 while (pos != NULL)
683 {
684 i = 0;
685 while (pos->handlers[i].callback != NULL)
689 { 686 {
690 i = 0; 687 mh = &pos->handlers[i];
691 while (pos->handlers[i].callback != NULL) 688 if ((mh->type == type) || (mh->type == GNUNET_MESSAGE_TYPE_ALL))
689 {
690 if ((mh->expected_size != 0) && (mh->expected_size != size))
692 { 691 {
693 mh = &pos->handlers[i];
694 if ( (mh->type == type) ||
695 (mh->type == GNUNET_MESSAGE_TYPE_ALL) )
696 {
697 if ((mh->expected_size != 0) && (mh->expected_size != size))
698 {
699#if GNUNET8_NETWORK_IS_DEAD 692#if GNUNET8_NETWORK_IS_DEAD
700 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 693 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
701 "Expected %u bytes for message of type %u, got %u\n", 694 "Expected %u bytes for message of type %u, got %u\n",
702 mh->expected_size, 695 mh->expected_size, mh->type, size);
703 mh->type, 696 GNUNET_break_op (0);
704 size);
705 GNUNET_break_op (0);
706#endif 697#endif
707 return GNUNET_SYSERR; 698 return GNUNET_SYSERR;
708 }
709 if (sender != NULL)
710 {
711 if (0 == sender->suspended)
712 {
713 sender->warn_start = GNUNET_TIME_absolute_get ();
714 sender->warn_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
715 &warn_no_receive_done,
716 sender);
717 sender->warn_type = type;
718 }
719 sender->suspended++;
720 }
721 mh->callback (mh->callback_cls, sender, message);
722 found = GNUNET_YES;
723 }
724 i++;
725 } 699 }
726 pos = pos->next; 700 if (sender != NULL)
701 {
702 if (0 == sender->suspended)
703 {
704 sender->warn_start = GNUNET_TIME_absolute_get ();
705 sender->warn_task =
706 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
707 &warn_no_receive_done, sender);
708 sender->warn_type = type;
709 }
710 sender->suspended++;
711 }
712 mh->callback (mh->callback_cls, sender, message);
713 found = GNUNET_YES;
714 }
715 i++;
727 } 716 }
717 pos = pos->next;
718 }
728 if (found == GNUNET_NO) 719 if (found == GNUNET_NO)
729 { 720 {
730 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, 721 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
731 "Received message of unknown type %d\n", 722 "Received message of unknown type %d\n", type);
732 type); 723 if (server->require_found == GNUNET_YES)
733 if (server->require_found == GNUNET_YES) 724 return GNUNET_SYSERR;
734 return GNUNET_SYSERR; 725 }
735 }
736 return GNUNET_OK; 726 return GNUNET_OK;
737} 727}
738 728
@@ -751,8 +741,7 @@ static void
751process_incoming (void *cls, 741process_incoming (void *cls,
752 const void *buf, 742 const void *buf,
753 size_t available, 743 size_t available,
754 const struct sockaddr *addr, 744 const struct sockaddr *addr, socklen_t addrlen, int errCode);
755 socklen_t addrlen, int errCode);
756 745
757 746
758/** 747/**
@@ -769,51 +758,49 @@ process_incoming (void *cls,
769 * GNUNET_SYSERR if we should instantly abort due to error in a previous step 758 * GNUNET_SYSERR if we should instantly abort due to error in a previous step
770 */ 759 */
771static void 760static void
772process_mst (struct GNUNET_SERVER_Client *client, 761process_mst (struct GNUNET_SERVER_Client *client, int ret)
773 int ret)
774{ 762{
775 while ( (ret != GNUNET_SYSERR) && 763 while ((ret != GNUNET_SYSERR) &&
776 (client->server != NULL) && 764 (client->server != NULL) &&
777 (GNUNET_YES != client->shutdown_now) && 765 (GNUNET_YES != client->shutdown_now) && (0 == client->suspended))
778 (0 == client->suspended) ) 766 {
767 if (ret == GNUNET_OK)
779 { 768 {
780 if (ret == GNUNET_OK) 769 client->receive_pending = GNUNET_YES;
781 {
782 client->receive_pending = GNUNET_YES;
783#if DEBUG_SERVER 770#if DEBUG_SERVER
784 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 771 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
785 "Server re-enters receive loop, timeout: %llu.\n", client->idle_timeout.rel_value); 772 "Server re-enters receive loop, timeout: %llu.\n",
773 client->idle_timeout.rel_value);
786#endif 774#endif
787 GNUNET_CONNECTION_receive (client->connection, 775 GNUNET_CONNECTION_receive (client->connection,
788 GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, 776 GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
789 client->idle_timeout, 777 client->idle_timeout,
790 &process_incoming, client); 778 &process_incoming, client);
791 break; 779 break;
792 } 780 }
793#if DEBUG_SERVER 781#if DEBUG_SERVER
794 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Server processes additional messages instantly.\n"); 782 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
783 "Server processes additional messages instantly.\n");
795#endif 784#endif
796 ret = GNUNET_SERVER_mst_receive (client->mst, client, NULL, 0, GNUNET_NO, GNUNET_YES); 785 ret =
797 } 786 GNUNET_SERVER_mst_receive (client->mst, client, NULL, 0, GNUNET_NO,
787 GNUNET_YES);
788 }
798#if DEBUG_SERVER 789#if DEBUG_SERVER
799 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 790 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
800 "Server leaves instant processing loop: ret = %d, server = %p, shutdown = %d, suspended = %u\n", 791 "Server leaves instant processing loop: ret = %d, server = %p, shutdown = %d, suspended = %u\n",
801 ret, 792 ret, client->server, client->shutdown_now, client->suspended);
802 client->server,
803 client->shutdown_now,
804 client->suspended);
805#endif 793#endif
806 794
807 if (ret == GNUNET_NO) 795 if (ret == GNUNET_NO)
808 { 796 {
809#if DEBUG_SERVER 797#if DEBUG_SERVER
810 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 798 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
811 "Server has more data pending but is suspended.\n"); 799 "Server has more data pending but is suspended.\n");
812#endif 800#endif
813 client->receive_pending = GNUNET_SYSERR; /* data pending */ 801 client->receive_pending = GNUNET_SYSERR; /* data pending */
814 } 802 }
815 if ( (ret == GNUNET_SYSERR) || 803 if ((ret == GNUNET_SYSERR) || (GNUNET_YES == client->shutdown_now))
816 (GNUNET_YES == client->shutdown_now) )
817 GNUNET_SERVER_client_disconnect (client); 804 GNUNET_SERVER_client_disconnect (client);
818 GNUNET_SERVER_client_drop (client); 805 GNUNET_SERVER_client_drop (client);
819} 806}
@@ -833,8 +820,7 @@ static void
833process_incoming (void *cls, 820process_incoming (void *cls,
834 const void *buf, 821 const void *buf,
835 size_t available, 822 size_t available,
836 const struct sockaddr *addr, 823 const struct sockaddr *addr, socklen_t addrlen, int errCode)
837 socklen_t addrlen, int errCode)
838{ 824{
839 struct GNUNET_SERVER_Client *client = cls; 825 struct GNUNET_SERVER_Client *client = cls;
840 struct GNUNET_SERVER_Handle *server = client->server; 826 struct GNUNET_SERVER_Handle *server = client->server;
@@ -845,48 +831,48 @@ process_incoming (void *cls,
845 GNUNET_assert (client->receive_pending == GNUNET_YES); 831 GNUNET_assert (client->receive_pending == GNUNET_YES);
846 client->receive_pending = GNUNET_NO; 832 client->receive_pending = GNUNET_NO;
847 now = GNUNET_TIME_absolute_get (); 833 now = GNUNET_TIME_absolute_get ();
848 end = GNUNET_TIME_absolute_add (client->last_activity, 834 end = GNUNET_TIME_absolute_add (client->last_activity, client->idle_timeout);
849 client->idle_timeout); 835
850 836 if ((buf == NULL) && (available == 0) && (addr == NULL) && (errCode == 0) &&
851 if ( (buf == NULL) && (available == 0) && (addr == NULL) && (errCode == 0) && 837 (client->shutdown_now != GNUNET_YES) &&
852 (client->shutdown_now != GNUNET_YES) && 838 (server != NULL) &&
853 (server != NULL) && 839 (GNUNET_YES == GNUNET_CONNECTION_check (client->connection)) &&
854 (GNUNET_YES == GNUNET_CONNECTION_check (client->connection)) && 840 (end.abs_value > now.abs_value))
855 (end.abs_value > now.abs_value) ) 841 {
856 { 842 /* wait longer, timeout changed (i.e. due to us sending) */
857 /* wait longer, timeout changed (i.e. due to us sending) */
858#if DEBUG_SERVER 843#if DEBUG_SERVER
859 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 844 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
860 "Receive time out, but no disconnect due to sending (%p)\n", 845 "Receive time out, but no disconnect due to sending (%p)\n",
861 GNUNET_a2s (addr, addrlen)); 846 GNUNET_a2s (addr, addrlen));
862#endif 847#endif
863 client->receive_pending = GNUNET_YES; 848 client->receive_pending = GNUNET_YES;
864 GNUNET_CONNECTION_receive (client->connection, 849 GNUNET_CONNECTION_receive (client->connection,
865 GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, 850 GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
866 GNUNET_TIME_absolute_get_remaining (end), 851 GNUNET_TIME_absolute_get_remaining (end),
867 &process_incoming, client); 852 &process_incoming, client);
868 return; 853 return;
869 } 854 }
870 if ((buf == NULL) || 855 if ((buf == NULL) ||
871 (available == 0) || 856 (available == 0) ||
872 (errCode != 0) || 857 (errCode != 0) ||
873 (server == NULL) || 858 (server == NULL) ||
874 (client->shutdown_now == GNUNET_YES) || 859 (client->shutdown_now == GNUNET_YES) ||
875 (GNUNET_YES != GNUNET_CONNECTION_check (client->connection))) 860 (GNUNET_YES != GNUNET_CONNECTION_check (client->connection)))
876 { 861 {
877 /* other side closed connection, error connecting, etc. */ 862 /* other side closed connection, error connecting, etc. */
878 GNUNET_SERVER_client_disconnect (client); 863 GNUNET_SERVER_client_disconnect (client);
879 return; 864 return;
880 } 865 }
881#if DEBUG_SERVER 866#if DEBUG_SERVER
882 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 867 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
883 "Server receives %u bytes from `%s'.\n", 868 "Server receives %u bytes from `%s'.\n",
884 (unsigned int) available, 869 (unsigned int) available, GNUNET_a2s (addr, addrlen));
885 GNUNET_a2s (addr, addrlen));
886#endif 870#endif
887 GNUNET_SERVER_client_keep (client); 871 GNUNET_SERVER_client_keep (client);
888 client->last_activity = now; 872 client->last_activity = now;
889 ret = GNUNET_SERVER_mst_receive (client->mst, client, buf, available, GNUNET_NO, GNUNET_YES); 873 ret =
874 GNUNET_SERVER_mst_receive (client->mst, client, buf, available, GNUNET_NO,
875 GNUNET_YES);
890 process_mst (client, ret); 876 process_mst (client, ret);
891} 877}
892 878
@@ -899,34 +885,33 @@ process_incoming (void *cls,
899 * @param tc scheduler context (unused) 885 * @param tc scheduler context (unused)
900 */ 886 */
901static void 887static void
902restart_processing (void *cls, 888restart_processing (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
903 const struct GNUNET_SCHEDULER_TaskContext *tc)
904{ 889{
905 struct GNUNET_SERVER_Client *client = cls; 890 struct GNUNET_SERVER_Client *client = cls;
906 struct GNUNET_SERVER_Handle *server = client->server; 891 struct GNUNET_SERVER_Handle *server = client->server;
907 892
908 client->restart_task = GNUNET_SCHEDULER_NO_TASK; 893 client->restart_task = GNUNET_SCHEDULER_NO_TASK;
909 if ( (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) && 894 if ((0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) &&
910 (GNUNET_NO == server->clients_ignore_shutdown) ) 895 (GNUNET_NO == server->clients_ignore_shutdown))
911 { 896 {
912 GNUNET_SERVER_client_disconnect (client); 897 GNUNET_SERVER_client_disconnect (client);
913 return; 898 return;
914 } 899 }
915 if (client->receive_pending == GNUNET_NO) 900 if (client->receive_pending == GNUNET_NO)
916 { 901 {
917#if DEBUG_SERVER 902#if DEBUG_SERVER
918 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 903 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
919 "Server begins to read again from client.\n"); 904 "Server begins to read again from client.\n");
920#endif 905#endif
921 client->receive_pending = GNUNET_YES; 906 client->receive_pending = GNUNET_YES;
922 GNUNET_CONNECTION_receive (client->connection, 907 GNUNET_CONNECTION_receive (client->connection,
923 GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, 908 GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
924 client->idle_timeout, &process_incoming, client); 909 client->idle_timeout, &process_incoming, client);
925 return; 910 return;
926 } 911 }
927#if DEBUG_SERVER 912#if DEBUG_SERVER
928 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 913 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
929 "Server continues processing messages still in the buffer.\n"); 914 "Server continues processing messages still in the buffer.\n");
930#endif 915#endif
931 GNUNET_SERVER_client_keep (client); 916 GNUNET_SERVER_client_keep (client);
932 client->receive_pending = GNUNET_NO; 917 client->receive_pending = GNUNET_NO;
@@ -944,8 +929,8 @@ restart_processing (void *cls,
944 */ 929 */
945static void 930static void
946client_message_tokenizer_callback (void *cls, 931client_message_tokenizer_callback (void *cls,
947 void *client, 932 void *client,
948 const struct GNUNET_MessageHeader *message) 933 const struct GNUNET_MessageHeader *message)
949{ 934{
950 struct GNUNET_SERVER_Handle *server = cls; 935 struct GNUNET_SERVER_Handle *server = cls;
951 struct GNUNET_SERVER_Client *sender = client; 936 struct GNUNET_SERVER_Client *sender = client;
@@ -954,14 +939,14 @@ client_message_tokenizer_callback (void *cls,
954#if DEBUG_SERVER 939#if DEBUG_SERVER
955 940
956 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 941 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
957 "Tokenizer gives server message of type %u from client\n", 942 "Tokenizer gives server message of type %u from client\n",
958 ntohs (message->type)); 943 ntohs (message->type));
959#endif 944#endif
960 sender->in_process_client_buffer = GNUNET_YES; 945 sender->in_process_client_buffer = GNUNET_YES;
961 ret = GNUNET_SERVER_inject (server, sender, message); 946 ret = GNUNET_SERVER_inject (server, sender, message);
962 sender->in_process_client_buffer = GNUNET_NO; 947 sender->in_process_client_buffer = GNUNET_NO;
963 if (GNUNET_OK != ret) 948 if (GNUNET_OK != ret)
964 GNUNET_SERVER_client_disconnect (sender); 949 GNUNET_SERVER_client_disconnect (sender);
965} 950}
966 951
967 952
@@ -988,7 +973,7 @@ GNUNET_SERVER_connect_socket (struct
988 client = GNUNET_malloc (sizeof (struct GNUNET_SERVER_Client)); 973 client = GNUNET_malloc (sizeof (struct GNUNET_SERVER_Client));
989 client->connection = connection; 974 client->connection = connection;
990 client->mst = GNUNET_SERVER_mst_create (&client_message_tokenizer_callback, 975 client->mst = GNUNET_SERVER_mst_create (&client_message_tokenizer_callback,
991 server); 976 server);
992 client->reference_count = 1; 977 client->reference_count = 1;
993 client->server = server; 978 client->server = server;
994 client->last_activity = GNUNET_TIME_absolute_get (); 979 client->last_activity = GNUNET_TIME_absolute_get ();
@@ -999,8 +984,8 @@ GNUNET_SERVER_connect_socket (struct
999 client->callback = NULL; 984 client->callback = NULL;
1000 client->callback_cls = NULL; 985 client->callback_cls = NULL;
1001 GNUNET_CONNECTION_receive (client->connection, 986 GNUNET_CONNECTION_receive (client->connection,
1002 GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, 987 GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
1003 client->idle_timeout, &process_incoming, client); 988 client->idle_timeout, &process_incoming, client);
1004 return client; 989 return client;
1005} 990}
1006 991
@@ -1014,8 +999,8 @@ GNUNET_SERVER_connect_socket (struct
1014 * @param timeout new timeout for activities on the socket 999 * @param timeout new timeout for activities on the socket
1015 */ 1000 */
1016void 1001void
1017GNUNET_SERVER_client_set_timeout(struct GNUNET_SERVER_Client *client, 1002GNUNET_SERVER_client_set_timeout (struct GNUNET_SERVER_Client *client,
1018 struct GNUNET_TIME_Relative timeout) 1003 struct GNUNET_TIME_Relative timeout)
1019{ 1004{
1020 client->idle_timeout = timeout; 1005 client->idle_timeout = timeout;
1021} 1006}
@@ -1048,8 +1033,7 @@ GNUNET_SERVER_client_drop (struct GNUNET_SERVER_Client *client)
1048{ 1033{
1049 GNUNET_assert (client->reference_count > 0); 1034 GNUNET_assert (client->reference_count > 0);
1050 client->reference_count--; 1035 client->reference_count--;
1051 if ( (client->shutdown_now == GNUNET_YES) && 1036 if ((client->shutdown_now == GNUNET_YES) && (client->reference_count == 0))
1052 (client->reference_count == 0) )
1053 GNUNET_SERVER_client_disconnect (client); 1037 GNUNET_SERVER_client_disconnect (client);
1054} 1038}
1055 1039
@@ -1066,8 +1050,7 @@ int
1066GNUNET_SERVER_client_get_address (struct GNUNET_SERVER_Client *client, 1050GNUNET_SERVER_client_get_address (struct GNUNET_SERVER_Client *client,
1067 void **addr, size_t * addrlen) 1051 void **addr, size_t * addrlen)
1068{ 1052{
1069 return GNUNET_CONNECTION_get_address (client->connection, 1053 return GNUNET_CONNECTION_get_address (client->connection, addr, addrlen);
1070 addr, addrlen);
1071} 1054}
1072 1055
1073 1056
@@ -1105,8 +1088,8 @@ GNUNET_SERVER_disconnect_notify (struct GNUNET_SERVER_Handle *server,
1105 */ 1088 */
1106void 1089void
1107GNUNET_SERVER_disconnect_notify_cancel (struct GNUNET_SERVER_Handle *server, 1090GNUNET_SERVER_disconnect_notify_cancel (struct GNUNET_SERVER_Handle *server,
1108 GNUNET_SERVER_DisconnectCallback callback, 1091 GNUNET_SERVER_DisconnectCallback
1109 void *callback_cls) 1092 callback, void *callback_cls)
1110{ 1093{
1111 struct NotifyList *pos; 1094 struct NotifyList *pos;
1112 struct NotifyList *prev; 1095 struct NotifyList *prev;
@@ -1114,18 +1097,17 @@ GNUNET_SERVER_disconnect_notify_cancel (struct GNUNET_SERVER_Handle *server,
1114 prev = NULL; 1097 prev = NULL;
1115 pos = server->disconnect_notify_list; 1098 pos = server->disconnect_notify_list;
1116 while (pos != NULL) 1099 while (pos != NULL)
1117 { 1100 {
1118 if ( (pos->callback == callback) && 1101 if ((pos->callback == callback) && (pos->callback_cls == callback_cls))
1119 (pos->callback_cls == callback_cls ) ) 1102 break;
1120 break; 1103 prev = pos;
1121 prev = pos; 1104 pos = pos->next;
1122 pos = pos->next; 1105 }
1123 }
1124 if (pos == NULL) 1106 if (pos == NULL)
1125 { 1107 {
1126 GNUNET_break (0); 1108 GNUNET_break (0);
1127 return; 1109 return;
1128 } 1110 }
1129 if (prev == NULL) 1111 if (prev == NULL)
1130 server->disconnect_notify_list = pos->next; 1112 server->disconnect_notify_list = pos->next;
1131 else 1113 else
@@ -1153,81 +1135,81 @@ GNUNET_SERVER_client_disconnect (struct GNUNET_SERVER_Client *client)
1153 1135
1154#if DEBUG_SERVER 1136#if DEBUG_SERVER
1155 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1137 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1156 "Client is being disconnected from the server.\n"); 1138 "Client is being disconnected from the server.\n");
1157#endif 1139#endif
1158 if (client->restart_task != GNUNET_SCHEDULER_NO_TASK) 1140 if (client->restart_task != GNUNET_SCHEDULER_NO_TASK)
1141 {
1142 GNUNET_SCHEDULER_cancel (client->restart_task);
1143 client->restart_task = GNUNET_SCHEDULER_NO_TASK;
1144 }
1145 if (client->warn_task != GNUNET_SCHEDULER_NO_TASK)
1146 {
1147 GNUNET_SCHEDULER_cancel (client->warn_task);
1148 client->warn_task = GNUNET_SCHEDULER_NO_TASK;
1149 }
1150 if (GNUNET_YES == client->receive_pending)
1151 {
1152 GNUNET_CONNECTION_receive_cancel (client->connection);
1153 client->receive_pending = GNUNET_NO;
1154 }
1155
1156 rc = client->reference_count;
1157 if (client->server != NULL)
1158 {
1159 server = client->server;
1160 client->server = NULL;
1161 client->shutdown_now = GNUNET_YES;
1162 prev = NULL;
1163 pos = server->clients;
1164 while ((pos != NULL) && (pos != client))
1165 {
1166 prev = pos;
1167 pos = pos->next;
1168 }
1169 GNUNET_assert (pos != NULL);
1170 if (prev == NULL)
1171 server->clients = pos->next;
1172 else
1173 prev->next = pos->next;
1174 if (client->restart_task != GNUNET_SCHEDULER_NO_TASK)
1159 { 1175 {
1160 GNUNET_SCHEDULER_cancel (client->restart_task); 1176 GNUNET_SCHEDULER_cancel (client->restart_task);
1161 client->restart_task = GNUNET_SCHEDULER_NO_TASK; 1177 client->restart_task = GNUNET_SCHEDULER_NO_TASK;
1162 } 1178 }
1163 if (client->warn_task != GNUNET_SCHEDULER_NO_TASK) 1179 if (client->warn_task != GNUNET_SCHEDULER_NO_TASK)
1164 { 1180 {
1165 GNUNET_SCHEDULER_cancel (client->warn_task); 1181 GNUNET_SCHEDULER_cancel (client->warn_task);
1166 client->warn_task = GNUNET_SCHEDULER_NO_TASK; 1182 client->warn_task = GNUNET_SCHEDULER_NO_TASK;
1167 } 1183 }
1168 if (GNUNET_YES == client->receive_pending) 1184 n = server->disconnect_notify_list;
1185 while (n != NULL)
1169 { 1186 {
1170 GNUNET_CONNECTION_receive_cancel (client->connection); 1187 n->callback (n->callback_cls, client);
1171 client->receive_pending = GNUNET_NO; 1188 n = n->next;
1172 }
1173
1174 rc = client->reference_count;
1175 if (client->server != NULL)
1176 {
1177 server = client->server;
1178 client->server = NULL;
1179 client->shutdown_now = GNUNET_YES;
1180 prev = NULL;
1181 pos = server->clients;
1182 while ((pos != NULL) && (pos != client))
1183 {
1184 prev = pos;
1185 pos = pos->next;
1186 }
1187 GNUNET_assert (pos != NULL);
1188 if (prev == NULL)
1189 server->clients = pos->next;
1190 else
1191 prev->next = pos->next;
1192 if (client->restart_task != GNUNET_SCHEDULER_NO_TASK)
1193 {
1194 GNUNET_SCHEDULER_cancel (client->restart_task);
1195 client->restart_task = GNUNET_SCHEDULER_NO_TASK;
1196 }
1197 if (client->warn_task != GNUNET_SCHEDULER_NO_TASK)
1198 {
1199 GNUNET_SCHEDULER_cancel (client->warn_task);
1200 client->warn_task = GNUNET_SCHEDULER_NO_TASK;
1201 }
1202 n = server->disconnect_notify_list;
1203 while (n != NULL)
1204 {
1205 n->callback (n->callback_cls, client);
1206 n = n->next;
1207 }
1208 } 1189 }
1190 }
1209 if (rc > 0) 1191 if (rc > 0)
1210 { 1192 {
1211#if DEBUG_SERVER 1193#if DEBUG_SERVER
1212 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1194 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1213 "RC still positive, not destroying everything.\n"); 1195 "RC still positive, not destroying everything.\n");
1214#endif 1196#endif
1215 return; 1197 return;
1216 } 1198 }
1217 if (client->in_process_client_buffer == GNUNET_YES) 1199 if (client->in_process_client_buffer == GNUNET_YES)
1218 { 1200 {
1219#if DEBUG_SERVER 1201#if DEBUG_SERVER
1220 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1202 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1221 "Still processing inputs, not destroying everything.\n"); 1203 "Still processing inputs, not destroying everything.\n");
1222#endif 1204#endif
1223 return; 1205 return;
1224 } 1206 }
1225 1207
1226 if (client->persist == GNUNET_YES) 1208 if (client->persist == GNUNET_YES)
1227 GNUNET_CONNECTION_persist_ (client->connection); 1209 GNUNET_CONNECTION_persist_ (client->connection);
1228 GNUNET_CONNECTION_destroy (client->connection, GNUNET_NO); 1210 GNUNET_CONNECTION_destroy (client->connection, GNUNET_NO);
1229 GNUNET_SERVER_mst_destroy (client->mst); 1211 GNUNET_SERVER_mst_destroy (client->mst);
1230 GNUNET_free (client); 1212 GNUNET_free (client);
1231} 1213}
1232 1214
1233 1215
@@ -1255,7 +1237,7 @@ GNUNET_SERVER_client_disable_corking (struct GNUNET_SERVER_Client *client)
1255 * @param buf where to copy the message 1237 * @param buf where to copy the message
1256 * @return number of bytes actually transmitted 1238 * @return number of bytes actually transmitted
1257 */ 1239 */
1258static size_t 1240static size_t
1259transmit_ready_callback_wrapper (void *cls, size_t size, void *buf) 1241transmit_ready_callback_wrapper (void *cls, size_t size, void *buf)
1260{ 1242{
1261 struct GNUNET_SERVER_Client *client = cls; 1243 struct GNUNET_SERVER_Client *client = cls;
@@ -1263,7 +1245,7 @@ transmit_ready_callback_wrapper (void *cls, size_t size, void *buf)
1263 1245
1264 ret = client->callback (client->callback_cls, size, buf); 1246 ret = client->callback (client->callback_cls, size, buf);
1265 if (ret > 0) 1247 if (ret > 0)
1266 client->last_activity = GNUNET_TIME_absolute_get(); 1248 client->last_activity = GNUNET_TIME_absolute_get ();
1267 return ret; 1249 return ret;
1268} 1250}
1269 1251
@@ -1293,9 +1275,10 @@ GNUNET_SERVER_notify_transmit_ready (struct GNUNET_SERVER_Client *client,
1293 client->callback_cls = callback_cls; 1275 client->callback_cls = callback_cls;
1294 client->callback = callback; 1276 client->callback = callback;
1295 return GNUNET_CONNECTION_notify_transmit_ready (client->connection, 1277 return GNUNET_CONNECTION_notify_transmit_ready (client->connection,
1296 size, 1278 size,
1297 timeout, 1279 timeout,
1298 &transmit_ready_callback_wrapper, client); 1280 &transmit_ready_callback_wrapper,
1281 client);
1299} 1282}
1300 1283
1301 1284
@@ -1332,47 +1315,46 @@ GNUNET_SERVER_receive_done (struct GNUNET_SERVER_Client *client, int success)
1332 GNUNET_assert (client->suspended > 0); 1315 GNUNET_assert (client->suspended > 0);
1333 client->suspended--; 1316 client->suspended--;
1334 if (success != GNUNET_OK) 1317 if (success != GNUNET_OK)
1335 { 1318 {
1336#if DEBUG_SERVER 1319#if DEBUG_SERVER
1337 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1320 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1338 "GNUNET_SERVER_receive_done called with failure indication\n"); 1321 "GNUNET_SERVER_receive_done called with failure indication\n");
1339#endif 1322#endif
1340 GNUNET_SERVER_client_disconnect (client); 1323 GNUNET_SERVER_client_disconnect (client);
1341 return; 1324 return;
1342 } 1325 }
1343 if (client->suspended > 0) 1326 if (client->suspended > 0)
1344 { 1327 {
1345#if DEBUG_SERVER 1328#if DEBUG_SERVER
1346 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1329 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1347 "GNUNET_SERVER_receive_done called, but more clients pending\n"); 1330 "GNUNET_SERVER_receive_done called, but more clients pending\n");
1348#endif 1331#endif
1349 return; 1332 return;
1350 } 1333 }
1351 if (GNUNET_SCHEDULER_NO_TASK != client->warn_task) 1334 if (GNUNET_SCHEDULER_NO_TASK != client->warn_task)
1352 { 1335 {
1353 GNUNET_SCHEDULER_cancel (client->warn_task); 1336 GNUNET_SCHEDULER_cancel (client->warn_task);
1354 client->warn_task = GNUNET_SCHEDULER_NO_TASK; 1337 client->warn_task = GNUNET_SCHEDULER_NO_TASK;
1355 } 1338 }
1356 if (client->in_process_client_buffer == GNUNET_YES) 1339 if (client->in_process_client_buffer == GNUNET_YES)
1357 { 1340 {
1358#if DEBUG_SERVER 1341#if DEBUG_SERVER
1359 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1342 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1360 "GNUNET_SERVER_receive_done called while still in processing loop\n"); 1343 "GNUNET_SERVER_receive_done called while still in processing loop\n");
1361#endif 1344#endif
1362 return; 1345 return;
1363 } 1346 }
1364 if (client->server == NULL) 1347 if (client->server == NULL)
1365 { 1348 {
1366 GNUNET_SERVER_client_disconnect (client); 1349 GNUNET_SERVER_client_disconnect (client);
1367 return; 1350 return;
1368 } 1351 }
1369#if DEBUG_SERVER 1352#if DEBUG_SERVER
1370 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1353 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1371 "GNUNET_SERVER_receive_done causes restart in reading from the socket\n"); 1354 "GNUNET_SERVER_receive_done causes restart in reading from the socket\n");
1372#endif 1355#endif
1373 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == client->restart_task); 1356 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == client->restart_task);
1374 client->restart_task = GNUNET_SCHEDULER_add_now (&restart_processing, 1357 client->restart_task = GNUNET_SCHEDULER_add_now (&restart_processing, client);
1375 client);
1376} 1358}
1377 1359
1378 1360