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