diff options
author | Christian Grothoff <christian@grothoff.org> | 2019-09-27 23:12:21 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2019-09-27 23:12:21 +0200 |
commit | c8ed84e481b4abfb7d4ed844a4d74b979917c466 (patch) | |
tree | b37f1dfbfb279b78a4346ec22bc298bb500e8fb4 /src | |
parent | eadf4b7379049d32d7cfc5cffd4c88613f8a2a93 (diff) | |
download | gnunet-c8ed84e481b4abfb7d4ed844a4d74b979917c466.tar.gz gnunet-c8ed84e481b4abfb7d4ed844a4d74b979917c466.zip |
implementing GNUNET_CLIENT_test() to check for service operating
Diffstat (limited to 'src')
-rw-r--r-- | src/include/gnunet_client_lib.h | 27 | ||||
-rw-r--r-- | src/util/client.c | 177 | ||||
-rw-r--r-- | src/util/service.c | 2152 |
3 files changed, 1263 insertions, 1093 deletions
diff --git a/src/include/gnunet_client_lib.h b/src/include/gnunet_client_lib.h index 8e4984124..9fc52724c 100644 --- a/src/include/gnunet_client_lib.h +++ b/src/include/gnunet_client_lib.h | |||
@@ -47,6 +47,23 @@ extern "C" | |||
47 | 47 | ||
48 | 48 | ||
49 | /** | 49 | /** |
50 | * Test if the port or UNIXPATH of the given @a service_name | ||
51 | * is in use and thus (most likely) the respective service is up. | ||
52 | * | ||
53 | * @param cfg our configuration | ||
54 | * @param service_name name of the service to connect to | ||
55 | * @return #GNUNET_YES if the service is (likely) up (or running remotely), | ||
56 | * #GNUNET_NO if the service is (definitively) down, | ||
57 | * #GNUNET_SYSERR if the configuration does not give us | ||
58 | * the necessary information about the service, or if | ||
59 | * we could not check (i.e. socket() failed) | ||
60 | */ | ||
61 | int | ||
62 | GNUNET_CLIENT_test (const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
63 | const char *service_name); | ||
64 | |||
65 | |||
66 | /** | ||
50 | * Create a message queue to connect to a GNUnet service. | 67 | * Create a message queue to connect to a GNUnet service. |
51 | * If handlers are specfied, receive messages from the connection. | 68 | * If handlers are specfied, receive messages from the connection. |
52 | * | 69 | * |
@@ -57,11 +74,11 @@ extern "C" | |||
57 | * @return the message queue, NULL on error | 74 | * @return the message queue, NULL on error |
58 | */ | 75 | */ |
59 | struct GNUNET_MQ_Handle * | 76 | struct GNUNET_MQ_Handle * |
60 | GNUNET_CLIENT_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, | 77 | GNUNET_CLIENT_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, |
61 | const char *service_name, | 78 | const char *service_name, |
62 | const struct GNUNET_MQ_MessageHandler *handlers, | 79 | const struct GNUNET_MQ_MessageHandler *handlers, |
63 | GNUNET_MQ_ErrorHandler error_handler, | 80 | GNUNET_MQ_ErrorHandler error_handler, |
64 | void *error_handler_cls); | 81 | void *error_handler_cls); |
65 | 82 | ||
66 | 83 | ||
67 | #if 0 /* keep Emacsens' auto-indent happy */ | 84 | #if 0 /* keep Emacsens' auto-indent happy */ |
diff --git a/src/util/client.c b/src/util/client.c index 5a77b9238..d431909cf 100644 --- a/src/util/client.c +++ b/src/util/client.c | |||
@@ -534,17 +534,6 @@ try_unixpath (const char *service_name, | |||
534 | GNUNET_strlcpy (s_un.sun_path, | 534 | GNUNET_strlcpy (s_un.sun_path, |
535 | unixpath, | 535 | unixpath, |
536 | sizeof(s_un.sun_path)); | 536 | sizeof(s_un.sun_path)); |
537 | #ifdef LINUX | ||
538 | { | ||
539 | int abstract; | ||
540 | |||
541 | abstract = GNUNET_CONFIGURATION_get_value_yesno (cfg, | ||
542 | "TESTING", | ||
543 | "USE_ABSTRACT_SOCKETS"); | ||
544 | if (GNUNET_YES == abstract) | ||
545 | s_un.sun_path[0] = '\0'; | ||
546 | } | ||
547 | #endif | ||
548 | #if HAVE_SOCKADDR_UN_SUN_LEN | 537 | #if HAVE_SOCKADDR_UN_SUN_LEN |
549 | s_un.sun_len = (u_char) sizeof(struct sockaddr_un); | 538 | s_un.sun_len = (u_char) sizeof(struct sockaddr_un); |
550 | #endif | 539 | #endif |
@@ -889,6 +878,172 @@ connection_client_cancel_impl (struct GNUNET_MQ_Handle *mq, | |||
889 | 878 | ||
890 | 879 | ||
891 | /** | 880 | /** |
881 | * Test if the port or UNIXPATH of the given @a service_name | ||
882 | * is in use and thus (most likely) the respective service is up. | ||
883 | * | ||
884 | * @param cfg our configuration | ||
885 | * @param service_name name of the service to connect to | ||
886 | * @return #GNUNET_YES if the service is (likely) up, | ||
887 | * #GNUNET_NO if the service is (definitively) down, | ||
888 | * #GNUNET_SYSERR if the configuration does not give us | ||
889 | * the necessary information about the service, or if | ||
890 | * we could not check (i.e. socket() failed) | ||
891 | */ | ||
892 | int | ||
893 | GNUNET_CLIENT_test (const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
894 | const char *service_name) | ||
895 | { | ||
896 | char *hostname = NULL; | ||
897 | unsigned long long port; | ||
898 | int ret; | ||
899 | |||
900 | #if AF_UNIX | ||
901 | { | ||
902 | char *unixpath = NULL; | ||
903 | |||
904 | if (GNUNET_OK == | ||
905 | GNUNET_CONFIGURATION_get_value_filename (cfg, | ||
906 | service_name, | ||
907 | "UNIXPATH", | ||
908 | &unixpath)) | ||
909 | { | ||
910 | if (0 == strlen (unixpath)) | ||
911 | { | ||
912 | GNUNET_free (unixpath); | ||
913 | return GNUNET_SYSERR; /* empty string not OK */ | ||
914 | } | ||
915 | if (0 == access (unixpath, | ||
916 | F_OK)) | ||
917 | { | ||
918 | GNUNET_free (unixpath); | ||
919 | return GNUNET_OK; /* file exists, we assume service is running */ | ||
920 | } | ||
921 | GNUNET_free (unixpath); | ||
922 | } | ||
923 | else if (GNUNET_OK == | ||
924 | GNUNET_CONFIGURATION_have_value (cfg, | ||
925 | service_name, | ||
926 | "UNIXPATH")) | ||
927 | { | ||
928 | /* UNIXPATH specified but not a valid path! */ | ||
929 | GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, | ||
930 | service_name, | ||
931 | "UNIXPATH", | ||
932 | _ ("not a valid filename")); | ||
933 | return GNUNET_SYSERR; | ||
934 | } | ||
935 | } | ||
936 | #endif | ||
937 | |||
938 | if ( (GNUNET_OK != | ||
939 | GNUNET_CONFIGURATION_get_value_number (cfg, | ||
940 | service_name, | ||
941 | "PORT", | ||
942 | &port)) || | ||
943 | (port > 65535) || | ||
944 | (0 == port) ) | ||
945 | { | ||
946 | return GNUNET_SYSERR; | ||
947 | } | ||
948 | if (GNUNET_OK == | ||
949 | GNUNET_CONFIGURATION_get_value_string (cfg, | ||
950 | service_name, | ||
951 | "HOSTNAME", | ||
952 | &hostname)) | ||
953 | { | ||
954 | /* We always assume remotes are up */ | ||
955 | ret = GNUNET_YES; | ||
956 | } | ||
957 | else | ||
958 | { | ||
959 | /* We look for evidence the service is up */ | ||
960 | ret = GNUNET_NO; | ||
961 | } | ||
962 | if ( (NULL == hostname) || | ||
963 | (0 == strcasecmp (hostname, | ||
964 | "localhost")) || | ||
965 | (0 == strcasecmp (hostname, | ||
966 | "ip6-localnet")) ) | ||
967 | { | ||
968 | /* service runs on loopback */ | ||
969 | struct sockaddr_in v4; | ||
970 | struct sockaddr_in6 v6; | ||
971 | int sock; | ||
972 | |||
973 | memset (&v4, 0, sizeof (v4)); | ||
974 | memset (&v6, 0, sizeof (v6)); | ||
975 | v4.sin_family = AF_INET; | ||
976 | v4.sin_port = htons ((uint16_t) port); | ||
977 | #if HAVE_SOCKADDR_IN_SUN_LEN | ||
978 | v4.sin_len = (u_char) sizeof(struct sockaddr_in); | ||
979 | #endif | ||
980 | inet_pton (AF_INET, | ||
981 | "127.0.0.1", | ||
982 | &v4.sin_addr); | ||
983 | ret = GNUNET_NO; | ||
984 | sock = socket (AF_INET, | ||
985 | SOCK_STREAM, | ||
986 | 0); | ||
987 | if (-1 != sock) | ||
988 | { | ||
989 | if (0 != bind (sock, | ||
990 | (struct sockaddr *) &v4, | ||
991 | sizeof (v4))) | ||
992 | { | ||
993 | /* bind failed, so someone is listening! */ | ||
994 | ret = GNUNET_YES; | ||
995 | } | ||
996 | (void) close (sock); | ||
997 | } | ||
998 | else | ||
999 | { | ||
1000 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, | ||
1001 | "socket"); | ||
1002 | if (GNUNET_NO == ret) | ||
1003 | ret = GNUNET_SYSERR; | ||
1004 | } | ||
1005 | v6.sin6_family = AF_INET6; | ||
1006 | v6.sin6_port = htons ((uint16_t) port); | ||
1007 | #if HAVE_SOCKADDR_IN_SUN_LEN | ||
1008 | v6.sin6_len = (u_char) sizeof(struct sockaddr_in6); | ||
1009 | #endif | ||
1010 | inet_pton (AF_INET6, | ||
1011 | "::1", | ||
1012 | &v6.sin6_addr); | ||
1013 | sock = socket (AF_INET6, | ||
1014 | SOCK_STREAM, | ||
1015 | 0); | ||
1016 | if (-1 != sock) | ||
1017 | { | ||
1018 | if (0 != bind (sock, | ||
1019 | (struct sockaddr *) &v6, | ||
1020 | sizeof (v6))) | ||
1021 | { | ||
1022 | /* bind failed, so someone is listening! */ | ||
1023 | ret = GNUNET_YES; | ||
1024 | } | ||
1025 | (void) close (sock); | ||
1026 | } | ||
1027 | else | ||
1028 | { | ||
1029 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, | ||
1030 | "socket"); | ||
1031 | /* not changing 'ret' intentionally here, as | ||
1032 | v4 succeeding and v6 failing just means we | ||
1033 | should use v4 */ | ||
1034 | } | ||
1035 | } | ||
1036 | else | ||
1037 | { | ||
1038 | /* service running remotely */ | ||
1039 | ret = GNUNET_OK; | ||
1040 | } | ||
1041 | GNUNET_free_non_null (hostname); | ||
1042 | return ret; | ||
1043 | } | ||
1044 | |||
1045 | |||
1046 | /** | ||
892 | * Create a message queue to connect to a GNUnet service. | 1047 | * Create a message queue to connect to a GNUnet service. |
893 | * If handlers are specfied, receive messages from the connection. | 1048 | * If handlers are specfied, receive messages from the connection. |
894 | * | 1049 | * |
diff --git a/src/util/service.c b/src/util/service.c index b0f4ea289..25c1ba338 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 | */ |
@@ -243,7 +246,8 @@ struct GNUNET_SERVICE_Handle { | |||
243 | /** | 246 | /** |
244 | * Handle to a client that is connected to a service. | 247 | * Handle to a client that is connected to a service. |
245 | */ | 248 | */ |
246 | struct GNUNET_SERVICE_Client { | 249 | struct GNUNET_SERVICE_Client |
250 | { | ||
247 | /** | 251 | /** |
248 | * Kept in a DLL. | 252 | * Kept in a DLL. |
249 | */ | 253 | */ |
@@ -353,15 +357,15 @@ struct GNUNET_SERVICE_Client { | |||
353 | * @return #GNUNET_YES if we have non-monitoring clients left | 357 | * @return #GNUNET_YES if we have non-monitoring clients left |
354 | */ | 358 | */ |
355 | static int | 359 | static int |
356 | have_non_monitor_clients(struct GNUNET_SERVICE_Handle *sh) | 360 | have_non_monitor_clients (struct GNUNET_SERVICE_Handle *sh) |
357 | { | 361 | { |
358 | for (struct GNUNET_SERVICE_Client *client = sh->clients_head; NULL != client; | 362 | for (struct GNUNET_SERVICE_Client *client = sh->clients_head; NULL != client; |
359 | client = client->next) | 363 | client = client->next) |
360 | { | 364 | { |
361 | if (client->is_monitor) | 365 | if (client->is_monitor) |
362 | continue; | 366 | continue; |
363 | return GNUNET_YES; | 367 | return GNUNET_YES; |
364 | } | 368 | } |
365 | return GNUNET_NO; | 369 | return GNUNET_NO; |
366 | } | 370 | } |
367 | 371 | ||
@@ -374,20 +378,20 @@ have_non_monitor_clients(struct GNUNET_SERVICE_Handle *sh) | |||
374 | * @param sr reason for suspending accepting connections | 378 | * @param sr reason for suspending accepting connections |
375 | */ | 379 | */ |
376 | static void | 380 | static void |
377 | do_suspend(struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr) | 381 | do_suspend (struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr) |
378 | { | 382 | { |
379 | struct ServiceListenContext *slc; | 383 | struct ServiceListenContext *slc; |
380 | 384 | ||
381 | GNUNET_assert(0 == (sh->suspend_state & sr)); | 385 | GNUNET_assert (0 == (sh->suspend_state & sr)); |
382 | sh->suspend_state |= sr; | 386 | sh->suspend_state |= sr; |
383 | for (slc = sh->slc_head; NULL != slc; slc = slc->next) | 387 | for (slc = sh->slc_head; NULL != slc; slc = slc->next) |
388 | { | ||
389 | if (NULL != slc->listen_task) | ||
384 | { | 390 | { |
385 | if (NULL != slc->listen_task) | 391 | GNUNET_SCHEDULER_cancel (slc->listen_task); |
386 | { | 392 | slc->listen_task = NULL; |
387 | GNUNET_SCHEDULER_cancel(slc->listen_task); | ||
388 | slc->listen_task = NULL; | ||
389 | } | ||
390 | } | 393 | } |
394 | } | ||
391 | } | 395 | } |
392 | 396 | ||
393 | 397 | ||
@@ -400,29 +404,29 @@ do_suspend(struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr) | |||
400 | * @param cls our `struct GNUNET_SERVICE_Handle` | 404 | * @param cls our `struct GNUNET_SERVICE_Handle` |
401 | */ | 405 | */ |
402 | static void | 406 | static void |
403 | service_shutdown(void *cls) | 407 | service_shutdown (void *cls) |
404 | { | 408 | { |
405 | struct GNUNET_SERVICE_Handle *sh = cls; | 409 | struct GNUNET_SERVICE_Handle *sh = cls; |
406 | 410 | ||
407 | switch (sh->options) | 411 | switch (sh->options) |
408 | { | 412 | { |
409 | case GNUNET_SERVICE_OPTION_NONE: | 413 | case GNUNET_SERVICE_OPTION_NONE: |
410 | GNUNET_SERVICE_shutdown(sh); | 414 | GNUNET_SERVICE_shutdown (sh); |
411 | break; | 415 | break; |
412 | 416 | ||
413 | case GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN: | 417 | case GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN: |
414 | /* This task should never be run if we are using | 418 | /* This task should never be run if we are using |
415 | the manual shutdown. */ | 419 | the manual shutdown. */ |
416 | GNUNET_assert(0); | 420 | GNUNET_assert (0); |
417 | break; | 421 | break; |
418 | 422 | ||
419 | case GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN: | 423 | case GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN: |
420 | if (0 == (sh->suspend_state & SUSPEND_STATE_SHUTDOWN)) | 424 | if (0 == (sh->suspend_state & SUSPEND_STATE_SHUTDOWN)) |
421 | do_suspend(sh, SUSPEND_STATE_SHUTDOWN); | 425 | do_suspend (sh, SUSPEND_STATE_SHUTDOWN); |
422 | if (GNUNET_NO == have_non_monitor_clients(sh)) | 426 | if (GNUNET_NO == have_non_monitor_clients (sh)) |
423 | GNUNET_SERVICE_shutdown(sh); | 427 | GNUNET_SERVICE_shutdown (sh); |
424 | break; | 428 | break; |
425 | } | 429 | } |
426 | } | 430 | } |
427 | 431 | ||
428 | 432 | ||
@@ -434,8 +438,8 @@ service_shutdown(void *cls) | |||
434 | * @return #GNUNET_NO if the IP is not in the list, #GNUNET_YES if it it is | 438 | * @return #GNUNET_NO if the IP is not in the list, #GNUNET_YES if it it is |
435 | */ | 439 | */ |
436 | static int | 440 | static int |
437 | check_ipv4_listed(const struct GNUNET_STRINGS_IPv4NetworkPolicy *list, | 441 | check_ipv4_listed (const struct GNUNET_STRINGS_IPv4NetworkPolicy *list, |
438 | const struct in_addr *add) | 442 | const struct in_addr *add) |
439 | { | 443 | { |
440 | unsigned int i; | 444 | unsigned int i; |
441 | 445 | ||
@@ -443,12 +447,12 @@ check_ipv4_listed(const struct GNUNET_STRINGS_IPv4NetworkPolicy *list, | |||
443 | return GNUNET_NO; | 447 | return GNUNET_NO; |
444 | i = 0; | 448 | i = 0; |
445 | while ((0 != list[i].network.s_addr) || (0 != list[i].netmask.s_addr)) | 449 | while ((0 != list[i].network.s_addr) || (0 != list[i].netmask.s_addr)) |
446 | { | 450 | { |
447 | if ((add->s_addr & list[i].netmask.s_addr) == | 451 | if ((add->s_addr & list[i].netmask.s_addr) == |
448 | (list[i].network.s_addr & list[i].netmask.s_addr)) | 452 | (list[i].network.s_addr & list[i].netmask.s_addr)) |
449 | return GNUNET_YES; | 453 | return GNUNET_YES; |
450 | i++; | 454 | i++; |
451 | } | 455 | } |
452 | return GNUNET_NO; | 456 | return GNUNET_NO; |
453 | } | 457 | } |
454 | 458 | ||
@@ -461,8 +465,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 | 465 | * @return #GNUNET_NO if the IP is not in the list, #GNUNET_YES if it it is |
462 | */ | 466 | */ |
463 | static int | 467 | static int |
464 | check_ipv6_listed(const struct GNUNET_STRINGS_IPv6NetworkPolicy *list, | 468 | check_ipv6_listed (const struct GNUNET_STRINGS_IPv6NetworkPolicy *list, |
465 | const struct in6_addr *ip) | 469 | const struct in6_addr *ip) |
466 | { | 470 | { |
467 | unsigned int i; | 471 | unsigned int i; |
468 | unsigned int j; | 472 | unsigned int j; |
@@ -471,17 +475,17 @@ check_ipv6_listed(const struct GNUNET_STRINGS_IPv6NetworkPolicy *list, | |||
471 | return GNUNET_NO; | 475 | return GNUNET_NO; |
472 | i = 0; | 476 | i = 0; |
473 | NEXT: | 477 | NEXT: |
474 | while (0 != GNUNET_is_zero(&list[i].network)) | 478 | while (0 != GNUNET_is_zero (&list[i].network)) |
475 | { | 479 | { |
476 | for (j = 0; j < sizeof(struct in6_addr) / sizeof(int); j++) | 480 | for (j = 0; j < sizeof(struct in6_addr) / sizeof(int); j++) |
477 | if (((((int *)ip)[j] & ((int *)&list[i].netmask)[j])) != | 481 | if (((((int *) ip)[j] & ((int *) &list[i].netmask)[j])) != |
478 | (((int *)&list[i].network)[j] & ((int *)&list[i].netmask)[j])) | 482 | (((int *) &list[i].network)[j] & ((int *) &list[i].netmask)[j])) |
479 | { | 483 | { |
480 | i++; | 484 | i++; |
481 | goto NEXT; | 485 | goto NEXT; |
482 | } | 486 | } |
483 | return GNUNET_YES; | 487 | return GNUNET_YES; |
484 | } | 488 | } |
485 | return GNUNET_NO; | 489 | return GNUNET_NO; |
486 | } | 490 | } |
487 | 491 | ||
@@ -493,63 +497,63 @@ NEXT: | |||
493 | * @param cls the `struct GNUNET_SERVICE_Client *` to send to | 497 | * @param cls the `struct GNUNET_SERVICE_Client *` to send to |
494 | */ | 498 | */ |
495 | static void | 499 | static void |
496 | do_send(void *cls) | 500 | do_send (void *cls) |
497 | { | 501 | { |
498 | struct GNUNET_SERVICE_Client *client = cls; | 502 | struct GNUNET_SERVICE_Client *client = cls; |
499 | ssize_t ret; | 503 | ssize_t ret; |
500 | size_t left; | 504 | size_t left; |
501 | const char *buf; | 505 | const char *buf; |
502 | 506 | ||
503 | LOG(GNUNET_ERROR_TYPE_DEBUG, | 507 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
504 | "service: sending message with type %u\n", | 508 | "service: sending message with type %u\n", |
505 | ntohs(client->msg->type)); | 509 | ntohs (client->msg->type)); |
506 | 510 | ||
507 | 511 | ||
508 | client->send_task = NULL; | 512 | client->send_task = NULL; |
509 | buf = (const char *)client->msg; | 513 | buf = (const char *) client->msg; |
510 | left = ntohs(client->msg->size) - client->msg_pos; | 514 | left = ntohs (client->msg->size) - client->msg_pos; |
511 | ret = GNUNET_NETWORK_socket_send(client->sock, &buf[client->msg_pos], left); | 515 | ret = GNUNET_NETWORK_socket_send (client->sock, &buf[client->msg_pos], left); |
512 | GNUNET_assert(ret <= (ssize_t)left); | 516 | GNUNET_assert (ret <= (ssize_t) left); |
513 | if (0 == ret) | 517 | if (0 == ret) |
514 | { | 518 | { |
515 | LOG(GNUNET_ERROR_TYPE_DEBUG, "no data send"); | 519 | LOG (GNUNET_ERROR_TYPE_DEBUG, "no data send"); |
516 | GNUNET_MQ_inject_error(client->mq, GNUNET_MQ_ERROR_WRITE); | 520 | GNUNET_MQ_inject_error (client->mq, GNUNET_MQ_ERROR_WRITE); |
517 | return; | 521 | return; |
518 | } | 522 | } |
519 | if (-1 == ret) | 523 | if (-1 == ret) |
524 | { | ||
525 | if ((EAGAIN == errno) || (EINTR == errno)) | ||
520 | { | 526 | { |
521 | if ((EAGAIN == errno) || (EINTR == errno)) | 527 | /* ignore */ |
522 | { | 528 | 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 | } | 529 | } |
541 | client->msg_pos += ret; | 530 | else |
542 | if (left > (size_t)ret) | ||
543 | { | 531 | { |
544 | GNUNET_assert(NULL == client->drop_task); | 532 | if (EPIPE != errno) |
545 | client->send_task = | 533 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "send"); |
546 | GNUNET_SCHEDULER_add_write_net(GNUNET_TIME_UNIT_FOREVER_REL, | 534 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
547 | client->sock, | 535 | "socket send returned with error code %i", |
548 | &do_send, | 536 | errno); |
549 | client); | 537 | GNUNET_MQ_inject_error (client->mq, GNUNET_MQ_ERROR_WRITE); |
550 | return; | 538 | return; |
551 | } | 539 | } |
552 | GNUNET_MQ_impl_send_continue(client->mq); | 540 | } |
541 | if (0 == client->msg_pos) | ||
542 | { | ||
543 | GNUNET_MQ_impl_send_in_flight (client->mq); | ||
544 | } | ||
545 | client->msg_pos += ret; | ||
546 | if (left > (size_t) ret) | ||
547 | { | ||
548 | GNUNET_assert (NULL == client->drop_task); | ||
549 | client->send_task = | ||
550 | GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, | ||
551 | client->sock, | ||
552 | &do_send, | ||
553 | client); | ||
554 | return; | ||
555 | } | ||
556 | GNUNET_MQ_impl_send_continue (client->mq); | ||
553 | } | 557 | } |
554 | 558 | ||
555 | 559 | ||
@@ -562,27 +566,27 @@ do_send(void *cls) | |||
562 | * @param impl_state our `struct GNUNET_SERVICE_Client *` | 566 | * @param impl_state our `struct GNUNET_SERVICE_Client *` |
563 | */ | 567 | */ |
564 | static void | 568 | static void |
565 | service_mq_send(struct GNUNET_MQ_Handle *mq, | 569 | service_mq_send (struct GNUNET_MQ_Handle *mq, |
566 | const struct GNUNET_MessageHeader *msg, | 570 | const struct GNUNET_MessageHeader *msg, |
567 | void *impl_state) | 571 | void *impl_state) |
568 | { | 572 | { |
569 | struct GNUNET_SERVICE_Client *client = impl_state; | 573 | struct GNUNET_SERVICE_Client *client = impl_state; |
570 | 574 | ||
571 | (void)mq; | 575 | (void) mq; |
572 | if (NULL != client->drop_task) | 576 | if (NULL != client->drop_task) |
573 | return; /* we're going down right now, do not try to send */ | 577 | return; /* we're going down right now, do not try to send */ |
574 | GNUNET_assert(NULL == client->send_task); | 578 | GNUNET_assert (NULL == client->send_task); |
575 | LOG(GNUNET_ERROR_TYPE_DEBUG, | 579 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
576 | "Sending message of type %u and size %u to client\n", | 580 | "Sending message of type %u and size %u to client\n", |
577 | ntohs(msg->type), | 581 | ntohs (msg->type), |
578 | ntohs(msg->size)); | 582 | ntohs (msg->size)); |
579 | client->msg = msg; | 583 | client->msg = msg; |
580 | client->msg_pos = 0; | 584 | client->msg_pos = 0; |
581 | client->send_task = | 585 | client->send_task = |
582 | GNUNET_SCHEDULER_add_write_net(GNUNET_TIME_UNIT_FOREVER_REL, | 586 | GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, |
583 | client->sock, | 587 | client->sock, |
584 | &do_send, | 588 | &do_send, |
585 | client); | 589 | client); |
586 | } | 590 | } |
587 | 591 | ||
588 | 592 | ||
@@ -593,14 +597,14 @@ service_mq_send(struct GNUNET_MQ_Handle *mq, | |||
593 | * @param impl_state state specific to the implementation | 597 | * @param impl_state state specific to the implementation |
594 | */ | 598 | */ |
595 | static void | 599 | static void |
596 | service_mq_cancel(struct GNUNET_MQ_Handle *mq, void *impl_state) | 600 | service_mq_cancel (struct GNUNET_MQ_Handle *mq, void *impl_state) |
597 | { | 601 | { |
598 | struct GNUNET_SERVICE_Client *client = impl_state; | 602 | struct GNUNET_SERVICE_Client *client = impl_state; |
599 | 603 | ||
600 | (void)mq; | 604 | (void) mq; |
601 | GNUNET_assert(0 == client->msg_pos); | 605 | GNUNET_assert (0 == client->msg_pos); |
602 | client->msg = NULL; | 606 | client->msg = NULL; |
603 | GNUNET_SCHEDULER_cancel(client->send_task); | 607 | GNUNET_SCHEDULER_cancel (client->send_task); |
604 | client->send_task = NULL; | 608 | client->send_task = NULL; |
605 | } | 609 | } |
606 | 610 | ||
@@ -615,20 +619,20 @@ service_mq_cancel(struct GNUNET_MQ_Handle *mq, void *impl_state) | |||
615 | * @param error error code | 619 | * @param error error code |
616 | */ | 620 | */ |
617 | static void | 621 | static void |
618 | service_mq_error_handler(void *cls, enum GNUNET_MQ_Error error) | 622 | service_mq_error_handler (void *cls, enum GNUNET_MQ_Error error) |
619 | { | 623 | { |
620 | struct GNUNET_SERVICE_Client *client = cls; | 624 | struct GNUNET_SERVICE_Client *client = cls; |
621 | struct GNUNET_SERVICE_Handle *sh = client->sh; | 625 | struct GNUNET_SERVICE_Handle *sh = client->sh; |
622 | 626 | ||
623 | if ((GNUNET_MQ_ERROR_NO_MATCH == error) && (GNUNET_NO == sh->require_found)) | 627 | if ((GNUNET_MQ_ERROR_NO_MATCH == error) && (GNUNET_NO == sh->require_found)) |
624 | { | 628 | { |
625 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | 629 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
626 | "No handler for message of type %u found\n", | 630 | "No handler for message of type %u found\n", |
627 | (unsigned int)client->warn_type); | 631 | (unsigned int) client->warn_type); |
628 | GNUNET_SERVICE_client_continue(client); | 632 | GNUNET_SERVICE_client_continue (client); |
629 | return; /* ignore error */ | 633 | return; /* ignore error */ |
630 | } | 634 | } |
631 | GNUNET_SERVICE_client_drop(client); | 635 | GNUNET_SERVICE_client_drop (client); |
632 | } | 636 | } |
633 | 637 | ||
634 | 638 | ||
@@ -638,24 +642,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 | 642 | * @param cls our `struct GNUNET_SERVICE_Client *` to process more requests from |
639 | */ | 643 | */ |
640 | static void | 644 | static void |
641 | warn_no_client_continue(void *cls) | 645 | warn_no_client_continue (void *cls) |
642 | { | 646 | { |
643 | struct GNUNET_SERVICE_Client *client = cls; | 647 | struct GNUNET_SERVICE_Client *client = cls; |
644 | 648 | ||
645 | GNUNET_break( | 649 | GNUNET_break ( |
646 | 0 != | 650 | 0 != |
647 | client->warn_type); /* type should never be 0 here, as we don't use 0 */ | 651 | 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, | 652 | client->warn_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, |
649 | &warn_no_client_continue, | 653 | &warn_no_client_continue, |
650 | client); | 654 | client); |
651 | LOG( | 655 | LOG ( |
652 | GNUNET_ERROR_TYPE_WARNING, | 656 | GNUNET_ERROR_TYPE_WARNING, |
653 | _( | 657 | _ ( |
654 | "Processing code for message of type %u did not call `GNUNET_SERVICE_client_continue' after %s\n"), | 658 | "Processing code for message of type %u did not call `GNUNET_SERVICE_client_continue' after %s\n"), |
655 | (unsigned int)client->warn_type, | 659 | (unsigned int) client->warn_type, |
656 | GNUNET_STRINGS_relative_time_to_string(GNUNET_TIME_absolute_get_duration( | 660 | GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration ( |
657 | client->warn_start), | 661 | client->warn_start), |
658 | GNUNET_YES)); | 662 | GNUNET_YES)); |
659 | } | 663 | } |
660 | 664 | ||
661 | 665 | ||
@@ -671,23 +675,23 @@ warn_no_client_continue(void *cls) | |||
671 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if the client was dropped | 675 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if the client was dropped |
672 | */ | 676 | */ |
673 | static int | 677 | static int |
674 | service_client_mst_cb(void *cls, const struct GNUNET_MessageHeader *message) | 678 | service_client_mst_cb (void *cls, const struct GNUNET_MessageHeader *message) |
675 | { | 679 | { |
676 | struct GNUNET_SERVICE_Client *client = cls; | 680 | struct GNUNET_SERVICE_Client *client = cls; |
677 | 681 | ||
678 | LOG(GNUNET_ERROR_TYPE_DEBUG, | 682 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
679 | "Received message of type %u and size %u from client\n", | 683 | "Received message of type %u and size %u from client\n", |
680 | ntohs(message->type), | 684 | ntohs (message->type), |
681 | ntohs(message->size)); | 685 | ntohs (message->size)); |
682 | GNUNET_assert(GNUNET_NO == client->needs_continue); | 686 | GNUNET_assert (GNUNET_NO == client->needs_continue); |
683 | client->needs_continue = GNUNET_YES; | 687 | client->needs_continue = GNUNET_YES; |
684 | client->warn_type = ntohs(message->type); | 688 | client->warn_type = ntohs (message->type); |
685 | client->warn_start = GNUNET_TIME_absolute_get(); | 689 | client->warn_start = GNUNET_TIME_absolute_get (); |
686 | GNUNET_assert(NULL == client->warn_task); | 690 | GNUNET_assert (NULL == client->warn_task); |
687 | client->warn_task = GNUNET_SCHEDULER_add_delayed(GNUNET_TIME_UNIT_MINUTES, | 691 | client->warn_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, |
688 | &warn_no_client_continue, | 692 | &warn_no_client_continue, |
689 | client); | 693 | client); |
690 | GNUNET_MQ_inject_message(client->mq, message); | 694 | GNUNET_MQ_inject_message (client->mq, message); |
691 | if (NULL != client->drop_task) | 695 | if (NULL != client->drop_task) |
692 | return GNUNET_SYSERR; | 696 | return GNUNET_SYSERR; |
693 | return GNUNET_OK; | 697 | return GNUNET_OK; |
@@ -701,37 +705,37 @@ service_client_mst_cb(void *cls, const struct GNUNET_MessageHeader *message) | |||
701 | * @param cls the `struct GNUNET_SERVICE_Client` that sent us data. | 705 | * @param cls the `struct GNUNET_SERVICE_Client` that sent us data. |
702 | */ | 706 | */ |
703 | static void | 707 | static void |
704 | service_client_recv(void *cls) | 708 | service_client_recv (void *cls) |
705 | { | 709 | { |
706 | struct GNUNET_SERVICE_Client *client = cls; | 710 | struct GNUNET_SERVICE_Client *client = cls; |
707 | int ret; | 711 | int ret; |
708 | 712 | ||
709 | client->recv_task = NULL; | 713 | client->recv_task = NULL; |
710 | ret = GNUNET_MST_read(client->mst, client->sock, GNUNET_NO, GNUNET_YES); | 714 | ret = GNUNET_MST_read (client->mst, client->sock, GNUNET_NO, GNUNET_YES); |
711 | if (GNUNET_SYSERR == ret) | 715 | if (GNUNET_SYSERR == ret) |
716 | { | ||
717 | /* client closed connection (or IO error) */ | ||
718 | if (NULL == client->drop_task) | ||
712 | { | 719 | { |
713 | /* client closed connection (or IO error) */ | 720 | GNUNET_assert (GNUNET_NO == client->needs_continue); |
714 | if (NULL == client->drop_task) | 721 | GNUNET_SERVICE_client_drop (client); |
715 | { | ||
716 | GNUNET_assert(GNUNET_NO == client->needs_continue); | ||
717 | GNUNET_SERVICE_client_drop(client); | ||
718 | } | ||
719 | return; | ||
720 | } | 722 | } |
723 | return; | ||
724 | } | ||
721 | if (GNUNET_NO == ret) | 725 | if (GNUNET_NO == ret) |
722 | return; /* more messages in buffer, wait for application | 726 | return; /* more messages in buffer, wait for application |
723 | to be done processing */ | 727 | to be done processing */ |
724 | GNUNET_assert(GNUNET_OK == ret); | 728 | GNUNET_assert (GNUNET_OK == ret); |
725 | if (GNUNET_YES == client->needs_continue) | 729 | if (GNUNET_YES == client->needs_continue) |
726 | return; | 730 | return; |
727 | if (NULL != client->recv_task) | 731 | if (NULL != client->recv_task) |
728 | return; | 732 | return; |
729 | /* MST needs more data, re-schedule read job */ | 733 | /* MST needs more data, re-schedule read job */ |
730 | client->recv_task = | 734 | client->recv_task = |
731 | GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, | 735 | GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, |
732 | client->sock, | 736 | client->sock, |
733 | &service_client_recv, | 737 | &service_client_recv, |
734 | client); | 738 | client); |
735 | } | 739 | } |
736 | 740 | ||
737 | 741 | ||
@@ -743,31 +747,31 @@ service_client_recv(void *cls) | |||
743 | * @param sock socket associated with the client | 747 | * @param sock socket associated with the client |
744 | */ | 748 | */ |
745 | static void | 749 | static void |
746 | start_client(struct GNUNET_SERVICE_Handle *sh, | 750 | start_client (struct GNUNET_SERVICE_Handle *sh, |
747 | struct GNUNET_NETWORK_Handle *csock) | 751 | struct GNUNET_NETWORK_Handle *csock) |
748 | { | 752 | { |
749 | struct GNUNET_SERVICE_Client *client; | 753 | struct GNUNET_SERVICE_Client *client; |
750 | 754 | ||
751 | client = GNUNET_new(struct GNUNET_SERVICE_Client); | 755 | client = GNUNET_new (struct GNUNET_SERVICE_Client); |
752 | GNUNET_CONTAINER_DLL_insert(sh->clients_head, sh->clients_tail, client); | 756 | GNUNET_CONTAINER_DLL_insert (sh->clients_head, sh->clients_tail, client); |
753 | client->sh = sh; | 757 | client->sh = sh; |
754 | client->sock = csock; | 758 | client->sock = csock; |
755 | client->mq = GNUNET_MQ_queue_for_callbacks(&service_mq_send, | 759 | client->mq = GNUNET_MQ_queue_for_callbacks (&service_mq_send, |
756 | NULL, | 760 | NULL, |
757 | &service_mq_cancel, | 761 | &service_mq_cancel, |
758 | client, | 762 | client, |
759 | sh->handlers, | 763 | sh->handlers, |
760 | &service_mq_error_handler, | 764 | &service_mq_error_handler, |
761 | client); | 765 | client); |
762 | client->mst = GNUNET_MST_create(&service_client_mst_cb, client); | 766 | client->mst = GNUNET_MST_create (&service_client_mst_cb, client); |
763 | if (NULL != sh->connect_cb) | 767 | if (NULL != sh->connect_cb) |
764 | client->user_context = sh->connect_cb(sh->cb_cls, client, client->mq); | 768 | client->user_context = sh->connect_cb (sh->cb_cls, client, client->mq); |
765 | GNUNET_MQ_set_handlers_closure(client->mq, client->user_context); | 769 | GNUNET_MQ_set_handlers_closure (client->mq, client->user_context); |
766 | client->recv_task = | 770 | client->recv_task = |
767 | GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, | 771 | GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, |
768 | client->sock, | 772 | client->sock, |
769 | &service_client_recv, | 773 | &service_client_recv, |
770 | client); | 774 | client); |
771 | } | 775 | } |
772 | 776 | ||
773 | 777 | ||
@@ -778,83 +782,83 @@ start_client(struct GNUNET_SERVICE_Handle *sh, | |||
778 | * @param cls the `struct ServiceListenContext` of the ready listen socket | 782 | * @param cls the `struct ServiceListenContext` of the ready listen socket |
779 | */ | 783 | */ |
780 | static void | 784 | static void |
781 | accept_client(void *cls) | 785 | accept_client (void *cls) |
782 | { | 786 | { |
783 | struct ServiceListenContext *slc = cls; | 787 | struct ServiceListenContext *slc = cls; |
784 | struct GNUNET_SERVICE_Handle *sh = slc->sh; | 788 | struct GNUNET_SERVICE_Handle *sh = slc->sh; |
785 | 789 | ||
786 | slc->listen_task = NULL; | 790 | slc->listen_task = NULL; |
787 | while (1) | 791 | while (1) |
792 | { | ||
793 | struct GNUNET_NETWORK_Handle *sock; | ||
794 | const struct sockaddr_in *v4; | ||
795 | const struct sockaddr_in6 *v6; | ||
796 | struct sockaddr_storage sa; | ||
797 | socklen_t addrlen; | ||
798 | int ok; | ||
799 | |||
800 | addrlen = sizeof(sa); | ||
801 | sock = GNUNET_NETWORK_socket_accept (slc->listen_socket, | ||
802 | (struct sockaddr *) &sa, | ||
803 | &addrlen); | ||
804 | if (NULL == sock) | ||
805 | { | ||
806 | if (EMFILE == errno) | ||
807 | do_suspend (sh, SUSPEND_STATE_EMFILE); | ||
808 | else if (EAGAIN != errno) | ||
809 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "accept"); | ||
810 | break; | ||
811 | } | ||
812 | switch (sa.ss_family) | ||
788 | { | 813 | { |
789 | struct GNUNET_NETWORK_Handle *sock; | 814 | case AF_INET: |
790 | const struct sockaddr_in *v4; | 815 | GNUNET_assert (addrlen == sizeof(struct sockaddr_in)); |
791 | const struct sockaddr_in6 *v6; | 816 | v4 = (const struct sockaddr_in *) &sa; |
792 | struct sockaddr_storage sa; | 817 | ok = (((NULL == sh->v4_allowed) || |
793 | socklen_t addrlen; | 818 | (check_ipv4_listed (sh->v4_allowed, &v4->sin_addr))) && |
794 | int ok; | 819 | ((NULL == sh->v4_denied) || |
795 | 820 | (! check_ipv4_listed (sh->v4_denied, &v4->sin_addr)))); | |
796 | addrlen = sizeof(sa); | 821 | break; |
797 | sock = GNUNET_NETWORK_socket_accept(slc->listen_socket, | 822 | |
798 | (struct sockaddr *)&sa, | 823 | case AF_INET6: |
799 | &addrlen); | 824 | GNUNET_assert (addrlen == sizeof(struct sockaddr_in6)); |
800 | if (NULL == sock) | 825 | v6 = (const struct sockaddr_in6 *) &sa; |
801 | { | 826 | ok = (((NULL == sh->v6_allowed) || |
802 | if (EMFILE == errno) | 827 | (check_ipv6_listed (sh->v6_allowed, &v6->sin6_addr))) && |
803 | do_suspend(sh, SUSPEND_STATE_EMFILE); | 828 | ((NULL == sh->v6_denied) || |
804 | else if (EAGAIN != errno) | 829 | (! check_ipv6_listed (sh->v6_denied, &v6->sin6_addr)))); |
805 | GNUNET_log_strerror(GNUNET_ERROR_TYPE_WARNING, "accept"); | 830 | break; |
806 | break; | 831 | |
807 | } | 832 | case AF_UNIX: |
808 | switch (sa.ss_family) | 833 | ok = GNUNET_OK; /* controlled using file-system ACL now */ |
809 | { | 834 | break; |
810 | case AF_INET: | 835 | |
811 | GNUNET_assert(addrlen == sizeof(struct sockaddr_in)); | 836 | default: |
812 | v4 = (const struct sockaddr_in *)&sa; | 837 | LOG (GNUNET_ERROR_TYPE_WARNING, |
813 | ok = (((NULL == sh->v4_allowed) || | 838 | _ ("Unknown address family %d\n"), |
814 | (check_ipv4_listed(sh->v4_allowed, &v4->sin_addr))) && | 839 | sa.ss_family); |
815 | ((NULL == sh->v4_denied) || | 840 | return; |
816 | (!check_ipv4_listed(sh->v4_denied, &v4->sin_addr)))); | 841 | } |
817 | break; | 842 | if (! ok) |
818 | 843 | { | |
819 | case AF_INET6: | 844 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
820 | GNUNET_assert(addrlen == sizeof(struct sockaddr_in6)); | 845 | "Service rejected incoming connection from %s due to policy.\n", |
821 | v6 = (const struct sockaddr_in6 *)&sa; | 846 | GNUNET_a2s ((const struct sockaddr *) &sa, addrlen)); |
822 | ok = (((NULL == sh->v6_allowed) || | 847 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); |
823 | (check_ipv6_listed(sh->v6_allowed, &v6->sin6_addr))) && | 848 | 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 | } | 849 | } |
850 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
851 | "Service accepted incoming connection from %s.\n", | ||
852 | GNUNET_a2s ((const struct sockaddr *) &sa, addrlen)); | ||
853 | start_client (slc->sh, sock); | ||
854 | } | ||
851 | if (0 != sh->suspend_state) | 855 | if (0 != sh->suspend_state) |
852 | return; | 856 | return; |
853 | slc->listen_task = | 857 | slc->listen_task = |
854 | GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, | 858 | GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, |
855 | slc->listen_socket, | 859 | slc->listen_socket, |
856 | &accept_client, | 860 | &accept_client, |
857 | slc); | 861 | slc); |
858 | } | 862 | } |
859 | 863 | ||
860 | 864 | ||
@@ -866,23 +870,23 @@ accept_client(void *cls) | |||
866 | * or #SUSPEND_STATE_NONE on first startup | 870 | * or #SUSPEND_STATE_NONE on first startup |
867 | */ | 871 | */ |
868 | static void | 872 | static void |
869 | do_resume(struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr) | 873 | do_resume (struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr) |
870 | { | 874 | { |
871 | struct ServiceListenContext *slc; | 875 | struct ServiceListenContext *slc; |
872 | 876 | ||
873 | GNUNET_assert((SUSPEND_STATE_NONE == sr) || (0 != (sh->suspend_state & sr))); | 877 | GNUNET_assert ((SUSPEND_STATE_NONE == sr) || (0 != (sh->suspend_state & sr))); |
874 | sh->suspend_state -= sr; | 878 | sh->suspend_state -= sr; |
875 | if (SUSPEND_STATE_NONE != sh->suspend_state) | 879 | if (SUSPEND_STATE_NONE != sh->suspend_state) |
876 | return; | 880 | return; |
877 | for (slc = sh->slc_head; NULL != slc; slc = slc->next) | 881 | for (slc = sh->slc_head; NULL != slc; slc = slc->next) |
878 | { | 882 | { |
879 | GNUNET_assert(NULL == slc->listen_task); | 883 | GNUNET_assert (NULL == slc->listen_task); |
880 | slc->listen_task = | 884 | slc->listen_task = |
881 | GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, | 885 | GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, |
882 | slc->listen_socket, | 886 | slc->listen_socket, |
883 | &accept_client, | 887 | &accept_client, |
884 | slc); | 888 | slc); |
885 | } | 889 | } |
886 | } | 890 | } |
887 | 891 | ||
888 | 892 | ||
@@ -894,23 +898,23 @@ do_resume(struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr) | |||
894 | * @param cls our `struct GNUNET_SERVICE_Handle` | 898 | * @param cls our `struct GNUNET_SERVICE_Handle` |
895 | */ | 899 | */ |
896 | static void | 900 | static void |
897 | service_main(void *cls) | 901 | service_main (void *cls) |
898 | { | 902 | { |
899 | struct GNUNET_SERVICE_Handle *sh = cls; | 903 | struct GNUNET_SERVICE_Handle *sh = cls; |
900 | 904 | ||
901 | if (GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN != sh->options) | 905 | if (GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN != sh->options) |
902 | GNUNET_SCHEDULER_add_shutdown(&service_shutdown, sh); | 906 | GNUNET_SCHEDULER_add_shutdown (&service_shutdown, sh); |
903 | do_resume(sh, SUSPEND_STATE_NONE); | 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)); | 1162 | } |
1173 | GNUNET_free(unixpath); | 1163 | else |
1174 | unixpath = NULL; | 1164 | { |
1175 | } | 1165 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc)); |
1176 | else | 1166 | desc = NULL; |
1177 | { | ||
1178 | GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(desc)); | ||
1179 | desc = NULL; | ||
1180 | } | ||
1181 | } | 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,96 @@ 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 | ||
1377 | case AF_INET6: | 1365 | case AF_INET6: |
1378 | port = ntohs(((const struct sockaddr_in6 *)server_addr)->sin6_port); | 1366 | port = ntohs (((const struct sockaddr_in6 *) server_addr)->sin6_port); |
1379 | break; | 1367 | break; |
1380 | 1368 | ||
1381 | case AF_UNIX: | 1369 | case AF_UNIX: |
1382 | port = 0; | 1370 | port = 0; |
1383 | break; | 1371 | break; |
1384 | 1372 | ||
1385 | default: | 1373 | default: |
1386 | GNUNET_break(0); | 1374 | GNUNET_break (0); |
1387 | port = 0; | 1375 | port = 0; |
1388 | break; | 1376 | break; |
1389 | } | 1377 | } |
1390 | sock = GNUNET_NETWORK_socket_create(server_addr->sa_family, SOCK_STREAM, 0); | 1378 | sock = GNUNET_NETWORK_socket_create (server_addr->sa_family, |
1379 | SOCK_STREAM, | ||
1380 | 0); | ||
1391 | if (NULL == sock) | 1381 | if (NULL == sock) |
1392 | { | 1382 | { |
1393 | LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "socket"); | 1383 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, |
1394 | errno = 0; | 1384 | "socket"); |
1395 | return NULL; | 1385 | errno = 0; |
1396 | } | 1386 | return NULL; |
1387 | } | ||
1397 | /* bind the socket */ | 1388 | /* bind the socket */ |
1398 | if (GNUNET_OK != GNUNET_NETWORK_socket_bind(sock, server_addr, socklen)) | 1389 | if (GNUNET_OK != |
1390 | GNUNET_NETWORK_socket_bind (sock, | ||
1391 | server_addr, | ||
1392 | socklen)) | ||
1393 | { | ||
1394 | eno = errno; | ||
1395 | if (EADDRINUSE != errno) | ||
1399 | { | 1396 | { |
1400 | eno = errno; | 1397 | /* we don't log 'EADDRINUSE' here since an IPv4 bind may |
1401 | if (EADDRINUSE != errno) | 1398 | * fail if we already took the port on IPv6; if both IPv4 and |
1402 | { | 1399 | * IPv6 binds fail, then our caller will log using the |
1403 | /* we don't log 'EADDRINUSE' here since an IPv4 bind may | 1400 | * errno preserved in 'eno' */ |
1404 | * fail if we already took the port on IPv6; if both IPv4 and | 1401 | if (0 != port) |
1405 | * IPv6 binds fail, then our caller will log using the | 1402 | LOG (GNUNET_ERROR_TYPE_ERROR, |
1406 | * errno preserved in 'eno' */ | 1403 | _ ("`%s' failed for port %d (%s).\n"), |
1407 | if (0 != port) | 1404 | "bind", |
1408 | LOG(GNUNET_ERROR_TYPE_ERROR, | 1405 | port, |
1409 | _("`%s' failed for port %d (%s).\n"), | 1406 | (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 | 1407 | else |
1418 | { | 1408 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "bind"); |
1419 | if (0 != port) | 1409 | 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 | } | 1410 | } |
1437 | if (GNUNET_OK != GNUNET_NETWORK_socket_listen(sock, 5)) | 1411 | else |
1438 | { | 1412 | { |
1439 | LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "listen"); | 1413 | if (0 != port) |
1440 | GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(sock)); | 1414 | LOG (GNUNET_ERROR_TYPE_WARNING, |
1441 | errno = 0; | 1415 | _ ("`%s' failed for port %d (%s): address already in use\n"), |
1442 | return NULL; | 1416 | "bind", |
1417 | port, | ||
1418 | (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6"); | ||
1419 | else if (AF_UNIX == server_addr->sa_family) | ||
1420 | { | ||
1421 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
1422 | _ ("`%s' failed for `%s': address already in use\n"), | ||
1423 | "bind", | ||
1424 | GNUNET_a2s (server_addr, socklen)); | ||
1425 | } | ||
1443 | } | 1426 | } |
1427 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); | ||
1428 | errno = eno; | ||
1429 | return NULL; | ||
1430 | } | ||
1431 | if (GNUNET_OK != GNUNET_NETWORK_socket_listen (sock, 5)) | ||
1432 | { | ||
1433 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "listen"); | ||
1434 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); | ||
1435 | errno = 0; | ||
1436 | return NULL; | ||
1437 | } | ||
1444 | if (0 != port) | 1438 | if (0 != port) |
1445 | LOG(GNUNET_ERROR_TYPE_DEBUG, | 1439 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1446 | "Server starts to listen on port %u.\n", | 1440 | "Server starts to listen on port %u.\n", |
1447 | port); | 1441 | port); |
1448 | return sock; | 1442 | return sock; |
1449 | } | 1443 | } |
1450 | 1444 | ||
@@ -1466,7 +1460,7 @@ open_listen_socket(const struct sockaddr *server_addr, socklen_t socklen) | |||
1466 | * @return #GNUNET_OK if configuration succeeded | 1460 | * @return #GNUNET_OK if configuration succeeded |
1467 | */ | 1461 | */ |
1468 | static int | 1462 | static int |
1469 | setup_service(struct GNUNET_SERVICE_Handle *sh) | 1463 | setup_service (struct GNUNET_SERVICE_Handle *sh) |
1470 | { | 1464 | { |
1471 | int tolerant; | 1465 | int tolerant; |
1472 | struct GNUNET_NETWORK_Handle **lsocks; | 1466 | struct GNUNET_NETWORK_Handle **lsocks; |
@@ -1475,119 +1469,119 @@ setup_service(struct GNUNET_SERVICE_Handle *sh) | |||
1475 | int flags; | 1469 | int flags; |
1476 | char dummy[2]; | 1470 | char dummy[2]; |
1477 | 1471 | ||
1478 | if (GNUNET_CONFIGURATION_have_value(sh->cfg, sh->service_name, "TOLERANT")) | 1472 | if (GNUNET_CONFIGURATION_have_value (sh->cfg, sh->service_name, "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 | 1490 | ||
1497 | errno = 0; | 1491 | errno = 0; |
1498 | if ((NULL != (nfds = getenv("LISTEN_FDS"))) && | 1492 | if ((NULL != (nfds = getenv ("LISTEN_FDS"))) && |
1499 | (1 == sscanf(nfds, "%u%1s", &cnt, dummy)) && (cnt > 0) && | 1493 | (1 == sscanf (nfds, "%u%1s", &cnt, dummy)) && (cnt > 0) && |
1500 | (cnt < FD_SETSIZE) && (cnt + 4 < FD_SETSIZE)) | 1494 | (cnt < FD_SETSIZE) && (cnt + 4 < FD_SETSIZE)) |
1495 | { | ||
1496 | lsocks = GNUNET_new_array (cnt + 1, struct GNUNET_NETWORK_Handle *); | ||
1497 | while (0 < cnt--) | ||
1501 | { | 1498 | { |
1502 | lsocks = GNUNET_new_array(cnt + 1, struct GNUNET_NETWORK_Handle *); | 1499 | flags = fcntl (3 + cnt, F_GETFD); |
1503 | while (0 < cnt--) | 1500 | if ((flags < 0) || (0 != (flags & FD_CLOEXEC)) || |
1504 | { | 1501 | (NULL == (lsocks[cnt] = GNUNET_NETWORK_socket_box_native (3 + cnt)))) |
1505 | flags = fcntl(3 + cnt, F_GETFD); | 1502 | { |
1506 | if ((flags < 0) || (0 != (flags & FD_CLOEXEC)) || | 1503 | LOG (GNUNET_ERROR_TYPE_ERROR, |
1507 | (NULL == (lsocks[cnt] = GNUNET_NETWORK_socket_box_native(3 + cnt)))) | 1504 | _ ( |
1508 | { | 1505 | "Could not access pre-bound socket %u, will try to bind myself\n"), |
1509 | LOG(GNUNET_ERROR_TYPE_ERROR, | 1506 | (unsigned int) 3 + cnt); |
1510 | _( | 1507 | cnt++; |
1511 | "Could not access pre-bound socket %u, will try to bind myself\n"), | 1508 | while (NULL != lsocks[cnt]) |
1512 | (unsigned int)3 + cnt); | 1509 | GNUNET_break (GNUNET_OK == |
1513 | cnt++; | 1510 | GNUNET_NETWORK_socket_close (lsocks[cnt++])); |
1514 | while (NULL != lsocks[cnt]) | 1511 | GNUNET_free (lsocks); |
1515 | GNUNET_break(GNUNET_OK == | 1512 | lsocks = NULL; |
1516 | GNUNET_NETWORK_socket_close(lsocks[cnt++])); | 1513 | break; |
1517 | GNUNET_free(lsocks); | 1514 | } |
1518 | lsocks = NULL; | ||
1519 | break; | ||
1520 | } | ||
1521 | } | ||
1522 | unsetenv("LISTEN_FDS"); | ||
1523 | } | 1515 | } |
1516 | unsetenv ("LISTEN_FDS"); | ||
1517 | } | ||
1524 | 1518 | ||
1525 | if (NULL != lsocks) | 1519 | if (NULL != lsocks) |
1520 | { | ||
1521 | /* listen only on inherited sockets if we have any */ | ||
1522 | struct GNUNET_NETWORK_Handle **ls; | ||
1523 | |||
1524 | for (ls = lsocks; NULL != *ls; ls++) | ||
1526 | { | 1525 | { |
1527 | /* listen only on inherited sockets if we have any */ | 1526 | struct ServiceListenContext *slc; |
1528 | struct GNUNET_NETWORK_Handle **ls; | 1527 | |
1529 | 1528 | slc = GNUNET_new (struct ServiceListenContext); | |
1530 | for (ls = lsocks; NULL != *ls; ls++) | 1529 | slc->sh = sh; |
1531 | { | 1530 | slc->listen_socket = *ls; |
1532 | struct ServiceListenContext *slc; | 1531 | 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 | } | 1532 | } |
1533 | GNUNET_free (lsocks); | ||
1534 | } | ||
1541 | else | 1535 | else |
1542 | { | 1536 | { |
1543 | struct sockaddr **addrs; | 1537 | struct sockaddr **addrs; |
1544 | socklen_t *addrlens; | 1538 | socklen_t *addrlens; |
1545 | int num; | 1539 | int num; |
1546 | 1540 | ||
1547 | num = get_server_addresses(sh->service_name, sh->cfg, &addrs, &addrlens); | 1541 | num = get_server_addresses (sh->service_name, sh->cfg, &addrs, &addrlens); |
1548 | if (GNUNET_SYSERR == num) | 1542 | if (GNUNET_SYSERR == num) |
1549 | return GNUNET_SYSERR; | 1543 | return GNUNET_SYSERR; |
1544 | |||
1545 | for (int i = 0; i < num; i++) | ||
1546 | { | ||
1547 | struct ServiceListenContext *slc; | ||
1550 | 1548 | ||
1551 | for (int i = 0; i < num; i++) | 1549 | slc = GNUNET_new (struct ServiceListenContext); |
1552 | { | 1550 | slc->sh = sh; |
1553 | struct ServiceListenContext *slc; | 1551 | slc->listen_socket = open_listen_socket (addrs[i], addrlens[i]); |
1554 | 1552 | GNUNET_free (addrs[i]); | |
1555 | slc = GNUNET_new(struct ServiceListenContext); | 1553 | if (NULL == slc->listen_socket) |
1556 | slc->sh = sh; | 1554 | { |
1557 | slc->listen_socket = open_listen_socket(addrs[i], addrlens[i]); | 1555 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "bind"); |
1558 | GNUNET_free(addrs[i]); | 1556 | GNUNET_free (slc); |
1559 | if (NULL == slc->listen_socket) | 1557 | continue; |
1560 | { | 1558 | } |
1561 | GNUNET_log_strerror(GNUNET_ERROR_TYPE_ERROR, "bind"); | 1559 | GNUNET_CONTAINER_DLL_insert (sh->slc_head, sh->slc_tail, slc); |
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 | } | 1560 | } |
1561 | GNUNET_free_non_null (addrlens); | ||
1562 | GNUNET_free_non_null (addrs); | ||
1563 | if ((0 != num) && (NULL == sh->slc_head)) | ||
1564 | { | ||
1565 | /* All attempts to bind failed, hard failure */ | ||
1566 | GNUNET_log ( | ||
1567 | GNUNET_ERROR_TYPE_ERROR, | ||
1568 | _ ( | ||
1569 | "Could not bind to any of the ports I was supposed to, refusing to run!\n")); | ||
1570 | return GNUNET_SYSERR; | ||
1571 | } | ||
1572 | } | ||
1579 | 1573 | ||
1580 | sh->require_found = tolerant ? GNUNET_NO : GNUNET_YES; | 1574 | sh->require_found = tolerant ? GNUNET_NO : GNUNET_YES; |
1581 | sh->match_uid = GNUNET_CONFIGURATION_get_value_yesno(sh->cfg, | 1575 | sh->match_uid = GNUNET_CONFIGURATION_get_value_yesno (sh->cfg, |
1582 | sh->service_name, | 1576 | sh->service_name, |
1583 | "UNIX_MATCH_UID"); | 1577 | "UNIX_MATCH_UID"); |
1584 | sh->match_gid = GNUNET_CONFIGURATION_get_value_yesno(sh->cfg, | 1578 | sh->match_gid = GNUNET_CONFIGURATION_get_value_yesno (sh->cfg, |
1585 | sh->service_name, | 1579 | sh->service_name, |
1586 | "UNIX_MATCH_GID"); | 1580 | "UNIX_MATCH_GID"); |
1587 | process_acl4(&sh->v4_denied, sh, "REJECT_FROM"); | 1581 | process_acl4 (&sh->v4_denied, sh, "REJECT_FROM"); |
1588 | process_acl4(&sh->v4_allowed, sh, "ACCEPT_FROM"); | 1582 | process_acl4 (&sh->v4_allowed, sh, "ACCEPT_FROM"); |
1589 | process_acl6(&sh->v6_denied, sh, "REJECT_FROM6"); | 1583 | process_acl6 (&sh->v6_denied, sh, "REJECT_FROM6"); |
1590 | process_acl6(&sh->v6_allowed, sh, "ACCEPT_FROM6"); | 1584 | process_acl6 (&sh->v6_allowed, sh, "ACCEPT_FROM6"); |
1591 | return GNUNET_OK; | 1585 | return GNUNET_OK; |
1592 | } | 1586 | } |
1593 | 1587 | ||
@@ -1600,14 +1594,14 @@ setup_service(struct GNUNET_SERVICE_Handle *sh) | |||
1600 | * @return value of the 'USERNAME' option | 1594 | * @return value of the 'USERNAME' option |
1601 | */ | 1595 | */ |
1602 | static char * | 1596 | static char * |
1603 | get_user_name(struct GNUNET_SERVICE_Handle *sh) | 1597 | get_user_name (struct GNUNET_SERVICE_Handle *sh) |
1604 | { | 1598 | { |
1605 | char *un; | 1599 | char *un; |
1606 | 1600 | ||
1607 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename(sh->cfg, | 1601 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (sh->cfg, |
1608 | sh->service_name, | 1602 | sh->service_name, |
1609 | "USERNAME", | 1603 | "USERNAME", |
1610 | &un)) | 1604 | &un)) |
1611 | return NULL; | 1605 | return NULL; |
1612 | return un; | 1606 | return un; |
1613 | } | 1607 | } |
@@ -1620,45 +1614,45 @@ get_user_name(struct GNUNET_SERVICE_Handle *sh) | |||
1620 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | 1614 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error |
1621 | */ | 1615 | */ |
1622 | static int | 1616 | static int |
1623 | set_user_id(struct GNUNET_SERVICE_Handle *sh) | 1617 | set_user_id (struct GNUNET_SERVICE_Handle *sh) |
1624 | { | 1618 | { |
1625 | char *user; | 1619 | char *user; |
1626 | 1620 | ||
1627 | if (NULL == (user = get_user_name(sh))) | 1621 | if (NULL == (user = get_user_name (sh))) |
1628 | return GNUNET_OK; /* keep */ | 1622 | return GNUNET_OK; /* keep */ |
1629 | 1623 | ||
1630 | struct passwd *pws; | 1624 | struct passwd *pws; |
1631 | 1625 | ||
1632 | errno = 0; | 1626 | errno = 0; |
1633 | pws = getpwnam(user); | 1627 | pws = getpwnam (user); |
1634 | if (NULL == pws) | 1628 | if (NULL == pws) |
1635 | { | 1629 | { |
1636 | LOG(GNUNET_ERROR_TYPE_ERROR, | 1630 | LOG (GNUNET_ERROR_TYPE_ERROR, |
1637 | _("Cannot obtain information about user `%s': %s\n"), | 1631 | _ ("Cannot obtain information about user `%s': %s\n"), |
1638 | user, | 1632 | user, |
1639 | errno == 0 ? _("No such user") : strerror(errno)); | 1633 | errno == 0 ? _ ("No such user") : strerror (errno)); |
1640 | GNUNET_free(user); | 1634 | GNUNET_free (user); |
1641 | return GNUNET_SYSERR; | 1635 | return GNUNET_SYSERR; |
1642 | } | 1636 | } |
1643 | if ((0 != setgid(pws->pw_gid)) || (0 != setegid(pws->pw_gid)) || | 1637 | if ((0 != setgid (pws->pw_gid)) || (0 != setegid (pws->pw_gid)) || |
1644 | #if HAVE_INITGROUPS | 1638 | #if HAVE_INITGROUPS |
1645 | (0 != initgroups(user, pws->pw_gid)) || | 1639 | (0 != initgroups (user, pws->pw_gid)) || |
1646 | #endif | 1640 | #endif |
1647 | (0 != setuid(pws->pw_uid)) || (0 != seteuid(pws->pw_uid))) | 1641 | (0 != setuid (pws->pw_uid)) || (0 != seteuid (pws->pw_uid))) |
1642 | { | ||
1643 | if ((0 != setregid (pws->pw_gid, pws->pw_gid)) || | ||
1644 | (0 != setreuid (pws->pw_uid, pws->pw_uid))) | ||
1648 | { | 1645 | { |
1649 | if ((0 != setregid(pws->pw_gid, pws->pw_gid)) || | 1646 | LOG (GNUNET_ERROR_TYPE_ERROR, |
1650 | (0 != setreuid(pws->pw_uid, pws->pw_uid))) | 1647 | _ ("Cannot change user/group to `%s': %s\n"), |
1651 | { | 1648 | user, |
1652 | LOG(GNUNET_ERROR_TYPE_ERROR, | 1649 | strerror (errno)); |
1653 | _("Cannot change user/group to `%s': %s\n"), | 1650 | GNUNET_free (user); |
1654 | user, | 1651 | return GNUNET_SYSERR; |
1655 | strerror(errno)); | ||
1656 | GNUNET_free(user); | ||
1657 | return GNUNET_SYSERR; | ||
1658 | } | ||
1659 | } | 1652 | } |
1653 | } | ||
1660 | 1654 | ||
1661 | GNUNET_free(user); | 1655 | GNUNET_free (user); |
1662 | return GNUNET_OK; | 1656 | return GNUNET_OK; |
1663 | } | 1657 | } |
1664 | 1658 | ||
@@ -1671,14 +1665,14 @@ set_user_id(struct GNUNET_SERVICE_Handle *sh) | |||
1671 | * @return name of the file for the process ID | 1665 | * @return name of the file for the process ID |
1672 | */ | 1666 | */ |
1673 | static char * | 1667 | static char * |
1674 | get_pid_file_name(struct GNUNET_SERVICE_Handle *sh) | 1668 | get_pid_file_name (struct GNUNET_SERVICE_Handle *sh) |
1675 | { | 1669 | { |
1676 | char *pif; | 1670 | char *pif; |
1677 | 1671 | ||
1678 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename(sh->cfg, | 1672 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (sh->cfg, |
1679 | sh->service_name, | 1673 | sh->service_name, |
1680 | "PIDFILE", | 1674 | "PIDFILE", |
1681 | &pif)) | 1675 | &pif)) |
1682 | return NULL; | 1676 | return NULL; |
1683 | return pif; | 1677 | return pif; |
1684 | } | 1678 | } |
@@ -1690,15 +1684,15 @@ get_pid_file_name(struct GNUNET_SERVICE_Handle *sh) | |||
1690 | * @param sh service context | 1684 | * @param sh service context |
1691 | */ | 1685 | */ |
1692 | static void | 1686 | static void |
1693 | pid_file_delete(struct GNUNET_SERVICE_Handle *sh) | 1687 | pid_file_delete (struct GNUNET_SERVICE_Handle *sh) |
1694 | { | 1688 | { |
1695 | char *pif = get_pid_file_name(sh); | 1689 | char *pif = get_pid_file_name (sh); |
1696 | 1690 | ||
1697 | if (NULL == pif) | 1691 | if (NULL == pif) |
1698 | return; /* no PID file */ | 1692 | return; /* no PID file */ |
1699 | if (0 != unlink(pif)) | 1693 | if (0 != unlink (pif)) |
1700 | LOG_STRERROR_FILE(GNUNET_ERROR_TYPE_WARNING, "unlink", pif); | 1694 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "unlink", pif); |
1701 | GNUNET_free(pif); | 1695 | GNUNET_free (pif); |
1702 | } | 1696 | } |
1703 | 1697 | ||
1704 | 1698 | ||
@@ -1709,73 +1703,73 @@ pid_file_delete(struct GNUNET_SERVICE_Handle *sh) | |||
1709 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | 1703 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error |
1710 | */ | 1704 | */ |
1711 | static int | 1705 | static int |
1712 | detach_terminal(struct GNUNET_SERVICE_Handle *sh) | 1706 | detach_terminal (struct GNUNET_SERVICE_Handle *sh) |
1713 | { | 1707 | { |
1714 | pid_t pid; | 1708 | pid_t pid; |
1715 | int nullfd; | 1709 | int nullfd; |
1716 | int filedes[2]; | 1710 | int filedes[2]; |
1717 | 1711 | ||
1718 | if (0 != pipe(filedes)) | 1712 | if (0 != pipe (filedes)) |
1719 | { | 1713 | { |
1720 | LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "pipe"); | 1714 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "pipe"); |
1721 | return GNUNET_SYSERR; | 1715 | return GNUNET_SYSERR; |
1722 | } | 1716 | } |
1723 | pid = fork(); | 1717 | pid = fork (); |
1724 | if (pid < 0) | 1718 | if (pid < 0) |
1725 | { | 1719 | { |
1726 | LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "fork"); | 1720 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "fork"); |
1727 | return GNUNET_SYSERR; | 1721 | return GNUNET_SYSERR; |
1728 | } | 1722 | } |
1729 | if (0 != pid) | 1723 | if (0 != pid) |
1724 | { | ||
1725 | /* Parent */ | ||
1726 | char c; | ||
1727 | |||
1728 | GNUNET_break (0 == close (filedes[1])); | ||
1729 | c = 'X'; | ||
1730 | if (1 != read (filedes[0], &c, sizeof(char))) | ||
1731 | LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "read"); | ||
1732 | fflush (stdout); | ||
1733 | switch (c) | ||
1730 | { | 1734 | { |
1731 | /* Parent */ | 1735 | case '.': |
1732 | char c; | 1736 | exit (0); |
1733 | 1737 | ||
1734 | GNUNET_break(0 == close(filedes[1])); | 1738 | case 'I': |
1735 | c = 'X'; | 1739 | LOG (GNUNET_ERROR_TYPE_INFO, |
1736 | if (1 != read(filedes[0], &c, sizeof(char))) | 1740 | _ ("Service process failed to initialize\n")); |
1737 | LOG_STRERROR(GNUNET_ERROR_TYPE_WARNING, "read"); | 1741 | break; |
1738 | fflush(stdout); | 1742 | |
1739 | switch (c) | 1743 | case 'S': |
1740 | { | 1744 | LOG (GNUNET_ERROR_TYPE_INFO, |
1741 | case '.': | 1745 | _ ("Service process could not initialize server function\n")); |
1742 | exit(0); | 1746 | break; |
1743 | 1747 | ||
1744 | case 'I': | 1748 | case 'X': |
1745 | LOG(GNUNET_ERROR_TYPE_INFO, | 1749 | LOG (GNUNET_ERROR_TYPE_INFO, |
1746 | _("Service process failed to initialize\n")); | 1750 | _ ("Service process failed to report status\n")); |
1747 | break; | 1751 | 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 | } | 1752 | } |
1761 | GNUNET_break(0 == close(0)); | 1753 | exit (1); /* child reported error */ |
1762 | GNUNET_break(0 == close(1)); | 1754 | } |
1763 | GNUNET_break(0 == close(filedes[0])); | 1755 | GNUNET_break (0 == close (0)); |
1764 | nullfd = open("/dev/null", O_RDWR | O_APPEND); | 1756 | GNUNET_break (0 == close (1)); |
1757 | GNUNET_break (0 == close (filedes[0])); | ||
1758 | nullfd = open ("/dev/null", O_RDWR | O_APPEND); | ||
1765 | if (nullfd < 0) | 1759 | if (nullfd < 0) |
1766 | return GNUNET_SYSERR; | 1760 | return GNUNET_SYSERR; |
1767 | /* set stdin/stdout to /dev/null */ | 1761 | /* set stdin/stdout to /dev/null */ |
1768 | if ((dup2(nullfd, 0) < 0) || (dup2(nullfd, 1) < 0)) | 1762 | if ((dup2 (nullfd, 0) < 0) || (dup2 (nullfd, 1) < 0)) |
1769 | { | 1763 | { |
1770 | LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "dup2"); | 1764 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "dup2"); |
1771 | (void)close(nullfd); | 1765 | (void) close (nullfd); |
1772 | return GNUNET_SYSERR; | 1766 | return GNUNET_SYSERR; |
1773 | } | 1767 | } |
1774 | (void)close(nullfd); | 1768 | (void) close (nullfd); |
1775 | /* Detach from controlling terminal */ | 1769 | /* Detach from controlling terminal */ |
1776 | pid = setsid(); | 1770 | pid = setsid (); |
1777 | if (-1 == pid) | 1771 | if (-1 == pid) |
1778 | LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "setsid"); | 1772 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "setsid"); |
1779 | sh->ready_confirm_fd = filedes[1]; | 1773 | sh->ready_confirm_fd = filedes[1]; |
1780 | 1774 | ||
1781 | return GNUNET_OK; | 1775 | return GNUNET_OK; |
@@ -1789,23 +1783,23 @@ detach_terminal(struct GNUNET_SERVICE_Handle *sh) | |||
1789 | * @param sh handle to the service to tear down. | 1783 | * @param sh handle to the service to tear down. |
1790 | */ | 1784 | */ |
1791 | static void | 1785 | static void |
1792 | teardown_service(struct GNUNET_SERVICE_Handle *sh) | 1786 | teardown_service (struct GNUNET_SERVICE_Handle *sh) |
1793 | { | 1787 | { |
1794 | struct ServiceListenContext *slc; | 1788 | struct ServiceListenContext *slc; |
1795 | 1789 | ||
1796 | GNUNET_free_non_null(sh->v4_denied); | 1790 | GNUNET_free_non_null (sh->v4_denied); |
1797 | GNUNET_free_non_null(sh->v6_denied); | 1791 | GNUNET_free_non_null (sh->v6_denied); |
1798 | GNUNET_free_non_null(sh->v4_allowed); | 1792 | GNUNET_free_non_null (sh->v4_allowed); |
1799 | GNUNET_free_non_null(sh->v6_allowed); | 1793 | GNUNET_free_non_null (sh->v6_allowed); |
1800 | while (NULL != (slc = sh->slc_head)) | 1794 | while (NULL != (slc = sh->slc_head)) |
1801 | { | 1795 | { |
1802 | GNUNET_CONTAINER_DLL_remove(sh->slc_head, sh->slc_tail, slc); | 1796 | GNUNET_CONTAINER_DLL_remove (sh->slc_head, sh->slc_tail, slc); |
1803 | if (NULL != slc->listen_task) | 1797 | if (NULL != slc->listen_task) |
1804 | GNUNET_SCHEDULER_cancel(slc->listen_task); | 1798 | GNUNET_SCHEDULER_cancel (slc->listen_task); |
1805 | GNUNET_break(GNUNET_OK == | 1799 | GNUNET_break (GNUNET_OK == |
1806 | GNUNET_NETWORK_socket_close(slc->listen_socket)); | 1800 | GNUNET_NETWORK_socket_close (slc->listen_socket)); |
1807 | GNUNET_free(slc); | 1801 | GNUNET_free (slc); |
1808 | } | 1802 | } |
1809 | } | 1803 | } |
1810 | 1804 | ||
1811 | 1805 | ||
@@ -1816,7 +1810,7 @@ teardown_service(struct GNUNET_SERVICE_Handle *sh) | |||
1816 | * @param msg AGPL request | 1810 | * @param msg AGPL request |
1817 | */ | 1811 | */ |
1818 | static void | 1812 | static void |
1819 | return_agpl(void *cls, const struct GNUNET_MessageHeader *msg) | 1813 | return_agpl (void *cls, const struct GNUNET_MessageHeader *msg) |
1820 | { | 1814 | { |
1821 | struct GNUNET_SERVICE_Client *client = cls; | 1815 | struct GNUNET_SERVICE_Client *client = cls; |
1822 | struct GNUNET_MQ_Handle *mq; | 1816 | struct GNUNET_MQ_Handle *mq; |
@@ -1824,13 +1818,13 @@ return_agpl(void *cls, const struct GNUNET_MessageHeader *msg) | |||
1824 | struct GNUNET_MessageHeader *res; | 1818 | struct GNUNET_MessageHeader *res; |
1825 | size_t slen; | 1819 | size_t slen; |
1826 | 1820 | ||
1827 | (void)msg; | 1821 | (void) msg; |
1828 | slen = strlen(GNUNET_AGPL_URL) + 1; | 1822 | slen = strlen (GNUNET_AGPL_URL) + 1; |
1829 | env = GNUNET_MQ_msg_extra(res, GNUNET_MESSAGE_TYPE_RESPONSE_AGPL, slen); | 1823 | env = GNUNET_MQ_msg_extra (res, GNUNET_MESSAGE_TYPE_RESPONSE_AGPL, slen); |
1830 | memcpy(&res[1], GNUNET_AGPL_URL, slen); | 1824 | memcpy (&res[1], GNUNET_AGPL_URL, slen); |
1831 | mq = GNUNET_SERVICE_client_get_mq(client); | 1825 | mq = GNUNET_SERVICE_client_get_mq (client); |
1832 | GNUNET_MQ_send(mq, env); | 1826 | GNUNET_MQ_send (mq, env); |
1833 | GNUNET_SERVICE_client_continue(client); | 1827 | GNUNET_SERVICE_client_continue (client); |
1834 | } | 1828 | } |
1835 | 1829 | ||
1836 | 1830 | ||
@@ -1871,29 +1865,29 @@ return_agpl(void *cls, const struct GNUNET_MessageHeader *msg) | |||
1871 | * @return NULL on error | 1865 | * @return NULL on error |
1872 | */ | 1866 | */ |
1873 | struct GNUNET_SERVICE_Handle * | 1867 | struct GNUNET_SERVICE_Handle * |
1874 | GNUNET_SERVICE_start(const char *service_name, | 1868 | GNUNET_SERVICE_start (const char *service_name, |
1875 | const struct GNUNET_CONFIGURATION_Handle *cfg, | 1869 | const struct GNUNET_CONFIGURATION_Handle *cfg, |
1876 | GNUNET_SERVICE_ConnectHandler connect_cb, | 1870 | GNUNET_SERVICE_ConnectHandler connect_cb, |
1877 | GNUNET_SERVICE_DisconnectHandler disconnect_cb, | 1871 | GNUNET_SERVICE_DisconnectHandler disconnect_cb, |
1878 | void *cls, | 1872 | void *cls, |
1879 | const struct GNUNET_MQ_MessageHandler *handlers) | 1873 | const struct GNUNET_MQ_MessageHandler *handlers) |
1880 | { | 1874 | { |
1881 | struct GNUNET_SERVICE_Handle *sh; | 1875 | struct GNUNET_SERVICE_Handle *sh; |
1882 | 1876 | ||
1883 | sh = GNUNET_new(struct GNUNET_SERVICE_Handle); | 1877 | sh = GNUNET_new (struct GNUNET_SERVICE_Handle); |
1884 | sh->service_name = service_name; | 1878 | sh->service_name = service_name; |
1885 | sh->cfg = cfg; | 1879 | sh->cfg = cfg; |
1886 | sh->connect_cb = connect_cb; | 1880 | sh->connect_cb = connect_cb; |
1887 | sh->disconnect_cb = disconnect_cb; | 1881 | sh->disconnect_cb = disconnect_cb; |
1888 | sh->cb_cls = cls; | 1882 | sh->cb_cls = cls; |
1889 | sh->handlers = GNUNET_MQ_copy_handlers2(handlers, &return_agpl, NULL); | 1883 | sh->handlers = GNUNET_MQ_copy_handlers2 (handlers, &return_agpl, NULL); |
1890 | if (GNUNET_OK != setup_service(sh)) | 1884 | if (GNUNET_OK != setup_service (sh)) |
1891 | { | 1885 | { |
1892 | GNUNET_free_non_null(sh->handlers); | 1886 | GNUNET_free_non_null (sh->handlers); |
1893 | GNUNET_free(sh); | 1887 | GNUNET_free (sh); |
1894 | return NULL; | 1888 | return NULL; |
1895 | } | 1889 | } |
1896 | do_resume(sh, SUSPEND_STATE_NONE); | 1890 | do_resume (sh, SUSPEND_STATE_NONE); |
1897 | return sh; | 1891 | return sh; |
1898 | } | 1892 | } |
1899 | 1893 | ||
@@ -1904,16 +1898,16 @@ GNUNET_SERVICE_start(const char *service_name, | |||
1904 | * @param srv service to stop | 1898 | * @param srv service to stop |
1905 | */ | 1899 | */ |
1906 | void | 1900 | void |
1907 | GNUNET_SERVICE_stop(struct GNUNET_SERVICE_Handle *srv) | 1901 | GNUNET_SERVICE_stop (struct GNUNET_SERVICE_Handle *srv) |
1908 | { | 1902 | { |
1909 | struct GNUNET_SERVICE_Client *client; | 1903 | struct GNUNET_SERVICE_Client *client; |
1910 | 1904 | ||
1911 | GNUNET_SERVICE_suspend(srv); | 1905 | GNUNET_SERVICE_suspend (srv); |
1912 | while (NULL != (client = srv->clients_head)) | 1906 | while (NULL != (client = srv->clients_head)) |
1913 | GNUNET_SERVICE_client_drop(client); | 1907 | GNUNET_SERVICE_client_drop (client); |
1914 | teardown_service(srv); | 1908 | teardown_service (srv); |
1915 | GNUNET_free_non_null(srv->handlers); | 1909 | GNUNET_free_non_null (srv->handlers); |
1916 | GNUNET_free(srv); | 1910 | GNUNET_free (srv); |
1917 | } | 1911 | } |
1918 | 1912 | ||
1919 | 1913 | ||
@@ -1959,15 +1953,15 @@ GNUNET_SERVICE_stop(struct GNUNET_SERVICE_Handle *srv) | |||
1959 | * @return 0 on success, non-zero on error | 1953 | * @return 0 on success, non-zero on error |
1960 | */ | 1954 | */ |
1961 | int | 1955 | int |
1962 | GNUNET_SERVICE_run_(int argc, | 1956 | GNUNET_SERVICE_run_ (int argc, |
1963 | char *const *argv, | 1957 | char *const *argv, |
1964 | const char *service_name, | 1958 | const char *service_name, |
1965 | enum GNUNET_SERVICE_Options options, | 1959 | enum GNUNET_SERVICE_Options options, |
1966 | GNUNET_SERVICE_InitCallback service_init_cb, | 1960 | GNUNET_SERVICE_InitCallback service_init_cb, |
1967 | GNUNET_SERVICE_ConnectHandler connect_cb, | 1961 | GNUNET_SERVICE_ConnectHandler connect_cb, |
1968 | GNUNET_SERVICE_DisconnectHandler disconnect_cb, | 1962 | GNUNET_SERVICE_DisconnectHandler disconnect_cb, |
1969 | void *cls, | 1963 | void *cls, |
1970 | const struct GNUNET_MQ_MessageHandler *handlers) | 1964 | const struct GNUNET_MQ_MessageHandler *handlers) |
1971 | { | 1965 | { |
1972 | struct GNUNET_SERVICE_Handle sh; | 1966 | struct GNUNET_SERVICE_Handle sh; |
1973 | 1967 | ||
@@ -1986,40 +1980,40 @@ GNUNET_SERVICE_run_(int argc, | |||
1986 | struct GNUNET_CONFIGURATION_Handle *cfg; | 1980 | struct GNUNET_CONFIGURATION_Handle *cfg; |
1987 | int ret; | 1981 | int ret; |
1988 | int err; | 1982 | int err; |
1989 | const struct GNUNET_OS_ProjectData *pd = GNUNET_OS_project_data_get(); | 1983 | const struct GNUNET_OS_ProjectData *pd = GNUNET_OS_project_data_get (); |
1990 | 1984 | ||
1991 | struct GNUNET_GETOPT_CommandLineOption service_options[] = | 1985 | struct GNUNET_GETOPT_CommandLineOption service_options[] = |
1992 | { GNUNET_GETOPT_option_cfgfile(&opt_cfg_filename), | 1986 | { GNUNET_GETOPT_option_cfgfile (&opt_cfg_filename), |
1993 | GNUNET_GETOPT_option_flag('d', | 1987 | GNUNET_GETOPT_option_flag ('d', |
1994 | "daemonize", | 1988 | "daemonize", |
1995 | gettext_noop( | 1989 | gettext_noop ( |
1996 | "do daemonize (detach from terminal)"), | 1990 | "do daemonize (detach from terminal)"), |
1997 | &do_daemonize), | 1991 | &do_daemonize), |
1998 | GNUNET_GETOPT_option_help(NULL), | 1992 | GNUNET_GETOPT_option_help (NULL), |
1999 | GNUNET_GETOPT_option_loglevel(&loglev), | 1993 | GNUNET_GETOPT_option_loglevel (&loglev), |
2000 | GNUNET_GETOPT_option_logfile(&logfile), | 1994 | GNUNET_GETOPT_option_logfile (&logfile), |
2001 | GNUNET_GETOPT_option_version(pd->version), | 1995 | GNUNET_GETOPT_option_version (pd->version), |
2002 | GNUNET_GETOPT_OPTION_END }; | 1996 | GNUNET_GETOPT_OPTION_END }; |
2003 | 1997 | ||
2004 | err = 1; | 1998 | err = 1; |
2005 | memset(&sh, 0, sizeof(sh)); | 1999 | memset (&sh, 0, sizeof(sh)); |
2006 | xdg = getenv("XDG_CONFIG_HOME"); | 2000 | xdg = getenv ("XDG_CONFIG_HOME"); |
2007 | if (NULL != xdg) | 2001 | if (NULL != xdg) |
2008 | GNUNET_asprintf(&cfg_filename, | 2002 | GNUNET_asprintf (&cfg_filename, |
2009 | "%s%s%s", | 2003 | "%s%s%s", |
2010 | xdg, | 2004 | xdg, |
2011 | DIR_SEPARATOR_STR, | 2005 | DIR_SEPARATOR_STR, |
2012 | pd->config_file); | 2006 | pd->config_file); |
2013 | else | 2007 | else |
2014 | cfg_filename = GNUNET_strdup(pd->user_config_file); | 2008 | cfg_filename = GNUNET_strdup (pd->user_config_file); |
2015 | sh.ready_confirm_fd = -1; | 2009 | sh.ready_confirm_fd = -1; |
2016 | sh.options = options; | 2010 | sh.options = options; |
2017 | sh.cfg = cfg = GNUNET_CONFIGURATION_create(); | 2011 | sh.cfg = cfg = GNUNET_CONFIGURATION_create (); |
2018 | sh.service_init_cb = service_init_cb; | 2012 | sh.service_init_cb = service_init_cb; |
2019 | sh.connect_cb = connect_cb; | 2013 | sh.connect_cb = connect_cb; |
2020 | sh.disconnect_cb = disconnect_cb; | 2014 | sh.disconnect_cb = disconnect_cb; |
2021 | sh.cb_cls = cls; | 2015 | sh.cb_cls = cls; |
2022 | sh.handlers = GNUNET_MQ_copy_handlers(handlers); | 2016 | sh.handlers = GNUNET_MQ_copy_handlers (handlers); |
2023 | sh.service_name = service_name; | 2017 | sh.service_name = service_name; |
2024 | sh.ret = 0; | 2018 | sh.ret = 0; |
2025 | /* setup subsystems */ | 2019 | /* setup subsystems */ |
@@ -2029,135 +2023,135 @@ GNUNET_SERVICE_run_(int argc, | |||
2029 | do_daemonize = 0; | 2023 | do_daemonize = 0; |
2030 | #if ENABLE_NLS | 2024 | #if ENABLE_NLS |
2031 | if (NULL != pd->gettext_domain) | 2025 | if (NULL != pd->gettext_domain) |
2026 | { | ||
2027 | setlocale (LC_ALL, ""); | ||
2028 | path = (NULL == pd->gettext_path) ? | ||
2029 | GNUNET_OS_installation_get_path (GNUNET_OS_IPK_LOCALEDIR) : | ||
2030 | GNUNET_strdup (pd->gettext_path); | ||
2031 | if (NULL != path) | ||
2032 | { | 2032 | { |
2033 | setlocale(LC_ALL, ""); | 2033 | bindtextdomain (pd->gettext_domain, path); |
2034 | path = (NULL == pd->gettext_path) ? | 2034 | 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 | } | 2035 | } |
2036 | textdomain (pd->gettext_domain); | ||
2037 | } | ||
2044 | #endif | 2038 | #endif |
2045 | ret = GNUNET_GETOPT_run(service_name, service_options, argc, argv); | 2039 | ret = GNUNET_GETOPT_run (service_name, service_options, argc, argv); |
2046 | if (GNUNET_SYSERR == ret) | 2040 | if (GNUNET_SYSERR == ret) |
2047 | goto shutdown; | 2041 | goto shutdown; |
2048 | if (GNUNET_NO == ret) | 2042 | if (GNUNET_NO == ret) |
2049 | { | 2043 | { |
2050 | err = 0; | 2044 | err = 0; |
2051 | goto shutdown; | 2045 | goto shutdown; |
2052 | } | 2046 | } |
2053 | if (GNUNET_OK != GNUNET_log_setup(service_name, loglev, logfile)) | 2047 | if (GNUNET_OK != GNUNET_log_setup (service_name, loglev, logfile)) |
2054 | { | 2048 | { |
2055 | GNUNET_break(0); | 2049 | GNUNET_break (0); |
2056 | goto shutdown; | 2050 | goto shutdown; |
2057 | } | 2051 | } |
2058 | if (NULL != opt_cfg_filename) | 2052 | if (NULL != opt_cfg_filename) |
2053 | { | ||
2054 | if ((GNUNET_YES != GNUNET_DISK_file_test (opt_cfg_filename)) || | ||
2055 | (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, opt_cfg_filename))) | ||
2059 | { | 2056 | { |
2060 | if ((GNUNET_YES != GNUNET_DISK_file_test(opt_cfg_filename)) || | 2057 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
2061 | (GNUNET_SYSERR == GNUNET_CONFIGURATION_load(cfg, opt_cfg_filename))) | 2058 | _ ("Malformed configuration file `%s', exit ...\n"), |
2062 | { | 2059 | opt_cfg_filename); |
2063 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | 2060 | goto shutdown; |
2064 | _("Malformed configuration file `%s', exit ...\n"), | ||
2065 | opt_cfg_filename); | ||
2066 | goto shutdown; | ||
2067 | } | ||
2068 | } | 2061 | } |
2062 | } | ||
2069 | else | 2063 | else |
2064 | { | ||
2065 | if (GNUNET_YES == GNUNET_DISK_file_test (cfg_filename)) | ||
2070 | { | 2066 | { |
2071 | if (GNUNET_YES == GNUNET_DISK_file_test(cfg_filename)) | 2067 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, cfg_filename)) |
2072 | { | 2068 | { |
2073 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load(cfg, cfg_filename)) | 2069 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
2074 | { | 2070 | _ ("Malformed configuration file `%s', exit ...\n"), |
2075 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | 2071 | cfg_filename); |
2076 | _("Malformed configuration file `%s', exit ...\n"), | 2072 | goto shutdown; |
2077 | cfg_filename); | 2073 | } |
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 | } | 2074 | } |
2091 | if (GNUNET_OK != setup_service(&sh)) | 2075 | else |
2092 | goto shutdown; | ||
2093 | if ((1 == do_daemonize) && (GNUNET_OK != detach_terminal(&sh))) | ||
2094 | { | 2076 | { |
2095 | GNUNET_break(0); | 2077 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, NULL)) |
2096 | goto shutdown; | 2078 | { |
2079 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
2080 | _ ("Malformed configuration, exit ...\n")); | ||
2081 | goto shutdown; | ||
2082 | } | ||
2097 | } | 2083 | } |
2098 | if (GNUNET_OK != set_user_id(&sh)) | 2084 | } |
2085 | if (GNUNET_OK != setup_service (&sh)) | ||
2099 | goto shutdown; | 2086 | goto shutdown; |
2100 | LOG(GNUNET_ERROR_TYPE_DEBUG, | 2087 | if ((1 == do_daemonize) && (GNUNET_OK != detach_terminal (&sh))) |
2101 | "Service `%s' runs with configuration from `%s'\n", | 2088 | { |
2102 | service_name, | 2089 | GNUNET_break (0); |
2103 | (NULL != opt_cfg_filename) ? opt_cfg_filename : cfg_filename); | 2090 | goto shutdown; |
2104 | if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_number(sh.cfg, | 2091 | } |
2105 | "TESTING", | 2092 | if (GNUNET_OK != set_user_id (&sh)) |
2106 | "SKEW_OFFSET", | 2093 | goto shutdown; |
2107 | &skew_offset)) && | 2094 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
2108 | (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number(sh.cfg, | 2095 | "Service `%s' runs with configuration from `%s'\n", |
2109 | "TESTING", | 2096 | service_name, |
2110 | "SKEW_VARIANCE", | 2097 | (NULL != opt_cfg_filename) ? opt_cfg_filename : cfg_filename); |
2111 | &skew_variance))) | 2098 | if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (sh.cfg, |
2112 | { | 2099 | "TESTING", |
2113 | clock_offset = skew_offset - skew_variance; | 2100 | "SKEW_OFFSET", |
2114 | GNUNET_TIME_set_offset(clock_offset); | 2101 | &skew_offset)) && |
2115 | LOG(GNUNET_ERROR_TYPE_DEBUG, "Skewing clock by %dll ms\n", clock_offset); | 2102 | (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (sh.cfg, |
2116 | } | 2103 | "TESTING", |
2117 | GNUNET_RESOLVER_connect(sh.cfg); | 2104 | "SKEW_VARIANCE", |
2105 | &skew_variance))) | ||
2106 | { | ||
2107 | clock_offset = skew_offset - skew_variance; | ||
2108 | GNUNET_TIME_set_offset (clock_offset); | ||
2109 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Skewing clock by %dll ms\n", clock_offset); | ||
2110 | } | ||
2111 | GNUNET_RESOLVER_connect (sh.cfg); | ||
2118 | 2112 | ||
2119 | /* actually run service */ | 2113 | /* actually run service */ |
2120 | err = 0; | 2114 | err = 0; |
2121 | GNUNET_SCHEDULER_run(&service_main, &sh); | 2115 | GNUNET_SCHEDULER_run (&service_main, &sh); |
2122 | /* shutdown */ | 2116 | /* shutdown */ |
2123 | if (1 == do_daemonize) | 2117 | if (1 == do_daemonize) |
2124 | pid_file_delete(&sh); | 2118 | pid_file_delete (&sh); |
2125 | 2119 | ||
2126 | shutdown: | 2120 | shutdown: |
2127 | if (-1 != sh.ready_confirm_fd) | 2121 | if (-1 != sh.ready_confirm_fd) |
2128 | { | 2122 | { |
2129 | if (1 != write(sh.ready_confirm_fd, err ? "I" : "S", 1)) | 2123 | if (1 != write (sh.ready_confirm_fd, err ? "I" : "S", 1)) |
2130 | LOG_STRERROR(GNUNET_ERROR_TYPE_WARNING, "write"); | 2124 | LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "write"); |
2131 | GNUNET_break(0 == close(sh.ready_confirm_fd)); | 2125 | GNUNET_break (0 == close (sh.ready_confirm_fd)); |
2132 | } | 2126 | } |
2133 | #if HAVE_MALLINFO | 2127 | #if HAVE_MALLINFO |
2134 | { | 2128 | { |
2135 | char *counter; | 2129 | char *counter; |
2136 | 2130 | ||
2137 | if ((GNUNET_YES == GNUNET_CONFIGURATION_have_value(sh.cfg, | 2131 | if ((GNUNET_YES == GNUNET_CONFIGURATION_have_value (sh.cfg, |
2138 | service_name, | 2132 | service_name, |
2139 | "GAUGER_HEAP")) && | 2133 | "GAUGER_HEAP")) && |
2140 | (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(sh.cfg, | 2134 | (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (sh.cfg, |
2141 | service_name, | 2135 | service_name, |
2142 | "GAUGER_HEAP", | 2136 | "GAUGER_HEAP", |
2143 | &counter))) | 2137 | &counter))) |
2144 | { | 2138 | { |
2145 | struct mallinfo mi; | 2139 | struct mallinfo mi; |
2146 | 2140 | ||
2147 | mi = mallinfo(); | 2141 | mi = mallinfo (); |
2148 | GAUGER(service_name, counter, mi.usmblks, "blocks"); | 2142 | GAUGER (service_name, counter, mi.usmblks, "blocks"); |
2149 | GNUNET_free(counter); | 2143 | GNUNET_free (counter); |
2150 | } | 2144 | } |
2151 | } | 2145 | } |
2152 | #endif | 2146 | #endif |
2153 | teardown_service(&sh); | 2147 | teardown_service (&sh); |
2154 | GNUNET_free_non_null(sh.handlers); | 2148 | GNUNET_free_non_null (sh.handlers); |
2155 | GNUNET_SPEEDUP_stop_(); | 2149 | GNUNET_SPEEDUP_stop_ (); |
2156 | GNUNET_CONFIGURATION_destroy(cfg); | 2150 | GNUNET_CONFIGURATION_destroy (cfg); |
2157 | GNUNET_free_non_null(logfile); | 2151 | GNUNET_free_non_null (logfile); |
2158 | GNUNET_free_non_null(loglev); | 2152 | GNUNET_free_non_null (loglev); |
2159 | GNUNET_free(cfg_filename); | 2153 | GNUNET_free (cfg_filename); |
2160 | GNUNET_free_non_null(opt_cfg_filename); | 2154 | GNUNET_free_non_null (opt_cfg_filename); |
2161 | 2155 | ||
2162 | return err ? GNUNET_SYSERR : sh.ret; | 2156 | return err ? GNUNET_SYSERR : sh.ret; |
2163 | } | 2157 | } |
@@ -2170,9 +2164,9 @@ shutdown: | |||
2170 | * @param sh service to stop accepting connections. | 2164 | * @param sh service to stop accepting connections. |
2171 | */ | 2165 | */ |
2172 | void | 2166 | void |
2173 | GNUNET_SERVICE_suspend(struct GNUNET_SERVICE_Handle *sh) | 2167 | GNUNET_SERVICE_suspend (struct GNUNET_SERVICE_Handle *sh) |
2174 | { | 2168 | { |
2175 | do_suspend(sh, SUSPEND_STATE_APP); | 2169 | do_suspend (sh, SUSPEND_STATE_APP); |
2176 | } | 2170 | } |
2177 | 2171 | ||
2178 | 2172 | ||
@@ -2182,9 +2176,9 @@ GNUNET_SERVICE_suspend(struct GNUNET_SERVICE_Handle *sh) | |||
2182 | * @param sh service to resume accepting connections. | 2176 | * @param sh service to resume accepting connections. |
2183 | */ | 2177 | */ |
2184 | void | 2178 | void |
2185 | GNUNET_SERVICE_resume(struct GNUNET_SERVICE_Handle *sh) | 2179 | GNUNET_SERVICE_resume (struct GNUNET_SERVICE_Handle *sh) |
2186 | { | 2180 | { |
2187 | do_resume(sh, SUSPEND_STATE_APP); | 2181 | do_resume (sh, SUSPEND_STATE_APP); |
2188 | } | 2182 | } |
2189 | 2183 | ||
2190 | 2184 | ||
@@ -2195,32 +2189,32 @@ GNUNET_SERVICE_resume(struct GNUNET_SERVICE_Handle *sh) | |||
2195 | * @param cls our `struct GNUNET_SERVICE_Client` | 2189 | * @param cls our `struct GNUNET_SERVICE_Client` |
2196 | */ | 2190 | */ |
2197 | static void | 2191 | static void |
2198 | resume_client_receive(void *cls) | 2192 | resume_client_receive (void *cls) |
2199 | { | 2193 | { |
2200 | struct GNUNET_SERVICE_Client *c = cls; | 2194 | struct GNUNET_SERVICE_Client *c = cls; |
2201 | int ret; | 2195 | int ret; |
2202 | 2196 | ||
2203 | c->recv_task = NULL; | 2197 | c->recv_task = NULL; |
2204 | /* first, check if there is still something in the buffer */ | 2198 | /* first, check if there is still something in the buffer */ |
2205 | ret = GNUNET_MST_next(c->mst, GNUNET_YES); | 2199 | ret = GNUNET_MST_next (c->mst, GNUNET_YES); |
2206 | if (GNUNET_SYSERR == ret) | 2200 | if (GNUNET_SYSERR == ret) |
2207 | { | 2201 | { |
2208 | if (NULL == c->drop_task) | 2202 | if (NULL == c->drop_task) |
2209 | GNUNET_SERVICE_client_drop(c); | 2203 | GNUNET_SERVICE_client_drop (c); |
2210 | return; | 2204 | return; |
2211 | } | 2205 | } |
2212 | if (GNUNET_NO == ret) | 2206 | if (GNUNET_NO == ret) |
2213 | return; /* done processing, wait for more later */ | 2207 | return; /* done processing, wait for more later */ |
2214 | GNUNET_assert(GNUNET_OK == ret); | 2208 | GNUNET_assert (GNUNET_OK == ret); |
2215 | if (GNUNET_YES == c->needs_continue) | 2209 | if (GNUNET_YES == c->needs_continue) |
2216 | return; /* #GNUNET_MST_next() did give a message to the client */ | 2210 | return; /* #GNUNET_MST_next() did give a message to the client */ |
2217 | /* need to receive more data from the network first */ | 2211 | /* need to receive more data from the network first */ |
2218 | if (NULL != c->recv_task) | 2212 | if (NULL != c->recv_task) |
2219 | return; | 2213 | return; |
2220 | c->recv_task = GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, | 2214 | c->recv_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, |
2221 | c->sock, | 2215 | c->sock, |
2222 | &service_client_recv, | 2216 | &service_client_recv, |
2223 | c); | 2217 | c); |
2224 | } | 2218 | } |
2225 | 2219 | ||
2226 | 2220 | ||
@@ -2231,18 +2225,18 @@ resume_client_receive(void *cls) | |||
2231 | * @param c the client to continue receiving from | 2225 | * @param c the client to continue receiving from |
2232 | */ | 2226 | */ |
2233 | void | 2227 | void |
2234 | GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c) | 2228 | GNUNET_SERVICE_client_continue (struct GNUNET_SERVICE_Client *c) |
2235 | { | 2229 | { |
2236 | GNUNET_assert(NULL == c->drop_task); | 2230 | GNUNET_assert (NULL == c->drop_task); |
2237 | GNUNET_assert(GNUNET_YES == c->needs_continue); | 2231 | GNUNET_assert (GNUNET_YES == c->needs_continue); |
2238 | GNUNET_assert(NULL == c->recv_task); | 2232 | GNUNET_assert (NULL == c->recv_task); |
2239 | c->needs_continue = GNUNET_NO; | 2233 | c->needs_continue = GNUNET_NO; |
2240 | if (NULL != c->warn_task) | 2234 | if (NULL != c->warn_task) |
2241 | { | 2235 | { |
2242 | GNUNET_SCHEDULER_cancel(c->warn_task); | 2236 | GNUNET_SCHEDULER_cancel (c->warn_task); |
2243 | c->warn_task = NULL; | 2237 | c->warn_task = NULL; |
2244 | } | 2238 | } |
2245 | c->recv_task = GNUNET_SCHEDULER_add_now(&resume_client_receive, c); | 2239 | c->recv_task = GNUNET_SCHEDULER_add_now (&resume_client_receive, c); |
2246 | } | 2240 | } |
2247 | 2241 | ||
2248 | 2242 | ||
@@ -2255,14 +2249,14 @@ GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c) | |||
2255 | * @param c client for which to disable the warning | 2249 | * @param c client for which to disable the warning |
2256 | */ | 2250 | */ |
2257 | void | 2251 | void |
2258 | GNUNET_SERVICE_client_disable_continue_warning(struct GNUNET_SERVICE_Client *c) | 2252 | GNUNET_SERVICE_client_disable_continue_warning (struct GNUNET_SERVICE_Client *c) |
2259 | { | 2253 | { |
2260 | GNUNET_break(NULL != c->warn_task); | 2254 | GNUNET_break (NULL != c->warn_task); |
2261 | if (NULL != c->warn_task) | 2255 | if (NULL != c->warn_task) |
2262 | { | 2256 | { |
2263 | GNUNET_SCHEDULER_cancel(c->warn_task); | 2257 | GNUNET_SCHEDULER_cancel (c->warn_task); |
2264 | c->warn_task = NULL; | 2258 | c->warn_task = NULL; |
2265 | } | 2259 | } |
2266 | } | 2260 | } |
2267 | 2261 | ||
2268 | 2262 | ||
@@ -2272,32 +2266,32 @@ GNUNET_SERVICE_client_disable_continue_warning(struct GNUNET_SERVICE_Client *c) | |||
2272 | * @param cls the `struct GNUNET_SERVICE_Client`. | 2266 | * @param cls the `struct GNUNET_SERVICE_Client`. |
2273 | */ | 2267 | */ |
2274 | static void | 2268 | static void |
2275 | finish_client_drop(void *cls) | 2269 | finish_client_drop (void *cls) |
2276 | { | 2270 | { |
2277 | struct GNUNET_SERVICE_Client *c = cls; | 2271 | struct GNUNET_SERVICE_Client *c = cls; |
2278 | struct GNUNET_SERVICE_Handle *sh = c->sh; | 2272 | struct GNUNET_SERVICE_Handle *sh = c->sh; |
2279 | 2273 | ||
2280 | c->drop_task = NULL; | 2274 | c->drop_task = NULL; |
2281 | GNUNET_assert(NULL == c->send_task); | 2275 | GNUNET_assert (NULL == c->send_task); |
2282 | GNUNET_assert(NULL == c->recv_task); | 2276 | GNUNET_assert (NULL == c->recv_task); |
2283 | GNUNET_assert(NULL == c->warn_task); | 2277 | GNUNET_assert (NULL == c->warn_task); |
2284 | GNUNET_MST_destroy(c->mst); | 2278 | GNUNET_MST_destroy (c->mst); |
2285 | GNUNET_MQ_destroy(c->mq); | 2279 | GNUNET_MQ_destroy (c->mq); |
2286 | if (GNUNET_NO == c->persist) | 2280 | if (GNUNET_NO == c->persist) |
2287 | { | 2281 | { |
2288 | GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(c->sock)); | 2282 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (c->sock)); |
2289 | if ((0 != (SUSPEND_STATE_EMFILE & sh->suspend_state)) && | 2283 | if ((0 != (SUSPEND_STATE_EMFILE & sh->suspend_state)) && |
2290 | (0 == (SUSPEND_STATE_SHUTDOWN & sh->suspend_state))) | 2284 | (0 == (SUSPEND_STATE_SHUTDOWN & sh->suspend_state))) |
2291 | do_resume(sh, SUSPEND_STATE_EMFILE); | 2285 | do_resume (sh, SUSPEND_STATE_EMFILE); |
2292 | } | 2286 | } |
2293 | else | 2287 | else |
2294 | { | 2288 | { |
2295 | GNUNET_NETWORK_socket_free_memory_only_(c->sock); | 2289 | GNUNET_NETWORK_socket_free_memory_only_ (c->sock); |
2296 | } | 2290 | } |
2297 | GNUNET_free(c); | 2291 | GNUNET_free (c); |
2298 | if ((0 != (SUSPEND_STATE_SHUTDOWN & sh->suspend_state)) && | 2292 | if ((0 != (SUSPEND_STATE_SHUTDOWN & sh->suspend_state)) && |
2299 | (GNUNET_NO == have_non_monitor_clients(sh))) | 2293 | (GNUNET_NO == have_non_monitor_clients (sh))) |
2300 | GNUNET_SERVICE_shutdown(sh); | 2294 | GNUNET_SERVICE_shutdown (sh); |
2301 | } | 2295 | } |
2302 | 2296 | ||
2303 | 2297 | ||
@@ -2312,52 +2306,56 @@ finish_client_drop(void *cls) | |||
2312 | * @param c client to disconnect now | 2306 | * @param c client to disconnect now |
2313 | */ | 2307 | */ |
2314 | void | 2308 | void |
2315 | GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c) | 2309 | GNUNET_SERVICE_client_drop (struct GNUNET_SERVICE_Client *c) |
2316 | { | 2310 | { |
2317 | struct GNUNET_SERVICE_Handle *sh = c->sh; | 2311 | struct GNUNET_SERVICE_Handle *sh = c->sh; |
2318 | 2312 | ||
2319 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | 2313 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2320 | "Client dropped: %p (MQ: %p)\n", | 2314 | "Client dropped: %p (MQ: %p)\n", |
2321 | c, | 2315 | c, |
2322 | c->mq); | 2316 | c->mq); |
2323 | #if EXECINFO | 2317 | #if EXECINFO |
2324 | { | 2318 | { |
2325 | void *backtrace_array[MAX_TRACE_DEPTH]; | 2319 | void *backtrace_array[MAX_TRACE_DEPTH]; |
2326 | int num_backtrace_strings = backtrace(backtrace_array, MAX_TRACE_DEPTH); | 2320 | int num_backtrace_strings = backtrace (backtrace_array, MAX_TRACE_DEPTH); |
2327 | char **backtrace_strings = | 2321 | char **backtrace_strings = |
2328 | backtrace_symbols(backtrace_array, t->num_backtrace_strings); | 2322 | backtrace_symbols (backtrace_array, t->num_backtrace_strings); |
2329 | for (unsigned int i = 0; i < num_backtrace_strings; i++) | 2323 | for (unsigned int i = 0; i < num_backtrace_strings; i++) |
2330 | LOG(GNUNET_ERROR_TYPE_DEBUG, | 2324 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
2331 | "client drop trace %u: %s\n", | 2325 | "client drop trace %u: %s\n", |
2332 | i, | 2326 | i, |
2333 | backtrace_strings[i]); | 2327 | backtrace_strings[i]); |
2334 | } | 2328 | } |
2335 | #endif | 2329 | #endif |
2336 | if (NULL != c->drop_task) | 2330 | if (NULL != c->drop_task) |
2337 | { | 2331 | { |
2338 | /* asked to drop twice! */ | 2332 | /* asked to drop twice! */ |
2339 | GNUNET_assert(0); | 2333 | GNUNET_assert (0); |
2340 | return; | 2334 | return; |
2341 | } | 2335 | } |
2342 | GNUNET_CONTAINER_DLL_remove(sh->clients_head, sh->clients_tail, c); | 2336 | GNUNET_CONTAINER_DLL_remove (sh->clients_head, |
2337 | sh->clients_tail, | ||
2338 | c); | ||
2343 | if (NULL != sh->disconnect_cb) | 2339 | if (NULL != sh->disconnect_cb) |
2344 | sh->disconnect_cb(sh->cb_cls, c, c->user_context); | 2340 | sh->disconnect_cb (sh->cb_cls, |
2341 | c, | ||
2342 | c->user_context); | ||
2345 | if (NULL != c->warn_task) | 2343 | if (NULL != c->warn_task) |
2346 | { | 2344 | { |
2347 | GNUNET_SCHEDULER_cancel(c->warn_task); | 2345 | GNUNET_SCHEDULER_cancel (c->warn_task); |
2348 | c->warn_task = NULL; | 2346 | c->warn_task = NULL; |
2349 | } | 2347 | } |
2350 | if (NULL != c->recv_task) | 2348 | if (NULL != c->recv_task) |
2351 | { | 2349 | { |
2352 | GNUNET_SCHEDULER_cancel(c->recv_task); | 2350 | GNUNET_SCHEDULER_cancel (c->recv_task); |
2353 | c->recv_task = NULL; | 2351 | c->recv_task = NULL; |
2354 | } | 2352 | } |
2355 | if (NULL != c->send_task) | 2353 | if (NULL != c->send_task) |
2356 | { | 2354 | { |
2357 | GNUNET_SCHEDULER_cancel(c->send_task); | 2355 | GNUNET_SCHEDULER_cancel (c->send_task); |
2358 | c->send_task = NULL; | 2356 | c->send_task = NULL; |
2359 | } | 2357 | } |
2360 | c->drop_task = GNUNET_SCHEDULER_add_now(&finish_client_drop, c); | 2358 | c->drop_task = GNUNET_SCHEDULER_add_now (&finish_client_drop, c); |
2361 | } | 2359 | } |
2362 | 2360 | ||
2363 | 2361 | ||
@@ -2367,14 +2365,14 @@ GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c) | |||
2367 | * @param sh server to shutdown | 2365 | * @param sh server to shutdown |
2368 | */ | 2366 | */ |
2369 | void | 2367 | void |
2370 | GNUNET_SERVICE_shutdown(struct GNUNET_SERVICE_Handle *sh) | 2368 | GNUNET_SERVICE_shutdown (struct GNUNET_SERVICE_Handle *sh) |
2371 | { | 2369 | { |
2372 | struct GNUNET_SERVICE_Client *client; | 2370 | struct GNUNET_SERVICE_Client *client; |
2373 | 2371 | ||
2374 | if (0 == (sh->suspend_state & SUSPEND_STATE_SHUTDOWN)) | 2372 | if (0 == (sh->suspend_state & SUSPEND_STATE_SHUTDOWN)) |
2375 | do_suspend(sh, SUSPEND_STATE_SHUTDOWN); | 2373 | do_suspend (sh, SUSPEND_STATE_SHUTDOWN); |
2376 | while (NULL != (client = sh->clients_head)) | 2374 | while (NULL != (client = sh->clients_head)) |
2377 | GNUNET_SERVICE_client_drop(client); | 2375 | GNUNET_SERVICE_client_drop (client); |
2378 | } | 2376 | } |
2379 | 2377 | ||
2380 | 2378 | ||
@@ -2391,12 +2389,12 @@ GNUNET_SERVICE_shutdown(struct GNUNET_SERVICE_Handle *sh) | |||
2391 | * @param c client to mark as a monitor | 2389 | * @param c client to mark as a monitor |
2392 | */ | 2390 | */ |
2393 | void | 2391 | void |
2394 | GNUNET_SERVICE_client_mark_monitor(struct GNUNET_SERVICE_Client *c) | 2392 | GNUNET_SERVICE_client_mark_monitor (struct GNUNET_SERVICE_Client *c) |
2395 | { | 2393 | { |
2396 | c->is_monitor = GNUNET_YES; | 2394 | c->is_monitor = GNUNET_YES; |
2397 | if (((0 != (SUSPEND_STATE_SHUTDOWN & c->sh->suspend_state)) && | 2395 | if (((0 != (SUSPEND_STATE_SHUTDOWN & c->sh->suspend_state)) && |
2398 | (GNUNET_NO == have_non_monitor_clients(c->sh)))) | 2396 | (GNUNET_NO == have_non_monitor_clients (c->sh)))) |
2399 | GNUNET_SERVICE_shutdown(c->sh); | 2397 | GNUNET_SERVICE_shutdown (c->sh); |
2400 | } | 2398 | } |
2401 | 2399 | ||
2402 | 2400 | ||
@@ -2408,7 +2406,7 @@ GNUNET_SERVICE_client_mark_monitor(struct GNUNET_SERVICE_Client *c) | |||
2408 | * @param c client to persist the socket (never to be closed) | 2406 | * @param c client to persist the socket (never to be closed) |
2409 | */ | 2407 | */ |
2410 | void | 2408 | void |
2411 | GNUNET_SERVICE_client_persist(struct GNUNET_SERVICE_Client *c) | 2409 | GNUNET_SERVICE_client_persist (struct GNUNET_SERVICE_Client *c) |
2412 | { | 2410 | { |
2413 | c->persist = GNUNET_YES; | 2411 | c->persist = GNUNET_YES; |
2414 | } | 2412 | } |
@@ -2421,10 +2419,10 @@ GNUNET_SERVICE_client_persist(struct GNUNET_SERVICE_Client *c) | |||
2421 | * @return the message queue of @a c | 2419 | * @return the message queue of @a c |
2422 | */ | 2420 | */ |
2423 | struct GNUNET_MQ_Handle * | 2421 | struct GNUNET_MQ_Handle * |
2424 | GNUNET_SERVICE_client_get_mq(struct GNUNET_SERVICE_Client *c) | 2422 | GNUNET_SERVICE_client_get_mq (struct GNUNET_SERVICE_Client *c) |
2425 | { | 2423 | { |
2426 | return c->mq; | 2424 | return c->mq; |
2427 | } | 2425 | } |
2428 | 2426 | ||
2429 | 2427 | ||
2430 | /* end of service_new.c */ | 2428 | /* end of service.c */ |