-fix off-by-one so we can also select on FD 0 (stdin)
[oweals/gnunet.git] / src / util / network.c
1 /*
2      This file is part of GNUnet.
3      (C) 2009-2013 Christian Grothoff (and other contributing authors)
4
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
7      by the Free Software Foundation; either version 3, or (at your
8      option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20
21 /**
22  * @file util/network.c
23  * @brief basic, low-level networking interface
24  * @author Nils Durner
25  * @author Christian Grothoff
26  */
27 #include "platform.h"
28 #include "gnunet_util_lib.h"
29 #include "disk.h"
30
31 #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
32 #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename)
33 #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util", syscall)
34
35 #define DEBUG_NETWORK GNUNET_EXTRA_LOGGING
36
37
38 #ifndef INVALID_SOCKET
39 #define INVALID_SOCKET -1
40 #endif
41
42
43 struct GNUNET_NETWORK_Handle
44 {
45 #ifndef MINGW
46   int fd;
47 #else
48   SOCKET fd;
49 #endif
50
51   /**
52    * Address family / domain.
53    */
54   int af;
55
56   /**
57    * Type of the socket
58    */
59   int type;
60
61   /**
62    * Number of bytes in addr.
63    */
64   socklen_t addrlen;
65
66   /**
67    * Address we were bound to, or NULL.
68    */
69   struct sockaddr *addr;
70
71 };
72
73
74 /**
75  * Test if the given protocol family is supported by this system.
76  *
77  * @param pf protocol family to test (PF_INET, PF_INET6, PF_UNIX)
78  * @return #GNUNET_OK if the PF is supported
79  */
80 int
81 GNUNET_NETWORK_test_pf (int pf)
82 {
83   int s;
84
85   s = socket (pf, SOCK_STREAM, 0);
86   if (-1 == s)
87   {
88     if (EAFNOSUPPORT == errno)
89       return GNUNET_NO;
90     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
91                 "Failed to create test socket: %s\n",
92                 STRERROR (errno));
93     return GNUNET_SYSERR;
94   }
95 #if WINDOWS
96   closesocket (s);
97 #else
98   close (s);
99 #endif
100   return GNUNET_OK;
101 }
102
103
104 /**
105  * Given a unixpath that is too long (larger than UNIX_PATH_MAX),
106  * shorten it to an acceptable length while keeping it unique
107  * and making sure it remains a valid filename (if possible).
108  *
109  * @param unixpath long path, will be freed (or same pointer returned
110  *        with moved 0-termination).
111  * @return shortened unixpath, NULL on error
112  */
113 char *
114 GNUNET_NETWORK_shorten_unixpath (char *unixpath)
115 {
116   struct sockaddr_un dummy;
117   size_t slen;
118   char *end;
119   struct GNUNET_HashCode sh;
120   struct GNUNET_CRYPTO_HashAsciiEncoded ae;
121   size_t upm;
122
123   upm = sizeof (dummy.sun_path);
124   slen = strlen (unixpath);
125   if (slen < upm)
126     return unixpath; /* no shortening required */
127   GNUNET_CRYPTO_hash (unixpath, slen, &sh);
128   while (16 +
129          strlen (unixpath) >= upm)
130   {
131     if (NULL == (end = strrchr (unixpath, '/')))
132     {
133       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
134                   _("Unable to shorten unix path `%s' while keeping name unique\n"),
135                   unixpath);
136       GNUNET_free (unixpath);
137       return NULL;
138     }
139     *end = '\0';
140   }
141   GNUNET_CRYPTO_hash_to_enc (&sh, &ae);
142   strncat (unixpath, (char*) ae.encoding, 16);
143   return unixpath;
144 }
145
146
147 #ifndef FD_COPY
148 #define FD_COPY(s, d) (memcpy ((d), (s), sizeof (fd_set)))
149 #endif
150
151
152 /**
153  * Set if a socket should use blocking or non-blocking IO.
154  *
155  * @param fd socket
156  * @param doBlock blocking mode
157  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
158  */
159 int
160 GNUNET_NETWORK_socket_set_blocking (struct GNUNET_NETWORK_Handle *fd, int doBlock)
161 {
162
163 #if MINGW
164   u_long mode;
165
166   mode = !doBlock;
167   if (ioctlsocket (fd->fd, FIONBIO, &mode) == SOCKET_ERROR)
168
169   {
170     SetErrnoFromWinsockError (WSAGetLastError ());
171     LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "ioctlsocket");
172     return GNUNET_SYSERR;
173   }
174   return GNUNET_OK;
175
176 #else
177   /* not MINGW */
178   int flags = fcntl (fd->fd, F_GETFL);
179
180   if (flags == -1)
181
182   {
183     LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "fcntl");
184     return GNUNET_SYSERR;
185   }
186   if (doBlock)
187     flags &= ~O_NONBLOCK;
188
189   else
190     flags |= O_NONBLOCK;
191   if (0 != fcntl (fd->fd, F_SETFL, flags))
192
193   {
194     LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "fcntl");
195     return GNUNET_SYSERR;
196   }
197   return GNUNET_OK;
198 #endif
199 }
200
201
202 /**
203  * Make a socket non-inheritable to child processes
204  *
205  * @param h the socket to make non-inheritable
206  * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
207  * @warning Not implemented on Windows
208  */
209 static int
210 socket_set_inheritable (const struct GNUNET_NETWORK_Handle *h)
211 {
212 #ifndef MINGW
213   int i;
214   i = fcntl (h->fd, F_GETFD);
215   if (i < 0)
216     return GNUNET_SYSERR;
217   if (i == (i | FD_CLOEXEC))
218     return GNUNET_OK;
219   i |= FD_CLOEXEC;
220   if (fcntl (h->fd, F_SETFD, i) < 0)
221     return GNUNET_SYSERR;
222 #else
223   BOOL b;
224   SetLastError (0);
225   b = SetHandleInformation ((HANDLE) h->fd, HANDLE_FLAG_INHERIT, 0);
226   if (!b)
227   {
228     SetErrnoFromWinsockError (WSAGetLastError ());
229     return GNUNET_SYSERR;
230   }
231 #endif
232   return GNUNET_OK;
233 }
234
235
236 #ifdef DARWIN
237 /**
238  * The MSG_NOSIGNAL equivalent on Mac OS X
239  *
240  * @param h the socket to make non-delaying
241  */
242 static void
243 socket_set_nosigpipe (const struct GNUNET_NETWORK_Handle *h)
244 {
245   int abs_value = 1;
246
247   if (0 !=
248       setsockopt (h->fd, SOL_SOCKET, SO_NOSIGPIPE,
249                   (const void *) &abs_value,
250                   sizeof (abs_value)))
251     LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "setsockopt");
252 }
253 #endif
254
255
256 /**
257  * Disable delays when sending data via the socket.
258  * (GNUnet makes sure that messages are as big as
259  * possible already).
260  *
261  * @param h the socket to make non-delaying
262  */
263 static void
264 socket_set_nodelay (const struct GNUNET_NETWORK_Handle *h)
265 {
266 #ifndef WINDOWS
267   int value = 1;
268
269   if (0 != setsockopt (h->fd, IPPROTO_TCP, TCP_NODELAY, &value, sizeof (value)))
270     LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "setsockopt");
271 #else
272   const char *abs_value = "1";
273
274   if (0 !=
275       setsockopt (h->fd, IPPROTO_TCP, TCP_NODELAY,
276                   (const void *) abs_value,
277                   sizeof (abs_value)))
278     LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "setsockopt");
279 #endif
280 }
281
282
283 /**
284  * Perform proper canonical initialization for a network handle.
285  * Set it to non-blocking, make it non-inheritable to child
286  * processes, disable SIGPIPE, enable "nodelay" (if non-UNIX
287  * stream socket) and check that it is smaller than FD_SETSIZE.
288  *
289  * @param h socket to initialize
290  * @param af address family of the socket
291  * @param type socket type
292  * @return #GNUNET_OK on success, #GNUNET_SYSERR if initialization
293  *         failed and the handle was destroyed
294  */
295 static int
296 initialize_network_handle (struct GNUNET_NETWORK_Handle *h,
297                            int af, int type)
298 {
299   h->af = af;
300   h->type = type;
301   if (h->fd == INVALID_SOCKET)
302   {
303 #ifdef MINGW
304     SetErrnoFromWinsockError (WSAGetLastError ());
305 #endif
306     GNUNET_free (h);
307     return GNUNET_SYSERR;
308   }
309 #ifndef MINGW
310   if (h->fd >= FD_SETSIZE)
311   {
312     GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (h));
313     errno = EMFILE;
314     return GNUNET_SYSERR;
315   }
316 #endif
317   if (GNUNET_OK != socket_set_inheritable (h))
318     LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
319                   "socket_set_inheritable");
320
321   if (GNUNET_SYSERR == GNUNET_NETWORK_socket_set_blocking (h, GNUNET_NO))
322   {
323     GNUNET_break (0);
324     GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (h));
325     return GNUNET_SYSERR;
326   }
327 #ifdef DARWIN
328   socket_set_nosigpipe (h);
329 #endif
330   if ( (type == SOCK_STREAM)
331 #ifdef AF_UNIX
332        && (af != AF_UNIX)
333 #endif
334        )
335     socket_set_nodelay (h);
336   return GNUNET_OK;
337 }
338
339
340 /**
341  * accept a new connection on a socket
342  *
343  * @param desc bound socket
344  * @param address address of the connecting peer, may be NULL
345  * @param address_len length of @a address
346  * @return client socket
347  */
348 struct GNUNET_NETWORK_Handle *
349 GNUNET_NETWORK_socket_accept (const struct GNUNET_NETWORK_Handle *desc,
350                               struct sockaddr *address,
351                               socklen_t *address_len)
352 {
353   struct GNUNET_NETWORK_Handle *ret;
354
355   ret = GNUNET_new (struct GNUNET_NETWORK_Handle);
356 #if DEBUG_NETWORK
357   {
358     struct sockaddr name;
359     socklen_t namelen = sizeof (name);
360     int gsn = getsockname (desc->fd, &name, &namelen);
361
362     if (gsn == 0)
363       LOG (GNUNET_ERROR_TYPE_DEBUG,
364            "Accepting connection on `%s'\n",
365            GNUNET_a2s (&name, namelen));
366   }
367 #endif
368   ret->fd = accept (desc->fd, address, address_len);
369   if (-1 == ret->fd)
370   {
371     GNUNET_free (ret);
372     return NULL;
373   }
374   if (GNUNET_OK != initialize_network_handle (ret,
375                                               (NULL != address) ? address->sa_family : desc->af,
376                                               SOCK_STREAM))
377     return NULL;
378   return ret;
379 }
380
381
382 /**
383  * Bind a socket to a particular address.
384  *
385  * @param desc socket to bind
386  * @param address address to be bound
387  * @param address_len length of @a address
388  * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
389  */
390 int
391 GNUNET_NETWORK_socket_bind (struct GNUNET_NETWORK_Handle *desc,
392                             const struct sockaddr *address,
393                             socklen_t address_len)
394 {
395   int ret;
396
397 #ifdef IPV6_V6ONLY
398 #ifdef IPPROTO_IPV6
399   {
400     const int on = 1;
401
402     if (AF_INET6 == desc->af)
403       if (setsockopt (desc->fd, IPPROTO_IPV6, IPV6_V6ONLY,
404                       (const void *) &on,
405                       sizeof (on)))
406         LOG_STRERROR (GNUNET_ERROR_TYPE_DEBUG, "setsockopt");
407   }
408 #endif
409 #endif
410 #ifndef WINDOWS
411   {
412     const int on = 1;
413
414     /* This is required here for TCP sockets, but only on UNIX */
415     if ((SOCK_STREAM == desc->type)
416         && (0 != setsockopt (desc->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on))))
417       LOG_STRERROR (GNUNET_ERROR_TYPE_DEBUG, "setsockopt");
418   }
419 #endif
420 #ifndef WINDOWS
421   {
422     /* set permissions of newly created UNIX domain socket to "user-only"; applications
423        can choose to relax this later */
424     mode_t old_mask = 0; /* assigned to make compiler happy */
425
426     if (AF_UNIX == address->sa_family)
427       old_mask = umask (S_IWGRP | S_IRGRP | S_IXGRP | S_IWOTH | S_IROTH | S_IXOTH);
428 #endif
429
430     ret = bind (desc->fd, address, address_len);
431 #ifndef WINDOWS
432     if (AF_UNIX == address->sa_family)
433       (void) umask (old_mask);
434   }
435 #endif
436 #ifdef MINGW
437   if (SOCKET_ERROR == ret)
438     SetErrnoFromWinsockError (WSAGetLastError ());
439 #endif
440   if (ret != 0)
441     return GNUNET_SYSERR;
442 #ifndef MINGW
443   desc->addr = GNUNET_malloc (address_len);
444   memcpy (desc->addr, address, address_len);
445   desc->addrlen = address_len;
446 #endif
447   return GNUNET_OK;
448 }
449
450
451 /**
452  * Close a socket
453  *
454  * @param desc socket
455  * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
456  */
457 int
458 GNUNET_NETWORK_socket_close (struct GNUNET_NETWORK_Handle *desc)
459 {
460   int ret;
461
462 #ifdef MINGW
463   DWORD error = 0;
464
465   SetLastError (0);
466   ret = closesocket (desc->fd);
467   error = WSAGetLastError ();
468   SetErrnoFromWinsockError (error);
469   LOG (GNUNET_ERROR_TYPE_DEBUG,
470        "Closed 0x%x, closesocket() returned %d, GLE is %u\n", desc->fd, ret,
471        error);
472 #else
473   ret = close (desc->fd);
474 #endif
475 #ifndef MINGW
476   if ((desc->af == AF_UNIX) && (NULL != desc->addr))
477   {
478     const struct sockaddr_un *un = (const struct sockaddr_un *) desc->addr;
479     char *dirname = GNUNET_strndup (un->sun_path,
480                                     sizeof (un->sun_path));
481
482     if (0 != unlink (dirname))
483     {
484       LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING,
485                          "unlink",
486                          dirname);
487     }
488     else
489     {
490       size_t len;
491
492       len = strlen (dirname);
493       while ((len > 0) && (dirname[len] != DIR_SEPARATOR))
494         len--;
495       dirname[len] = '\0';
496       if (0 != rmdir (dirname))
497       {
498         switch (errno)
499         {
500         case EACCES:
501         case ENOTEMPTY:
502         case EPERM:
503           /* these are normal and can just be ignored */
504           break;
505         default:
506           GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
507                                     "rmdir",
508                                     dirname);
509           break;
510         }
511       }
512     }
513     GNUNET_free (dirname);
514   }
515 #endif
516   GNUNET_NETWORK_socket_free_memory_only_ (desc);
517   return (ret == 0) ? GNUNET_OK : GNUNET_SYSERR;
518 }
519
520
521 /**
522  * Only free memory of a socket, keep the file descriptor untouched.
523  *
524  * @param desc socket
525  */
526 void
527 GNUNET_NETWORK_socket_free_memory_only_ (struct GNUNET_NETWORK_Handle *desc)
528 {
529   GNUNET_free_non_null (desc->addr);
530   GNUNET_free (desc);
531 }
532
533
534 /**
535  * Box a native socket (and check that it is a socket).
536  *
537  * @param fd socket to box
538  * @return NULL on error (including not supported on target platform)
539  */
540 struct GNUNET_NETWORK_Handle *
541 GNUNET_NETWORK_socket_box_native (SOCKTYPE fd)
542 {
543   struct GNUNET_NETWORK_Handle *ret;
544 #if MINGW
545   unsigned long i;
546   DWORD d;
547   /* FIXME: Find a better call to check that FD is valid */
548   if (WSAIoctl (fd, FIONBIO, (void *) &i, sizeof (i), NULL, 0, &d, NULL, NULL) != 0)
549     return NULL;                /* invalid FD */
550   ret = GNUNET_new (struct GNUNET_NETWORK_Handle);
551   ret->fd = fd;
552   ret->af = AF_UNSPEC;
553   return ret;
554 #else
555   if (fcntl (fd, F_GETFD) < 0)
556     return NULL;                /* invalid FD */
557   ret = GNUNET_new (struct GNUNET_NETWORK_Handle);
558   ret->fd = fd;
559   ret->af = AF_UNSPEC;
560   return ret;
561 #endif
562 }
563
564
565 /**
566  * Connect a socket to some remote address.
567  *
568  * @param desc socket
569  * @param address peer address
570  * @param address_len length of @a address
571  * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
572  */
573 int
574 GNUNET_NETWORK_socket_connect (const struct GNUNET_NETWORK_Handle *desc,
575                                const struct sockaddr *address,
576                                socklen_t address_len)
577 {
578   int ret;
579
580   ret = connect (desc->fd, address, address_len);
581
582 #ifdef MINGW
583   if (SOCKET_ERROR == ret)
584   {
585     SetErrnoFromWinsockError (WSAGetLastError ());
586     if (errno == EWOULDBLOCK)
587       errno = EINPROGRESS;
588   }
589 #endif
590   return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;
591 }
592
593
594 /**
595  * Get socket options
596  *
597  * @param desc socket
598  * @param level protocol level of the option
599  * @param optname identifier of the option
600  * @param optval options
601  * @param optlen length of @a optval
602  * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
603  */
604 int
605 GNUNET_NETWORK_socket_getsockopt (const struct GNUNET_NETWORK_Handle *desc,
606                                   int level, int optname, void *optval,
607                                   socklen_t *optlen)
608 {
609   int ret;
610
611   ret = getsockopt (desc->fd, level, optname, optval, optlen);
612
613 #ifdef MINGW
614   if (ret == 0 && level == SOL_SOCKET && optname == SO_ERROR)
615     *((int *) optval) = GetErrnoFromWinsockError (*((int *) optval));
616
617   else if (SOCKET_ERROR == ret)
618     SetErrnoFromWinsockError (WSAGetLastError ());
619 #endif
620   return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;
621 }
622
623
624 /**
625  * Listen on a socket
626  *
627  * @param desc socket
628  * @param backlog length of the listen queue
629  * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
630  */
631 int
632 GNUNET_NETWORK_socket_listen (const struct GNUNET_NETWORK_Handle *desc,
633                               int backlog)
634 {
635   int ret;
636
637   ret = listen (desc->fd, backlog);
638
639 #ifdef MINGW
640   if (SOCKET_ERROR == ret)
641     SetErrnoFromWinsockError (WSAGetLastError ());
642
643 #endif
644   return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;
645 }
646
647
648 /**
649  * How much data is available to be read on this descriptor?
650  *
651  * @param desc socket
652  * @returns #GNUNET_NO if no data is available, or on error!
653  */
654 ssize_t
655 GNUNET_NETWORK_socket_recvfrom_amount (const struct GNUNET_NETWORK_Handle *
656                                        desc)
657 {
658   int error;
659
660   /* How much is there to be read? */
661 #ifndef WINDOWS
662   int pending;
663
664   error = ioctl (desc->fd, FIONREAD, &pending);
665   if (error == 0)
666     return (ssize_t) pending;
667   return GNUNET_NO;
668 #else
669   u_long pending;
670
671   error = ioctlsocket (desc->fd, FIONREAD, &pending);
672   if (error != SOCKET_ERROR)
673     return (ssize_t) pending;
674   return GNUNET_NO;
675 #endif
676 }
677
678
679 /**
680  * Read data from a socket (always non-blocking).
681  *
682  * @param desc socket
683  * @param buffer buffer
684  * @param length length of @a buffer
685  * @param src_addr either the source to recv from, or all zeroes
686  *        to be filled in by recvfrom
687  * @param addrlen length of the @a src_addr
688  */
689 ssize_t
690 GNUNET_NETWORK_socket_recvfrom (const struct GNUNET_NETWORK_Handle *desc,
691                                 void *buffer, size_t length,
692                                 struct sockaddr *src_addr, socklen_t *addrlen)
693 {
694   int ret;
695   int flags;
696
697   flags = 0;
698
699 #ifdef MSG_DONTWAIT
700   flags |= MSG_DONTWAIT;
701
702 #endif
703   ret = recvfrom (desc->fd, buffer, length, flags, src_addr, addrlen);
704 #ifdef MINGW
705   if (SOCKET_ERROR == ret)
706     SetErrnoFromWinsockError (WSAGetLastError ());
707 #endif
708   return ret;
709 }
710
711
712 /**
713  * Read data from a connected socket (always non-blocking).
714  *
715  * @param desc socket
716  * @param buffer buffer
717  * @param length length of @a buffer
718  */
719 ssize_t
720 GNUNET_NETWORK_socket_recv (const struct GNUNET_NETWORK_Handle * desc,
721                             void *buffer, size_t length)
722 {
723   int ret;
724   int flags;
725
726   flags = 0;
727
728 #ifdef MSG_DONTWAIT
729   flags |= MSG_DONTWAIT;
730 #endif
731   ret = recv (desc->fd, buffer, length, flags);
732 #ifdef MINGW
733   if (SOCKET_ERROR == ret)
734     SetErrnoFromWinsockError (WSAGetLastError ());
735 #endif
736   return ret;
737 }
738
739
740 /**
741  * Send data (always non-blocking).
742  *
743  * @param desc socket
744  * @param buffer data to send
745  * @param length size of the @a buffer
746  * @return number of bytes sent, #GNUNET_SYSERR on error
747  */
748 ssize_t
749 GNUNET_NETWORK_socket_send (const struct GNUNET_NETWORK_Handle * desc,
750                             const void *buffer, size_t length)
751 {
752   int ret;
753   int flags;
754
755   flags = 0;
756
757 #ifdef MSG_DONTWAIT
758   flags |= MSG_DONTWAIT;
759
760 #endif
761 #ifdef MSG_NOSIGNAL
762   flags |= MSG_NOSIGNAL;
763
764 #endif
765   ret = send (desc->fd, buffer, length, flags);
766
767 #ifdef MINGW
768   if (SOCKET_ERROR == ret)
769     SetErrnoFromWinsockError (WSAGetLastError ());
770
771 #endif
772   return ret;
773 }
774
775
776 /**
777  * Send data to a particular destination (always non-blocking).
778  * This function only works for UDP sockets.
779  *
780  * @param desc socket
781  * @param message data to send
782  * @param length size of the data
783  * @param dest_addr destination address
784  * @param dest_len length of @a address
785  * @return number of bytes sent, #GNUNET_SYSERR on error
786  */
787 ssize_t
788 GNUNET_NETWORK_socket_sendto (const struct GNUNET_NETWORK_Handle * desc,
789                               const void *message, size_t length,
790                               const struct sockaddr * dest_addr,
791                               socklen_t dest_len)
792 {
793   int ret;
794   int flags;
795
796   flags = 0;
797
798 #ifdef MSG_DONTWAIT
799   flags |= MSG_DONTWAIT;
800 #endif
801 #ifdef MSG_NOSIGNAL
802   flags |= MSG_NOSIGNAL;
803 #endif
804   ret = sendto (desc->fd, message, length, flags, dest_addr, dest_len);
805 #ifdef MINGW
806   if (SOCKET_ERROR == ret)
807     SetErrnoFromWinsockError (WSAGetLastError ());
808 #endif
809   return ret;
810 }
811
812
813 /**
814  * Set socket option
815  *
816  * @param fd socket
817  * @param level protocol level of the option
818  * @param option_name option identifier
819  * @param option_value value to set
820  * @param option_len size of option_value
821  * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
822  */
823 int
824 GNUNET_NETWORK_socket_setsockopt (struct GNUNET_NETWORK_Handle *fd, int level,
825                                   int option_name, const void *option_value,
826                                   socklen_t option_len)
827 {
828   int ret;
829
830   ret = setsockopt (fd->fd, level, option_name, option_value, option_len);
831 #ifdef MINGW
832   if (SOCKET_ERROR == ret)
833     SetErrnoFromWinsockError (WSAGetLastError ());
834 #endif
835   return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;
836 }
837
838
839 /**
840  * Create a new socket.  Configure it for non-blocking IO and
841  * mark it as non-inheritable to child processes (set the
842  * close-on-exec flag).
843  *
844  * @param domain domain of the socket
845  * @param type socket type
846  * @param protocol network protocol
847  * @return new socket, NULL on error
848  */
849 struct GNUNET_NETWORK_Handle *
850 GNUNET_NETWORK_socket_create (int domain, int type, int protocol)
851 {
852   struct GNUNET_NETWORK_Handle *ret;
853
854   ret = GNUNET_new (struct GNUNET_NETWORK_Handle);
855   ret->fd = socket (domain, type, protocol);
856   if (-1 == ret->fd)
857   {
858     GNUNET_free (ret);
859     return NULL;
860   }
861   if (GNUNET_OK !=
862       initialize_network_handle (ret, domain, type))
863     return NULL;
864   return ret;
865 }
866
867
868 /**
869  * Shut down socket operations
870  * @param desc socket
871  * @param how type of shutdown
872  * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
873  */
874 int
875 GNUNET_NETWORK_socket_shutdown (struct GNUNET_NETWORK_Handle *desc, int how)
876 {
877   int ret;
878
879   ret = shutdown (desc->fd, how);
880 #ifdef MINGW
881   if (ret != 0)
882     SetErrnoFromWinsockError (WSAGetLastError ());
883 #endif
884   return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;
885 }
886
887
888 /**
889  * Disable the "CORK" feature for communication with the given socket,
890  * forcing the OS to immediately flush the buffer on transmission
891  * instead of potentially buffering multiple messages.  Essentially
892  * reduces the OS send buffers to zero.
893  *
894  * @param desc socket
895  * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
896  */
897 int
898 GNUNET_NETWORK_socket_disable_corking (struct GNUNET_NETWORK_Handle *desc)
899 {
900   int ret = 0;
901
902 #if WINDOWS
903   int value = 0;
904
905   if (0 !=
906       (ret =
907        setsockopt (desc->fd, SOL_SOCKET, SO_SNDBUF, (char *) &value,
908                    sizeof (value))))
909     LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "setsockopt");
910   if (0 !=
911       (ret =
912        setsockopt (desc->fd, SOL_SOCKET, SO_RCVBUF, (char *) &value,
913                    sizeof (value))))
914     LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "setsockopt");
915 #elif LINUX
916   int value = 0;
917
918   if (0 !=
919       (ret =
920        setsockopt (desc->fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof (value))))
921     LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "setsockopt");
922   if (0 !=
923       (ret =
924        setsockopt (desc->fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof (value))))
925     LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "setsockopt");
926 #endif
927   return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;
928 }
929
930
931 /**
932  * Reset FD set
933  *
934  * @param fds fd set
935  */
936 void
937 GNUNET_NETWORK_fdset_zero (struct GNUNET_NETWORK_FDSet *fds)
938 {
939   FD_ZERO (&fds->sds);
940   fds->nsds = 0;
941 #ifdef MINGW
942   GNUNET_CONTAINER_slist_clear (fds->handles);
943 #endif
944 }
945
946
947 /**
948  * Add a socket to the FD set
949  *
950  * @param fds fd set
951  * @param desc socket to add
952  */
953 void
954 GNUNET_NETWORK_fdset_set (struct GNUNET_NETWORK_FDSet *fds,
955                           const struct GNUNET_NETWORK_Handle *desc)
956 {
957   FD_SET (desc->fd, &fds->sds);
958   if (desc->fd + 1 > fds->nsds)
959     fds->nsds = desc->fd + 1;
960 }
961
962
963 /**
964  * Check whether a socket is part of the fd set
965  *
966  * @param fds fd set
967  * @param desc socket
968  * @return 0 if the FD is not set
969  */
970 int
971 GNUNET_NETWORK_fdset_isset (const struct GNUNET_NETWORK_FDSet *fds,
972                             const struct GNUNET_NETWORK_Handle *desc)
973 {
974   return FD_ISSET (desc->fd, &fds->sds);
975 }
976
977
978 /**
979  * Add one fd set to another
980  *
981  * @param dst the fd set to add to
982  * @param src the fd set to add from
983  */
984 void
985 GNUNET_NETWORK_fdset_add (struct GNUNET_NETWORK_FDSet *dst,
986                           const struct GNUNET_NETWORK_FDSet *src)
987 {
988 #ifndef MINGW
989   int nfds;
990
991   for (nfds = src->nsds; nfds >= 0; nfds--)
992     if (FD_ISSET (nfds, &src->sds))
993
994     {
995       FD_SET (nfds, &dst->sds);
996       if (nfds + 1 > dst->nsds)
997         dst->nsds = nfds + 1;
998     }
999 #else
1000   /* This is MinGW32-specific implementation that relies on the code that
1001    * winsock2.h defines for FD_SET. Namely, it relies on FD_SET checking
1002    * that fd being added is not already in the set.
1003    * Also relies on us knowing what's inside fd_set (fd_count and fd_array).
1004    */
1005   int i;
1006   for (i = 0; i < src->sds.fd_count; i++)
1007     FD_SET (src->sds.fd_array[i], &dst->sds);
1008   if (src->nsds > dst->nsds)
1009     dst->nsds = src->nsds;
1010
1011   GNUNET_CONTAINER_slist_append (dst->handles, src->handles);
1012 #endif
1013 }
1014
1015
1016 /**
1017  * Copy one fd set to another
1018  *
1019  * @param to destination
1020  * @param from source
1021  */
1022 void
1023 GNUNET_NETWORK_fdset_copy (struct GNUNET_NETWORK_FDSet *to,
1024                            const struct GNUNET_NETWORK_FDSet *from)
1025 {
1026   FD_COPY (&from->sds, &to->sds);
1027   to->nsds = from->nsds;
1028
1029 #ifdef MINGW
1030   GNUNET_CONTAINER_slist_clear (to->handles);
1031   GNUNET_CONTAINER_slist_append (to->handles, from->handles);
1032 #endif
1033 }
1034
1035
1036 /**
1037  * Return file descriptor for this network handle
1038  *
1039  * @param desc wrapper to process
1040  * @return POSIX file descriptor
1041  */
1042 int
1043 GNUNET_NETWORK_get_fd (struct GNUNET_NETWORK_Handle *desc)
1044 {
1045   return desc->fd;
1046 }
1047
1048
1049 /**
1050  * Return sockaddr for this network handle
1051  *
1052  * @param desc wrapper to process
1053  * @return sockaddr
1054  */
1055 struct sockaddr*
1056 GNUNET_NETWORK_get_addr (struct GNUNET_NETWORK_Handle *desc)
1057 {
1058   return desc->addr;
1059 }
1060
1061
1062 /**
1063  * Return sockaddr length for this network handle
1064  *
1065  * @param desc wrapper to process
1066  * @return socklen_t for sockaddr
1067  */
1068 socklen_t
1069 GNUNET_NETWORK_get_addrlen (struct GNUNET_NETWORK_Handle *desc)
1070 {
1071   return desc->addrlen;
1072 }
1073
1074
1075 /**
1076  * Copy a native fd set
1077  *
1078  * @param to destination
1079  * @param from native source set
1080  * @param nfds the biggest socket number in from + 1
1081  */
1082 void
1083 GNUNET_NETWORK_fdset_copy_native (struct GNUNET_NETWORK_FDSet *to,
1084                                   const fd_set * from, int nfds)
1085 {
1086   FD_COPY (from, &to->sds);
1087   to->nsds = nfds;
1088 }
1089
1090
1091 /**
1092  * Set a native fd in a set
1093  *
1094  * @param to destination
1095  * @param nfd native FD to set
1096  */
1097 void
1098 GNUNET_NETWORK_fdset_set_native (struct GNUNET_NETWORK_FDSet *to, int nfd)
1099 {
1100   GNUNET_assert ((nfd >= 0) && (nfd < FD_SETSIZE));
1101   FD_SET (nfd, &to->sds);
1102   to->nsds = GNUNET_MAX (nfd + 1, to->nsds);
1103 }
1104
1105
1106 /**
1107  * Test native fd in a set
1108  *
1109  * @param to set to test, NULL for empty set
1110  * @param nfd native FD to test, or -1 for none
1111  * @return #GNUNET_YES if FD is set in the set
1112  */
1113 int
1114 GNUNET_NETWORK_fdset_test_native (const struct GNUNET_NETWORK_FDSet *to,
1115                                   int nfd)
1116 {
1117   if ((nfd == -1) || (to == NULL))
1118     return GNUNET_NO;
1119   return FD_ISSET (nfd, &to->sds) ? GNUNET_YES : GNUNET_NO;
1120 }
1121
1122
1123 /**
1124  * Add a file handle to the fd set
1125  * @param fds fd set
1126  * @param h the file handle to add
1127  */
1128 void
1129 GNUNET_NETWORK_fdset_handle_set (struct GNUNET_NETWORK_FDSet *fds,
1130                                  const struct GNUNET_DISK_FileHandle *h)
1131 {
1132 #ifdef MINGW
1133   GNUNET_CONTAINER_slist_add (fds->handles,
1134                               GNUNET_CONTAINER_SLIST_DISPOSITION_TRANSIENT, h,
1135                               sizeof (struct GNUNET_DISK_FileHandle));
1136
1137 #else
1138   int fd;
1139
1140   GNUNET_DISK_internal_file_handle_ (h, &fd, sizeof (int));
1141   FD_SET (fd, &fds->sds);
1142   if (fd + 1 > fds->nsds)
1143     fds->nsds = fd + 1;
1144
1145 #endif
1146 }
1147
1148
1149 /**
1150  * Check if a file handle is part of an fd set
1151  * @param fds fd set
1152  * @param h file handle
1153  * @return #GNUNET_YES if the file handle is part of the set
1154  */
1155 int
1156 GNUNET_NETWORK_fdset_handle_isset (const struct GNUNET_NETWORK_FDSet *fds,
1157                                    const struct GNUNET_DISK_FileHandle *h)
1158 {
1159
1160 #ifdef MINGW
1161   return GNUNET_CONTAINER_slist_contains (fds->handles, h,
1162                                           sizeof (struct
1163                                                   GNUNET_DISK_FileHandle));
1164 #else
1165   return FD_ISSET (h->fd, &fds->sds);
1166 #endif
1167 }
1168
1169
1170 /**
1171  * Checks if two fd sets overlap
1172  * @param fds1 first fd set
1173  * @param fds2 second fd set
1174  * @return #GNUNET_YES if they do overlap, #GNUNET_NO otherwise
1175  */
1176 int
1177 GNUNET_NETWORK_fdset_overlap (const struct GNUNET_NETWORK_FDSet *fds1,
1178                               const struct GNUNET_NETWORK_FDSet *fds2)
1179 {
1180 #ifndef MINGW
1181   int nfds;
1182
1183   nfds = fds1->nsds;
1184   if (nfds > fds2->nsds)
1185     nfds = fds2->nsds;
1186   while (nfds > 0)
1187   {
1188     nfds--;
1189     if (FD_ISSET (nfds, &fds1->sds) && FD_ISSET (nfds, &fds2->sds))
1190       return GNUNET_YES;
1191   }
1192 #else
1193   struct GNUNET_CONTAINER_SList_Iterator it;
1194   struct GNUNET_DISK_FileHandle *h;
1195   int i;
1196   int j;
1197
1198   /*This code is somewhat hacky, we are not supposed to know what's
1199    * inside of fd_set; also the O(n^2) is really bad... */
1200
1201   for (i = 0; i < fds1->sds.fd_count; i++)
1202   {
1203     for (j = 0; j < fds2->sds.fd_count; j++)
1204     {
1205       if (fds1->sds.fd_array[i] == fds2->sds.fd_array[j])
1206         return GNUNET_YES;
1207     }
1208   }
1209   it = GNUNET_CONTAINER_slist_begin (fds1->handles);
1210   while (GNUNET_CONTAINER_slist_end (&it) != GNUNET_YES)
1211   {
1212 #if DEBUG_NETWORK
1213     struct GNUNET_CONTAINER_SList_Iterator t;
1214 #endif
1215     h = (struct GNUNET_DISK_FileHandle *) GNUNET_CONTAINER_slist_get (&it,
1216                                                                       NULL);
1217 #if DEBUG_NETWORK
1218     LOG (GNUNET_ERROR_TYPE_DEBUG, "Checking that FD 0x%x is in another set:\n",
1219          h->h);
1220     for (t = GNUNET_CONTAINER_slist_begin (fds2->handles);
1221          GNUNET_CONTAINER_slist_end (&t) != GNUNET_YES;
1222          GNUNET_CONTAINER_slist_next (&t))
1223     {
1224       struct GNUNET_DISK_FileHandle *fh;
1225
1226       fh = (struct GNUNET_DISK_FileHandle *) GNUNET_CONTAINER_slist_get (&t,
1227                                                                          NULL);
1228       LOG (GNUNET_ERROR_TYPE_DEBUG, "0x%x\n", fh->h);
1229     }
1230 #endif
1231     if (GNUNET_CONTAINER_slist_contains
1232         (fds2->handles, h, sizeof (struct GNUNET_DISK_FileHandle)))
1233     {
1234       return GNUNET_YES;
1235     }
1236     GNUNET_CONTAINER_slist_next (&it);
1237   }
1238 #endif
1239   return GNUNET_NO;
1240 }
1241
1242
1243 /**
1244  * Creates an fd set
1245  *
1246  * @return a new fd set
1247  */
1248 struct GNUNET_NETWORK_FDSet *
1249 GNUNET_NETWORK_fdset_create ()
1250 {
1251   struct GNUNET_NETWORK_FDSet *fds;
1252
1253   fds = GNUNET_new (struct GNUNET_NETWORK_FDSet);
1254 #ifdef MINGW
1255   fds->handles = GNUNET_CONTAINER_slist_create ();
1256 #endif
1257   GNUNET_NETWORK_fdset_zero (fds);
1258   return fds;
1259 }
1260
1261
1262 /**
1263  * Releases the associated memory of an fd set
1264  *
1265  * @param fds fd set
1266  */
1267 void
1268 GNUNET_NETWORK_fdset_destroy (struct GNUNET_NETWORK_FDSet *fds)
1269 {
1270 #ifdef MINGW
1271   GNUNET_CONTAINER_slist_destroy (fds->handles);
1272 #endif
1273   GNUNET_free (fds);
1274 }
1275
1276 #if MINGW
1277 struct _select_params
1278 {
1279   fd_set *r;
1280   fd_set *w;
1281   fd_set *e;
1282   struct timeval *tv;
1283   HANDLE wakeup;
1284   HANDLE standby;
1285   SOCKET wakeup_socket;
1286   int status;
1287 };
1288
1289 static DWORD WINAPI
1290 _selector (LPVOID p)
1291 {
1292   struct _select_params *sp = p;
1293
1294   while (1)
1295   {
1296     WaitForSingleObject (sp->standby, INFINITE);
1297     ResetEvent (sp->standby);
1298     sp->status = select (1, sp->r, sp->w, sp->e, sp->tv);
1299     if (FD_ISSET (sp->wakeup_socket, sp->r))
1300     {
1301       FD_CLR (sp->wakeup_socket, sp->r);
1302       sp->status -= 1;
1303     }
1304     SetEvent (sp->wakeup);
1305   }
1306   return 0;
1307 }
1308 #endif
1309
1310
1311 /**
1312  * Check if sockets or pipes meet certain conditions
1313  *
1314  * @param rfds set of sockets or pipes to be checked for readability
1315  * @param wfds set of sockets or pipes to be checked for writability
1316  * @param efds set of sockets or pipes to be checked for exceptions
1317  * @param timeout relative value when to return
1318  * @return number of selected sockets or pipes, #GNUNET_SYSERR on error
1319  */
1320 int
1321 GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds,
1322                               struct GNUNET_NETWORK_FDSet *wfds,
1323                               struct GNUNET_NETWORK_FDSet *efds,
1324                               const struct GNUNET_TIME_Relative timeout)
1325 {
1326   int nfds = 0;
1327 #ifdef MINGW
1328   int handles = 0;
1329   int ex_handles = 0;
1330   int read_handles = 0;
1331   int write_handles = 0;
1332
1333   int i = 0;
1334   int retcode = 0;
1335   uint64_t mcs_total = 0;
1336   DWORD ms_rounded = 0;
1337
1338   int nhandles = 0;
1339
1340   static HANDLE hEventPipeWrite = 0;
1341   static HANDLE hEventReadReady = 0;
1342
1343   static struct _select_params sp;
1344   static HANDLE select_thread = NULL;
1345   static HANDLE select_finished_event = NULL;
1346   static HANDLE select_standby_event = NULL;
1347   static SOCKET select_wakeup_socket = -1;
1348   static SOCKET select_send_socket = -1;
1349   static struct timeval select_timeout;
1350
1351   int readPipes = 0;
1352   int writePipePos = 0;
1353
1354   HANDLE handle_array[FD_SETSIZE + 2];
1355   int returncode = -1;
1356   int returnedpos = 0;
1357
1358   struct GNUNET_CONTAINER_SList *handles_read;
1359   struct GNUNET_CONTAINER_SList *handles_write;
1360   struct GNUNET_CONTAINER_SList *handles_except;
1361
1362   int selectret = 0;
1363
1364   fd_set aread;
1365   fd_set awrite;
1366   fd_set aexcept;
1367
1368 #if DEBUG_NETWORK
1369   fd_set bread;
1370   fd_set bwrite;
1371   fd_set bexcept;
1372 #endif
1373
1374   /* TODO: Make this growable */
1375   struct GNUNET_DISK_FileHandle *readArray[50];
1376 #else
1377   struct timeval tv;
1378 #endif
1379   if (NULL != rfds)
1380   {
1381     nfds = rfds->nsds;
1382 #ifdef MINGW
1383     handles += read_handles = GNUNET_CONTAINER_slist_count (rfds->handles);
1384 #if DEBUG_NETWORK
1385     {
1386       struct GNUNET_CONTAINER_SList_Iterator t;
1387
1388       for (t = GNUNET_CONTAINER_slist_begin (rfds->handles);
1389            GNUNET_CONTAINER_slist_end (&t) != GNUNET_YES;
1390            GNUNET_CONTAINER_slist_next (&t))
1391       {
1392         struct GNUNET_DISK_FileHandle *fh;
1393
1394         fh = (struct GNUNET_DISK_FileHandle *) GNUNET_CONTAINER_slist_get (&t,
1395                                                                            NULL);
1396         LOG (GNUNET_ERROR_TYPE_DEBUG, "FD 0x%x (0x%x) is SET in rfds\n", fh->h,
1397              fh);
1398       }
1399     }
1400 #endif
1401 #endif
1402   }
1403   if (NULL != wfds)
1404   {
1405     nfds = GNUNET_MAX (nfds, wfds->nsds);
1406 #ifdef MINGW
1407     handles += write_handles = GNUNET_CONTAINER_slist_count (wfds->handles);
1408 #endif
1409   }
1410   if (NULL != efds)
1411   {
1412     nfds = GNUNET_MAX (nfds, efds->nsds);
1413 #ifdef MINGW
1414     handles += ex_handles = GNUNET_CONTAINER_slist_count (efds->handles);
1415 #endif
1416   }
1417
1418   if ((nfds == 0) &&
1419       (timeout.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
1420 #ifdef MINGW
1421       && handles == 0
1422 #endif
1423       )
1424   {
1425     GNUNET_break (0);
1426     LOG (GNUNET_ERROR_TYPE_ERROR,
1427          _("Fatal internal logic error, process hangs in `%s' (abort with CTRL-C)!\n"),
1428          "select");
1429   }
1430 #ifndef MINGW
1431   tv.tv_sec = timeout.rel_value_us / GNUNET_TIME_UNIT_SECONDS.rel_value_us;
1432   tv.tv_usec =
1433     (timeout.rel_value_us -
1434      (tv.tv_sec * GNUNET_TIME_UNIT_SECONDS.rel_value_us));
1435   return select (nfds,
1436                  (NULL != rfds) ? &rfds->sds : NULL,
1437                  (NULL != wfds) ? &wfds->sds : NULL,
1438                  (NULL != efds) ? &efds->sds : NULL,
1439                  (timeout.rel_value_us ==
1440                   GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us) ? NULL : &tv);
1441
1442 #else
1443 #define SAFE_FD_ISSET(fd, set)  (set != NULL && FD_ISSET(fd, set))
1444   /* calculate how long we need to wait in microseconds */
1445   if (timeout.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
1446   {
1447     mcs_total = INFINITE;
1448     ms_rounded = INFINITE;
1449   }
1450   else
1451   {
1452     mcs_total = timeout.rel_value_us / GNUNET_TIME_UNIT_MICROSECONDS.rel_value_us;
1453     ms_rounded = (DWORD) (mcs_total / GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us);
1454     if (mcs_total > 0 && ms_rounded == 0)
1455       ms_rounded = 1;
1456   }
1457   /* select() may be used as a portable way to sleep */
1458   if (!(rfds || wfds || efds))
1459   {
1460     Sleep (ms_rounded);
1461     return 0;
1462   }
1463
1464   if (NULL == select_thread)
1465   {
1466     SOCKET select_listening_socket = -1;
1467     struct sockaddr_in s_in;
1468     int alen;
1469     int res;
1470     unsigned long p;
1471
1472     select_standby_event = CreateEvent (NULL, TRUE, FALSE, NULL);
1473     select_finished_event = CreateEvent (NULL, TRUE, FALSE, NULL);
1474
1475     select_wakeup_socket = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
1476
1477     select_listening_socket = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
1478
1479     p = 1;
1480     res = ioctlsocket (select_wakeup_socket, FIONBIO, &p);
1481     LOG (GNUNET_ERROR_TYPE_DEBUG, "Select thread initialization: ioctlsocket() returns %d\n", res);
1482
1483     alen = sizeof (s_in);
1484     s_in.sin_family = AF_INET;
1485     s_in.sin_port = 0;
1486     s_in.sin_addr.S_un.S_un_b.s_b1 = 127;
1487     s_in.sin_addr.S_un.S_un_b.s_b2 = 0;
1488     s_in.sin_addr.S_un.S_un_b.s_b3 = 0;
1489     s_in.sin_addr.S_un.S_un_b.s_b4 = 1;
1490     res = bind (select_listening_socket, (const struct sockaddr *) &s_in, sizeof (s_in));
1491     LOG (GNUNET_ERROR_TYPE_DEBUG, "Select thread initialization: bind() returns %d\n", res);
1492
1493     res = getsockname (select_listening_socket, (struct sockaddr *) &s_in, &alen);
1494     LOG (GNUNET_ERROR_TYPE_DEBUG, "Select thread initialization: getsockname() returns %d\n", res);
1495
1496     res = listen (select_listening_socket, SOMAXCONN);
1497     LOG (GNUNET_ERROR_TYPE_DEBUG, "Select thread initialization: listen() returns %d\n", res);
1498
1499     res = connect (select_wakeup_socket, (const struct sockaddr *) &s_in, sizeof (s_in));
1500     LOG (GNUNET_ERROR_TYPE_DEBUG, "Select thread initialization: connect() returns %d\n", res);
1501
1502     select_send_socket = accept (select_listening_socket, (struct sockaddr *) &s_in, &alen);
1503
1504     closesocket (select_listening_socket);
1505
1506     sp.wakeup = select_finished_event;
1507     sp.standby = select_standby_event;
1508     sp.wakeup_socket = select_wakeup_socket;
1509
1510     select_thread = CreateThread (NULL, 0, _selector, &sp, 0, NULL);
1511   }
1512
1513
1514   handles_read = GNUNET_CONTAINER_slist_create ();
1515   handles_write = GNUNET_CONTAINER_slist_create ();
1516   handles_except = GNUNET_CONTAINER_slist_create ();
1517   FD_ZERO (&aread);
1518   FD_ZERO (&awrite);
1519   FD_ZERO (&aexcept);
1520 #if DEBUG_NETWORK
1521   FD_ZERO (&bread);
1522   FD_ZERO (&bwrite);
1523   FD_ZERO (&bexcept);
1524 #endif
1525   if (rfds)
1526   {
1527     FD_COPY (&rfds->sds, &aread);
1528 #if DEBUG_NETWORK
1529     FD_COPY (&rfds->sds, &bread);
1530 #endif
1531   }
1532   if (wfds)
1533   {
1534     FD_COPY (&wfds->sds, &awrite);
1535 #if DEBUG_NETWORK
1536     FD_COPY (&wfds->sds, &bwrite);
1537 #endif
1538   }
1539   if (efds)
1540   {
1541     FD_COPY (&efds->sds, &aexcept);
1542 #if DEBUG_NETWORK
1543     FD_COPY (&efds->sds, &bexcept);
1544 #endif
1545   }
1546
1547   /* Start by doing a fast check on sockets and pipes (without waiting). It is cheap, and is sufficient most of the time.
1548      By profiling we detected that to be true in 90% of the cases.
1549   */
1550
1551   /* Do the select now */
1552   select_timeout.tv_sec = 0;
1553   select_timeout.tv_usec = 0;
1554
1555   /* Copy all the writes to the except, so we can detect connect() errors */
1556   for (i = 0; i < awrite.fd_count; i++)
1557     FD_SET (awrite.fd_array[i], &aexcept);
1558   if (aread.fd_count > 0 || awrite.fd_count > 0 || aexcept.fd_count > 0)
1559     selectret = select (1, (rfds != NULL) ? &aread : NULL,
1560         (wfds != NULL) ? &awrite : NULL, &aexcept, &select_timeout);
1561   else
1562     selectret = 0;
1563   if (selectret == -1)
1564   {
1565     /* Throw an error early on, while we still have the context. */
1566     LOG (GNUNET_ERROR_TYPE_ERROR, "W32 select(%d, %d, %d) failed: %lu\n",
1567         rfds ? aread.fd_count : 0, wfds ? awrite.fd_count : 0, aexcept.fd_count, GetLastError ());
1568     GNUNET_abort ();
1569   }
1570
1571   /* Check aexcept, add its contents to awrite
1572      This is technically wrong (aexcept might have its own descriptors), we should
1573      have checked that descriptors were in awrite originally before re-adding them from
1574      aexcept. Luckily, GNUnet never uses aexcept for anything, so this does not become a problem (yet). */
1575   for (i = 0; i < aexcept.fd_count; i++)
1576     FD_SET (aexcept.fd_array[i], &awrite);
1577
1578   /* If our select returned something or is a 0-timed request, then also check the pipes and get out of here! */
1579   /* Sadly, it means code duplication :( */
1580   if ((selectret > 0) || (mcs_total == 0))
1581   {
1582     /* Read Pipes */
1583     if (rfds && read_handles)
1584     {
1585       struct GNUNET_CONTAINER_SList_Iterator i;
1586       int c;
1587
1588       for (c = 0, i = GNUNET_CONTAINER_slist_begin (rfds->handles);
1589           GNUNET_CONTAINER_slist_end (&i) != GNUNET_YES;
1590           GNUNET_CONTAINER_slist_next (&i), c++)
1591       {
1592         struct GNUNET_DISK_FileHandle *fh;
1593
1594         fh = (struct GNUNET_DISK_FileHandle *) GNUNET_CONTAINER_slist_get (&i,NULL);
1595         if (fh->type == GNUNET_DISK_HANLDE_TYPE_PIPE)
1596         {
1597           DWORD error;
1598           BOOL bret;
1599
1600           SetLastError (0);
1601           DWORD waitstatus = 0;
1602           bret = PeekNamedPipe (fh->h, NULL, 0, NULL, &waitstatus, NULL);
1603           error = GetLastError ();
1604           LOG (GNUNET_ERROR_TYPE_DEBUG, "Peek at read pipe %d (0x%x) returned %d (%d bytes available) GLE %u\n",
1605               c, fh->h, bret, waitstatus, error);
1606           if (bret == 0)
1607           {
1608             /* TODO: either add more errors to this condition, or eliminate it
1609              * entirely (failed to peek -> pipe is in serious trouble, should
1610              * be selected as readable).
1611              */
1612             if (error != ERROR_BROKEN_PIPE && error != ERROR_INVALID_HANDLE)
1613               continue;
1614           }
1615           else if (waitstatus <= 0)
1616             continue;
1617           GNUNET_CONTAINER_slist_add (handles_read, GNUNET_CONTAINER_SLIST_DISPOSITION_TRANSIENT,
1618               fh, sizeof (struct GNUNET_DISK_FileHandle));
1619           retcode++;
1620           LOG (GNUNET_ERROR_TYPE_DEBUG, "Added read Pipe 0x%x (0x%x)\n",
1621               fh, fh->h);
1622         }
1623         else
1624         {
1625           GNUNET_CONTAINER_slist_add (handles_read, GNUNET_CONTAINER_SLIST_DISPOSITION_TRANSIENT,
1626               fh, sizeof (struct GNUNET_DISK_FileHandle));
1627           retcode++;
1628         }
1629       }
1630     }
1631     if (wfds && write_handles)
1632     {
1633       LOG (GNUNET_ERROR_TYPE_DEBUG,
1634           "Adding the write ready event to the array as %d\n", nhandles);
1635       GNUNET_CONTAINER_slist_append (handles_write, wfds->handles);
1636       retcode += write_handles;
1637     }
1638     if (efds && ex_handles)
1639     {
1640       struct GNUNET_CONTAINER_SList_Iterator i;
1641
1642       for (i = GNUNET_CONTAINER_slist_begin (efds->handles);
1643           GNUNET_CONTAINER_slist_end (&i) != GNUNET_YES;
1644           GNUNET_CONTAINER_slist_next (&i))
1645       {
1646         struct GNUNET_DISK_FileHandle *fh;
1647         DWORD dwBytes;
1648
1649         fh = (struct GNUNET_DISK_FileHandle *) GNUNET_CONTAINER_slist_get (&i, NULL);
1650         if (fh->type == GNUNET_DISK_HANLDE_TYPE_PIPE)
1651         {
1652           if (PeekNamedPipe (fh->h, NULL, 0, NULL, &dwBytes, NULL))
1653             continue;
1654           GNUNET_CONTAINER_slist_add (handles_except, GNUNET_CONTAINER_SLIST_DISPOSITION_TRANSIENT,
1655               fh, sizeof (struct GNUNET_DISK_FileHandle));
1656           retcode++;
1657         }
1658       }
1659     }
1660
1661     /* Add our select() result.*/
1662     if (selectret >= 0)
1663       retcode += selectret;
1664
1665     if (rfds)
1666     {
1667       GNUNET_NETWORK_fdset_zero (rfds);
1668       if (selectret != -1)
1669         GNUNET_NETWORK_fdset_copy_native (rfds, &aread, selectret);
1670       GNUNET_CONTAINER_slist_append (rfds->handles, handles_read);
1671     }
1672     if (wfds)
1673     {
1674       GNUNET_NETWORK_fdset_zero (wfds);
1675       if (selectret != -1)
1676         GNUNET_NETWORK_fdset_copy_native (wfds, &awrite, selectret);
1677       GNUNET_CONTAINER_slist_append (wfds->handles, handles_write);
1678     }
1679     if (efds)
1680     {
1681       GNUNET_NETWORK_fdset_zero (efds);
1682       if (selectret != -1)
1683         GNUNET_NETWORK_fdset_copy_native (efds, &aexcept, selectret);
1684       GNUNET_CONTAINER_slist_append (efds->handles, handles_except);
1685     }
1686     GNUNET_CONTAINER_slist_destroy (handles_read);
1687     GNUNET_CONTAINER_slist_destroy (handles_write);
1688     GNUNET_CONTAINER_slist_destroy (handles_except);
1689
1690     if (selectret == -1)
1691       return -1;
1692     return retcode;
1693   }
1694
1695   /* If we got this far, use slower implementation that is able to do a waiting select
1696      on both sockets and pipes simultaneously */
1697
1698   /* Events for pipes */
1699   if (!hEventReadReady)
1700     hEventReadReady = CreateEvent (NULL, TRUE, TRUE, NULL);
1701   if (!hEventPipeWrite)
1702     hEventPipeWrite = CreateEvent (NULL, TRUE, TRUE, NULL);
1703   readPipes = 0;
1704   writePipePos = -1;
1705
1706   retcode = 0;
1707
1708   FD_ZERO (&aread);
1709   FD_ZERO (&awrite);
1710   FD_ZERO (&aexcept);
1711 #if DEBUG_NETWORK
1712   FD_ZERO (&bread);
1713   FD_ZERO (&bwrite);
1714   FD_ZERO (&bexcept);
1715 #endif
1716   if (rfds)
1717   {
1718     FD_COPY (&rfds->sds, &aread);
1719 #if DEBUG_NETWORK
1720     FD_COPY (&rfds->sds, &bread);
1721 #endif
1722   }
1723   if (wfds)
1724   {
1725     FD_COPY (&wfds->sds, &awrite);
1726 #if DEBUG_NETWORK
1727     FD_COPY (&wfds->sds, &bwrite);
1728 #endif
1729   }
1730   if (efds)
1731   {
1732     FD_COPY (&efds->sds, &aexcept);
1733 #if DEBUG_NETWORK
1734     FD_COPY (&efds->sds, &bexcept);
1735 #endif
1736   }
1737   /* We will first Add the PIPES to the events */
1738   /* Read Pipes */
1739   if (rfds && read_handles)
1740   {
1741     struct GNUNET_CONTAINER_SList_Iterator i;
1742
1743     for (i = GNUNET_CONTAINER_slist_begin (rfds->handles);
1744          GNUNET_CONTAINER_slist_end (&i) != GNUNET_YES;
1745          GNUNET_CONTAINER_slist_next (&i))
1746     {
1747       struct GNUNET_DISK_FileHandle *fh;
1748
1749       fh = (struct GNUNET_DISK_FileHandle *) GNUNET_CONTAINER_slist_get (&i,
1750                                                                          NULL);
1751       if (fh->type == GNUNET_DISK_HANLDE_TYPE_PIPE)
1752       {
1753         /* Read zero bytes to check the status of the pipe */
1754         LOG (GNUNET_ERROR_TYPE_DEBUG, "Reading 0 bytes from the pipe 0x%x\n",
1755              fh->h);
1756         if (!ReadFile (fh->h, NULL, 0, NULL, fh->oOverlapRead))
1757         {
1758           DWORD error_code = GetLastError ();
1759
1760           if (error_code == ERROR_IO_PENDING)
1761           {
1762             LOG (GNUNET_ERROR_TYPE_DEBUG,
1763                  "Adding the pipe's 0x%x overlapped event to the array as %d\n",
1764                  fh->h, nhandles);
1765             handle_array[nhandles++] = fh->oOverlapRead->hEvent;
1766             readArray[readPipes++] = fh;
1767           }
1768           else
1769           {
1770             LOG (GNUNET_ERROR_TYPE_DEBUG,
1771                  "Read failed, adding the read ready event to the array as %d\n", nhandles);
1772             handle_array[nhandles++] = hEventReadReady;
1773             readArray[readPipes++] = fh;
1774           }
1775         }
1776         else
1777         {
1778           LOG (GNUNET_ERROR_TYPE_DEBUG,
1779                "Adding the read ready event to the array as %d\n", nhandles);
1780           handle_array[nhandles++] = hEventReadReady;
1781           readArray[readPipes++] = fh;
1782         }
1783       }
1784       else
1785       {
1786         GNUNET_CONTAINER_slist_add (handles_read,
1787                                     GNUNET_CONTAINER_SLIST_DISPOSITION_TRANSIENT,
1788                                     fh, sizeof (struct GNUNET_DISK_FileHandle));
1789       }
1790     }
1791   }
1792   if (wfds && write_handles)
1793   {
1794     LOG (GNUNET_ERROR_TYPE_DEBUG,
1795          "Adding the write ready event to the array as %d\n", nhandles);
1796     handle_array[nhandles++] = hEventPipeWrite;
1797     writePipePos = nhandles;
1798   }
1799   if (efds && ex_handles)
1800   {
1801     struct GNUNET_CONTAINER_SList_Iterator i;
1802
1803     for (i = GNUNET_CONTAINER_slist_begin (efds->handles);
1804          GNUNET_CONTAINER_slist_end (&i) != GNUNET_YES;
1805          GNUNET_CONTAINER_slist_next (&i))
1806     {
1807       struct GNUNET_DISK_FileHandle *fh;
1808       DWORD dwBytes;
1809
1810       fh = (struct GNUNET_DISK_FileHandle *) GNUNET_CONTAINER_slist_get (&i,
1811                                                                          NULL);
1812       if (fh->type == GNUNET_DISK_HANLDE_TYPE_PIPE)
1813       {
1814         if (!PeekNamedPipe (fh->h, NULL, 0, NULL, &dwBytes, NULL))
1815         {
1816           GNUNET_CONTAINER_slist_add (handles_except,
1817                                       GNUNET_CONTAINER_SLIST_DISPOSITION_TRANSIENT,
1818                                       fh,
1819                                       sizeof (struct GNUNET_DISK_FileHandle));
1820         }
1821       }
1822     }
1823   }
1824
1825   sp.status = 0;
1826
1827   if (nfds > 0)
1828   {
1829     LOG (GNUNET_ERROR_TYPE_DEBUG,
1830          "Adding the socket event to the array as %d\n",
1831          nhandles);
1832     handle_array[nhandles++] = select_finished_event;
1833     if (timeout.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
1834       sp.tv = NULL;
1835     else
1836     {
1837       select_timeout.tv_sec = timeout.rel_value_us / GNUNET_TIME_UNIT_SECONDS.rel_value_us;
1838       select_timeout.tv_usec =(timeout.rel_value_us -
1839           (select_timeout.tv_sec * GNUNET_TIME_UNIT_SECONDS.rel_value_us));
1840       sp.tv = &select_timeout;
1841     }
1842     FD_SET (select_wakeup_socket, &aread);
1843     do
1844     {
1845       i = recv (select_wakeup_socket, (char *) &returnedpos, 1, 0);
1846     } while (i == 1);
1847     sp.r = &aread;
1848     sp.w = &awrite;
1849     sp.e = &aexcept;
1850     /* Failed connections cause sockets to be set in errorfds on W32,
1851      * but on POSIX it should set them in writefds.
1852      * First copy all awrite sockets to aexcept, later we'll
1853      * check aexcept and set its contents in awrite as well
1854      * Sockets are also set in errorfds when OOB data is available,
1855      * but we don't use OOB data.
1856      */
1857     for (i = 0; i < awrite.fd_count; i++)
1858       FD_SET (awrite.fd_array[i], &aexcept);
1859     ResetEvent (select_finished_event);
1860     SetEvent (select_standby_event);
1861   }
1862
1863   handle_array[nhandles] = NULL;
1864   LOG (GNUNET_ERROR_TYPE_DEBUG, "nfds: %d, handles: %d, will wait: %llu mcs\n",
1865        nfds, nhandles, mcs_total);
1866   if (nhandles)
1867   {
1868     returncode =
1869         WaitForMultipleObjects (nhandles, handle_array, FALSE, ms_rounded);
1870     LOG (GNUNET_ERROR_TYPE_DEBUG, "WaitForMultipleObjects Returned : %d\n", returncode);
1871   }
1872   else if (nfds > 0)
1873   {
1874     GNUNET_break (0); /* This branch shouldn't actually be executed...*/
1875     i = (int) WaitForSingleObject (select_finished_event, INFINITE);
1876     returncode = WAIT_TIMEOUT;
1877   }
1878   else
1879   {
1880     /* Shouldn't come this far. If it does - investigate. */
1881     GNUNET_assert (0);
1882   }
1883
1884   if (nfds > 0)
1885   {
1886     /* Don't wake up select-thread when delay is 0, it should return immediately
1887      * and wake up by itself.
1888      */
1889     if (mcs_total != 0)
1890       i = send (select_send_socket, (const char *) &returnedpos, 1, 0);
1891     i = (int) WaitForSingleObject (select_finished_event, INFINITE);
1892     LOG (GNUNET_ERROR_TYPE_DEBUG, "Finished waiting for the select thread: %d %d\n", i, sp.status);
1893     if (mcs_total != 0)
1894     {
1895       do
1896       {
1897         i = recv (select_wakeup_socket, (char *) &returnedpos, 1, 0);
1898       } while (i == 1);
1899     }
1900     /* Check aexcept, add its contents to awrite */
1901     for (i = 0; i < aexcept.fd_count; i++)
1902       FD_SET (aexcept.fd_array[i], &awrite);
1903   }
1904
1905   returnedpos = returncode - WAIT_OBJECT_0;
1906   LOG (GNUNET_ERROR_TYPE_DEBUG, "return pos is : %d\n", returnedpos);
1907
1908   if (nhandles && (returnedpos < nhandles))
1909   {
1910     DWORD waitstatus;
1911
1912     if (sp.status > 0)
1913       retcode += sp.status;
1914
1915     if ((writePipePos != -1) && (returnedpos < writePipePos))
1916     {
1917       GNUNET_CONTAINER_slist_append (handles_write, wfds->handles);
1918       retcode += write_handles;
1919       LOG (GNUNET_ERROR_TYPE_DEBUG, "Added write pipe\n");
1920     }
1921     LOG (GNUNET_ERROR_TYPE_DEBUG, "ReadPipes is : %d\n", readPipes);
1922     /* We have some pipes ready for read. */
1923     if (returnedpos < readPipes)
1924     {
1925       for (i = 0; i < readPipes; i++)
1926       {
1927         DWORD error;
1928         BOOL bret;
1929
1930         SetLastError (0);
1931         waitstatus = 0;
1932         bret =
1933             PeekNamedPipe (readArray[i]->h, NULL, 0, NULL, &waitstatus, NULL);
1934         error = GetLastError ();
1935         LOG (GNUNET_ERROR_TYPE_DEBUG,
1936              "Peek at read pipe %d (0x%x) returned %d (%d bytes available) GLE %u\n",
1937              i, readArray[i]->h, bret, waitstatus, error);
1938         if (bret == 0)
1939         {
1940           /* TODO: either add more errors to this condition, or eliminate it
1941            * entirely (failed to peek -> pipe is in serious trouble, should
1942            * be selected as readable).
1943            */
1944           if (error != ERROR_BROKEN_PIPE && error != ERROR_INVALID_HANDLE)
1945             continue;
1946         }
1947         else if (waitstatus <= 0)
1948           continue;
1949         GNUNET_CONTAINER_slist_add (handles_read,
1950                                     GNUNET_CONTAINER_SLIST_DISPOSITION_TRANSIENT,
1951                                     readArray[i],
1952                                     sizeof (struct GNUNET_DISK_FileHandle));
1953         retcode++;
1954         LOG (GNUNET_ERROR_TYPE_DEBUG, "Added read Pipe 0x%x (0x%x)\n",
1955              readArray[i], readArray[i]->h);
1956       }
1957     }
1958   }
1959   if (!nhandles || (returnedpos >= nhandles))
1960     LOG (GNUNET_ERROR_TYPE_DEBUG, "Returning from _select() with nothing!\n");
1961   if (rfds)
1962   {
1963     struct GNUNET_CONTAINER_SList_Iterator t;
1964
1965     for (t = GNUNET_CONTAINER_slist_begin (rfds->handles);
1966          GNUNET_CONTAINER_slist_end (&t) != GNUNET_YES;
1967          GNUNET_CONTAINER_slist_next (&t))
1968     {
1969       struct GNUNET_DISK_FileHandle *fh;
1970
1971       fh = (struct GNUNET_DISK_FileHandle *) GNUNET_CONTAINER_slist_get (&t,
1972                                                                          NULL);
1973       if (fh->type == GNUNET_DISK_HANLDE_TYPE_PIPE)
1974       {
1975         CancelIo (fh->h);
1976       }
1977     }
1978     LOG (GNUNET_ERROR_TYPE_DEBUG, "Zeroing rfds%s\n", (retcode != -1 && nhandles && (returnedpos < nhandles)) ? ", copying fdset" : "");
1979     GNUNET_NETWORK_fdset_zero (rfds);
1980     if (retcode != -1 && nhandles && (returnedpos < nhandles))
1981       GNUNET_NETWORK_fdset_copy_native (rfds, &aread, retcode);
1982     GNUNET_CONTAINER_slist_append (rfds->handles, handles_read);
1983   }
1984   if (wfds)
1985   {
1986     LOG (GNUNET_ERROR_TYPE_DEBUG, "Zeroing wfds%s\n", (retcode != -1 && nhandles && (returnedpos < nhandles)) ? ", copying fdset" : "");
1987     GNUNET_NETWORK_fdset_zero (wfds);
1988     if (retcode != -1 && nhandles && (returnedpos < nhandles))
1989       GNUNET_NETWORK_fdset_copy_native (wfds, &awrite, retcode);
1990     GNUNET_CONTAINER_slist_append (wfds->handles, handles_write);
1991   }
1992   if (efds)
1993   {
1994     LOG (GNUNET_ERROR_TYPE_DEBUG, "Zeroing efds%s\n", (retcode != -1 && nhandles && (returnedpos < nhandles)) ? ", copying fdset" : "");
1995     GNUNET_NETWORK_fdset_zero (efds);
1996     if (retcode != -1 && nhandles && (returnedpos < nhandles))
1997       GNUNET_NETWORK_fdset_copy_native (efds, &aexcept, retcode);
1998     GNUNET_CONTAINER_slist_append (efds->handles, handles_except);
1999   }
2000   GNUNET_CONTAINER_slist_destroy (handles_read);
2001   GNUNET_CONTAINER_slist_destroy (handles_write);
2002   GNUNET_CONTAINER_slist_destroy (handles_except);
2003 #if DEBUG_NETWORK
2004   if (rfds)
2005   {
2006     struct GNUNET_CONTAINER_SList_Iterator t;
2007
2008     LOG (GNUNET_ERROR_TYPE_DEBUG, "rfds:\n");
2009     for (i = 0; i < rfds->sds.fd_count; i++)
2010     {
2011       LOG (GNUNET_ERROR_TYPE_DEBUG, "%d\n", rfds->sds.fd_array[i]);
2012     }
2013     for (t = GNUNET_CONTAINER_slist_begin (rfds->handles);
2014          GNUNET_CONTAINER_slist_end (&t) != GNUNET_YES;
2015          GNUNET_CONTAINER_slist_next (&t))
2016     {
2017       struct GNUNET_DISK_FileHandle *fh;
2018
2019       fh = (struct GNUNET_DISK_FileHandle *) GNUNET_CONTAINER_slist_get (&t,
2020                                                                          NULL);
2021       LOG (GNUNET_ERROR_TYPE_DEBUG, "%d\n", fh->h);
2022     }
2023   }
2024   if (wfds)
2025   {
2026     LOG (GNUNET_ERROR_TYPE_DEBUG, "wfds:\n");
2027     for (i = 0; i < wfds->sds.fd_count; i++)
2028     {
2029       LOG (GNUNET_ERROR_TYPE_DEBUG, "%d\n", wfds->sds.fd_array[i]);
2030     }
2031   }
2032   if (efds)
2033   {
2034     LOG (GNUNET_ERROR_TYPE_DEBUG, "efds:\n");
2035     for (i = 0; i < efds->sds.fd_count; i++)
2036     {
2037       LOG (GNUNET_ERROR_TYPE_DEBUG, "%d\n", efds->sds.fd_array[i]);
2038     }
2039   }
2040   LOG (GNUNET_ERROR_TYPE_DEBUG, "Returning %d or 0\n", retcode);
2041 #endif
2042   if (nhandles && (returnedpos < nhandles))
2043     return retcode;
2044   else
2045 #endif
2046     return 0;
2047 }
2048
2049 /* end of network.c */