diff options
Diffstat (limited to 'src/util/service.c')
-rw-r--r-- | src/util/service.c | 2181 |
1 files changed, 1097 insertions, 1084 deletions
diff --git a/src/util/service.c b/src/util/service.c index b0f4ea289..21b99547c 100644 --- a/src/util/service.c +++ b/src/util/service.c | |||
@@ -37,19 +37,20 @@ | |||
37 | #endif | 37 | #endif |
38 | 38 | ||
39 | 39 | ||
40 | #define LOG(kind, ...) GNUNET_log_from(kind, "util-service", __VA_ARGS__) | 40 | #define LOG(kind, ...) GNUNET_log_from (kind, "util-service", __VA_ARGS__) |
41 | 41 | ||
42 | #define LOG_STRERROR(kind, syscall) \ | 42 | #define LOG_STRERROR(kind, syscall) \ |
43 | GNUNET_log_from_strerror(kind, "util-service", syscall) | 43 | GNUNET_log_from_strerror (kind, "util-service", syscall) |
44 | 44 | ||
45 | #define LOG_STRERROR_FILE(kind, syscall, filename) \ | 45 | #define LOG_STRERROR_FILE(kind, syscall, filename) \ |
46 | GNUNET_log_from_strerror_file(kind, "util-service", syscall, filename) | 46 | GNUNET_log_from_strerror_file (kind, "util-service", syscall, filename) |
47 | 47 | ||
48 | 48 | ||
49 | /** | 49 | /** |
50 | * Information the service tracks per listen operation. | 50 | * Information the service tracks per listen operation. |
51 | */ | 51 | */ |
52 | struct ServiceListenContext { | 52 | struct ServiceListenContext |
53 | { | ||
53 | /** | 54 | /** |
54 | * Kept in a DLL. | 55 | * Kept in a DLL. |
55 | */ | 56 | */ |
@@ -80,7 +81,8 @@ struct ServiceListenContext { | |||
80 | /** | 81 | /** |
81 | * Reasons why we might be suspended. | 82 | * Reasons why we might be suspended. |
82 | */ | 83 | */ |
83 | enum SuspendReason { | 84 | enum SuspendReason |
85 | { | ||
84 | /** | 86 | /** |
85 | * We are running normally. | 87 | * We are running normally. |
86 | */ | 88 | */ |
@@ -111,7 +113,8 @@ enum SuspendReason { | |||
111 | /** | 113 | /** |
112 | * Handle to a service. | 114 | * Handle to a service. |
113 | */ | 115 | */ |
114 | struct GNUNET_SERVICE_Handle { | 116 | struct GNUNET_SERVICE_Handle |
117 | { | ||
115 | /** | 118 | /** |
116 | * Our configuration. | 119 | * Our configuration. |
117 | */ | 120 | */ |
@@ -172,6 +175,7 @@ struct GNUNET_SERVICE_Handle { | |||
172 | */ | 175 | */ |
173 | void *task_cls; | 176 | void *task_cls; |
174 | 177 | ||
178 | |||
175 | /** | 179 | /** |
176 | * IPv4 addresses that are not allowed to connect. | 180 | * IPv4 addresses that are not allowed to connect. |
177 | */ | 181 | */ |
@@ -243,7 +247,8 @@ struct GNUNET_SERVICE_Handle { | |||
243 | /** | 247 | /** |
244 | * Handle to a client that is connected to a service. | 248 | * Handle to a client that is connected to a service. |
245 | */ | 249 | */ |
246 | struct GNUNET_SERVICE_Client { | 250 | struct GNUNET_SERVICE_Client |
251 | { | ||
247 | /** | 252 | /** |
248 | * Kept in a DLL. | 253 | * Kept in a DLL. |
249 | */ | 254 | */ |
@@ -353,15 +358,15 @@ struct GNUNET_SERVICE_Client { | |||
353 | * @return #GNUNET_YES if we have non-monitoring clients left | 358 | * @return #GNUNET_YES if we have non-monitoring clients left |
354 | */ | 359 | */ |
355 | static int | 360 | static int |
356 | have_non_monitor_clients(struct GNUNET_SERVICE_Handle *sh) | 361 | have_non_monitor_clients (struct GNUNET_SERVICE_Handle *sh) |
357 | { | 362 | { |
358 | for (struct GNUNET_SERVICE_Client *client = sh->clients_head; NULL != client; | 363 | for (struct GNUNET_SERVICE_Client *client = sh->clients_head; NULL != client; |
359 | client = client->next) | 364 | client = client->next) |
360 | { | 365 | { |
361 | if (client->is_monitor) | 366 | if (client->is_monitor) |
362 | continue; | 367 | continue; |
363 | return GNUNET_YES; | 368 | return GNUNET_YES; |
364 | } | 369 | } |
365 | return GNUNET_NO; | 370 | return GNUNET_NO; |
366 | } | 371 | } |
367 | 372 | ||
@@ -374,20 +379,20 @@ have_non_monitor_clients(struct GNUNET_SERVICE_Handle *sh) | |||
374 | * @param sr reason for suspending accepting connections | 379 | * @param sr reason for suspending accepting connections |
375 | */ | 380 | */ |
376 | static void | 381 | static void |
377 | do_suspend(struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr) | 382 | do_suspend (struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr) |
378 | { | 383 | { |
379 | struct ServiceListenContext *slc; | 384 | struct ServiceListenContext *slc; |
380 | 385 | ||
381 | GNUNET_assert(0 == (sh->suspend_state & sr)); | 386 | GNUNET_assert (0 == (sh->suspend_state & sr)); |
382 | sh->suspend_state |= sr; | 387 | sh->suspend_state |= sr; |
383 | for (slc = sh->slc_head; NULL != slc; slc = slc->next) | 388 | for (slc = sh->slc_head; NULL != slc; slc = slc->next) |
389 | { | ||
390 | if (NULL != slc->listen_task) | ||
384 | { | 391 | { |
385 | if (NULL != slc->listen_task) | 392 | GNUNET_SCHEDULER_cancel (slc->listen_task); |
386 | { | 393 | slc->listen_task = NULL; |
387 | GNUNET_SCHEDULER_cancel(slc->listen_task); | ||
388 | slc->listen_task = NULL; | ||
389 | } | ||
390 | } | 394 | } |
395 | } | ||
391 | } | 396 | } |
392 | 397 | ||
393 | 398 | ||
@@ -400,29 +405,27 @@ do_suspend(struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr) | |||
400 | * @param cls our `struct GNUNET_SERVICE_Handle` | 405 | * @param cls our `struct GNUNET_SERVICE_Handle` |
401 | */ | 406 | */ |
402 | static void | 407 | static void |
403 | service_shutdown(void *cls) | 408 | service_shutdown (void *cls) |
404 | { | 409 | { |
405 | struct GNUNET_SERVICE_Handle *sh = cls; | 410 | struct GNUNET_SERVICE_Handle *sh = cls; |
406 | 411 | ||
407 | switch (sh->options) | 412 | switch (sh->options & GNUNET_SERVICE_OPTION_SHUTDOWN_BITMASK) |
408 | { | 413 | { |
409 | case GNUNET_SERVICE_OPTION_NONE: | 414 | case GNUNET_SERVICE_OPTION_NONE: |
410 | GNUNET_SERVICE_shutdown(sh); | 415 | GNUNET_SERVICE_shutdown (sh); |
411 | break; | 416 | break; |
412 | 417 | case GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN: | |
413 | case GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN: | 418 | /* This task should never be run if we are using |
414 | /* This task should never be run if we are using | 419 | the manual shutdown. */ |
415 | the manual shutdown. */ | 420 | GNUNET_assert (0); |
416 | GNUNET_assert(0); | 421 | break; |
417 | break; | 422 | case GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN: |
418 | 423 | if (0 == (sh->suspend_state & SUSPEND_STATE_SHUTDOWN)) | |
419 | case GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN: | 424 | do_suspend (sh, SUSPEND_STATE_SHUTDOWN); |
420 | if (0 == (sh->suspend_state & SUSPEND_STATE_SHUTDOWN)) | 425 | if (GNUNET_NO == have_non_monitor_clients (sh)) |
421 | do_suspend(sh, SUSPEND_STATE_SHUTDOWN); | 426 | GNUNET_SERVICE_shutdown (sh); |
422 | if (GNUNET_NO == have_non_monitor_clients(sh)) | 427 | break; |
423 | GNUNET_SERVICE_shutdown(sh); | 428 | } |
424 | break; | ||
425 | } | ||
426 | } | 429 | } |
427 | 430 | ||
428 | 431 | ||
@@ -434,8 +437,8 @@ service_shutdown(void *cls) | |||
434 | * @return #GNUNET_NO if the IP is not in the list, #GNUNET_YES if it it is | 437 | * @return #GNUNET_NO if the IP is not in the list, #GNUNET_YES if it it is |
435 | */ | 438 | */ |
436 | static int | 439 | static int |
437 | check_ipv4_listed(const struct GNUNET_STRINGS_IPv4NetworkPolicy *list, | 440 | check_ipv4_listed (const struct GNUNET_STRINGS_IPv4NetworkPolicy *list, |
438 | const struct in_addr *add) | 441 | const struct in_addr *add) |
439 | { | 442 | { |
440 | unsigned int i; | 443 | unsigned int i; |
441 | 444 | ||
@@ -443,12 +446,12 @@ check_ipv4_listed(const struct GNUNET_STRINGS_IPv4NetworkPolicy *list, | |||
443 | return GNUNET_NO; | 446 | return GNUNET_NO; |
444 | i = 0; | 447 | i = 0; |
445 | while ((0 != list[i].network.s_addr) || (0 != list[i].netmask.s_addr)) | 448 | while ((0 != list[i].network.s_addr) || (0 != list[i].netmask.s_addr)) |
446 | { | 449 | { |
447 | if ((add->s_addr & list[i].netmask.s_addr) == | 450 | if ((add->s_addr & list[i].netmask.s_addr) == |
448 | (list[i].network.s_addr & list[i].netmask.s_addr)) | 451 | (list[i].network.s_addr & list[i].netmask.s_addr)) |
449 | return GNUNET_YES; | 452 | return GNUNET_YES; |
450 | i++; | 453 | i++; |
451 | } | 454 | } |
452 | return GNUNET_NO; | 455 | return GNUNET_NO; |
453 | } | 456 | } |
454 | 457 | ||
@@ -461,8 +464,8 @@ check_ipv4_listed(const struct GNUNET_STRINGS_IPv4NetworkPolicy *list, | |||
461 | * @return #GNUNET_NO if the IP is not in the list, #GNUNET_YES if it it is | 464 | * @return #GNUNET_NO if the IP is not in the list, #GNUNET_YES if it it is |
462 | */ | 465 | */ |
463 | static int | 466 | static int |
464 | check_ipv6_listed(const struct GNUNET_STRINGS_IPv6NetworkPolicy *list, | 467 | check_ipv6_listed (const struct GNUNET_STRINGS_IPv6NetworkPolicy *list, |
465 | const struct in6_addr *ip) | 468 | const struct in6_addr *ip) |
466 | { | 469 | { |
467 | unsigned int i; | 470 | unsigned int i; |
468 | unsigned int j; | 471 | unsigned int j; |
@@ -471,17 +474,17 @@ check_ipv6_listed(const struct GNUNET_STRINGS_IPv6NetworkPolicy *list, | |||
471 | return GNUNET_NO; | 474 | return GNUNET_NO; |
472 | i = 0; | 475 | i = 0; |
473 | NEXT: | 476 | NEXT: |
474 | while (0 != GNUNET_is_zero(&list[i].network)) | 477 | while (0 != GNUNET_is_zero (&list[i].network)) |
475 | { | 478 | { |
476 | for (j = 0; j < sizeof(struct in6_addr) / sizeof(int); j++) | 479 | for (j = 0; j < sizeof(struct in6_addr) / sizeof(int); j++) |
477 | if (((((int *)ip)[j] & ((int *)&list[i].netmask)[j])) != | 480 | if (((((int *) ip)[j] & ((int *) &list[i].netmask)[j])) != |
478 | (((int *)&list[i].network)[j] & ((int *)&list[i].netmask)[j])) | 481 | (((int *) &list[i].network)[j] & ((int *) &list[i].netmask)[j])) |
479 | { | 482 | { |
480 | i++; | 483 | i++; |
481 | goto NEXT; | 484 | goto NEXT; |
482 | } | 485 | } |
483 | return GNUNET_YES; | 486 | return GNUNET_YES; |
484 | } | 487 | } |
485 | return GNUNET_NO; | 488 | return GNUNET_NO; |
486 | } | 489 | } |
487 | 490 | ||
@@ -493,63 +496,63 @@ NEXT: | |||
493 | * @param cls the `struct GNUNET_SERVICE_Client *` to send to | 496 | * @param cls the `struct GNUNET_SERVICE_Client *` to send to |
494 | */ | 497 | */ |
495 | static void | 498 | static void |
496 | do_send(void *cls) | 499 | do_send (void *cls) |
497 | { | 500 | { |
498 | struct GNUNET_SERVICE_Client *client = cls; | 501 | struct GNUNET_SERVICE_Client *client = cls; |
499 | ssize_t ret; | 502 | ssize_t ret; |
500 | size_t left; | 503 | size_t left; |
501 | const char *buf; | 504 | const char *buf; |
502 | 505 | ||
503 | LOG(GNUNET_ERROR_TYPE_DEBUG, | 506 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
504 | "service: sending message with type %u\n", | 507 | "service: sending message with type %u\n", |
505 | ntohs(client->msg->type)); | 508 | ntohs (client->msg->type)); |
506 | 509 | ||
507 | 510 | ||
508 | client->send_task = NULL; | 511 | client->send_task = NULL; |
509 | buf = (const char *)client->msg; | 512 | buf = (const char *) client->msg; |
510 | left = ntohs(client->msg->size) - client->msg_pos; | 513 | left = ntohs (client->msg->size) - client->msg_pos; |
511 | ret = GNUNET_NETWORK_socket_send(client->sock, &buf[client->msg_pos], left); | 514 | ret = GNUNET_NETWORK_socket_send (client->sock, &buf[client->msg_pos], left); |
512 | GNUNET_assert(ret <= (ssize_t)left); | 515 | GNUNET_assert (ret <= (ssize_t) left); |
513 | if (0 == ret) | 516 | if (0 == ret) |
514 | { | 517 | { |
515 | LOG(GNUNET_ERROR_TYPE_DEBUG, "no data send"); | 518 | LOG (GNUNET_ERROR_TYPE_DEBUG, "no data send"); |
516 | GNUNET_MQ_inject_error(client->mq, GNUNET_MQ_ERROR_WRITE); | 519 | GNUNET_MQ_inject_error (client->mq, GNUNET_MQ_ERROR_WRITE); |
517 | return; | 520 | return; |
518 | } | 521 | } |
519 | if (-1 == ret) | 522 | if (-1 == ret) |
523 | { | ||
524 | if ((EAGAIN == errno) || (EINTR == errno)) | ||
520 | { | 525 | { |
521 | if ((EAGAIN == errno) || (EINTR == errno)) | 526 | /* ignore */ |
522 | { | 527 | ret = 0; |
523 | /* ignore */ | ||
524 | ret = 0; | ||
525 | } | ||
526 | else | ||
527 | { | ||
528 | if (EPIPE != errno) | ||
529 | GNUNET_log_strerror(GNUNET_ERROR_TYPE_WARNING, "send"); | ||
530 | LOG(GNUNET_ERROR_TYPE_DEBUG, | ||
531 | "socket send returned with error code %i", | ||
532 | errno); | ||
533 | GNUNET_MQ_inject_error(client->mq, GNUNET_MQ_ERROR_WRITE); | ||
534 | return; | ||
535 | } | ||
536 | } | ||
537 | if (0 == client->msg_pos) | ||
538 | { | ||
539 | GNUNET_MQ_impl_send_in_flight(client->mq); | ||
540 | } | 528 | } |
541 | client->msg_pos += ret; | 529 | else |
542 | if (left > (size_t)ret) | ||
543 | { | 530 | { |
544 | GNUNET_assert(NULL == client->drop_task); | 531 | if (EPIPE != errno) |
545 | client->send_task = | 532 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "send"); |
546 | GNUNET_SCHEDULER_add_write_net(GNUNET_TIME_UNIT_FOREVER_REL, | 533 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
547 | client->sock, | 534 | "socket send returned with error code %i", |
548 | &do_send, | 535 | errno); |
549 | client); | 536 | GNUNET_MQ_inject_error (client->mq, GNUNET_MQ_ERROR_WRITE); |
550 | return; | 537 | return; |
551 | } | 538 | } |
552 | GNUNET_MQ_impl_send_continue(client->mq); | 539 | } |
540 | if (0 == client->msg_pos) | ||
541 | { | ||
542 | GNUNET_MQ_impl_send_in_flight (client->mq); | ||
543 | } | ||
544 | client->msg_pos += ret; | ||
545 | if (left > (size_t) ret) | ||
546 | { | ||
547 | GNUNET_assert (NULL == client->drop_task); | ||
548 | client->send_task = | ||
549 | GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, | ||
550 | client->sock, | ||
551 | &do_send, | ||
552 | client); | ||
553 | return; | ||
554 | } | ||
555 | GNUNET_MQ_impl_send_continue (client->mq); | ||
553 | } | 556 | } |
554 | 557 | ||
555 | 558 | ||
@@ -562,27 +565,27 @@ do_send(void *cls) | |||
562 | * @param impl_state our `struct GNUNET_SERVICE_Client *` | 565 | * @param impl_state our `struct GNUNET_SERVICE_Client *` |
563 | */ | 566 | */ |
564 | static void | 567 | static void |
565 | service_mq_send(struct GNUNET_MQ_Handle *mq, | 568 | service_mq_send (struct GNUNET_MQ_Handle *mq, |
566 | const struct GNUNET_MessageHeader *msg, | 569 | const struct GNUNET_MessageHeader *msg, |
567 | void *impl_state) | 570 | void *impl_state) |
568 | { | 571 | { |
569 | struct GNUNET_SERVICE_Client *client = impl_state; | 572 | struct GNUNET_SERVICE_Client *client = impl_state; |
570 | 573 | ||
571 | (void)mq; | 574 | (void) mq; |
572 | if (NULL != client->drop_task) | 575 | if (NULL != client->drop_task) |
573 | return; /* we're going down right now, do not try to send */ | 576 | return; /* we're going down right now, do not try to send */ |
574 | GNUNET_assert(NULL == client->send_task); | 577 | GNUNET_assert (NULL == client->send_task); |
575 | LOG(GNUNET_ERROR_TYPE_DEBUG, | 578 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
576 | "Sending message of type %u and size %u to client\n", | 579 | "Sending message of type %u and size %u to client\n", |
577 | ntohs(msg->type), | 580 | ntohs (msg->type), |
578 | ntohs(msg->size)); | 581 | ntohs (msg->size)); |
579 | client->msg = msg; | 582 | client->msg = msg; |
580 | client->msg_pos = 0; | 583 | client->msg_pos = 0; |
581 | client->send_task = | 584 | client->send_task = |
582 | GNUNET_SCHEDULER_add_write_net(GNUNET_TIME_UNIT_FOREVER_REL, | 585 | GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, |
583 | client->sock, | 586 | client->sock, |
584 | &do_send, | 587 | &do_send, |
585 | client); | 588 | client); |
586 | } | 589 | } |
587 | 590 | ||
588 | 591 | ||
@@ -593,14 +596,14 @@ service_mq_send(struct GNUNET_MQ_Handle *mq, | |||
593 | * @param impl_state state specific to the implementation | 596 | * @param impl_state state specific to the implementation |
594 | */ | 597 | */ |
595 | static void | 598 | static void |
596 | service_mq_cancel(struct GNUNET_MQ_Handle *mq, void *impl_state) | 599 | service_mq_cancel (struct GNUNET_MQ_Handle *mq, void *impl_state) |
597 | { | 600 | { |
598 | struct GNUNET_SERVICE_Client *client = impl_state; | 601 | struct GNUNET_SERVICE_Client *client = impl_state; |
599 | 602 | ||
600 | (void)mq; | 603 | (void) mq; |
601 | GNUNET_assert(0 == client->msg_pos); | 604 | GNUNET_assert (0 == client->msg_pos); |
602 | client->msg = NULL; | 605 | client->msg = NULL; |
603 | GNUNET_SCHEDULER_cancel(client->send_task); | 606 | GNUNET_SCHEDULER_cancel (client->send_task); |
604 | client->send_task = NULL; | 607 | client->send_task = NULL; |
605 | } | 608 | } |
606 | 609 | ||
@@ -615,20 +618,20 @@ service_mq_cancel(struct GNUNET_MQ_Handle *mq, void *impl_state) | |||
615 | * @param error error code | 618 | * @param error error code |
616 | */ | 619 | */ |
617 | static void | 620 | static void |
618 | service_mq_error_handler(void *cls, enum GNUNET_MQ_Error error) | 621 | service_mq_error_handler (void *cls, enum GNUNET_MQ_Error error) |
619 | { | 622 | { |
620 | struct GNUNET_SERVICE_Client *client = cls; | 623 | struct GNUNET_SERVICE_Client *client = cls; |
621 | struct GNUNET_SERVICE_Handle *sh = client->sh; | 624 | struct GNUNET_SERVICE_Handle *sh = client->sh; |
622 | 625 | ||
623 | if ((GNUNET_MQ_ERROR_NO_MATCH == error) && (GNUNET_NO == sh->require_found)) | 626 | if ((GNUNET_MQ_ERROR_NO_MATCH == error) && (GNUNET_NO == sh->require_found)) |
624 | { | 627 | { |
625 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | 628 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
626 | "No handler for message of type %u found\n", | 629 | "No handler for message of type %u found\n", |
627 | (unsigned int)client->warn_type); | 630 | (unsigned int) client->warn_type); |
628 | GNUNET_SERVICE_client_continue(client); | 631 | GNUNET_SERVICE_client_continue (client); |
629 | return; /* ignore error */ | 632 | return; /* ignore error */ |
630 | } | 633 | } |
631 | GNUNET_SERVICE_client_drop(client); | 634 | GNUNET_SERVICE_client_drop (client); |
632 | } | 635 | } |
633 | 636 | ||
634 | 637 | ||
@@ -638,24 +641,24 @@ service_mq_error_handler(void *cls, enum GNUNET_MQ_Error error) | |||
638 | * @param cls our `struct GNUNET_SERVICE_Client *` to process more requests from | 641 | * @param cls our `struct GNUNET_SERVICE_Client *` to process more requests from |
639 | */ | 642 | */ |
640 | static void | 643 | static void |
641 | warn_no_client_continue(void *cls) | 644 | warn_no_client_continue (void *cls) |
642 | { | 645 | { |
643 | struct GNUNET_SERVICE_Client *client = cls; | 646 | struct GNUNET_SERVICE_Client *client = cls; |
644 | 647 | ||
645 | GNUNET_break( | 648 | GNUNET_break ( |
646 | 0 != | 649 | 0 != |
647 | client->warn_type); /* type should never be 0 here, as we don't use 0 */ | 650 | client->warn_type); /* type should never be 0 here, as we don't use 0 */ |
648 | client->warn_task = GNUNET_SCHEDULER_add_delayed(GNUNET_TIME_UNIT_MINUTES, | 651 | client->warn_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, |
649 | &warn_no_client_continue, | 652 | &warn_no_client_continue, |
650 | client); | 653 | client); |
651 | LOG( | 654 | LOG ( |
652 | GNUNET_ERROR_TYPE_WARNING, | 655 | GNUNET_ERROR_TYPE_WARNING, |
653 | _( | 656 | _ ( |
654 | "Processing code for message of type %u did not call `GNUNET_SERVICE_client_continue' after %s\n"), | 657 | "Processing code for message of type %u did not call `GNUNET_SERVICE_client_continue' after %s\n"), |
655 | (unsigned int)client->warn_type, | 658 | (unsigned int) client->warn_type, |
656 | GNUNET_STRINGS_relative_time_to_string(GNUNET_TIME_absolute_get_duration( | 659 | GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration ( |
657 | client->warn_start), | 660 | client->warn_start), |
658 | GNUNET_YES)); | 661 | GNUNET_YES)); |
659 | } | 662 | } |
660 | 663 | ||
661 | 664 | ||
@@ -671,23 +674,23 @@ warn_no_client_continue(void *cls) | |||
671 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if the client was dropped | 674 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if the client was dropped |
672 | */ | 675 | */ |
673 | static int | 676 | static int |
674 | service_client_mst_cb(void *cls, const struct GNUNET_MessageHeader *message) | 677 | service_client_mst_cb (void *cls, const struct GNUNET_MessageHeader *message) |
675 | { | 678 | { |
676 | struct GNUNET_SERVICE_Client *client = cls; | 679 | struct GNUNET_SERVICE_Client *client = cls; |
677 | 680 | ||
678 | LOG(GNUNET_ERROR_TYPE_DEBUG, | 681 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
679 | "Received message of type %u and size %u from client\n", | 682 | "Received message of type %u and size %u from client\n", |
680 | ntohs(message->type), | 683 | ntohs (message->type), |
681 | ntohs(message->size)); | 684 | ntohs (message->size)); |
682 | GNUNET_assert(GNUNET_NO == client->needs_continue); | 685 | GNUNET_assert (GNUNET_NO == client->needs_continue); |
683 | client->needs_continue = GNUNET_YES; | 686 | client->needs_continue = GNUNET_YES; |
684 | client->warn_type = ntohs(message->type); | 687 | client->warn_type = ntohs (message->type); |
685 | client->warn_start = GNUNET_TIME_absolute_get(); | 688 | client->warn_start = GNUNET_TIME_absolute_get (); |
686 | GNUNET_assert(NULL == client->warn_task); | 689 | GNUNET_assert (NULL == client->warn_task); |
687 | client->warn_task = GNUNET_SCHEDULER_add_delayed(GNUNET_TIME_UNIT_MINUTES, | 690 | client->warn_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, |
688 | &warn_no_client_continue, | 691 | &warn_no_client_continue, |
689 | client); | 692 | client); |
690 | GNUNET_MQ_inject_message(client->mq, message); | 693 | GNUNET_MQ_inject_message (client->mq, message); |
691 | if (NULL != client->drop_task) | 694 | if (NULL != client->drop_task) |
692 | return GNUNET_SYSERR; | 695 | return GNUNET_SYSERR; |
693 | return GNUNET_OK; | 696 | return GNUNET_OK; |
@@ -701,37 +704,37 @@ service_client_mst_cb(void *cls, const struct GNUNET_MessageHeader *message) | |||
701 | * @param cls the `struct GNUNET_SERVICE_Client` that sent us data. | 704 | * @param cls the `struct GNUNET_SERVICE_Client` that sent us data. |
702 | */ | 705 | */ |
703 | static void | 706 | static void |
704 | service_client_recv(void *cls) | 707 | service_client_recv (void *cls) |
705 | { | 708 | { |
706 | struct GNUNET_SERVICE_Client *client = cls; | 709 | struct GNUNET_SERVICE_Client *client = cls; |
707 | int ret; | 710 | int ret; |
708 | 711 | ||
709 | client->recv_task = NULL; | 712 | client->recv_task = NULL; |
710 | ret = GNUNET_MST_read(client->mst, client->sock, GNUNET_NO, GNUNET_YES); | 713 | ret = GNUNET_MST_read (client->mst, client->sock, GNUNET_NO, GNUNET_YES); |
711 | if (GNUNET_SYSERR == ret) | 714 | if (GNUNET_SYSERR == ret) |
715 | { | ||
716 | /* client closed connection (or IO error) */ | ||
717 | if (NULL == client->drop_task) | ||
712 | { | 718 | { |
713 | /* client closed connection (or IO error) */ | 719 | GNUNET_assert (GNUNET_NO == client->needs_continue); |
714 | if (NULL == client->drop_task) | 720 | GNUNET_SERVICE_client_drop (client); |
715 | { | ||
716 | GNUNET_assert(GNUNET_NO == client->needs_continue); | ||
717 | GNUNET_SERVICE_client_drop(client); | ||
718 | } | ||
719 | return; | ||
720 | } | 721 | } |
722 | return; | ||
723 | } | ||
721 | if (GNUNET_NO == ret) | 724 | if (GNUNET_NO == ret) |
722 | return; /* more messages in buffer, wait for application | 725 | return; /* more messages in buffer, wait for application |
723 | to be done processing */ | 726 | to be done processing */ |
724 | GNUNET_assert(GNUNET_OK == ret); | 727 | GNUNET_assert (GNUNET_OK == ret); |
725 | if (GNUNET_YES == client->needs_continue) | 728 | if (GNUNET_YES == client->needs_continue) |
726 | return; | 729 | return; |
727 | if (NULL != client->recv_task) | 730 | if (NULL != client->recv_task) |
728 | return; | 731 | return; |
729 | /* MST needs more data, re-schedule read job */ | 732 | /* MST needs more data, re-schedule read job */ |
730 | client->recv_task = | 733 | client->recv_task = |
731 | GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, | 734 | GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, |
732 | client->sock, | 735 | client->sock, |
733 | &service_client_recv, | 736 | &service_client_recv, |
734 | client); | 737 | client); |
735 | } | 738 | } |
736 | 739 | ||
737 | 740 | ||
@@ -743,31 +746,31 @@ service_client_recv(void *cls) | |||
743 | * @param sock socket associated with the client | 746 | * @param sock socket associated with the client |
744 | */ | 747 | */ |
745 | static void | 748 | static void |
746 | start_client(struct GNUNET_SERVICE_Handle *sh, | 749 | start_client (struct GNUNET_SERVICE_Handle *sh, |
747 | struct GNUNET_NETWORK_Handle *csock) | 750 | struct GNUNET_NETWORK_Handle *csock) |
748 | { | 751 | { |
749 | struct GNUNET_SERVICE_Client *client; | 752 | struct GNUNET_SERVICE_Client *client; |
750 | 753 | ||
751 | client = GNUNET_new(struct GNUNET_SERVICE_Client); | 754 | client = GNUNET_new (struct GNUNET_SERVICE_Client); |
752 | GNUNET_CONTAINER_DLL_insert(sh->clients_head, sh->clients_tail, client); | 755 | GNUNET_CONTAINER_DLL_insert (sh->clients_head, sh->clients_tail, client); |
753 | client->sh = sh; | 756 | client->sh = sh; |
754 | client->sock = csock; | 757 | client->sock = csock; |
755 | client->mq = GNUNET_MQ_queue_for_callbacks(&service_mq_send, | 758 | client->mq = GNUNET_MQ_queue_for_callbacks (&service_mq_send, |
756 | NULL, | 759 | NULL, |
757 | &service_mq_cancel, | 760 | &service_mq_cancel, |
758 | client, | 761 | client, |
759 | sh->handlers, | 762 | sh->handlers, |
760 | &service_mq_error_handler, | 763 | &service_mq_error_handler, |
761 | client); | 764 | client); |
762 | client->mst = GNUNET_MST_create(&service_client_mst_cb, client); | 765 | client->mst = GNUNET_MST_create (&service_client_mst_cb, client); |
763 | if (NULL != sh->connect_cb) | 766 | if (NULL != sh->connect_cb) |
764 | client->user_context = sh->connect_cb(sh->cb_cls, client, client->mq); | 767 | client->user_context = sh->connect_cb (sh->cb_cls, client, client->mq); |
765 | GNUNET_MQ_set_handlers_closure(client->mq, client->user_context); | 768 | GNUNET_MQ_set_handlers_closure (client->mq, client->user_context); |
766 | client->recv_task = | 769 | client->recv_task = |
767 | GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, | 770 | GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, |
768 | client->sock, | 771 | client->sock, |
769 | &service_client_recv, | 772 | &service_client_recv, |
770 | client); | 773 | client); |
771 | } | 774 | } |
772 | 775 | ||
773 | 776 | ||
@@ -778,83 +781,83 @@ start_client(struct GNUNET_SERVICE_Handle *sh, | |||
778 | * @param cls the `struct ServiceListenContext` of the ready listen socket | 781 | * @param cls the `struct ServiceListenContext` of the ready listen socket |
779 | */ | 782 | */ |
780 | static void | 783 | static void |
781 | accept_client(void *cls) | 784 | accept_client (void *cls) |
782 | { | 785 | { |
783 | struct ServiceListenContext *slc = cls; | 786 | struct ServiceListenContext *slc = cls; |
784 | struct GNUNET_SERVICE_Handle *sh = slc->sh; | 787 | struct GNUNET_SERVICE_Handle *sh = slc->sh; |
785 | 788 | ||
786 | slc->listen_task = NULL; | 789 | slc->listen_task = NULL; |
787 | while (1) | 790 | while (1) |
791 | { | ||
792 | struct GNUNET_NETWORK_Handle *sock; | ||
793 | const struct sockaddr_in *v4; | ||
794 | const struct sockaddr_in6 *v6; | ||
795 | struct sockaddr_storage sa; | ||
796 | socklen_t addrlen; | ||
797 | int ok; | ||
798 | |||
799 | addrlen = sizeof(sa); | ||
800 | sock = GNUNET_NETWORK_socket_accept (slc->listen_socket, | ||
801 | (struct sockaddr *) &sa, | ||
802 | &addrlen); | ||
803 | if (NULL == sock) | ||
804 | { | ||
805 | if (EMFILE == errno) | ||
806 | do_suspend (sh, SUSPEND_STATE_EMFILE); | ||
807 | else if (EAGAIN != errno) | ||
808 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "accept"); | ||
809 | break; | ||
810 | } | ||
811 | switch (sa.ss_family) | ||
788 | { | 812 | { |
789 | struct GNUNET_NETWORK_Handle *sock; | 813 | case AF_INET: |
790 | const struct sockaddr_in *v4; | 814 | GNUNET_assert (addrlen == sizeof(struct sockaddr_in)); |
791 | const struct sockaddr_in6 *v6; | 815 | v4 = (const struct sockaddr_in *) &sa; |
792 | struct sockaddr_storage sa; | 816 | ok = (((NULL == sh->v4_allowed) || |
793 | socklen_t addrlen; | 817 | (check_ipv4_listed (sh->v4_allowed, &v4->sin_addr))) && |
794 | int ok; | 818 | ((NULL == sh->v4_denied) || |
795 | 819 | (! check_ipv4_listed (sh->v4_denied, &v4->sin_addr)))); | |
796 | addrlen = sizeof(sa); | 820 | break; |
797 | sock = GNUNET_NETWORK_socket_accept(slc->listen_socket, | 821 | |
798 | (struct sockaddr *)&sa, | 822 | case AF_INET6: |
799 | &addrlen); | 823 | GNUNET_assert (addrlen == sizeof(struct sockaddr_in6)); |
800 | if (NULL == sock) | 824 | v6 = (const struct sockaddr_in6 *) &sa; |
801 | { | 825 | ok = (((NULL == sh->v6_allowed) || |
802 | if (EMFILE == errno) | 826 | (check_ipv6_listed (sh->v6_allowed, &v6->sin6_addr))) && |
803 | do_suspend(sh, SUSPEND_STATE_EMFILE); | 827 | ((NULL == sh->v6_denied) || |
804 | else if (EAGAIN != errno) | 828 | (! check_ipv6_listed (sh->v6_denied, &v6->sin6_addr)))); |
805 | GNUNET_log_strerror(GNUNET_ERROR_TYPE_WARNING, "accept"); | 829 | break; |
806 | break; | 830 | |
807 | } | 831 | case AF_UNIX: |
808 | switch (sa.ss_family) | 832 | ok = GNUNET_OK; /* controlled using file-system ACL now */ |
809 | { | 833 | break; |
810 | case AF_INET: | 834 | |
811 | GNUNET_assert(addrlen == sizeof(struct sockaddr_in)); | 835 | default: |
812 | v4 = (const struct sockaddr_in *)&sa; | 836 | LOG (GNUNET_ERROR_TYPE_WARNING, |
813 | ok = (((NULL == sh->v4_allowed) || | 837 | _ ("Unknown address family %d\n"), |
814 | (check_ipv4_listed(sh->v4_allowed, &v4->sin_addr))) && | 838 | sa.ss_family); |
815 | ((NULL == sh->v4_denied) || | 839 | return; |
816 | (!check_ipv4_listed(sh->v4_denied, &v4->sin_addr)))); | 840 | } |
817 | break; | 841 | if (! ok) |
818 | 842 | { | |
819 | case AF_INET6: | 843 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
820 | GNUNET_assert(addrlen == sizeof(struct sockaddr_in6)); | 844 | "Service rejected incoming connection from %s due to policy.\n", |
821 | v6 = (const struct sockaddr_in6 *)&sa; | 845 | GNUNET_a2s ((const struct sockaddr *) &sa, addrlen)); |
822 | ok = (((NULL == sh->v6_allowed) || | 846 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); |
823 | (check_ipv6_listed(sh->v6_allowed, &v6->sin6_addr))) && | 847 | continue; |
824 | ((NULL == sh->v6_denied) || | ||
825 | (!check_ipv6_listed(sh->v6_denied, &v6->sin6_addr)))); | ||
826 | break; | ||
827 | |||
828 | case AF_UNIX: | ||
829 | ok = GNUNET_OK; /* controlled using file-system ACL now */ | ||
830 | break; | ||
831 | |||
832 | default: | ||
833 | LOG(GNUNET_ERROR_TYPE_WARNING, | ||
834 | _("Unknown address family %d\n"), | ||
835 | sa.ss_family); | ||
836 | return; | ||
837 | } | ||
838 | if (!ok) | ||
839 | { | ||
840 | LOG(GNUNET_ERROR_TYPE_DEBUG, | ||
841 | "Service rejected incoming connection from %s due to policy.\n", | ||
842 | GNUNET_a2s((const struct sockaddr *)&sa, addrlen)); | ||
843 | GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(sock)); | ||
844 | continue; | ||
845 | } | ||
846 | LOG(GNUNET_ERROR_TYPE_DEBUG, | ||
847 | "Service accepted incoming connection from %s.\n", | ||
848 | GNUNET_a2s((const struct sockaddr *)&sa, addrlen)); | ||
849 | start_client(slc->sh, sock); | ||
850 | } | 848 | } |
849 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
850 | "Service accepted incoming connection from %s.\n", | ||
851 | GNUNET_a2s ((const struct sockaddr *) &sa, addrlen)); | ||
852 | start_client (slc->sh, sock); | ||
853 | } | ||
851 | if (0 != sh->suspend_state) | 854 | if (0 != sh->suspend_state) |
852 | return; | 855 | return; |
853 | slc->listen_task = | 856 | slc->listen_task = |
854 | GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, | 857 | GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, |
855 | slc->listen_socket, | 858 | slc->listen_socket, |
856 | &accept_client, | 859 | &accept_client, |
857 | slc); | 860 | slc); |
858 | } | 861 | } |
859 | 862 | ||
860 | 863 | ||
@@ -866,23 +869,23 @@ accept_client(void *cls) | |||
866 | * or #SUSPEND_STATE_NONE on first startup | 869 | * or #SUSPEND_STATE_NONE on first startup |
867 | */ | 870 | */ |
868 | static void | 871 | static void |
869 | do_resume(struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr) | 872 | do_resume (struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr) |
870 | { | 873 | { |
871 | struct ServiceListenContext *slc; | 874 | struct ServiceListenContext *slc; |
872 | 875 | ||
873 | GNUNET_assert((SUSPEND_STATE_NONE == sr) || (0 != (sh->suspend_state & sr))); | 876 | GNUNET_assert ((SUSPEND_STATE_NONE == sr) || (0 != (sh->suspend_state & sr))); |
874 | sh->suspend_state -= sr; | 877 | sh->suspend_state -= sr; |
875 | if (SUSPEND_STATE_NONE != sh->suspend_state) | 878 | if (SUSPEND_STATE_NONE != sh->suspend_state) |
876 | return; | 879 | return; |
877 | for (slc = sh->slc_head; NULL != slc; slc = slc->next) | 880 | for (slc = sh->slc_head; NULL != slc; slc = slc->next) |
878 | { | 881 | { |
879 | GNUNET_assert(NULL == slc->listen_task); | 882 | GNUNET_assert (NULL == slc->listen_task); |
880 | slc->listen_task = | 883 | slc->listen_task = |
881 | GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, | 884 | GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, |
882 | slc->listen_socket, | 885 | slc->listen_socket, |
883 | &accept_client, | 886 | &accept_client, |
884 | slc); | 887 | slc); |
885 | } | 888 | } |
886 | } | 889 | } |
887 | 890 | ||
888 | 891 | ||
@@ -894,23 +897,24 @@ do_resume(struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr) | |||
894 | * @param cls our `struct GNUNET_SERVICE_Handle` | 897 | * @param cls our `struct GNUNET_SERVICE_Handle` |
895 | */ | 898 | */ |
896 | static void | 899 | static void |
897 | service_main(void *cls) | 900 | service_main (void *cls) |
898 | { | 901 | { |
899 | struct GNUNET_SERVICE_Handle *sh = cls; | 902 | struct GNUNET_SERVICE_Handle *sh = cls; |
900 | 903 | ||
901 | if (GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN != sh->options) | 904 | if (GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN != |
902 | GNUNET_SCHEDULER_add_shutdown(&service_shutdown, sh); | 905 | (sh->options & GNUNET_SERVICE_OPTION_SHUTDOWN_BITMASK)) |
903 | do_resume(sh, SUSPEND_STATE_NONE); | 906 | GNUNET_SCHEDULER_add_shutdown (&service_shutdown, sh); |
907 | do_resume (sh, SUSPEND_STATE_NONE); | ||
904 | 908 | ||
905 | if (-1 != sh->ready_confirm_fd) | 909 | if (-1 != sh->ready_confirm_fd) |
906 | { | 910 | { |
907 | GNUNET_break(1 == write(sh->ready_confirm_fd, ".", 1)); | 911 | GNUNET_break (1 == write (sh->ready_confirm_fd, ".", 1)); |
908 | GNUNET_break(0 == close(sh->ready_confirm_fd)); | 912 | GNUNET_break (0 == close (sh->ready_confirm_fd)); |
909 | sh->ready_confirm_fd = -1; | 913 | sh->ready_confirm_fd = -1; |
910 | } | 914 | } |
911 | 915 | ||
912 | if (NULL != sh->service_init_cb) | 916 | if (NULL != sh->service_init_cb) |
913 | sh->service_init_cb(sh->cb_cls, sh->cfg, sh); | 917 | sh->service_init_cb (sh->cb_cls, sh->cfg, sh); |
914 | } | 918 | } |
915 | 919 | ||
916 | 920 | ||
@@ -924,33 +928,33 @@ service_main(void *cls) | |||
924 | * no ACL configured) | 928 | * no ACL configured) |
925 | */ | 929 | */ |
926 | static int | 930 | static int |
927 | process_acl4(struct GNUNET_STRINGS_IPv4NetworkPolicy **ret, | 931 | process_acl4 (struct GNUNET_STRINGS_IPv4NetworkPolicy **ret, |
928 | struct GNUNET_SERVICE_Handle *sh, | 932 | struct GNUNET_SERVICE_Handle *sh, |
929 | const char *option) | 933 | const char *option) |
930 | { | 934 | { |
931 | char *opt; | 935 | char *opt; |
932 | 936 | ||
933 | if (!GNUNET_CONFIGURATION_have_value(sh->cfg, sh->service_name, option)) | 937 | if (! GNUNET_CONFIGURATION_have_value (sh->cfg, sh->service_name, option)) |
934 | { | 938 | { |
935 | *ret = NULL; | 939 | *ret = NULL; |
936 | return GNUNET_OK; | 940 | return GNUNET_OK; |
937 | } | 941 | } |
938 | GNUNET_break(GNUNET_OK == | 942 | GNUNET_break (GNUNET_OK == |
939 | GNUNET_CONFIGURATION_get_value_string(sh->cfg, | 943 | GNUNET_CONFIGURATION_get_value_string (sh->cfg, |
940 | sh->service_name, | 944 | sh->service_name, |
941 | option, | 945 | option, |
942 | &opt)); | 946 | &opt)); |
943 | if (NULL == (*ret = GNUNET_STRINGS_parse_ipv4_policy(opt))) | 947 | if (NULL == (*ret = GNUNET_STRINGS_parse_ipv4_policy (opt))) |
944 | { | 948 | { |
945 | LOG(GNUNET_ERROR_TYPE_WARNING, | 949 | LOG (GNUNET_ERROR_TYPE_WARNING, |
946 | _("Could not parse IPv4 network specification `%s' for `%s:%s'\n"), | 950 | _ ("Could not parse IPv4 network specification `%s' for `%s:%s'\n"), |
947 | opt, | 951 | opt, |
948 | sh->service_name, | 952 | sh->service_name, |
949 | option); | 953 | option); |
950 | GNUNET_free(opt); | 954 | GNUNET_free (opt); |
951 | return GNUNET_SYSERR; | 955 | return GNUNET_SYSERR; |
952 | } | 956 | } |
953 | GNUNET_free(opt); | 957 | GNUNET_free (opt); |
954 | return GNUNET_OK; | 958 | return GNUNET_OK; |
955 | } | 959 | } |
956 | 960 | ||
@@ -965,33 +969,33 @@ process_acl4(struct GNUNET_STRINGS_IPv4NetworkPolicy **ret, | |||
965 | * no ACL configured) | 969 | * no ACL configured) |
966 | */ | 970 | */ |
967 | static int | 971 | static int |
968 | process_acl6(struct GNUNET_STRINGS_IPv6NetworkPolicy **ret, | 972 | process_acl6 (struct GNUNET_STRINGS_IPv6NetworkPolicy **ret, |
969 | struct GNUNET_SERVICE_Handle *sh, | 973 | struct GNUNET_SERVICE_Handle *sh, |
970 | const char *option) | 974 | const char *option) |
971 | { | 975 | { |
972 | char *opt; | 976 | char *opt; |
973 | 977 | ||
974 | if (!GNUNET_CONFIGURATION_have_value(sh->cfg, sh->service_name, option)) | 978 | if (! GNUNET_CONFIGURATION_have_value (sh->cfg, sh->service_name, option)) |
975 | { | 979 | { |
976 | *ret = NULL; | 980 | *ret = NULL; |
977 | return GNUNET_OK; | 981 | return GNUNET_OK; |
978 | } | 982 | } |
979 | GNUNET_break(GNUNET_OK == | 983 | GNUNET_break (GNUNET_OK == |
980 | GNUNET_CONFIGURATION_get_value_string(sh->cfg, | 984 | GNUNET_CONFIGURATION_get_value_string (sh->cfg, |
981 | sh->service_name, | 985 | sh->service_name, |
982 | option, | 986 | option, |
983 | &opt)); | 987 | &opt)); |
984 | if (NULL == (*ret = GNUNET_STRINGS_parse_ipv6_policy(opt))) | 988 | if (NULL == (*ret = GNUNET_STRINGS_parse_ipv6_policy (opt))) |
985 | { | 989 | { |
986 | LOG(GNUNET_ERROR_TYPE_WARNING, | 990 | LOG (GNUNET_ERROR_TYPE_WARNING, |
987 | _("Could not parse IPv6 network specification `%s' for `%s:%s'\n"), | 991 | _ ("Could not parse IPv6 network specification `%s' for `%s:%s'\n"), |
988 | opt, | 992 | opt, |
989 | sh->service_name, | 993 | sh->service_name, |
990 | option); | 994 | option); |
991 | GNUNET_free(opt); | 995 | GNUNET_free (opt); |
992 | return GNUNET_SYSERR; | 996 | return GNUNET_SYSERR; |
993 | } | 997 | } |
994 | GNUNET_free(opt); | 998 | GNUNET_free (opt); |
995 | return GNUNET_OK; | 999 | return GNUNET_OK; |
996 | } | 1000 | } |
997 | 1001 | ||
@@ -1003,34 +1007,27 @@ process_acl6(struct GNUNET_STRINGS_IPv6NetworkPolicy **ret, | |||
1003 | * @param saddrs array to update | 1007 | * @param saddrs array to update |
1004 | * @param saddrlens where to store the address length | 1008 | * @param saddrlens where to store the address length |
1005 | * @param unixpath path to add | 1009 | * @param unixpath path to add |
1006 | * @param abstract #GNUNET_YES to add an abstract UNIX domain socket. This | ||
1007 | * parameter is ignore on systems other than LINUX | ||
1008 | */ | 1010 | */ |
1009 | static void | 1011 | static void |
1010 | add_unixpath(struct sockaddr **saddrs, | 1012 | add_unixpath (struct sockaddr **saddrs, |
1011 | socklen_t *saddrlens, | 1013 | socklen_t *saddrlens, |
1012 | const char *unixpath, | 1014 | const char *unixpath) |
1013 | int abstract) | ||
1014 | { | 1015 | { |
1015 | #ifdef AF_UNIX | 1016 | #ifdef AF_UNIX |
1016 | struct sockaddr_un *un; | 1017 | struct sockaddr_un *un; |
1017 | 1018 | ||
1018 | un = GNUNET_new(struct sockaddr_un); | 1019 | un = GNUNET_new (struct sockaddr_un); |
1019 | un->sun_family = AF_UNIX; | 1020 | un->sun_family = AF_UNIX; |
1020 | GNUNET_strlcpy(un->sun_path, unixpath, sizeof(un->sun_path)); | 1021 | GNUNET_strlcpy (un->sun_path, unixpath, sizeof(un->sun_path)); |
1021 | #ifdef LINUX | ||
1022 | if (GNUNET_YES == abstract) | ||
1023 | un->sun_path[0] = '\0'; | ||
1024 | #endif | ||
1025 | #if HAVE_SOCKADDR_UN_SUN_LEN | 1022 | #if HAVE_SOCKADDR_UN_SUN_LEN |
1026 | un->sun_len = (u_char)sizeof(struct sockaddr_un); | 1023 | un->sun_len = (u_char) sizeof(struct sockaddr_un); |
1027 | #endif | 1024 | #endif |
1028 | *saddrs = (struct sockaddr *)un; | 1025 | *saddrs = (struct sockaddr *) un; |
1029 | *saddrlens = sizeof(struct sockaddr_un); | 1026 | *saddrlens = sizeof(struct sockaddr_un); |
1030 | #else | 1027 | #else |
1031 | /* this function should never be called | 1028 | /* this function should never be called |
1032 | * unless AF_UNIX is defined! */ | 1029 | * unless AF_UNIX is defined! */ |
1033 | GNUNET_assert(0); | 1030 | GNUNET_assert (0); |
1034 | #endif | 1031 | #endif |
1035 | } | 1032 | } |
1036 | 1033 | ||
@@ -1056,10 +1053,10 @@ add_unixpath(struct sockaddr **saddrs, | |||
1056 | * set to NULL). | 1053 | * set to NULL). |
1057 | */ | 1054 | */ |
1058 | static int | 1055 | static int |
1059 | get_server_addresses(const char *service_name, | 1056 | get_server_addresses (const char *service_name, |
1060 | const struct GNUNET_CONFIGURATION_Handle *cfg, | 1057 | const struct GNUNET_CONFIGURATION_Handle *cfg, |
1061 | struct sockaddr ***addrs, | 1058 | struct sockaddr ***addrs, |
1062 | socklen_t **addr_lens) | 1059 | socklen_t **addr_lens) |
1063 | { | 1060 | { |
1064 | int disablev6; | 1061 | int disablev6; |
1065 | struct GNUNET_NETWORK_Handle *desc; | 1062 | struct GNUNET_NETWORK_Handle *desc; |
@@ -1072,7 +1069,6 @@ get_server_addresses(const char *service_name, | |||
1072 | unsigned int i; | 1069 | unsigned int i; |
1073 | int resi; | 1070 | int resi; |
1074 | int ret; | 1071 | int ret; |
1075 | int abstract; | ||
1076 | struct sockaddr **saddrs; | 1072 | struct sockaddr **saddrs; |
1077 | socklen_t *saddrlens; | 1073 | socklen_t *saddrlens; |
1078 | char *hostname; | 1074 | char *hostname; |
@@ -1081,273 +1077,264 @@ get_server_addresses(const char *service_name, | |||
1081 | *addr_lens = NULL; | 1077 | *addr_lens = NULL; |
1082 | desc = NULL; | 1078 | desc = NULL; |
1083 | disablev6 = GNUNET_NO; | 1079 | disablev6 = GNUNET_NO; |
1084 | if ((GNUNET_NO == GNUNET_NETWORK_test_pf(PF_INET6)) || | 1080 | if ((GNUNET_NO == GNUNET_NETWORK_test_pf (PF_INET6)) || |
1085 | (GNUNET_YES == | 1081 | (GNUNET_YES == |
1086 | GNUNET_CONFIGURATION_get_value_yesno(cfg, service_name, "DISABLEV6"))) | 1082 | GNUNET_CONFIGURATION_get_value_yesno (cfg, service_name, "DISABLEV6"))) |
1087 | disablev6 = GNUNET_YES; | 1083 | disablev6 = GNUNET_YES; |
1088 | 1084 | ||
1089 | port = 0; | 1085 | port = 0; |
1090 | if (GNUNET_CONFIGURATION_have_value(cfg, service_name, "PORT")) | 1086 | if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "PORT")) |
1087 | { | ||
1088 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg, | ||
1089 | service_name, | ||
1090 | "PORT", | ||
1091 | &port)) | ||
1091 | { | 1092 | { |
1092 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number(cfg, | 1093 | LOG (GNUNET_ERROR_TYPE_ERROR, |
1093 | service_name, | 1094 | _ ("Require valid port number for service `%s' in configuration!\n"), |
1094 | "PORT", | 1095 | service_name); |
1095 | &port)) | ||
1096 | { | ||
1097 | LOG(GNUNET_ERROR_TYPE_ERROR, | ||
1098 | _("Require valid port number for service `%s' in configuration!\n"), | ||
1099 | service_name); | ||
1100 | } | ||
1101 | if (port > 65535) | ||
1102 | { | ||
1103 | LOG(GNUNET_ERROR_TYPE_ERROR, | ||
1104 | _("Require valid port number for service `%s' in configuration!\n"), | ||
1105 | service_name); | ||
1106 | return GNUNET_SYSERR; | ||
1107 | } | ||
1108 | } | 1096 | } |
1109 | 1097 | if (port > 65535) | |
1110 | if (GNUNET_CONFIGURATION_have_value(cfg, service_name, "BINDTO")) | ||
1111 | { | 1098 | { |
1112 | GNUNET_break(GNUNET_OK == | 1099 | LOG (GNUNET_ERROR_TYPE_ERROR, |
1113 | GNUNET_CONFIGURATION_get_value_string(cfg, | 1100 | _ ("Require valid port number for service `%s' in configuration!\n"), |
1101 | service_name); | ||
1102 | return GNUNET_SYSERR; | ||
1103 | } | ||
1104 | } | ||
1105 | |||
1106 | if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "BINDTO")) | ||
1107 | { | ||
1108 | GNUNET_break (GNUNET_OK == | ||
1109 | GNUNET_CONFIGURATION_get_value_string (cfg, | ||
1114 | service_name, | 1110 | service_name, |
1115 | "BINDTO", | 1111 | "BINDTO", |
1116 | &hostname)); | 1112 | &hostname)); |
1117 | } | 1113 | } |
1118 | else | 1114 | else |
1119 | hostname = NULL; | 1115 | hostname = NULL; |
1120 | 1116 | ||
1121 | unixpath = NULL; | 1117 | unixpath = NULL; |
1122 | abstract = GNUNET_NO; | ||
1123 | #ifdef AF_UNIX | 1118 | #ifdef AF_UNIX |
1124 | if ((GNUNET_YES == | 1119 | if ((GNUNET_YES == |
1125 | GNUNET_CONFIGURATION_have_value(cfg, service_name, "UNIXPATH")) && | 1120 | GNUNET_CONFIGURATION_have_value (cfg, service_name, "UNIXPATH")) && |
1126 | (GNUNET_OK == GNUNET_CONFIGURATION_get_value_filename(cfg, | 1121 | (GNUNET_OK == GNUNET_CONFIGURATION_get_value_filename (cfg, |
1127 | service_name, | 1122 | service_name, |
1128 | "UNIXPATH", | 1123 | "UNIXPATH", |
1129 | &unixpath)) && | 1124 | &unixpath)) && |
1130 | (0 < strlen(unixpath))) | 1125 | (0 < strlen (unixpath))) |
1126 | { | ||
1127 | /* probe UNIX support */ | ||
1128 | struct sockaddr_un s_un; | ||
1129 | |||
1130 | if (strlen (unixpath) >= sizeof(s_un.sun_path)) | ||
1131 | { | 1131 | { |
1132 | /* probe UNIX support */ | 1132 | LOG (GNUNET_ERROR_TYPE_WARNING, |
1133 | struct sockaddr_un s_un; | 1133 | _ ("UNIXPATH `%s' too long, maximum length is %llu\n"), |
1134 | 1134 | unixpath, | |
1135 | if (strlen(unixpath) >= sizeof(s_un.sun_path)) | 1135 | (unsigned long long) sizeof(s_un.sun_path)); |
1136 | { | 1136 | unixpath = GNUNET_NETWORK_shorten_unixpath (unixpath); |
1137 | LOG(GNUNET_ERROR_TYPE_WARNING, | 1137 | LOG (GNUNET_ERROR_TYPE_INFO, _ ("Using `%s' instead\n"), unixpath); |
1138 | _("UNIXPATH `%s' too long, maximum length is %llu\n"), | ||
1139 | unixpath, | ||
1140 | (unsigned long long)sizeof(s_un.sun_path)); | ||
1141 | unixpath = GNUNET_NETWORK_shorten_unixpath(unixpath); | ||
1142 | LOG(GNUNET_ERROR_TYPE_INFO, _("Using `%s' instead\n"), unixpath); | ||
1143 | } | ||
1144 | #ifdef LINUX | ||
1145 | abstract = GNUNET_CONFIGURATION_get_value_yesno(cfg, | ||
1146 | "TESTING", | ||
1147 | "USE_ABSTRACT_SOCKETS"); | ||
1148 | if (GNUNET_SYSERR == abstract) | ||
1149 | abstract = GNUNET_NO; | ||
1150 | #endif | ||
1151 | if ((GNUNET_YES != abstract) && | ||
1152 | (GNUNET_OK != GNUNET_DISK_directory_create_for_file(unixpath))) | ||
1153 | GNUNET_log_strerror_file(GNUNET_ERROR_TYPE_ERROR, "mkdir", unixpath); | ||
1154 | } | 1138 | } |
1139 | if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (unixpath)) | ||
1140 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "mkdir", unixpath); | ||
1141 | } | ||
1155 | if (NULL != unixpath) | 1142 | if (NULL != unixpath) |
1143 | { | ||
1144 | desc = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0); | ||
1145 | if (NULL == desc) | ||
1156 | { | 1146 | { |
1157 | desc = GNUNET_NETWORK_socket_create(AF_UNIX, SOCK_STREAM, 0); | 1147 | if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) || |
1158 | if (NULL == desc) | 1148 | (EACCES == errno)) |
1159 | { | 1149 | { |
1160 | if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) || | 1150 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket"); |
1161 | (EACCES == errno)) | 1151 | GNUNET_free_non_null (hostname); |
1162 | { | 1152 | GNUNET_free (unixpath); |
1163 | LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "socket"); | 1153 | return GNUNET_SYSERR; |
1164 | GNUNET_free_non_null(hostname); | 1154 | } |
1165 | GNUNET_free(unixpath); | 1155 | LOG (GNUNET_ERROR_TYPE_INFO, |
1166 | return GNUNET_SYSERR; | 1156 | _ ( |
1167 | } | 1157 | "Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"), |
1168 | LOG(GNUNET_ERROR_TYPE_INFO, | 1158 | service_name, |
1169 | _( | 1159 | strerror (errno)); |
1170 | "Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"), | 1160 | GNUNET_free (unixpath); |
1171 | service_name, | 1161 | unixpath = NULL; |
1172 | strerror(errno)); | ||
1173 | GNUNET_free(unixpath); | ||
1174 | unixpath = NULL; | ||
1175 | } | ||
1176 | else | ||
1177 | { | ||
1178 | GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(desc)); | ||
1179 | desc = NULL; | ||
1180 | } | ||
1181 | } | 1162 | } |
1163 | else | ||
1164 | { | ||
1165 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc)); | ||
1166 | desc = NULL; | ||
1167 | } | ||
1168 | } | ||
1182 | #endif | 1169 | #endif |
1183 | 1170 | ||
1184 | if ((0 == port) && (NULL == unixpath)) | 1171 | if ((0 == port) && (NULL == unixpath)) |
1172 | { | ||
1173 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
1174 | _ ( | ||
1175 | "Have neither PORT nor UNIXPATH for service `%s', but one is required\n"), | ||
1176 | service_name); | ||
1177 | GNUNET_free_non_null (hostname); | ||
1178 | return GNUNET_SYSERR; | ||
1179 | } | ||
1180 | if (0 == port) | ||
1181 | { | ||
1182 | saddrs = GNUNET_new_array (2, struct sockaddr *); | ||
1183 | saddrlens = GNUNET_new_array (2, socklen_t); | ||
1184 | add_unixpath (saddrs, saddrlens, unixpath); | ||
1185 | GNUNET_free_non_null (unixpath); | ||
1186 | GNUNET_free_non_null (hostname); | ||
1187 | *addrs = saddrs; | ||
1188 | *addr_lens = saddrlens; | ||
1189 | return 1; | ||
1190 | } | ||
1191 | |||
1192 | if (NULL != hostname) | ||
1193 | { | ||
1194 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1195 | "Resolving `%s' since that is where `%s' will bind to.\n", | ||
1196 | hostname, | ||
1197 | service_name); | ||
1198 | memset (&hints, 0, sizeof(struct addrinfo)); | ||
1199 | if (disablev6) | ||
1200 | hints.ai_family = AF_INET; | ||
1201 | hints.ai_protocol = IPPROTO_TCP; | ||
1202 | if ((0 != (ret = getaddrinfo (hostname, NULL, &hints, &res))) || | ||
1203 | (NULL == res)) | ||
1185 | { | 1204 | { |
1186 | LOG(GNUNET_ERROR_TYPE_ERROR, | 1205 | LOG (GNUNET_ERROR_TYPE_ERROR, |
1187 | _( | 1206 | _ ("Failed to resolve `%s': %s\n"), |
1188 | "Have neither PORT nor UNIXPATH for service `%s', but one is required\n"), | 1207 | hostname, |
1189 | service_name); | 1208 | gai_strerror (ret)); |
1190 | GNUNET_free_non_null(hostname); | 1209 | GNUNET_free (hostname); |
1210 | GNUNET_free_non_null (unixpath); | ||
1191 | return GNUNET_SYSERR; | 1211 | return GNUNET_SYSERR; |
1192 | } | 1212 | } |
1193 | if (0 == port) | 1213 | next = res; |
1214 | i = 0; | ||
1215 | while (NULL != (pos = next)) | ||
1194 | { | 1216 | { |
1195 | saddrs = GNUNET_new_array(2, struct sockaddr *); | 1217 | next = pos->ai_next; |
1196 | saddrlens = GNUNET_new_array(2, socklen_t); | 1218 | if ((disablev6) && (pos->ai_family == AF_INET6)) |
1197 | add_unixpath(saddrs, saddrlens, unixpath, abstract); | 1219 | continue; |
1198 | GNUNET_free_non_null(unixpath); | 1220 | i++; |
1199 | GNUNET_free_non_null(hostname); | ||
1200 | *addrs = saddrs; | ||
1201 | *addr_lens = saddrlens; | ||
1202 | return 1; | ||
1203 | } | 1221 | } |
1204 | 1222 | if (0 == i) | |
1205 | if (NULL != hostname) | ||
1206 | { | 1223 | { |
1207 | LOG(GNUNET_ERROR_TYPE_DEBUG, | 1224 | LOG (GNUNET_ERROR_TYPE_ERROR, |
1208 | "Resolving `%s' since that is where `%s' will bind to.\n", | 1225 | _ ("Failed to find %saddress for `%s'.\n"), |
1209 | hostname, | 1226 | disablev6 ? "IPv4 " : "", |
1210 | service_name); | 1227 | hostname); |
1211 | memset(&hints, 0, sizeof(struct addrinfo)); | 1228 | freeaddrinfo (res); |
1212 | if (disablev6) | 1229 | GNUNET_free (hostname); |
1213 | hints.ai_family = AF_INET; | 1230 | GNUNET_free_non_null (unixpath); |
1214 | hints.ai_protocol = IPPROTO_TCP; | 1231 | return GNUNET_SYSERR; |
1215 | if ((0 != (ret = getaddrinfo(hostname, NULL, &hints, &res))) || | 1232 | } |
1216 | (NULL == res)) | 1233 | resi = i; |
1217 | { | 1234 | if (NULL != unixpath) |
1218 | LOG(GNUNET_ERROR_TYPE_ERROR, | 1235 | resi++; |
1219 | _("Failed to resolve `%s': %s\n"), | 1236 | saddrs = GNUNET_new_array (resi + 1, struct sockaddr *); |
1220 | hostname, | 1237 | saddrlens = GNUNET_new_array (resi + 1, socklen_t); |
1221 | gai_strerror(ret)); | 1238 | i = 0; |
1222 | GNUNET_free(hostname); | 1239 | if (NULL != unixpath) |
1223 | GNUNET_free_non_null(unixpath); | 1240 | { |
1224 | return GNUNET_SYSERR; | 1241 | add_unixpath (saddrs, saddrlens, unixpath); |
1225 | } | 1242 | i++; |
1226 | next = res; | 1243 | } |
1227 | i = 0; | 1244 | next = res; |
1228 | while (NULL != (pos = next)) | 1245 | while (NULL != (pos = next)) |
1229 | { | 1246 | { |
1230 | next = pos->ai_next; | 1247 | next = pos->ai_next; |
1231 | if ((disablev6) && (pos->ai_family == AF_INET6)) | 1248 | if ((disablev6) && (AF_INET6 == pos->ai_family)) |
1232 | continue; | 1249 | continue; |
1233 | i++; | 1250 | if ((IPPROTO_TCP != pos->ai_protocol) && (0 != pos->ai_protocol)) |
1234 | } | 1251 | continue; /* not TCP */ |
1235 | if (0 == i) | 1252 | if ((SOCK_STREAM != pos->ai_socktype) && (0 != pos->ai_socktype)) |
1236 | { | 1253 | continue; /* huh? */ |
1237 | LOG(GNUNET_ERROR_TYPE_ERROR, | 1254 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1238 | _("Failed to find %saddress for `%s'.\n"), | 1255 | "Service `%s' will bind to `%s'\n", |
1239 | disablev6 ? "IPv4 " : "", | 1256 | service_name, |
1240 | hostname); | 1257 | GNUNET_a2s (pos->ai_addr, pos->ai_addrlen)); |
1241 | freeaddrinfo(res); | 1258 | if (AF_INET == pos->ai_family) |
1242 | GNUNET_free(hostname); | 1259 | { |
1243 | GNUNET_free_non_null(unixpath); | 1260 | GNUNET_assert (sizeof(struct sockaddr_in) == pos->ai_addrlen); |
1244 | return GNUNET_SYSERR; | 1261 | saddrlens[i] = pos->ai_addrlen; |
1245 | } | 1262 | saddrs[i] = GNUNET_malloc (saddrlens[i]); |
1246 | resi = i; | 1263 | GNUNET_memcpy (saddrs[i], pos->ai_addr, saddrlens[i]); |
1264 | ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port); | ||
1265 | } | ||
1266 | else | ||
1267 | { | ||
1268 | GNUNET_assert (AF_INET6 == pos->ai_family); | ||
1269 | GNUNET_assert (sizeof(struct sockaddr_in6) == pos->ai_addrlen); | ||
1270 | saddrlens[i] = pos->ai_addrlen; | ||
1271 | saddrs[i] = GNUNET_malloc (saddrlens[i]); | ||
1272 | GNUNET_memcpy (saddrs[i], pos->ai_addr, saddrlens[i]); | ||
1273 | ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port); | ||
1274 | } | ||
1275 | i++; | ||
1276 | } | ||
1277 | GNUNET_free (hostname); | ||
1278 | freeaddrinfo (res); | ||
1279 | resi = i; | ||
1280 | } | ||
1281 | else | ||
1282 | { | ||
1283 | /* will bind against everything, just set port */ | ||
1284 | if (disablev6) | ||
1285 | { | ||
1286 | /* V4-only */ | ||
1287 | resi = 1; | ||
1247 | if (NULL != unixpath) | 1288 | if (NULL != unixpath) |
1248 | resi++; | 1289 | resi++; |
1249 | saddrs = GNUNET_new_array(resi + 1, struct sockaddr *); | ||
1250 | saddrlens = GNUNET_new_array(resi + 1, socklen_t); | ||
1251 | i = 0; | 1290 | i = 0; |
1291 | saddrs = GNUNET_new_array (resi + 1, struct sockaddr *); | ||
1292 | saddrlens = GNUNET_new_array (resi + 1, socklen_t); | ||
1252 | if (NULL != unixpath) | 1293 | if (NULL != unixpath) |
1253 | { | 1294 | { |
1254 | add_unixpath(saddrs, saddrlens, unixpath, abstract); | 1295 | add_unixpath (saddrs, saddrlens, unixpath); |
1255 | i++; | 1296 | i++; |
1256 | } | 1297 | } |
1257 | next = res; | 1298 | saddrlens[i] = sizeof(struct sockaddr_in); |
1258 | while (NULL != (pos = next)) | 1299 | saddrs[i] = GNUNET_malloc (saddrlens[i]); |
1259 | { | ||
1260 | next = pos->ai_next; | ||
1261 | if ((disablev6) && (AF_INET6 == pos->ai_family)) | ||
1262 | continue; | ||
1263 | if ((IPPROTO_TCP != pos->ai_protocol) && (0 != pos->ai_protocol)) | ||
1264 | continue; /* not TCP */ | ||
1265 | if ((SOCK_STREAM != pos->ai_socktype) && (0 != pos->ai_socktype)) | ||
1266 | continue; /* huh? */ | ||
1267 | LOG(GNUNET_ERROR_TYPE_DEBUG, | ||
1268 | "Service `%s' will bind to `%s'\n", | ||
1269 | service_name, | ||
1270 | GNUNET_a2s(pos->ai_addr, pos->ai_addrlen)); | ||
1271 | if (AF_INET == pos->ai_family) | ||
1272 | { | ||
1273 | GNUNET_assert(sizeof(struct sockaddr_in) == pos->ai_addrlen); | ||
1274 | saddrlens[i] = pos->ai_addrlen; | ||
1275 | saddrs[i] = GNUNET_malloc(saddrlens[i]); | ||
1276 | GNUNET_memcpy(saddrs[i], pos->ai_addr, saddrlens[i]); | ||
1277 | ((struct sockaddr_in *)saddrs[i])->sin_port = htons(port); | ||
1278 | } | ||
1279 | else | ||
1280 | { | ||
1281 | GNUNET_assert(AF_INET6 == pos->ai_family); | ||
1282 | GNUNET_assert(sizeof(struct sockaddr_in6) == pos->ai_addrlen); | ||
1283 | saddrlens[i] = pos->ai_addrlen; | ||
1284 | saddrs[i] = GNUNET_malloc(saddrlens[i]); | ||
1285 | GNUNET_memcpy(saddrs[i], pos->ai_addr, saddrlens[i]); | ||
1286 | ((struct sockaddr_in6 *)saddrs[i])->sin6_port = htons(port); | ||
1287 | } | ||
1288 | i++; | ||
1289 | } | ||
1290 | GNUNET_free(hostname); | ||
1291 | freeaddrinfo(res); | ||
1292 | resi = i; | ||
1293 | } | ||
1294 | else | ||
1295 | { | ||
1296 | /* will bind against everything, just set port */ | ||
1297 | if (disablev6) | ||
1298 | { | ||
1299 | /* V4-only */ | ||
1300 | resi = 1; | ||
1301 | if (NULL != unixpath) | ||
1302 | resi++; | ||
1303 | i = 0; | ||
1304 | saddrs = GNUNET_new_array(resi + 1, struct sockaddr *); | ||
1305 | saddrlens = GNUNET_new_array(resi + 1, socklen_t); | ||
1306 | if (NULL != unixpath) | ||
1307 | { | ||
1308 | add_unixpath(saddrs, saddrlens, unixpath, abstract); | ||
1309 | i++; | ||
1310 | } | ||
1311 | saddrlens[i] = sizeof(struct sockaddr_in); | ||
1312 | saddrs[i] = GNUNET_malloc(saddrlens[i]); | ||
1313 | #if HAVE_SOCKADDR_IN_SIN_LEN | 1300 | #if HAVE_SOCKADDR_IN_SIN_LEN |
1314 | ((struct sockaddr_in *)saddrs[i])->sin_len = saddrlens[i]; | 1301 | ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[i]; |
1315 | #endif | 1302 | #endif |
1316 | ((struct sockaddr_in *)saddrs[i])->sin_family = AF_INET; | 1303 | ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET; |
1317 | ((struct sockaddr_in *)saddrs[i])->sin_port = htons(port); | 1304 | ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port); |
1318 | } | 1305 | } |
1319 | else | 1306 | else |
1320 | { | 1307 | { |
1321 | /* dual stack */ | 1308 | /* dual stack */ |
1322 | resi = 2; | 1309 | resi = 2; |
1323 | if (NULL != unixpath) | 1310 | if (NULL != unixpath) |
1324 | resi++; | 1311 | resi++; |
1325 | saddrs = GNUNET_new_array(resi + 1, struct sockaddr *); | 1312 | saddrs = GNUNET_new_array (resi + 1, struct sockaddr *); |
1326 | saddrlens = GNUNET_new_array(resi + 1, socklen_t); | 1313 | saddrlens = GNUNET_new_array (resi + 1, socklen_t); |
1327 | i = 0; | 1314 | i = 0; |
1328 | if (NULL != unixpath) | 1315 | if (NULL != unixpath) |
1329 | { | 1316 | { |
1330 | add_unixpath(saddrs, saddrlens, unixpath, abstract); | 1317 | add_unixpath (saddrs, saddrlens, unixpath); |
1331 | i++; | 1318 | i++; |
1332 | } | 1319 | } |
1333 | saddrlens[i] = sizeof(struct sockaddr_in6); | 1320 | saddrlens[i] = sizeof(struct sockaddr_in6); |
1334 | saddrs[i] = GNUNET_malloc(saddrlens[i]); | 1321 | saddrs[i] = GNUNET_malloc (saddrlens[i]); |
1335 | #if HAVE_SOCKADDR_IN_SIN_LEN | 1322 | #if HAVE_SOCKADDR_IN_SIN_LEN |
1336 | ((struct sockaddr_in6 *)saddrs[i])->sin6_len = saddrlens[0]; | 1323 | ((struct sockaddr_in6 *) saddrs[i])->sin6_len = saddrlens[0]; |
1337 | #endif | 1324 | #endif |
1338 | ((struct sockaddr_in6 *)saddrs[i])->sin6_family = AF_INET6; | 1325 | ((struct sockaddr_in6 *) saddrs[i])->sin6_family = AF_INET6; |
1339 | ((struct sockaddr_in6 *)saddrs[i])->sin6_port = htons(port); | 1326 | ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port); |
1340 | i++; | 1327 | i++; |
1341 | saddrlens[i] = sizeof(struct sockaddr_in); | 1328 | saddrlens[i] = sizeof(struct sockaddr_in); |
1342 | saddrs[i] = GNUNET_malloc(saddrlens[i]); | 1329 | saddrs[i] = GNUNET_malloc (saddrlens[i]); |
1343 | #if HAVE_SOCKADDR_IN_SIN_LEN | 1330 | #if HAVE_SOCKADDR_IN_SIN_LEN |
1344 | ((struct sockaddr_in *)saddrs[i])->sin_len = saddrlens[1]; | 1331 | ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[1]; |
1345 | #endif | 1332 | #endif |
1346 | ((struct sockaddr_in *)saddrs[i])->sin_family = AF_INET; | 1333 | ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET; |
1347 | ((struct sockaddr_in *)saddrs[i])->sin_port = htons(port); | 1334 | ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port); |
1348 | } | ||
1349 | } | 1335 | } |
1350 | GNUNET_free_non_null(unixpath); | 1336 | } |
1337 | GNUNET_free_non_null (unixpath); | ||
1351 | *addrs = saddrs; | 1338 | *addrs = saddrs; |
1352 | *addr_lens = saddrlens; | 1339 | *addr_lens = saddrlens; |
1353 | return resi; | 1340 | return resi; |
@@ -1362,89 +1349,93 @@ get_server_addresses(const char *service_name, | |||
1362 | * @return NULL on error, otherwise the listen socket | 1349 | * @return NULL on error, otherwise the listen socket |
1363 | */ | 1350 | */ |
1364 | static struct GNUNET_NETWORK_Handle * | 1351 | static struct GNUNET_NETWORK_Handle * |
1365 | open_listen_socket(const struct sockaddr *server_addr, socklen_t socklen) | 1352 | open_listen_socket (const struct sockaddr *server_addr, |
1353 | socklen_t socklen) | ||
1366 | { | 1354 | { |
1367 | struct GNUNET_NETWORK_Handle *sock; | 1355 | struct GNUNET_NETWORK_Handle *sock; |
1368 | uint16_t port; | 1356 | uint16_t port; |
1369 | int eno; | 1357 | int eno; |
1370 | 1358 | ||
1371 | switch (server_addr->sa_family) | 1359 | switch (server_addr->sa_family) |
1372 | { | 1360 | { |
1373 | case AF_INET: | 1361 | case AF_INET: |
1374 | port = ntohs(((const struct sockaddr_in *)server_addr)->sin_port); | 1362 | port = ntohs (((const struct sockaddr_in *) server_addr)->sin_port); |
1375 | break; | 1363 | break; |
1376 | 1364 | case AF_INET6: | |
1377 | case AF_INET6: | 1365 | port = ntohs (((const struct sockaddr_in6 *) server_addr)->sin6_port); |
1378 | port = ntohs(((const struct sockaddr_in6 *)server_addr)->sin6_port); | 1366 | break; |
1379 | break; | 1367 | case AF_UNIX: |
1380 | 1368 | port = 0; | |
1381 | case AF_UNIX: | 1369 | break; |
1382 | port = 0; | 1370 | default: |
1383 | break; | 1371 | GNUNET_break (0); |
1384 | 1372 | port = 0; | |
1385 | default: | 1373 | break; |
1386 | GNUNET_break(0); | 1374 | } |
1387 | port = 0; | 1375 | sock = GNUNET_NETWORK_socket_create (server_addr->sa_family, |
1388 | break; | 1376 | SOCK_STREAM, |
1389 | } | 1377 | 0); |
1390 | sock = GNUNET_NETWORK_socket_create(server_addr->sa_family, SOCK_STREAM, 0); | ||
1391 | if (NULL == sock) | 1378 | if (NULL == sock) |
1392 | { | 1379 | { |
1393 | LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "socket"); | 1380 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, |
1394 | errno = 0; | 1381 | "socket"); |
1395 | return NULL; | 1382 | errno = 0; |
1396 | } | 1383 | return NULL; |
1384 | } | ||
1397 | /* bind the socket */ | 1385 | /* bind the socket */ |
1398 | if (GNUNET_OK != GNUNET_NETWORK_socket_bind(sock, server_addr, socklen)) | 1386 | if (GNUNET_OK != |
1387 | GNUNET_NETWORK_socket_bind (sock, | ||
1388 | server_addr, | ||
1389 | socklen)) | ||
1390 | { | ||
1391 | eno = errno; | ||
1392 | if (EADDRINUSE != errno) | ||
1399 | { | 1393 | { |
1400 | eno = errno; | 1394 | /* we don't log 'EADDRINUSE' here since an IPv4 bind may |
1401 | if (EADDRINUSE != errno) | 1395 | * fail if we already took the port on IPv6; if both IPv4 and |
1402 | { | 1396 | * IPv6 binds fail, then our caller will log using the |
1403 | /* we don't log 'EADDRINUSE' here since an IPv4 bind may | 1397 | * errno preserved in 'eno' */ |
1404 | * fail if we already took the port on IPv6; if both IPv4 and | 1398 | if (0 != port) |
1405 | * IPv6 binds fail, then our caller will log using the | 1399 | LOG (GNUNET_ERROR_TYPE_ERROR, |
1406 | * errno preserved in 'eno' */ | 1400 | _ ("`%s' failed for port %d (%s).\n"), |
1407 | if (0 != port) | 1401 | "bind", |
1408 | LOG(GNUNET_ERROR_TYPE_ERROR, | 1402 | port, |
1409 | _("`%s' failed for port %d (%s).\n"), | 1403 | (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6"); |
1410 | "bind", | ||
1411 | port, | ||
1412 | (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6"); | ||
1413 | else | ||
1414 | LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "bind"); | ||
1415 | eno = 0; | ||
1416 | } | ||
1417 | else | 1404 | else |
1418 | { | 1405 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "bind"); |
1419 | if (0 != port) | 1406 | eno = 0; |
1420 | LOG(GNUNET_ERROR_TYPE_WARNING, | ||
1421 | _("`%s' failed for port %d (%s): address already in use\n"), | ||
1422 | "bind", | ||
1423 | port, | ||
1424 | (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6"); | ||
1425 | else if (AF_UNIX == server_addr->sa_family) | ||
1426 | { | ||
1427 | LOG(GNUNET_ERROR_TYPE_WARNING, | ||
1428 | _("`%s' failed for `%s': address already in use\n"), | ||
1429 | "bind", | ||
1430 | GNUNET_a2s(server_addr, socklen)); | ||
1431 | } | ||
1432 | } | ||
1433 | GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(sock)); | ||
1434 | errno = eno; | ||
1435 | return NULL; | ||
1436 | } | 1407 | } |
1437 | if (GNUNET_OK != GNUNET_NETWORK_socket_listen(sock, 5)) | 1408 | else |
1438 | { | 1409 | { |
1439 | LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "listen"); | 1410 | if (0 != port) |
1440 | GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(sock)); | 1411 | LOG (GNUNET_ERROR_TYPE_WARNING, |
1441 | errno = 0; | 1412 | _ ("`%s' failed for port %d (%s): address already in use\n"), |
1442 | return NULL; | 1413 | "bind", |
1414 | port, | ||
1415 | (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6"); | ||
1416 | else if (AF_UNIX == server_addr->sa_family) | ||
1417 | { | ||
1418 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
1419 | _ ("`%s' failed for `%s': address already in use\n"), | ||
1420 | "bind", | ||
1421 | GNUNET_a2s (server_addr, socklen)); | ||
1422 | } | ||
1443 | } | 1423 | } |
1424 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); | ||
1425 | errno = eno; | ||
1426 | return NULL; | ||
1427 | } | ||
1428 | if (GNUNET_OK != GNUNET_NETWORK_socket_listen (sock, 5)) | ||
1429 | { | ||
1430 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "listen"); | ||
1431 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); | ||
1432 | errno = 0; | ||
1433 | return NULL; | ||
1434 | } | ||
1444 | if (0 != port) | 1435 | if (0 != port) |
1445 | LOG(GNUNET_ERROR_TYPE_DEBUG, | 1436 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1446 | "Server starts to listen on port %u.\n", | 1437 | "Server starts to listen on port %u.\n", |
1447 | port); | 1438 | port); |
1448 | return sock; | 1439 | return sock; |
1449 | } | 1440 | } |
1450 | 1441 | ||
@@ -1466,128 +1457,141 @@ open_listen_socket(const struct sockaddr *server_addr, socklen_t socklen) | |||
1466 | * @return #GNUNET_OK if configuration succeeded | 1457 | * @return #GNUNET_OK if configuration succeeded |
1467 | */ | 1458 | */ |
1468 | static int | 1459 | static int |
1469 | setup_service(struct GNUNET_SERVICE_Handle *sh) | 1460 | setup_service (struct GNUNET_SERVICE_Handle *sh) |
1470 | { | 1461 | { |
1471 | int tolerant; | 1462 | int tolerant; |
1463 | struct GNUNET_NETWORK_Handle **csocks = NULL; | ||
1472 | struct GNUNET_NETWORK_Handle **lsocks; | 1464 | struct GNUNET_NETWORK_Handle **lsocks; |
1473 | const char *nfds; | 1465 | const char *nfds; |
1474 | unsigned int cnt; | 1466 | unsigned int cnt; |
1475 | int flags; | 1467 | int flags; |
1476 | char dummy[2]; | 1468 | char dummy[2]; |
1477 | 1469 | ||
1478 | if (GNUNET_CONFIGURATION_have_value(sh->cfg, sh->service_name, "TOLERANT")) | 1470 | if (GNUNET_CONFIGURATION_have_value (sh->cfg, |
1471 | sh->service_name, | ||
1472 | "TOLERANT")) | ||
1473 | { | ||
1474 | if (GNUNET_SYSERR == | ||
1475 | (tolerant = GNUNET_CONFIGURATION_get_value_yesno (sh->cfg, | ||
1476 | sh->service_name, | ||
1477 | "TOLERANT"))) | ||
1479 | { | 1478 | { |
1480 | if (GNUNET_SYSERR == | 1479 | LOG (GNUNET_ERROR_TYPE_ERROR, |
1481 | (tolerant = GNUNET_CONFIGURATION_get_value_yesno(sh->cfg, | 1480 | _ ("Specified value for `%s' of service `%s' is invalid\n"), |
1482 | sh->service_name, | 1481 | "TOLERANT", |
1483 | "TOLERANT"))) | 1482 | sh->service_name); |
1484 | { | 1483 | return GNUNET_SYSERR; |
1485 | LOG(GNUNET_ERROR_TYPE_ERROR, | ||
1486 | _("Specified value for `%s' of service `%s' is invalid\n"), | ||
1487 | "TOLERANT", | ||
1488 | sh->service_name); | ||
1489 | return GNUNET_SYSERR; | ||
1490 | } | ||
1491 | } | 1484 | } |
1485 | } | ||
1492 | else | 1486 | else |
1493 | tolerant = GNUNET_NO; | 1487 | tolerant = GNUNET_NO; |
1494 | 1488 | ||
1495 | lsocks = NULL; | 1489 | lsocks = NULL; |
1496 | |||
1497 | errno = 0; | 1490 | errno = 0; |
1498 | if ((NULL != (nfds = getenv("LISTEN_FDS"))) && | 1491 | if ((NULL != (nfds = getenv ("LISTEN_FDS"))) && |
1499 | (1 == sscanf(nfds, "%u%1s", &cnt, dummy)) && (cnt > 0) && | 1492 | (1 == sscanf (nfds, "%u%1s", &cnt, dummy)) && (cnt > 0) && |
1500 | (cnt < FD_SETSIZE) && (cnt + 4 < FD_SETSIZE)) | 1493 | (cnt < FD_SETSIZE) && (cnt + 4 < FD_SETSIZE)) |
1494 | { | ||
1495 | lsocks = GNUNET_new_array (cnt + 1, struct GNUNET_NETWORK_Handle *); | ||
1496 | while (0 < cnt--) | ||
1501 | { | 1497 | { |
1502 | lsocks = GNUNET_new_array(cnt + 1, struct GNUNET_NETWORK_Handle *); | 1498 | flags = fcntl (3 + cnt, F_GETFD); |
1503 | while (0 < cnt--) | 1499 | if ((flags < 0) || (0 != (flags & FD_CLOEXEC)) || |
1504 | { | 1500 | (NULL == (lsocks[cnt] = GNUNET_NETWORK_socket_box_native (3 + cnt)))) |
1505 | flags = fcntl(3 + cnt, F_GETFD); | 1501 | { |
1506 | if ((flags < 0) || (0 != (flags & FD_CLOEXEC)) || | 1502 | LOG (GNUNET_ERROR_TYPE_ERROR, |
1507 | (NULL == (lsocks[cnt] = GNUNET_NETWORK_socket_box_native(3 + cnt)))) | 1503 | _ ( |
1508 | { | 1504 | "Could not access pre-bound socket %u, will try to bind myself\n"), |
1509 | LOG(GNUNET_ERROR_TYPE_ERROR, | 1505 | (unsigned int) 3 + cnt); |
1510 | _( | 1506 | cnt++; |
1511 | "Could not access pre-bound socket %u, will try to bind myself\n"), | 1507 | while (NULL != lsocks[cnt]) |
1512 | (unsigned int)3 + cnt); | 1508 | GNUNET_break (GNUNET_OK == |
1513 | cnt++; | 1509 | GNUNET_NETWORK_socket_close (lsocks[cnt++])); |
1514 | while (NULL != lsocks[cnt]) | 1510 | GNUNET_free (lsocks); |
1515 | GNUNET_break(GNUNET_OK == | 1511 | lsocks = NULL; |
1516 | GNUNET_NETWORK_socket_close(lsocks[cnt++])); | 1512 | break; |
1517 | GNUNET_free(lsocks); | 1513 | } |
1518 | lsocks = NULL; | ||
1519 | break; | ||
1520 | } | ||
1521 | } | ||
1522 | unsetenv("LISTEN_FDS"); | ||
1523 | } | 1514 | } |
1515 | unsetenv ("LISTEN_FDS"); | ||
1516 | } | ||
1517 | if ( (0 != (GNUNET_SERVICE_OPTION_CLOSE_LSOCKS & sh->options)) && | ||
1518 | (NULL != lsocks) ) | ||
1519 | { | ||
1520 | csocks = lsocks; | ||
1521 | lsocks = NULL; | ||
1522 | } | ||
1524 | 1523 | ||
1525 | if (NULL != lsocks) | 1524 | if (NULL != lsocks) |
1525 | { | ||
1526 | /* listen only on inherited sockets if we have any */ | ||
1527 | for (struct GNUNET_NETWORK_Handle **ls = lsocks; NULL != *ls; ls++) | ||
1526 | { | 1528 | { |
1527 | /* listen only on inherited sockets if we have any */ | 1529 | struct ServiceListenContext *slc; |
1528 | struct GNUNET_NETWORK_Handle **ls; | 1530 | |
1529 | 1531 | slc = GNUNET_new (struct ServiceListenContext); | |
1530 | for (ls = lsocks; NULL != *ls; ls++) | 1532 | slc->sh = sh; |
1531 | { | 1533 | slc->listen_socket = *ls; |
1532 | struct ServiceListenContext *slc; | 1534 | GNUNET_CONTAINER_DLL_insert (sh->slc_head, sh->slc_tail, slc); |
1533 | |||
1534 | slc = GNUNET_new(struct ServiceListenContext); | ||
1535 | slc->sh = sh; | ||
1536 | slc->listen_socket = *ls; | ||
1537 | GNUNET_CONTAINER_DLL_insert(sh->slc_head, sh->slc_tail, slc); | ||
1538 | } | ||
1539 | GNUNET_free(lsocks); | ||
1540 | } | 1535 | } |
1536 | GNUNET_free (lsocks); | ||
1537 | } | ||
1541 | else | 1538 | else |
1542 | { | 1539 | { |
1543 | struct sockaddr **addrs; | 1540 | struct sockaddr **addrs; |
1544 | socklen_t *addrlens; | 1541 | socklen_t *addrlens; |
1545 | int num; | 1542 | int num; |
1546 | 1543 | ||
1547 | num = get_server_addresses(sh->service_name, sh->cfg, &addrs, &addrlens); | 1544 | num = get_server_addresses (sh->service_name, sh->cfg, &addrs, &addrlens); |
1548 | if (GNUNET_SYSERR == num) | 1545 | if (GNUNET_SYSERR == num) |
1549 | return GNUNET_SYSERR; | 1546 | return GNUNET_SYSERR; |
1550 | 1547 | ||
1551 | for (int i = 0; i < num; i++) | 1548 | for (int i = 0; i < num; i++) |
1552 | { | 1549 | { |
1553 | struct ServiceListenContext *slc; | 1550 | struct ServiceListenContext *slc; |
1554 | |||
1555 | slc = GNUNET_new(struct ServiceListenContext); | ||
1556 | slc->sh = sh; | ||
1557 | slc->listen_socket = open_listen_socket(addrs[i], addrlens[i]); | ||
1558 | GNUNET_free(addrs[i]); | ||
1559 | if (NULL == slc->listen_socket) | ||
1560 | { | ||
1561 | GNUNET_log_strerror(GNUNET_ERROR_TYPE_ERROR, "bind"); | ||
1562 | GNUNET_free(slc); | ||
1563 | continue; | ||
1564 | } | ||
1565 | GNUNET_CONTAINER_DLL_insert(sh->slc_head, sh->slc_tail, slc); | ||
1566 | } | ||
1567 | GNUNET_free_non_null(addrlens); | ||
1568 | GNUNET_free_non_null(addrs); | ||
1569 | if ((0 != num) && (NULL == sh->slc_head)) | ||
1570 | { | ||
1571 | /* All attempts to bind failed, hard failure */ | ||
1572 | GNUNET_log( | ||
1573 | GNUNET_ERROR_TYPE_ERROR, | ||
1574 | _( | ||
1575 | "Could not bind to any of the ports I was supposed to, refusing to run!\n")); | ||
1576 | return GNUNET_SYSERR; | ||
1577 | } | ||
1578 | } | ||
1579 | 1551 | ||
1552 | slc = GNUNET_new (struct ServiceListenContext); | ||
1553 | slc->sh = sh; | ||
1554 | slc->listen_socket = open_listen_socket (addrs[i], addrlens[i]); | ||
1555 | GNUNET_free (addrs[i]); | ||
1556 | if (NULL == slc->listen_socket) | ||
1557 | { | ||
1558 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "bind"); | ||
1559 | GNUNET_free (slc); | ||
1560 | continue; | ||
1561 | } | ||
1562 | GNUNET_CONTAINER_DLL_insert (sh->slc_head, sh->slc_tail, slc); | ||
1563 | } | ||
1564 | GNUNET_free_non_null (addrlens); | ||
1565 | GNUNET_free_non_null (addrs); | ||
1566 | if ((0 != num) && (NULL == sh->slc_head)) | ||
1567 | { | ||
1568 | /* All attempts to bind failed, hard failure */ | ||
1569 | GNUNET_log ( | ||
1570 | GNUNET_ERROR_TYPE_ERROR, | ||
1571 | _ ( | ||
1572 | "Could not bind to any of the ports I was supposed to, refusing to run!\n")); | ||
1573 | GNUNET_free_non_null (csocks); | ||
1574 | return GNUNET_SYSERR; | ||
1575 | } | ||
1576 | } | ||
1577 | if (NULL != csocks) | ||
1578 | { | ||
1579 | /* close inherited sockets to signal parent that we are ready */ | ||
1580 | for (struct GNUNET_NETWORK_Handle **ls = csocks; NULL != *ls; ls++) | ||
1581 | GNUNET_NETWORK_socket_close (*ls); | ||
1582 | GNUNET_free (csocks); | ||
1583 | } | ||
1580 | sh->require_found = tolerant ? GNUNET_NO : GNUNET_YES; | 1584 | sh->require_found = tolerant ? GNUNET_NO : GNUNET_YES; |
1581 | sh->match_uid = GNUNET_CONFIGURATION_get_value_yesno(sh->cfg, | 1585 | sh->match_uid = GNUNET_CONFIGURATION_get_value_yesno (sh->cfg, |
1582 | sh->service_name, | 1586 | sh->service_name, |
1583 | "UNIX_MATCH_UID"); | 1587 | "UNIX_MATCH_UID"); |
1584 | sh->match_gid = GNUNET_CONFIGURATION_get_value_yesno(sh->cfg, | 1588 | sh->match_gid = GNUNET_CONFIGURATION_get_value_yesno (sh->cfg, |
1585 | sh->service_name, | 1589 | sh->service_name, |
1586 | "UNIX_MATCH_GID"); | 1590 | "UNIX_MATCH_GID"); |
1587 | process_acl4(&sh->v4_denied, sh, "REJECT_FROM"); | 1591 | process_acl4 (&sh->v4_denied, sh, "REJECT_FROM"); |
1588 | process_acl4(&sh->v4_allowed, sh, "ACCEPT_FROM"); | 1592 | process_acl4 (&sh->v4_allowed, sh, "ACCEPT_FROM"); |
1589 | process_acl6(&sh->v6_denied, sh, "REJECT_FROM6"); | 1593 | process_acl6 (&sh->v6_denied, sh, "REJECT_FROM6"); |
1590 | process_acl6(&sh->v6_allowed, sh, "ACCEPT_FROM6"); | 1594 | process_acl6 (&sh->v6_allowed, sh, "ACCEPT_FROM6"); |
1591 | return GNUNET_OK; | 1595 | return GNUNET_OK; |
1592 | } | 1596 | } |
1593 | 1597 | ||
@@ -1600,14 +1604,14 @@ setup_service(struct GNUNET_SERVICE_Handle *sh) | |||
1600 | * @return value of the 'USERNAME' option | 1604 | * @return value of the 'USERNAME' option |
1601 | */ | 1605 | */ |
1602 | static char * | 1606 | static char * |
1603 | get_user_name(struct GNUNET_SERVICE_Handle *sh) | 1607 | get_user_name (struct GNUNET_SERVICE_Handle *sh) |
1604 | { | 1608 | { |
1605 | char *un; | 1609 | char *un; |
1606 | 1610 | ||
1607 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename(sh->cfg, | 1611 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (sh->cfg, |
1608 | sh->service_name, | 1612 | sh->service_name, |
1609 | "USERNAME", | 1613 | "USERNAME", |
1610 | &un)) | 1614 | &un)) |
1611 | return NULL; | 1615 | return NULL; |
1612 | return un; | 1616 | return un; |
1613 | } | 1617 | } |
@@ -1620,45 +1624,45 @@ get_user_name(struct GNUNET_SERVICE_Handle *sh) | |||
1620 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | 1624 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error |
1621 | */ | 1625 | */ |
1622 | static int | 1626 | static int |
1623 | set_user_id(struct GNUNET_SERVICE_Handle *sh) | 1627 | set_user_id (struct GNUNET_SERVICE_Handle *sh) |
1624 | { | 1628 | { |
1625 | char *user; | 1629 | char *user; |
1626 | 1630 | ||
1627 | if (NULL == (user = get_user_name(sh))) | 1631 | if (NULL == (user = get_user_name (sh))) |
1628 | return GNUNET_OK; /* keep */ | 1632 | return GNUNET_OK; /* keep */ |
1629 | 1633 | ||
1630 | struct passwd *pws; | 1634 | struct passwd *pws; |
1631 | 1635 | ||
1632 | errno = 0; | 1636 | errno = 0; |
1633 | pws = getpwnam(user); | 1637 | pws = getpwnam (user); |
1634 | if (NULL == pws) | 1638 | if (NULL == pws) |
1635 | { | 1639 | { |
1636 | LOG(GNUNET_ERROR_TYPE_ERROR, | 1640 | LOG (GNUNET_ERROR_TYPE_ERROR, |
1637 | _("Cannot obtain information about user `%s': %s\n"), | 1641 | _ ("Cannot obtain information about user `%s': %s\n"), |
1638 | user, | 1642 | user, |
1639 | errno == 0 ? _("No such user") : strerror(errno)); | 1643 | errno == 0 ? _ ("No such user") : strerror (errno)); |
1640 | GNUNET_free(user); | 1644 | GNUNET_free (user); |
1641 | return GNUNET_SYSERR; | 1645 | return GNUNET_SYSERR; |
1642 | } | 1646 | } |
1643 | if ((0 != setgid(pws->pw_gid)) || (0 != setegid(pws->pw_gid)) || | 1647 | if ((0 != setgid (pws->pw_gid)) || (0 != setegid (pws->pw_gid)) || |
1644 | #if HAVE_INITGROUPS | 1648 | #if HAVE_INITGROUPS |
1645 | (0 != initgroups(user, pws->pw_gid)) || | 1649 | (0 != initgroups (user, pws->pw_gid)) || |
1646 | #endif | 1650 | #endif |
1647 | (0 != setuid(pws->pw_uid)) || (0 != seteuid(pws->pw_uid))) | 1651 | (0 != setuid (pws->pw_uid)) || (0 != seteuid (pws->pw_uid))) |
1652 | { | ||
1653 | if ((0 != setregid (pws->pw_gid, pws->pw_gid)) || | ||
1654 | (0 != setreuid (pws->pw_uid, pws->pw_uid))) | ||
1648 | { | 1655 | { |
1649 | if ((0 != setregid(pws->pw_gid, pws->pw_gid)) || | 1656 | LOG (GNUNET_ERROR_TYPE_ERROR, |
1650 | (0 != setreuid(pws->pw_uid, pws->pw_uid))) | 1657 | _ ("Cannot change user/group to `%s': %s\n"), |
1651 | { | 1658 | user, |
1652 | LOG(GNUNET_ERROR_TYPE_ERROR, | 1659 | strerror (errno)); |
1653 | _("Cannot change user/group to `%s': %s\n"), | 1660 | GNUNET_free (user); |
1654 | user, | 1661 | return GNUNET_SYSERR; |
1655 | strerror(errno)); | ||
1656 | GNUNET_free(user); | ||
1657 | return GNUNET_SYSERR; | ||
1658 | } | ||
1659 | } | 1662 | } |
1663 | } | ||
1660 | 1664 | ||
1661 | GNUNET_free(user); | 1665 | GNUNET_free (user); |
1662 | return GNUNET_OK; | 1666 | return GNUNET_OK; |
1663 | } | 1667 | } |
1664 | 1668 | ||
@@ -1671,14 +1675,14 @@ set_user_id(struct GNUNET_SERVICE_Handle *sh) | |||
1671 | * @return name of the file for the process ID | 1675 | * @return name of the file for the process ID |
1672 | */ | 1676 | */ |
1673 | static char * | 1677 | static char * |
1674 | get_pid_file_name(struct GNUNET_SERVICE_Handle *sh) | 1678 | get_pid_file_name (struct GNUNET_SERVICE_Handle *sh) |
1675 | { | 1679 | { |
1676 | char *pif; | 1680 | char *pif; |
1677 | 1681 | ||
1678 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename(sh->cfg, | 1682 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (sh->cfg, |
1679 | sh->service_name, | 1683 | sh->service_name, |
1680 | "PIDFILE", | 1684 | "PIDFILE", |
1681 | &pif)) | 1685 | &pif)) |
1682 | return NULL; | 1686 | return NULL; |
1683 | return pif; | 1687 | return pif; |
1684 | } | 1688 | } |
@@ -1690,15 +1694,15 @@ get_pid_file_name(struct GNUNET_SERVICE_Handle *sh) | |||
1690 | * @param sh service context | 1694 | * @param sh service context |
1691 | */ | 1695 | */ |
1692 | static void | 1696 | static void |
1693 | pid_file_delete(struct GNUNET_SERVICE_Handle *sh) | 1697 | pid_file_delete (struct GNUNET_SERVICE_Handle *sh) |
1694 | { | 1698 | { |
1695 | char *pif = get_pid_file_name(sh); | 1699 | char *pif = get_pid_file_name (sh); |
1696 | 1700 | ||
1697 | if (NULL == pif) | 1701 | if (NULL == pif) |
1698 | return; /* no PID file */ | 1702 | return; /* no PID file */ |
1699 | if (0 != unlink(pif)) | 1703 | if (0 != unlink (pif)) |
1700 | LOG_STRERROR_FILE(GNUNET_ERROR_TYPE_WARNING, "unlink", pif); | 1704 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "unlink", pif); |
1701 | GNUNET_free(pif); | 1705 | GNUNET_free (pif); |
1702 | } | 1706 | } |
1703 | 1707 | ||
1704 | 1708 | ||
@@ -1709,73 +1713,73 @@ pid_file_delete(struct GNUNET_SERVICE_Handle *sh) | |||
1709 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | 1713 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error |
1710 | */ | 1714 | */ |
1711 | static int | 1715 | static int |
1712 | detach_terminal(struct GNUNET_SERVICE_Handle *sh) | 1716 | detach_terminal (struct GNUNET_SERVICE_Handle *sh) |
1713 | { | 1717 | { |
1714 | pid_t pid; | 1718 | pid_t pid; |
1715 | int nullfd; | 1719 | int nullfd; |
1716 | int filedes[2]; | 1720 | int filedes[2]; |
1717 | 1721 | ||
1718 | if (0 != pipe(filedes)) | 1722 | if (0 != pipe (filedes)) |
1719 | { | 1723 | { |
1720 | LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "pipe"); | 1724 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "pipe"); |
1721 | return GNUNET_SYSERR; | 1725 | return GNUNET_SYSERR; |
1722 | } | 1726 | } |
1723 | pid = fork(); | 1727 | pid = fork (); |
1724 | if (pid < 0) | 1728 | if (pid < 0) |
1725 | { | 1729 | { |
1726 | LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "fork"); | 1730 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "fork"); |
1727 | return GNUNET_SYSERR; | 1731 | return GNUNET_SYSERR; |
1728 | } | 1732 | } |
1729 | if (0 != pid) | 1733 | if (0 != pid) |
1734 | { | ||
1735 | /* Parent */ | ||
1736 | char c; | ||
1737 | |||
1738 | GNUNET_break (0 == close (filedes[1])); | ||
1739 | c = 'X'; | ||
1740 | if (1 != read (filedes[0], &c, sizeof(char))) | ||
1741 | LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "read"); | ||
1742 | fflush (stdout); | ||
1743 | switch (c) | ||
1730 | { | 1744 | { |
1731 | /* Parent */ | 1745 | case '.': |
1732 | char c; | 1746 | exit (0); |
1733 | 1747 | ||
1734 | GNUNET_break(0 == close(filedes[1])); | 1748 | case 'I': |
1735 | c = 'X'; | 1749 | LOG (GNUNET_ERROR_TYPE_INFO, |
1736 | if (1 != read(filedes[0], &c, sizeof(char))) | 1750 | _ ("Service process failed to initialize\n")); |
1737 | LOG_STRERROR(GNUNET_ERROR_TYPE_WARNING, "read"); | 1751 | break; |
1738 | fflush(stdout); | 1752 | |
1739 | switch (c) | 1753 | case 'S': |
1740 | { | 1754 | LOG (GNUNET_ERROR_TYPE_INFO, |
1741 | case '.': | 1755 | _ ("Service process could not initialize server function\n")); |
1742 | exit(0); | 1756 | break; |
1743 | 1757 | ||
1744 | case 'I': | 1758 | case 'X': |
1745 | LOG(GNUNET_ERROR_TYPE_INFO, | 1759 | LOG (GNUNET_ERROR_TYPE_INFO, |
1746 | _("Service process failed to initialize\n")); | 1760 | _ ("Service process failed to report status\n")); |
1747 | break; | 1761 | break; |
1748 | |||
1749 | case 'S': | ||
1750 | LOG(GNUNET_ERROR_TYPE_INFO, | ||
1751 | _("Service process could not initialize server function\n")); | ||
1752 | break; | ||
1753 | |||
1754 | case 'X': | ||
1755 | LOG(GNUNET_ERROR_TYPE_INFO, | ||
1756 | _("Service process failed to report status\n")); | ||
1757 | break; | ||
1758 | } | ||
1759 | exit(1); /* child reported error */ | ||
1760 | } | 1762 | } |
1761 | GNUNET_break(0 == close(0)); | 1763 | exit (1); /* child reported error */ |
1762 | GNUNET_break(0 == close(1)); | 1764 | } |
1763 | GNUNET_break(0 == close(filedes[0])); | 1765 | GNUNET_break (0 == close (0)); |
1764 | nullfd = open("/dev/null", O_RDWR | O_APPEND); | 1766 | GNUNET_break (0 == close (1)); |
1767 | GNUNET_break (0 == close (filedes[0])); | ||
1768 | nullfd = open ("/dev/null", O_RDWR | O_APPEND); | ||
1765 | if (nullfd < 0) | 1769 | if (nullfd < 0) |
1766 | return GNUNET_SYSERR; | 1770 | return GNUNET_SYSERR; |
1767 | /* set stdin/stdout to /dev/null */ | 1771 | /* set stdin/stdout to /dev/null */ |
1768 | if ((dup2(nullfd, 0) < 0) || (dup2(nullfd, 1) < 0)) | 1772 | if ((dup2 (nullfd, 0) < 0) || (dup2 (nullfd, 1) < 0)) |
1769 | { | 1773 | { |
1770 | LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "dup2"); | 1774 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "dup2"); |
1771 | (void)close(nullfd); | 1775 | (void) close (nullfd); |
1772 | return GNUNET_SYSERR; | 1776 | return GNUNET_SYSERR; |
1773 | } | 1777 | } |
1774 | (void)close(nullfd); | 1778 | (void) close (nullfd); |
1775 | /* Detach from controlling terminal */ | 1779 | /* Detach from controlling terminal */ |
1776 | pid = setsid(); | 1780 | pid = setsid (); |
1777 | if (-1 == pid) | 1781 | if (-1 == pid) |
1778 | LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "setsid"); | 1782 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "setsid"); |
1779 | sh->ready_confirm_fd = filedes[1]; | 1783 | sh->ready_confirm_fd = filedes[1]; |
1780 | 1784 | ||
1781 | return GNUNET_OK; | 1785 | return GNUNET_OK; |
@@ -1789,23 +1793,23 @@ detach_terminal(struct GNUNET_SERVICE_Handle *sh) | |||
1789 | * @param sh handle to the service to tear down. | 1793 | * @param sh handle to the service to tear down. |
1790 | */ | 1794 | */ |
1791 | static void | 1795 | static void |
1792 | teardown_service(struct GNUNET_SERVICE_Handle *sh) | 1796 | teardown_service (struct GNUNET_SERVICE_Handle *sh) |
1793 | { | 1797 | { |
1794 | struct ServiceListenContext *slc; | 1798 | struct ServiceListenContext *slc; |
1795 | 1799 | ||
1796 | GNUNET_free_non_null(sh->v4_denied); | 1800 | GNUNET_free_non_null (sh->v4_denied); |
1797 | GNUNET_free_non_null(sh->v6_denied); | 1801 | GNUNET_free_non_null (sh->v6_denied); |
1798 | GNUNET_free_non_null(sh->v4_allowed); | 1802 | GNUNET_free_non_null (sh->v4_allowed); |
1799 | GNUNET_free_non_null(sh->v6_allowed); | 1803 | GNUNET_free_non_null (sh->v6_allowed); |
1800 | while (NULL != (slc = sh->slc_head)) | 1804 | while (NULL != (slc = sh->slc_head)) |
1801 | { | 1805 | { |
1802 | GNUNET_CONTAINER_DLL_remove(sh->slc_head, sh->slc_tail, slc); | 1806 | GNUNET_CONTAINER_DLL_remove (sh->slc_head, sh->slc_tail, slc); |
1803 | if (NULL != slc->listen_task) | 1807 | if (NULL != slc->listen_task) |
1804 | GNUNET_SCHEDULER_cancel(slc->listen_task); | 1808 | GNUNET_SCHEDULER_cancel (slc->listen_task); |
1805 | GNUNET_break(GNUNET_OK == | 1809 | GNUNET_break (GNUNET_OK == |
1806 | GNUNET_NETWORK_socket_close(slc->listen_socket)); | 1810 | GNUNET_NETWORK_socket_close (slc->listen_socket)); |
1807 | GNUNET_free(slc); | 1811 | GNUNET_free (slc); |
1808 | } | 1812 | } |
1809 | } | 1813 | } |
1810 | 1814 | ||
1811 | 1815 | ||
@@ -1816,7 +1820,7 @@ teardown_service(struct GNUNET_SERVICE_Handle *sh) | |||
1816 | * @param msg AGPL request | 1820 | * @param msg AGPL request |
1817 | */ | 1821 | */ |
1818 | static void | 1822 | static void |
1819 | return_agpl(void *cls, const struct GNUNET_MessageHeader *msg) | 1823 | return_agpl (void *cls, const struct GNUNET_MessageHeader *msg) |
1820 | { | 1824 | { |
1821 | struct GNUNET_SERVICE_Client *client = cls; | 1825 | struct GNUNET_SERVICE_Client *client = cls; |
1822 | struct GNUNET_MQ_Handle *mq; | 1826 | struct GNUNET_MQ_Handle *mq; |
@@ -1824,13 +1828,13 @@ return_agpl(void *cls, const struct GNUNET_MessageHeader *msg) | |||
1824 | struct GNUNET_MessageHeader *res; | 1828 | struct GNUNET_MessageHeader *res; |
1825 | size_t slen; | 1829 | size_t slen; |
1826 | 1830 | ||
1827 | (void)msg; | 1831 | (void) msg; |
1828 | slen = strlen(GNUNET_AGPL_URL) + 1; | 1832 | slen = strlen (GNUNET_AGPL_URL) + 1; |
1829 | env = GNUNET_MQ_msg_extra(res, GNUNET_MESSAGE_TYPE_RESPONSE_AGPL, slen); | 1833 | env = GNUNET_MQ_msg_extra (res, GNUNET_MESSAGE_TYPE_RESPONSE_AGPL, slen); |
1830 | memcpy(&res[1], GNUNET_AGPL_URL, slen); | 1834 | memcpy (&res[1], GNUNET_AGPL_URL, slen); |
1831 | mq = GNUNET_SERVICE_client_get_mq(client); | 1835 | mq = GNUNET_SERVICE_client_get_mq (client); |
1832 | GNUNET_MQ_send(mq, env); | 1836 | GNUNET_MQ_send (mq, env); |
1833 | GNUNET_SERVICE_client_continue(client); | 1837 | GNUNET_SERVICE_client_continue (client); |
1834 | } | 1838 | } |
1835 | 1839 | ||
1836 | 1840 | ||
@@ -1871,29 +1875,29 @@ return_agpl(void *cls, const struct GNUNET_MessageHeader *msg) | |||
1871 | * @return NULL on error | 1875 | * @return NULL on error |
1872 | */ | 1876 | */ |
1873 | struct GNUNET_SERVICE_Handle * | 1877 | struct GNUNET_SERVICE_Handle * |
1874 | GNUNET_SERVICE_start(const char *service_name, | 1878 | GNUNET_SERVICE_start (const char *service_name, |
1875 | const struct GNUNET_CONFIGURATION_Handle *cfg, | 1879 | const struct GNUNET_CONFIGURATION_Handle *cfg, |
1876 | GNUNET_SERVICE_ConnectHandler connect_cb, | 1880 | GNUNET_SERVICE_ConnectHandler connect_cb, |
1877 | GNUNET_SERVICE_DisconnectHandler disconnect_cb, | 1881 | GNUNET_SERVICE_DisconnectHandler disconnect_cb, |
1878 | void *cls, | 1882 | void *cls, |
1879 | const struct GNUNET_MQ_MessageHandler *handlers) | 1883 | const struct GNUNET_MQ_MessageHandler *handlers) |
1880 | { | 1884 | { |
1881 | struct GNUNET_SERVICE_Handle *sh; | 1885 | struct GNUNET_SERVICE_Handle *sh; |
1882 | 1886 | ||
1883 | sh = GNUNET_new(struct GNUNET_SERVICE_Handle); | 1887 | sh = GNUNET_new (struct GNUNET_SERVICE_Handle); |
1884 | sh->service_name = service_name; | 1888 | sh->service_name = service_name; |
1885 | sh->cfg = cfg; | 1889 | sh->cfg = cfg; |
1886 | sh->connect_cb = connect_cb; | 1890 | sh->connect_cb = connect_cb; |
1887 | sh->disconnect_cb = disconnect_cb; | 1891 | sh->disconnect_cb = disconnect_cb; |
1888 | sh->cb_cls = cls; | 1892 | sh->cb_cls = cls; |
1889 | sh->handlers = GNUNET_MQ_copy_handlers2(handlers, &return_agpl, NULL); | 1893 | sh->handlers = GNUNET_MQ_copy_handlers2 (handlers, &return_agpl, NULL); |
1890 | if (GNUNET_OK != setup_service(sh)) | 1894 | if (GNUNET_OK != setup_service (sh)) |
1891 | { | 1895 | { |
1892 | GNUNET_free_non_null(sh->handlers); | 1896 | GNUNET_free_non_null (sh->handlers); |
1893 | GNUNET_free(sh); | 1897 | GNUNET_free (sh); |
1894 | return NULL; | 1898 | return NULL; |
1895 | } | 1899 | } |
1896 | do_resume(sh, SUSPEND_STATE_NONE); | 1900 | do_resume (sh, SUSPEND_STATE_NONE); |
1897 | return sh; | 1901 | return sh; |
1898 | } | 1902 | } |
1899 | 1903 | ||
@@ -1904,16 +1908,16 @@ GNUNET_SERVICE_start(const char *service_name, | |||
1904 | * @param srv service to stop | 1908 | * @param srv service to stop |
1905 | */ | 1909 | */ |
1906 | void | 1910 | void |
1907 | GNUNET_SERVICE_stop(struct GNUNET_SERVICE_Handle *srv) | 1911 | GNUNET_SERVICE_stop (struct GNUNET_SERVICE_Handle *srv) |
1908 | { | 1912 | { |
1909 | struct GNUNET_SERVICE_Client *client; | 1913 | struct GNUNET_SERVICE_Client *client; |
1910 | 1914 | ||
1911 | GNUNET_SERVICE_suspend(srv); | 1915 | GNUNET_SERVICE_suspend (srv); |
1912 | while (NULL != (client = srv->clients_head)) | 1916 | while (NULL != (client = srv->clients_head)) |
1913 | GNUNET_SERVICE_client_drop(client); | 1917 | GNUNET_SERVICE_client_drop (client); |
1914 | teardown_service(srv); | 1918 | teardown_service (srv); |
1915 | GNUNET_free_non_null(srv->handlers); | 1919 | GNUNET_free_non_null (srv->handlers); |
1916 | GNUNET_free(srv); | 1920 | GNUNET_free (srv); |
1917 | } | 1921 | } |
1918 | 1922 | ||
1919 | 1923 | ||
@@ -1959,15 +1963,15 @@ GNUNET_SERVICE_stop(struct GNUNET_SERVICE_Handle *srv) | |||
1959 | * @return 0 on success, non-zero on error | 1963 | * @return 0 on success, non-zero on error |
1960 | */ | 1964 | */ |
1961 | int | 1965 | int |
1962 | GNUNET_SERVICE_run_(int argc, | 1966 | GNUNET_SERVICE_run_ (int argc, |
1963 | char *const *argv, | 1967 | char *const *argv, |
1964 | const char *service_name, | 1968 | const char *service_name, |
1965 | enum GNUNET_SERVICE_Options options, | 1969 | enum GNUNET_SERVICE_Options options, |
1966 | GNUNET_SERVICE_InitCallback service_init_cb, | 1970 | GNUNET_SERVICE_InitCallback service_init_cb, |
1967 | GNUNET_SERVICE_ConnectHandler connect_cb, | 1971 | GNUNET_SERVICE_ConnectHandler connect_cb, |
1968 | GNUNET_SERVICE_DisconnectHandler disconnect_cb, | 1972 | GNUNET_SERVICE_DisconnectHandler disconnect_cb, |
1969 | void *cls, | 1973 | void *cls, |
1970 | const struct GNUNET_MQ_MessageHandler *handlers) | 1974 | const struct GNUNET_MQ_MessageHandler *handlers) |
1971 | { | 1975 | { |
1972 | struct GNUNET_SERVICE_Handle sh; | 1976 | struct GNUNET_SERVICE_Handle sh; |
1973 | 1977 | ||
@@ -1986,40 +1990,40 @@ GNUNET_SERVICE_run_(int argc, | |||
1986 | struct GNUNET_CONFIGURATION_Handle *cfg; | 1990 | struct GNUNET_CONFIGURATION_Handle *cfg; |
1987 | int ret; | 1991 | int ret; |
1988 | int err; | 1992 | int err; |
1989 | const struct GNUNET_OS_ProjectData *pd = GNUNET_OS_project_data_get(); | 1993 | const struct GNUNET_OS_ProjectData *pd = GNUNET_OS_project_data_get (); |
1990 | 1994 | struct GNUNET_GETOPT_CommandLineOption service_options[] = { | |
1991 | struct GNUNET_GETOPT_CommandLineOption service_options[] = | 1995 | GNUNET_GETOPT_option_cfgfile (&opt_cfg_filename), |
1992 | { GNUNET_GETOPT_option_cfgfile(&opt_cfg_filename), | 1996 | GNUNET_GETOPT_option_flag ('d', |
1993 | GNUNET_GETOPT_option_flag('d', | 1997 | "daemonize", |
1994 | "daemonize", | 1998 | gettext_noop ( |
1995 | gettext_noop( | 1999 | "do daemonize (detach from terminal)"), |
1996 | "do daemonize (detach from terminal)"), | 2000 | &do_daemonize), |
1997 | &do_daemonize), | 2001 | GNUNET_GETOPT_option_help (NULL), |
1998 | GNUNET_GETOPT_option_help(NULL), | 2002 | GNUNET_GETOPT_option_loglevel (&loglev), |
1999 | GNUNET_GETOPT_option_loglevel(&loglev), | 2003 | GNUNET_GETOPT_option_logfile (&logfile), |
2000 | GNUNET_GETOPT_option_logfile(&logfile), | 2004 | GNUNET_GETOPT_option_version (pd->version), |
2001 | GNUNET_GETOPT_option_version(pd->version), | 2005 | GNUNET_GETOPT_OPTION_END |
2002 | GNUNET_GETOPT_OPTION_END }; | 2006 | }; |
2003 | 2007 | ||
2004 | err = 1; | 2008 | err = 1; |
2005 | memset(&sh, 0, sizeof(sh)); | 2009 | memset (&sh, 0, sizeof(sh)); |
2006 | xdg = getenv("XDG_CONFIG_HOME"); | 2010 | xdg = getenv ("XDG_CONFIG_HOME"); |
2007 | if (NULL != xdg) | 2011 | if (NULL != xdg) |
2008 | GNUNET_asprintf(&cfg_filename, | 2012 | GNUNET_asprintf (&cfg_filename, |
2009 | "%s%s%s", | 2013 | "%s%s%s", |
2010 | xdg, | 2014 | xdg, |
2011 | DIR_SEPARATOR_STR, | 2015 | DIR_SEPARATOR_STR, |
2012 | pd->config_file); | 2016 | pd->config_file); |
2013 | else | 2017 | else |
2014 | cfg_filename = GNUNET_strdup(pd->user_config_file); | 2018 | cfg_filename = GNUNET_strdup (pd->user_config_file); |
2015 | sh.ready_confirm_fd = -1; | 2019 | sh.ready_confirm_fd = -1; |
2016 | sh.options = options; | 2020 | sh.options = options; |
2017 | sh.cfg = cfg = GNUNET_CONFIGURATION_create(); | 2021 | sh.cfg = cfg = GNUNET_CONFIGURATION_create (); |
2018 | sh.service_init_cb = service_init_cb; | 2022 | sh.service_init_cb = service_init_cb; |
2019 | sh.connect_cb = connect_cb; | 2023 | sh.connect_cb = connect_cb; |
2020 | sh.disconnect_cb = disconnect_cb; | 2024 | sh.disconnect_cb = disconnect_cb; |
2021 | sh.cb_cls = cls; | 2025 | sh.cb_cls = cls; |
2022 | sh.handlers = GNUNET_MQ_copy_handlers(handlers); | 2026 | sh.handlers = GNUNET_MQ_copy_handlers (handlers); |
2023 | sh.service_name = service_name; | 2027 | sh.service_name = service_name; |
2024 | sh.ret = 0; | 2028 | sh.ret = 0; |
2025 | /* setup subsystems */ | 2029 | /* setup subsystems */ |
@@ -2029,135 +2033,140 @@ GNUNET_SERVICE_run_(int argc, | |||
2029 | do_daemonize = 0; | 2033 | do_daemonize = 0; |
2030 | #if ENABLE_NLS | 2034 | #if ENABLE_NLS |
2031 | if (NULL != pd->gettext_domain) | 2035 | if (NULL != pd->gettext_domain) |
2036 | { | ||
2037 | setlocale (LC_ALL, ""); | ||
2038 | path = (NULL == pd->gettext_path) ? | ||
2039 | GNUNET_OS_installation_get_path (GNUNET_OS_IPK_LOCALEDIR) : | ||
2040 | GNUNET_strdup (pd->gettext_path); | ||
2041 | if (NULL != path) | ||
2032 | { | 2042 | { |
2033 | setlocale(LC_ALL, ""); | 2043 | bindtextdomain (pd->gettext_domain, path); |
2034 | path = (NULL == pd->gettext_path) ? | 2044 | GNUNET_free (path); |
2035 | GNUNET_OS_installation_get_path(GNUNET_OS_IPK_LOCALEDIR) : | ||
2036 | GNUNET_strdup(pd->gettext_path); | ||
2037 | if (NULL != path) | ||
2038 | { | ||
2039 | bindtextdomain(pd->gettext_domain, path); | ||
2040 | GNUNET_free(path); | ||
2041 | } | ||
2042 | textdomain(pd->gettext_domain); | ||
2043 | } | 2045 | } |
2046 | textdomain (pd->gettext_domain); | ||
2047 | } | ||
2044 | #endif | 2048 | #endif |
2045 | ret = GNUNET_GETOPT_run(service_name, service_options, argc, argv); | 2049 | ret = GNUNET_GETOPT_run (service_name, |
2050 | service_options, | ||
2051 | argc, | ||
2052 | argv); | ||
2046 | if (GNUNET_SYSERR == ret) | 2053 | if (GNUNET_SYSERR == ret) |
2047 | goto shutdown; | 2054 | goto shutdown; |
2048 | if (GNUNET_NO == ret) | 2055 | if (GNUNET_NO == ret) |
2049 | { | 2056 | { |
2050 | err = 0; | 2057 | err = 0; |
2051 | goto shutdown; | 2058 | goto shutdown; |
2052 | } | 2059 | } |
2053 | if (GNUNET_OK != GNUNET_log_setup(service_name, loglev, logfile)) | 2060 | if (GNUNET_OK != GNUNET_log_setup (service_name, |
2054 | { | 2061 | loglev, |
2055 | GNUNET_break(0); | 2062 | logfile)) |
2056 | goto shutdown; | 2063 | { |
2057 | } | 2064 | GNUNET_break (0); |
2065 | goto shutdown; | ||
2066 | } | ||
2058 | if (NULL != opt_cfg_filename) | 2067 | if (NULL != opt_cfg_filename) |
2068 | { | ||
2069 | if ((GNUNET_YES != GNUNET_DISK_file_test (opt_cfg_filename)) || | ||
2070 | (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, opt_cfg_filename))) | ||
2059 | { | 2071 | { |
2060 | if ((GNUNET_YES != GNUNET_DISK_file_test(opt_cfg_filename)) || | 2072 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
2061 | (GNUNET_SYSERR == GNUNET_CONFIGURATION_load(cfg, opt_cfg_filename))) | 2073 | _ ("Malformed configuration file `%s', exit ...\n"), |
2062 | { | 2074 | opt_cfg_filename); |
2063 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | 2075 | goto shutdown; |
2064 | _("Malformed configuration file `%s', exit ...\n"), | ||
2065 | opt_cfg_filename); | ||
2066 | goto shutdown; | ||
2067 | } | ||
2068 | } | 2076 | } |
2077 | } | ||
2069 | else | 2078 | else |
2079 | { | ||
2080 | if (GNUNET_YES == GNUNET_DISK_file_test (cfg_filename)) | ||
2070 | { | 2081 | { |
2071 | if (GNUNET_YES == GNUNET_DISK_file_test(cfg_filename)) | 2082 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, cfg_filename)) |
2072 | { | 2083 | { |
2073 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load(cfg, cfg_filename)) | 2084 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
2074 | { | 2085 | _ ("Malformed configuration file `%s', exit ...\n"), |
2075 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | 2086 | cfg_filename); |
2076 | _("Malformed configuration file `%s', exit ...\n"), | 2087 | goto shutdown; |
2077 | cfg_filename); | 2088 | } |
2078 | goto shutdown; | ||
2079 | } | ||
2080 | } | ||
2081 | else | ||
2082 | { | ||
2083 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load(cfg, NULL)) | ||
2084 | { | ||
2085 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | ||
2086 | _("Malformed configuration, exit ...\n")); | ||
2087 | goto shutdown; | ||
2088 | } | ||
2089 | } | ||
2090 | } | 2089 | } |
2091 | if (GNUNET_OK != setup_service(&sh)) | 2090 | else |
2092 | goto shutdown; | ||
2093 | if ((1 == do_daemonize) && (GNUNET_OK != detach_terminal(&sh))) | ||
2094 | { | 2091 | { |
2095 | GNUNET_break(0); | 2092 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, NULL)) |
2096 | goto shutdown; | 2093 | { |
2094 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
2095 | _ ("Malformed configuration, exit ...\n")); | ||
2096 | goto shutdown; | ||
2097 | } | ||
2097 | } | 2098 | } |
2098 | if (GNUNET_OK != set_user_id(&sh)) | 2099 | } |
2100 | if (GNUNET_OK != setup_service (&sh)) | ||
2099 | goto shutdown; | 2101 | goto shutdown; |
2100 | LOG(GNUNET_ERROR_TYPE_DEBUG, | 2102 | if ((1 == do_daemonize) && (GNUNET_OK != detach_terminal (&sh))) |
2101 | "Service `%s' runs with configuration from `%s'\n", | 2103 | { |
2102 | service_name, | 2104 | GNUNET_break (0); |
2103 | (NULL != opt_cfg_filename) ? opt_cfg_filename : cfg_filename); | 2105 | goto shutdown; |
2104 | if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_number(sh.cfg, | 2106 | } |
2105 | "TESTING", | 2107 | if (GNUNET_OK != set_user_id (&sh)) |
2106 | "SKEW_OFFSET", | 2108 | goto shutdown; |
2107 | &skew_offset)) && | 2109 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
2108 | (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number(sh.cfg, | 2110 | "Service `%s' runs with configuration from `%s'\n", |
2109 | "TESTING", | 2111 | service_name, |
2110 | "SKEW_VARIANCE", | 2112 | (NULL != opt_cfg_filename) ? opt_cfg_filename : cfg_filename); |
2111 | &skew_variance))) | 2113 | if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (sh.cfg, |
2112 | { | 2114 | "TESTING", |
2113 | clock_offset = skew_offset - skew_variance; | 2115 | "SKEW_OFFSET", |
2114 | GNUNET_TIME_set_offset(clock_offset); | 2116 | &skew_offset)) && |
2115 | LOG(GNUNET_ERROR_TYPE_DEBUG, "Skewing clock by %dll ms\n", clock_offset); | 2117 | (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (sh.cfg, |
2116 | } | 2118 | "TESTING", |
2117 | GNUNET_RESOLVER_connect(sh.cfg); | 2119 | "SKEW_VARIANCE", |
2120 | &skew_variance))) | ||
2121 | { | ||
2122 | clock_offset = skew_offset - skew_variance; | ||
2123 | GNUNET_TIME_set_offset (clock_offset); | ||
2124 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Skewing clock by %dll ms\n", clock_offset); | ||
2125 | } | ||
2126 | GNUNET_RESOLVER_connect (sh.cfg); | ||
2118 | 2127 | ||
2119 | /* actually run service */ | 2128 | /* actually run service */ |
2120 | err = 0; | 2129 | err = 0; |
2121 | GNUNET_SCHEDULER_run(&service_main, &sh); | 2130 | GNUNET_SCHEDULER_run (&service_main, &sh); |
2122 | /* shutdown */ | 2131 | /* shutdown */ |
2123 | if (1 == do_daemonize) | 2132 | if (1 == do_daemonize) |
2124 | pid_file_delete(&sh); | 2133 | pid_file_delete (&sh); |
2125 | 2134 | ||
2126 | shutdown: | 2135 | shutdown: |
2127 | if (-1 != sh.ready_confirm_fd) | 2136 | if (-1 != sh.ready_confirm_fd) |
2128 | { | 2137 | { |
2129 | if (1 != write(sh.ready_confirm_fd, err ? "I" : "S", 1)) | 2138 | if (1 != write (sh.ready_confirm_fd, err ? "I" : "S", 1)) |
2130 | LOG_STRERROR(GNUNET_ERROR_TYPE_WARNING, "write"); | 2139 | LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "write"); |
2131 | GNUNET_break(0 == close(sh.ready_confirm_fd)); | 2140 | GNUNET_break (0 == close (sh.ready_confirm_fd)); |
2132 | } | 2141 | } |
2133 | #if HAVE_MALLINFO | 2142 | #if HAVE_MALLINFO |
2134 | { | 2143 | { |
2135 | char *counter; | 2144 | char *counter; |
2136 | 2145 | ||
2137 | if ((GNUNET_YES == GNUNET_CONFIGURATION_have_value(sh.cfg, | 2146 | if ((GNUNET_YES == GNUNET_CONFIGURATION_have_value (sh.cfg, |
2138 | service_name, | 2147 | service_name, |
2139 | "GAUGER_HEAP")) && | 2148 | "GAUGER_HEAP")) && |
2140 | (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(sh.cfg, | 2149 | (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (sh.cfg, |
2141 | service_name, | 2150 | service_name, |
2142 | "GAUGER_HEAP", | 2151 | "GAUGER_HEAP", |
2143 | &counter))) | 2152 | &counter))) |
2144 | { | 2153 | { |
2145 | struct mallinfo mi; | 2154 | struct mallinfo mi; |
2146 | 2155 | ||
2147 | mi = mallinfo(); | 2156 | mi = mallinfo (); |
2148 | GAUGER(service_name, counter, mi.usmblks, "blocks"); | 2157 | GAUGER (service_name, counter, mi.usmblks, "blocks"); |
2149 | GNUNET_free(counter); | 2158 | GNUNET_free (counter); |
2150 | } | 2159 | } |
2151 | } | 2160 | } |
2152 | #endif | 2161 | #endif |
2153 | teardown_service(&sh); | 2162 | teardown_service (&sh); |
2154 | GNUNET_free_non_null(sh.handlers); | 2163 | GNUNET_free_non_null (sh.handlers); |
2155 | GNUNET_SPEEDUP_stop_(); | 2164 | GNUNET_SPEEDUP_stop_ (); |
2156 | GNUNET_CONFIGURATION_destroy(cfg); | 2165 | GNUNET_CONFIGURATION_destroy (cfg); |
2157 | GNUNET_free_non_null(logfile); | 2166 | GNUNET_free_non_null (logfile); |
2158 | GNUNET_free_non_null(loglev); | 2167 | GNUNET_free_non_null (loglev); |
2159 | GNUNET_free(cfg_filename); | 2168 | GNUNET_free (cfg_filename); |
2160 | GNUNET_free_non_null(opt_cfg_filename); | 2169 | GNUNET_free_non_null (opt_cfg_filename); |
2161 | 2170 | ||
2162 | return err ? GNUNET_SYSERR : sh.ret; | 2171 | return err ? GNUNET_SYSERR : sh.ret; |
2163 | } | 2172 | } |
@@ -2170,9 +2179,9 @@ shutdown: | |||
2170 | * @param sh service to stop accepting connections. | 2179 | * @param sh service to stop accepting connections. |
2171 | */ | 2180 | */ |
2172 | void | 2181 | void |
2173 | GNUNET_SERVICE_suspend(struct GNUNET_SERVICE_Handle *sh) | 2182 | GNUNET_SERVICE_suspend (struct GNUNET_SERVICE_Handle *sh) |
2174 | { | 2183 | { |
2175 | do_suspend(sh, SUSPEND_STATE_APP); | 2184 | do_suspend (sh, SUSPEND_STATE_APP); |
2176 | } | 2185 | } |
2177 | 2186 | ||
2178 | 2187 | ||
@@ -2182,9 +2191,9 @@ GNUNET_SERVICE_suspend(struct GNUNET_SERVICE_Handle *sh) | |||
2182 | * @param sh service to resume accepting connections. | 2191 | * @param sh service to resume accepting connections. |
2183 | */ | 2192 | */ |
2184 | void | 2193 | void |
2185 | GNUNET_SERVICE_resume(struct GNUNET_SERVICE_Handle *sh) | 2194 | GNUNET_SERVICE_resume (struct GNUNET_SERVICE_Handle *sh) |
2186 | { | 2195 | { |
2187 | do_resume(sh, SUSPEND_STATE_APP); | 2196 | do_resume (sh, SUSPEND_STATE_APP); |
2188 | } | 2197 | } |
2189 | 2198 | ||
2190 | 2199 | ||
@@ -2195,32 +2204,32 @@ GNUNET_SERVICE_resume(struct GNUNET_SERVICE_Handle *sh) | |||
2195 | * @param cls our `struct GNUNET_SERVICE_Client` | 2204 | * @param cls our `struct GNUNET_SERVICE_Client` |
2196 | */ | 2205 | */ |
2197 | static void | 2206 | static void |
2198 | resume_client_receive(void *cls) | 2207 | resume_client_receive (void *cls) |
2199 | { | 2208 | { |
2200 | struct GNUNET_SERVICE_Client *c = cls; | 2209 | struct GNUNET_SERVICE_Client *c = cls; |
2201 | int ret; | 2210 | int ret; |
2202 | 2211 | ||
2203 | c->recv_task = NULL; | 2212 | c->recv_task = NULL; |
2204 | /* first, check if there is still something in the buffer */ | 2213 | /* first, check if there is still something in the buffer */ |
2205 | ret = GNUNET_MST_next(c->mst, GNUNET_YES); | 2214 | ret = GNUNET_MST_next (c->mst, GNUNET_YES); |
2206 | if (GNUNET_SYSERR == ret) | 2215 | if (GNUNET_SYSERR == ret) |
2207 | { | 2216 | { |
2208 | if (NULL == c->drop_task) | 2217 | if (NULL == c->drop_task) |
2209 | GNUNET_SERVICE_client_drop(c); | 2218 | GNUNET_SERVICE_client_drop (c); |
2210 | return; | 2219 | return; |
2211 | } | 2220 | } |
2212 | if (GNUNET_NO == ret) | 2221 | if (GNUNET_NO == ret) |
2213 | return; /* done processing, wait for more later */ | 2222 | return; /* done processing, wait for more later */ |
2214 | GNUNET_assert(GNUNET_OK == ret); | 2223 | GNUNET_assert (GNUNET_OK == ret); |
2215 | if (GNUNET_YES == c->needs_continue) | 2224 | if (GNUNET_YES == c->needs_continue) |
2216 | return; /* #GNUNET_MST_next() did give a message to the client */ | 2225 | return; /* #GNUNET_MST_next() did give a message to the client */ |
2217 | /* need to receive more data from the network first */ | 2226 | /* need to receive more data from the network first */ |
2218 | if (NULL != c->recv_task) | 2227 | if (NULL != c->recv_task) |
2219 | return; | 2228 | return; |
2220 | c->recv_task = GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, | 2229 | c->recv_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, |
2221 | c->sock, | 2230 | c->sock, |
2222 | &service_client_recv, | 2231 | &service_client_recv, |
2223 | c); | 2232 | c); |
2224 | } | 2233 | } |
2225 | 2234 | ||
2226 | 2235 | ||
@@ -2231,18 +2240,18 @@ resume_client_receive(void *cls) | |||
2231 | * @param c the client to continue receiving from | 2240 | * @param c the client to continue receiving from |
2232 | */ | 2241 | */ |
2233 | void | 2242 | void |
2234 | GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c) | 2243 | GNUNET_SERVICE_client_continue (struct GNUNET_SERVICE_Client *c) |
2235 | { | 2244 | { |
2236 | GNUNET_assert(NULL == c->drop_task); | 2245 | GNUNET_assert (NULL == c->drop_task); |
2237 | GNUNET_assert(GNUNET_YES == c->needs_continue); | 2246 | GNUNET_assert (GNUNET_YES == c->needs_continue); |
2238 | GNUNET_assert(NULL == c->recv_task); | 2247 | GNUNET_assert (NULL == c->recv_task); |
2239 | c->needs_continue = GNUNET_NO; | 2248 | c->needs_continue = GNUNET_NO; |
2240 | if (NULL != c->warn_task) | 2249 | if (NULL != c->warn_task) |
2241 | { | 2250 | { |
2242 | GNUNET_SCHEDULER_cancel(c->warn_task); | 2251 | GNUNET_SCHEDULER_cancel (c->warn_task); |
2243 | c->warn_task = NULL; | 2252 | c->warn_task = NULL; |
2244 | } | 2253 | } |
2245 | c->recv_task = GNUNET_SCHEDULER_add_now(&resume_client_receive, c); | 2254 | c->recv_task = GNUNET_SCHEDULER_add_now (&resume_client_receive, c); |
2246 | } | 2255 | } |
2247 | 2256 | ||
2248 | 2257 | ||
@@ -2255,14 +2264,14 @@ GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c) | |||
2255 | * @param c client for which to disable the warning | 2264 | * @param c client for which to disable the warning |
2256 | */ | 2265 | */ |
2257 | void | 2266 | void |
2258 | GNUNET_SERVICE_client_disable_continue_warning(struct GNUNET_SERVICE_Client *c) | 2267 | GNUNET_SERVICE_client_disable_continue_warning (struct GNUNET_SERVICE_Client *c) |
2259 | { | 2268 | { |
2260 | GNUNET_break(NULL != c->warn_task); | 2269 | GNUNET_break (NULL != c->warn_task); |
2261 | if (NULL != c->warn_task) | 2270 | if (NULL != c->warn_task) |
2262 | { | 2271 | { |
2263 | GNUNET_SCHEDULER_cancel(c->warn_task); | 2272 | GNUNET_SCHEDULER_cancel (c->warn_task); |
2264 | c->warn_task = NULL; | 2273 | c->warn_task = NULL; |
2265 | } | 2274 | } |
2266 | } | 2275 | } |
2267 | 2276 | ||
2268 | 2277 | ||
@@ -2272,32 +2281,32 @@ GNUNET_SERVICE_client_disable_continue_warning(struct GNUNET_SERVICE_Client *c) | |||
2272 | * @param cls the `struct GNUNET_SERVICE_Client`. | 2281 | * @param cls the `struct GNUNET_SERVICE_Client`. |
2273 | */ | 2282 | */ |
2274 | static void | 2283 | static void |
2275 | finish_client_drop(void *cls) | 2284 | finish_client_drop (void *cls) |
2276 | { | 2285 | { |
2277 | struct GNUNET_SERVICE_Client *c = cls; | 2286 | struct GNUNET_SERVICE_Client *c = cls; |
2278 | struct GNUNET_SERVICE_Handle *sh = c->sh; | 2287 | struct GNUNET_SERVICE_Handle *sh = c->sh; |
2279 | 2288 | ||
2280 | c->drop_task = NULL; | 2289 | c->drop_task = NULL; |
2281 | GNUNET_assert(NULL == c->send_task); | 2290 | GNUNET_assert (NULL == c->send_task); |
2282 | GNUNET_assert(NULL == c->recv_task); | 2291 | GNUNET_assert (NULL == c->recv_task); |
2283 | GNUNET_assert(NULL == c->warn_task); | 2292 | GNUNET_assert (NULL == c->warn_task); |
2284 | GNUNET_MST_destroy(c->mst); | 2293 | GNUNET_MST_destroy (c->mst); |
2285 | GNUNET_MQ_destroy(c->mq); | 2294 | GNUNET_MQ_destroy (c->mq); |
2286 | if (GNUNET_NO == c->persist) | 2295 | if (GNUNET_NO == c->persist) |
2287 | { | 2296 | { |
2288 | GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(c->sock)); | 2297 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (c->sock)); |
2289 | if ((0 != (SUSPEND_STATE_EMFILE & sh->suspend_state)) && | 2298 | if ((0 != (SUSPEND_STATE_EMFILE & sh->suspend_state)) && |
2290 | (0 == (SUSPEND_STATE_SHUTDOWN & sh->suspend_state))) | 2299 | (0 == (SUSPEND_STATE_SHUTDOWN & sh->suspend_state))) |
2291 | do_resume(sh, SUSPEND_STATE_EMFILE); | 2300 | do_resume (sh, SUSPEND_STATE_EMFILE); |
2292 | } | 2301 | } |
2293 | else | 2302 | else |
2294 | { | 2303 | { |
2295 | GNUNET_NETWORK_socket_free_memory_only_(c->sock); | 2304 | GNUNET_NETWORK_socket_free_memory_only_ (c->sock); |
2296 | } | 2305 | } |
2297 | GNUNET_free(c); | 2306 | GNUNET_free (c); |
2298 | if ((0 != (SUSPEND_STATE_SHUTDOWN & sh->suspend_state)) && | 2307 | if ((0 != (SUSPEND_STATE_SHUTDOWN & sh->suspend_state)) && |
2299 | (GNUNET_NO == have_non_monitor_clients(sh))) | 2308 | (GNUNET_NO == have_non_monitor_clients (sh))) |
2300 | GNUNET_SERVICE_shutdown(sh); | 2309 | GNUNET_SERVICE_shutdown (sh); |
2301 | } | 2310 | } |
2302 | 2311 | ||
2303 | 2312 | ||
@@ -2312,52 +2321,56 @@ finish_client_drop(void *cls) | |||
2312 | * @param c client to disconnect now | 2321 | * @param c client to disconnect now |
2313 | */ | 2322 | */ |
2314 | void | 2323 | void |
2315 | GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c) | 2324 | GNUNET_SERVICE_client_drop (struct GNUNET_SERVICE_Client *c) |
2316 | { | 2325 | { |
2317 | struct GNUNET_SERVICE_Handle *sh = c->sh; | 2326 | struct GNUNET_SERVICE_Handle *sh = c->sh; |
2318 | 2327 | ||
2319 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | 2328 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2320 | "Client dropped: %p (MQ: %p)\n", | 2329 | "Client dropped: %p (MQ: %p)\n", |
2321 | c, | 2330 | c, |
2322 | c->mq); | 2331 | c->mq); |
2323 | #if EXECINFO | 2332 | #if EXECINFO |
2324 | { | 2333 | { |
2325 | void *backtrace_array[MAX_TRACE_DEPTH]; | 2334 | void *backtrace_array[MAX_TRACE_DEPTH]; |
2326 | int num_backtrace_strings = backtrace(backtrace_array, MAX_TRACE_DEPTH); | 2335 | int num_backtrace_strings = backtrace (backtrace_array, MAX_TRACE_DEPTH); |
2327 | char **backtrace_strings = | 2336 | char **backtrace_strings = |
2328 | backtrace_symbols(backtrace_array, t->num_backtrace_strings); | 2337 | backtrace_symbols (backtrace_array, t->num_backtrace_strings); |
2329 | for (unsigned int i = 0; i < num_backtrace_strings; i++) | 2338 | for (unsigned int i = 0; i < num_backtrace_strings; i++) |
2330 | LOG(GNUNET_ERROR_TYPE_DEBUG, | 2339 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
2331 | "client drop trace %u: %s\n", | 2340 | "client drop trace %u: %s\n", |
2332 | i, | 2341 | i, |
2333 | backtrace_strings[i]); | 2342 | backtrace_strings[i]); |
2334 | } | 2343 | } |
2335 | #endif | 2344 | #endif |
2336 | if (NULL != c->drop_task) | 2345 | if (NULL != c->drop_task) |
2337 | { | 2346 | { |
2338 | /* asked to drop twice! */ | 2347 | /* asked to drop twice! */ |
2339 | GNUNET_assert(0); | 2348 | GNUNET_assert (0); |
2340 | return; | 2349 | return; |
2341 | } | 2350 | } |
2342 | GNUNET_CONTAINER_DLL_remove(sh->clients_head, sh->clients_tail, c); | 2351 | GNUNET_CONTAINER_DLL_remove (sh->clients_head, |
2352 | sh->clients_tail, | ||
2353 | c); | ||
2343 | if (NULL != sh->disconnect_cb) | 2354 | if (NULL != sh->disconnect_cb) |
2344 | sh->disconnect_cb(sh->cb_cls, c, c->user_context); | 2355 | sh->disconnect_cb (sh->cb_cls, |
2356 | c, | ||
2357 | c->user_context); | ||
2345 | if (NULL != c->warn_task) | 2358 | if (NULL != c->warn_task) |
2346 | { | 2359 | { |
2347 | GNUNET_SCHEDULER_cancel(c->warn_task); | 2360 | GNUNET_SCHEDULER_cancel (c->warn_task); |
2348 | c->warn_task = NULL; | 2361 | c->warn_task = NULL; |
2349 | } | 2362 | } |
2350 | if (NULL != c->recv_task) | 2363 | if (NULL != c->recv_task) |
2351 | { | 2364 | { |
2352 | GNUNET_SCHEDULER_cancel(c->recv_task); | 2365 | GNUNET_SCHEDULER_cancel (c->recv_task); |
2353 | c->recv_task = NULL; | 2366 | c->recv_task = NULL; |
2354 | } | 2367 | } |
2355 | if (NULL != c->send_task) | 2368 | if (NULL != c->send_task) |
2356 | { | 2369 | { |
2357 | GNUNET_SCHEDULER_cancel(c->send_task); | 2370 | GNUNET_SCHEDULER_cancel (c->send_task); |
2358 | c->send_task = NULL; | 2371 | c->send_task = NULL; |
2359 | } | 2372 | } |
2360 | c->drop_task = GNUNET_SCHEDULER_add_now(&finish_client_drop, c); | 2373 | c->drop_task = GNUNET_SCHEDULER_add_now (&finish_client_drop, c); |
2361 | } | 2374 | } |
2362 | 2375 | ||
2363 | 2376 | ||
@@ -2367,14 +2380,14 @@ GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c) | |||
2367 | * @param sh server to shutdown | 2380 | * @param sh server to shutdown |
2368 | */ | 2381 | */ |
2369 | void | 2382 | void |
2370 | GNUNET_SERVICE_shutdown(struct GNUNET_SERVICE_Handle *sh) | 2383 | GNUNET_SERVICE_shutdown (struct GNUNET_SERVICE_Handle *sh) |
2371 | { | 2384 | { |
2372 | struct GNUNET_SERVICE_Client *client; | 2385 | struct GNUNET_SERVICE_Client *client; |
2373 | 2386 | ||
2374 | if (0 == (sh->suspend_state & SUSPEND_STATE_SHUTDOWN)) | 2387 | if (0 == (sh->suspend_state & SUSPEND_STATE_SHUTDOWN)) |
2375 | do_suspend(sh, SUSPEND_STATE_SHUTDOWN); | 2388 | do_suspend (sh, SUSPEND_STATE_SHUTDOWN); |
2376 | while (NULL != (client = sh->clients_head)) | 2389 | while (NULL != (client = sh->clients_head)) |
2377 | GNUNET_SERVICE_client_drop(client); | 2390 | GNUNET_SERVICE_client_drop (client); |
2378 | } | 2391 | } |
2379 | 2392 | ||
2380 | 2393 | ||
@@ -2391,12 +2404,12 @@ GNUNET_SERVICE_shutdown(struct GNUNET_SERVICE_Handle *sh) | |||
2391 | * @param c client to mark as a monitor | 2404 | * @param c client to mark as a monitor |
2392 | */ | 2405 | */ |
2393 | void | 2406 | void |
2394 | GNUNET_SERVICE_client_mark_monitor(struct GNUNET_SERVICE_Client *c) | 2407 | GNUNET_SERVICE_client_mark_monitor (struct GNUNET_SERVICE_Client *c) |
2395 | { | 2408 | { |
2396 | c->is_monitor = GNUNET_YES; | 2409 | c->is_monitor = GNUNET_YES; |
2397 | if (((0 != (SUSPEND_STATE_SHUTDOWN & c->sh->suspend_state)) && | 2410 | if (((0 != (SUSPEND_STATE_SHUTDOWN & c->sh->suspend_state)) && |
2398 | (GNUNET_NO == have_non_monitor_clients(c->sh)))) | 2411 | (GNUNET_NO == have_non_monitor_clients (c->sh)))) |
2399 | GNUNET_SERVICE_shutdown(c->sh); | 2412 | GNUNET_SERVICE_shutdown (c->sh); |
2400 | } | 2413 | } |
2401 | 2414 | ||
2402 | 2415 | ||
@@ -2408,7 +2421,7 @@ GNUNET_SERVICE_client_mark_monitor(struct GNUNET_SERVICE_Client *c) | |||
2408 | * @param c client to persist the socket (never to be closed) | 2421 | * @param c client to persist the socket (never to be closed) |
2409 | */ | 2422 | */ |
2410 | void | 2423 | void |
2411 | GNUNET_SERVICE_client_persist(struct GNUNET_SERVICE_Client *c) | 2424 | GNUNET_SERVICE_client_persist (struct GNUNET_SERVICE_Client *c) |
2412 | { | 2425 | { |
2413 | c->persist = GNUNET_YES; | 2426 | c->persist = GNUNET_YES; |
2414 | } | 2427 | } |
@@ -2421,10 +2434,10 @@ GNUNET_SERVICE_client_persist(struct GNUNET_SERVICE_Client *c) | |||
2421 | * @return the message queue of @a c | 2434 | * @return the message queue of @a c |
2422 | */ | 2435 | */ |
2423 | struct GNUNET_MQ_Handle * | 2436 | struct GNUNET_MQ_Handle * |
2424 | GNUNET_SERVICE_client_get_mq(struct GNUNET_SERVICE_Client *c) | 2437 | GNUNET_SERVICE_client_get_mq (struct GNUNET_SERVICE_Client *c) |
2425 | { | 2438 | { |
2426 | return c->mq; | 2439 | return c->mq; |
2427 | } | 2440 | } |
2428 | 2441 | ||
2429 | 2442 | ||
2430 | /* end of service_new.c */ | 2443 | /* end of service.c */ |