diff options
Diffstat (limited to 'src/util/server.c')
-rw-r--r-- | src/util/server.c | 820 |
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 | */ |
260 | static void | 260 | static void |
261 | process_listen_socket (void *cls, | 261 | process_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 | */ |
442 | struct GNUNET_SERVER_Handle * | 438 | struct GNUNET_SERVER_Handle * |
443 | GNUNET_SERVER_create_with_sockets (GNUNET_CONNECTION_AccessCheck access, void *access_cls, | 439 | GNUNET_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 | */ |
596 | void | 589 | void |
597 | GNUNET_SERVER_add_handlers (struct GNUNET_SERVER_Handle *server, | 590 | GNUNET_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 | */ |
616 | static void | 608 | static void |
617 | warn_no_receive_done (void *cls, | 609 | warn_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 | |||
641 | GNUNET_SERVER_disable_receive_done_warning (struct GNUNET_SERVER_Client *client) | 635 | GNUNET_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 | |||
751 | process_incoming (void *cls, | 741 | process_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 | */ |
771 | static void | 760 | static void |
772 | process_mst (struct GNUNET_SERVER_Client *client, | 761 | process_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 | |||
833 | process_incoming (void *cls, | 820 | process_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 | */ |
901 | static void | 887 | static void |
902 | restart_processing (void *cls, | 888 | restart_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 | */ |
945 | static void | 930 | static void |
946 | client_message_tokenizer_callback (void *cls, | 931 | client_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 | */ |
1016 | void | 1001 | void |
1017 | GNUNET_SERVER_client_set_timeout(struct GNUNET_SERVER_Client *client, | 1002 | GNUNET_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 | |||
1066 | GNUNET_SERVER_client_get_address (struct GNUNET_SERVER_Client *client, | 1050 | GNUNET_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 | */ |
1106 | void | 1089 | void |
1107 | GNUNET_SERVER_disconnect_notify_cancel (struct GNUNET_SERVER_Handle *server, | 1090 | GNUNET_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 | */ |
1258 | static size_t | 1240 | static size_t |
1259 | transmit_ready_callback_wrapper (void *cls, size_t size, void *buf) | 1241 | transmit_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 | ||