diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-09-17 10:45:23 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-09-17 10:45:23 +0000 |
commit | 7e065c18499688141eb68513058131a49344cac1 (patch) | |
tree | e441b44c8f0db8a4f214775e4945039cc820cf2f /src/util | |
parent | b3ad920b6e0107c3da946fe1f2f720955dbac151 (diff) | |
download | gnunet-7e065c18499688141eb68513058131a49344cac1.tar.gz gnunet-7e065c18499688141eb68513058131a49344cac1.zip |
Diffstat (limited to 'src/util')
-rw-r--r-- | src/util/crypto_random.c | 37 | ||||
-rw-r--r-- | src/util/crypto_rsa.c | 46 | ||||
-rw-r--r-- | src/util/gnunet-rsa.c | 10 | ||||
-rw-r--r-- | src/util/server.c | 95 |
4 files changed, 136 insertions, 52 deletions
diff --git a/src/util/crypto_random.c b/src/util/crypto_random.c index dbf71d78a..8dce1080c 100644 --- a/src/util/crypto_random.c +++ b/src/util/crypto_random.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | (C) 2001, 2002, 2003, 2004, 2005, 2006 Christian Grothoff (and other contributing authors) | 3 | (C) 2001, 2002, 2003, 2004, 2005, 2006, 2012 Christian Grothoff (and other contributing authors) |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -34,6 +34,14 @@ | |||
34 | 34 | ||
35 | #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util", syscall) | 35 | #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util", syscall) |
36 | 36 | ||
37 | |||
38 | /** | ||
39 | * GNUNET_YES if we are using a 'weak' (low-entropy) PRNG. | ||
40 | */ | ||
41 | static int weak_random; | ||
42 | |||
43 | |||
44 | |||
37 | /* TODO: ndurner, move this to plibc? */ | 45 | /* TODO: ndurner, move this to plibc? */ |
38 | /* The code is derived from glibc, obviously */ | 46 | /* The code is derived from glibc, obviously */ |
39 | #if MINGW | 47 | #if MINGW |
@@ -49,14 +57,18 @@ | |||
49 | #undef RAND_MAX | 57 | #undef RAND_MAX |
50 | #endif | 58 | #endif |
51 | #define RAND_MAX 0x7fffffff /* Hopefully this is correct */ | 59 | #define RAND_MAX 0x7fffffff /* Hopefully this is correct */ |
60 | |||
61 | |||
52 | static int32_t glibc_weak_rand32_state = 1; | 62 | static int32_t glibc_weak_rand32_state = 1; |
53 | 63 | ||
64 | |||
54 | void | 65 | void |
55 | glibc_weak_srand32 (int32_t s) | 66 | glibc_weak_srand32 (int32_t s) |
56 | { | 67 | { |
57 | glibc_weak_rand32_state = s; | 68 | glibc_weak_rand32_state = s; |
58 | } | 69 | } |
59 | 70 | ||
71 | |||
60 | int32_t | 72 | int32_t |
61 | glibc_weak_rand32 () | 73 | glibc_weak_rand32 () |
62 | { | 74 | { |
@@ -74,11 +86,12 @@ glibc_weak_rand32 () | |||
74 | * @return number between 0 and 1. | 86 | * @return number between 0 and 1. |
75 | */ | 87 | */ |
76 | static double | 88 | static double |
77 | weak_random () | 89 | get_weak_random () |
78 | { | 90 | { |
79 | return ((double) RANDOM () / RAND_MAX); | 91 | return ((double) RANDOM () / RAND_MAX); |
80 | } | 92 | } |
81 | 93 | ||
94 | |||
82 | /** | 95 | /** |
83 | * Seed a weak random generator. Only GNUNET_CRYPTO_QUALITY_WEAK-mode generator | 96 | * Seed a weak random generator. Only GNUNET_CRYPTO_QUALITY_WEAK-mode generator |
84 | * can be seeded. | 97 | * can be seeded. |
@@ -91,6 +104,7 @@ GNUNET_CRYPTO_seed_weak_random (int32_t seed) | |||
91 | SRANDOM (seed); | 104 | SRANDOM (seed); |
92 | } | 105 | } |
93 | 106 | ||
107 | |||
94 | /** | 108 | /** |
95 | * Produce a random value. | 109 | * Produce a random value. |
96 | * | 110 | * |
@@ -134,7 +148,7 @@ GNUNET_CRYPTO_random_u32 (enum GNUNET_CRYPTO_Quality mode, uint32_t i) | |||
134 | while (ret >= ul); | 148 | while (ret >= ul); |
135 | return ret % i; | 149 | return ret % i; |
136 | case GNUNET_CRYPTO_QUALITY_WEAK: | 150 | case GNUNET_CRYPTO_QUALITY_WEAK: |
137 | ret = i * weak_random (); | 151 | ret = i * get_weak_random (); |
138 | if (ret >= i) | 152 | if (ret >= i) |
139 | ret = i - 1; | 153 | ret = i - 1; |
140 | return ret; | 154 | return ret; |
@@ -211,7 +225,7 @@ GNUNET_CRYPTO_random_u64 (enum GNUNET_CRYPTO_Quality mode, uint64_t max) | |||
211 | 225 | ||
212 | return ret % max; | 226 | return ret % max; |
213 | case GNUNET_CRYPTO_QUALITY_WEAK: | 227 | case GNUNET_CRYPTO_QUALITY_WEAK: |
214 | ret = max * weak_random (); | 228 | ret = max * get_weak_random (); |
215 | if (ret >= max) | 229 | if (ret >= max) |
216 | ret = max - 1; | 230 | ret = max - 1; |
217 | return ret; | 231 | return ret; |
@@ -221,6 +235,19 @@ GNUNET_CRYPTO_random_u64 (enum GNUNET_CRYPTO_Quality mode, uint64_t max) | |||
221 | return 0; | 235 | return 0; |
222 | } | 236 | } |
223 | 237 | ||
238 | |||
239 | /** | ||
240 | * Check if we are using weak random number generation. | ||
241 | * | ||
242 | * @return GNUNET_YES if weak number generation is on | ||
243 | */ | ||
244 | int | ||
245 | GNUNET_CRYPTO_random_is_weak () | ||
246 | { | ||
247 | return weak_random; | ||
248 | } | ||
249 | |||
250 | |||
224 | /** | 251 | /** |
225 | * This function should only be called in testcases | 252 | * This function should only be called in testcases |
226 | * where strong entropy gathering is not desired | 253 | * where strong entropy gathering is not desired |
@@ -229,6 +256,7 @@ GNUNET_CRYPTO_random_u64 (enum GNUNET_CRYPTO_Quality mode, uint64_t max) | |||
229 | void | 256 | void |
230 | GNUNET_CRYPTO_random_disable_entropy_gathering () | 257 | GNUNET_CRYPTO_random_disable_entropy_gathering () |
231 | { | 258 | { |
259 | weak_random = GNUNET_YES; | ||
232 | gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); | 260 | gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); |
233 | } | 261 | } |
234 | 262 | ||
@@ -239,6 +267,7 @@ GNUNET_CRYPTO_random_disable_entropy_gathering () | |||
239 | */ | 267 | */ |
240 | static struct GNUNET_OS_Process *genproc; | 268 | static struct GNUNET_OS_Process *genproc; |
241 | 269 | ||
270 | |||
242 | /** | 271 | /** |
243 | * Function called by libgcrypt whenever we are | 272 | * Function called by libgcrypt whenever we are |
244 | * blocked gathering entropy. | 273 | * blocked gathering entropy. |
diff --git a/src/util/crypto_rsa.c b/src/util/crypto_rsa.c index 4afda1f6e..8843464a2 100644 --- a/src/util/crypto_rsa.c +++ b/src/util/crypto_rsa.c | |||
@@ -629,11 +629,17 @@ try_read_key (const char *filename) | |||
629 | (void) GNUNET_DISK_file_close (fd); | 629 | (void) GNUNET_DISK_file_close (fd); |
630 | return NULL; | 630 | return NULL; |
631 | } | 631 | } |
632 | if (0 == fs) | ||
633 | { | ||
634 | GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (fd)); | ||
635 | return NULL; | ||
636 | } | ||
632 | if (fs > UINT16_MAX) | 637 | if (fs > UINT16_MAX) |
633 | { | 638 | { |
634 | LOG (GNUNET_ERROR_TYPE_ERROR, | 639 | LOG (GNUNET_ERROR_TYPE_ERROR, |
635 | _("File `%s' does not contain a valid private key. Deleting it.\n"), | 640 | _("File `%s' does not contain a valid private key (too long, %llu bytes). Deleting it.\n"), |
636 | filename); | 641 | filename, |
642 | (unsigned long long) fs); | ||
637 | GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (fd)); | 643 | GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (fd)); |
638 | if (0 != UNLINK (filename)) | 644 | if (0 != UNLINK (filename)) |
639 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "unlink", filename); | 645 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "unlink", filename); |
@@ -648,8 +654,9 @@ try_read_key (const char *filename) | |||
648 | (NULL == (ret = GNUNET_CRYPTO_rsa_decode_key ((char *) enc, len)))) | 654 | (NULL == (ret = GNUNET_CRYPTO_rsa_decode_key ((char *) enc, len)))) |
649 | { | 655 | { |
650 | LOG (GNUNET_ERROR_TYPE_ERROR, | 656 | LOG (GNUNET_ERROR_TYPE_ERROR, |
651 | _("File `%s' does not contain a valid private key. Deleting it.\n"), | 657 | _("File `%s' does not contain a valid private key (failed decode, %llu bytes). Deleting it.\n"), |
652 | filename); | 658 | filename, |
659 | (unsigned long long) fs); | ||
653 | GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (fd)); | 660 | GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (fd)); |
654 | if (0 != UNLINK (filename)) | 661 | if (0 != UNLINK (filename)) |
655 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "unlink", filename); | 662 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "unlink", filename); |
@@ -664,6 +671,23 @@ try_read_key (const char *filename) | |||
664 | 671 | ||
665 | 672 | ||
666 | /** | 673 | /** |
674 | * Wait for a short time (we're trying to lock a file or want | ||
675 | * to give another process a shot at finishing a disk write, etc.). | ||
676 | * Sleeps for 100ms (as that should be long enough for virtually all | ||
677 | * modern systems to context switch and allow another process to do | ||
678 | * some 'real' work). | ||
679 | */ | ||
680 | static void | ||
681 | short_wait () | ||
682 | { | ||
683 | struct GNUNET_TIME_Relative timeout; | ||
684 | |||
685 | timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 100); | ||
686 | GNUNET_NETWORK_socket_select (NULL, NULL, NULL, timeout); | ||
687 | } | ||
688 | |||
689 | |||
690 | /** | ||
667 | * Create a new private key by reading it from a file. If the | 691 | * Create a new private key by reading it from a file. If the |
668 | * files does not exist, create a new key and write it to the | 692 | * files does not exist, create a new key and write it to the |
669 | * file. Caller must free return value. Note that this function | 693 | * file. Caller must free return value. Note that this function |
@@ -723,7 +747,7 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename) | |||
723 | sizeof (struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded), | 747 | sizeof (struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded), |
724 | GNUNET_YES)) | 748 | GNUNET_YES)) |
725 | { | 749 | { |
726 | sleep (1); | 750 | short_wait (1); |
727 | if (0 == ++cnt % 10) | 751 | if (0 == ++cnt % 10) |
728 | { | 752 | { |
729 | ec = errno; | 753 | ec = errno; |
@@ -781,7 +805,7 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename) | |||
781 | _ | 805 | _ |
782 | ("This may be ok if someone is currently generating a hostkey.\n")); | 806 | ("This may be ok if someone is currently generating a hostkey.\n")); |
783 | } | 807 | } |
784 | sleep (1); | 808 | short_wait (1); |
785 | continue; | 809 | continue; |
786 | } | 810 | } |
787 | if (GNUNET_YES != GNUNET_DISK_file_test (filename)) | 811 | if (GNUNET_YES != GNUNET_DISK_file_test (filename)) |
@@ -817,7 +841,7 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename) | |||
817 | _ | 841 | _ |
818 | ("This may be ok if someone is currently generating a hostkey.\n")); | 842 | ("This may be ok if someone is currently generating a hostkey.\n")); |
819 | } | 843 | } |
820 | sleep (2); /* wait a bit longer! */ | 844 | short_wait (1); /* wait a bit longer! */ |
821 | continue; | 845 | continue; |
822 | } | 846 | } |
823 | break; | 847 | break; |
@@ -996,6 +1020,7 @@ GNUNET_CRYPTO_rsa_key_create_start (const char *filename, | |||
996 | { | 1020 | { |
997 | struct GNUNET_CRYPTO_RsaKeyGenerationContext *gc; | 1021 | struct GNUNET_CRYPTO_RsaKeyGenerationContext *gc; |
998 | struct GNUNET_CRYPTO_RsaPrivateKey *pk; | 1022 | struct GNUNET_CRYPTO_RsaPrivateKey *pk; |
1023 | const char *weak_random; | ||
999 | 1024 | ||
1000 | if (NULL != (pk = try_read_key (filename))) | 1025 | if (NULL != (pk = try_read_key (filename))) |
1001 | { | 1026 | { |
@@ -1023,13 +1048,18 @@ GNUNET_CRYPTO_rsa_key_create_start (const char *filename, | |||
1023 | GNUNET_free (gc); | 1048 | GNUNET_free (gc); |
1024 | return NULL; | 1049 | return NULL; |
1025 | } | 1050 | } |
1051 | weak_random = NULL; | ||
1052 | if (GNUNET_YES == | ||
1053 | GNUNET_CRYPTO_random_is_weak ()) | ||
1054 | weak_random = "-w"; | ||
1026 | gc->gnunet_rsa = GNUNET_OS_start_process (GNUNET_NO, | 1055 | gc->gnunet_rsa = GNUNET_OS_start_process (GNUNET_NO, |
1027 | GNUNET_OS_INHERIT_STD_ERR, | 1056 | GNUNET_OS_INHERIT_STD_ERR, |
1028 | NULL, | 1057 | NULL, |
1029 | gc->gnunet_rsa_out, | 1058 | gc->gnunet_rsa_out, |
1030 | "gnunet-rsa", | 1059 | "gnunet-rsa", |
1031 | "gnunet-rsa", | 1060 | "gnunet-rsa", |
1032 | gc->filename, | 1061 | gc->filename, |
1062 | weak_random, | ||
1033 | NULL); | 1063 | NULL); |
1034 | if (NULL == gc->gnunet_rsa) | 1064 | if (NULL == gc->gnunet_rsa) |
1035 | { | 1065 | { |
diff --git a/src/util/gnunet-rsa.c b/src/util/gnunet-rsa.c index 61e1b66df..e9fbf15df 100644 --- a/src/util/gnunet-rsa.c +++ b/src/util/gnunet-rsa.c | |||
@@ -43,6 +43,11 @@ static int print_peer_identity; | |||
43 | */ | 43 | */ |
44 | static int print_short_identity; | 44 | static int print_short_identity; |
45 | 45 | ||
46 | /** | ||
47 | * Use weak random number generator for key generation. | ||
48 | */ | ||
49 | static int weak_random; | ||
50 | |||
46 | 51 | ||
47 | /** | 52 | /** |
48 | * The private information of an RSA key pair. | 53 | * The private information of an RSA key pair. |
@@ -104,6 +109,8 @@ run (void *cls, char *const *args, const char *cfgfile, | |||
104 | fprintf (stderr, _("No hostkey file specified on command line\n")); | 109 | fprintf (stderr, _("No hostkey file specified on command line\n")); |
105 | return; | 110 | return; |
106 | } | 111 | } |
112 | if (0 != weak_random) | ||
113 | GNUNET_CRYPTO_random_disable_entropy_gathering (); | ||
107 | pk = GNUNET_CRYPTO_rsa_key_create_from_file (args[0]); | 114 | pk = GNUNET_CRYPTO_rsa_key_create_from_file (args[0]); |
108 | if (NULL == pk) | 115 | if (NULL == pk) |
109 | return; | 116 | return; |
@@ -159,6 +166,9 @@ main (int argc, char *const *argv) | |||
159 | { 's', "print-short-identity", NULL, | 166 | { 's', "print-short-identity", NULL, |
160 | gettext_noop ("print the short hash of the public key in ASCII format"), | 167 | gettext_noop ("print the short hash of the public key in ASCII format"), |
161 | 0, &GNUNET_GETOPT_set_one, &print_short_identity }, | 168 | 0, &GNUNET_GETOPT_set_one, &print_short_identity }, |
169 | { 'w', "weak-random", NULL, | ||
170 | gettext_noop ("use insecure, weak random number generator for key generation (for testing only)"), | ||
171 | 0, &GNUNET_GETOPT_set_one, &weak_random }, | ||
162 | GNUNET_GETOPT_OPTION_END | 172 | GNUNET_GETOPT_OPTION_END |
163 | }; | 173 | }; |
164 | 174 | ||
diff --git a/src/util/server.c b/src/util/server.c index ff4584677..4622e0779 100644 --- a/src/util/server.c +++ b/src/util/server.c | |||
@@ -334,43 +334,6 @@ process_listen_socket (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
334 | 334 | ||
335 | 335 | ||
336 | /** | 336 | /** |
337 | * Add a listen task with the scheduler for this server. | ||
338 | * | ||
339 | * @param server handle to our server for which we are adding the listen | ||
340 | * socket | ||
341 | */ | ||
342 | static void | ||
343 | schedule_listen_task (struct GNUNET_SERVER_Handle *server) | ||
344 | { | ||
345 | struct GNUNET_NETWORK_FDSet *r; | ||
346 | unsigned int i; | ||
347 | |||
348 | if (NULL == server->listen_sockets[0]) | ||
349 | return; /* nothing to do, no listen sockets! */ | ||
350 | if (NULL == server->listen_sockets[1]) | ||
351 | { | ||
352 | /* simplified method: no fd set needed; this is then much simpler and | ||
353 | much more efficient */ | ||
354 | server->listen_task = | ||
355 | GNUNET_SCHEDULER_add_read_net_with_priority (GNUNET_TIME_UNIT_FOREVER_REL, | ||
356 | GNUNET_SCHEDULER_PRIORITY_HIGH, | ||
357 | server->listen_sockets[0], | ||
358 | &process_listen_socket, server); | ||
359 | return; | ||
360 | } | ||
361 | r = GNUNET_NETWORK_fdset_create (); | ||
362 | i = 0; | ||
363 | while (NULL != server->listen_sockets[i]) | ||
364 | GNUNET_NETWORK_fdset_set (r, server->listen_sockets[i++]); | ||
365 | server->listen_task = | ||
366 | GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH, | ||
367 | GNUNET_TIME_UNIT_FOREVER_REL, r, NULL, | ||
368 | &process_listen_socket, server); | ||
369 | GNUNET_NETWORK_fdset_destroy (r); | ||
370 | } | ||
371 | |||
372 | |||
373 | /** | ||
374 | * Scheduler says our listen socket is ready. Process it! | 337 | * Scheduler says our listen socket is ready. Process it! |
375 | * | 338 | * |
376 | * @param cls handle to our server for which we are processing the listen | 339 | * @param cls handle to our server for which we are processing the listen |
@@ -389,7 +352,7 @@ process_listen_socket (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
389 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | 352 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) |
390 | { | 353 | { |
391 | /* ignore shutdown, someone else will take care of it! */ | 354 | /* ignore shutdown, someone else will take care of it! */ |
392 | schedule_listen_task (server); | 355 | GNUNET_SERVER_resume (server); |
393 | return; | 356 | return; |
394 | } | 357 | } |
395 | i = 0; | 358 | i = 0; |
@@ -412,7 +375,7 @@ process_listen_socket (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
412 | i++; | 375 | i++; |
413 | } | 376 | } |
414 | /* listen for more! */ | 377 | /* listen for more! */ |
415 | schedule_listen_task (server); | 378 | GNUNET_SERVER_resume (server); |
416 | } | 379 | } |
417 | 380 | ||
418 | 381 | ||
@@ -536,7 +499,7 @@ GNUNET_SERVER_create_with_sockets (GNUNET_CONNECTION_AccessCheck access, | |||
536 | server->access_cls = access_cls; | 499 | server->access_cls = access_cls; |
537 | server->require_found = require_found; | 500 | server->require_found = require_found; |
538 | if (NULL != lsocks) | 501 | if (NULL != lsocks) |
539 | schedule_listen_task (server); | 502 | GNUNET_SERVER_resume (server); |
540 | return server; | 503 | return server; |
541 | } | 504 | } |
542 | 505 | ||
@@ -671,6 +634,58 @@ test_monitor_clients (struct GNUNET_SERVER_Handle *server) | |||
671 | 634 | ||
672 | 635 | ||
673 | /** | 636 | /** |
637 | * Suspend accepting connections from the listen socket temporarily. | ||
638 | * | ||
639 | * @param server server to stop accepting connections. | ||
640 | */ | ||
641 | void | ||
642 | GNUNET_SERVER_suspend (struct GNUNET_SERVER_Handle *server) | ||
643 | { | ||
644 | if (GNUNET_SCHEDULER_NO_TASK != server->listen_task) | ||
645 | { | ||
646 | GNUNET_SCHEDULER_cancel (server->listen_task); | ||
647 | server->listen_task = GNUNET_SCHEDULER_NO_TASK; | ||
648 | } | ||
649 | } | ||
650 | |||
651 | |||
652 | /** | ||
653 | * Resume accepting connections from the listen socket. | ||
654 | * | ||
655 | * @param server server to stop accepting connections. | ||
656 | */ | ||
657 | void | ||
658 | GNUNET_SERVER_resume (struct GNUNET_SERVER_Handle *server) | ||
659 | { | ||
660 | struct GNUNET_NETWORK_FDSet *r; | ||
661 | unsigned int i; | ||
662 | |||
663 | if (NULL == server->listen_sockets[0]) | ||
664 | return; /* nothing to do, no listen sockets! */ | ||
665 | if (NULL == server->listen_sockets[1]) | ||
666 | { | ||
667 | /* simplified method: no fd set needed; this is then much simpler and | ||
668 | much more efficient */ | ||
669 | server->listen_task = | ||
670 | GNUNET_SCHEDULER_add_read_net_with_priority (GNUNET_TIME_UNIT_FOREVER_REL, | ||
671 | GNUNET_SCHEDULER_PRIORITY_HIGH, | ||
672 | server->listen_sockets[0], | ||
673 | &process_listen_socket, server); | ||
674 | return; | ||
675 | } | ||
676 | r = GNUNET_NETWORK_fdset_create (); | ||
677 | i = 0; | ||
678 | while (NULL != server->listen_sockets[i]) | ||
679 | GNUNET_NETWORK_fdset_set (r, server->listen_sockets[i++]); | ||
680 | server->listen_task = | ||
681 | GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH, | ||
682 | GNUNET_TIME_UNIT_FOREVER_REL, r, NULL, | ||
683 | &process_listen_socket, server); | ||
684 | GNUNET_NETWORK_fdset_destroy (r); | ||
685 | } | ||
686 | |||
687 | |||
688 | /** | ||
674 | * Stop the listen socket and get ready to shutdown the server | 689 | * Stop the listen socket and get ready to shutdown the server |
675 | * once only 'monitor' clients are left. | 690 | * once only 'monitor' clients are left. |
676 | * | 691 | * |