minor changes for address conversion
[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 option_value
833  * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
834  */
835 int
836 GNUNET_NETWORK_socket_setsockopt (struct GNUNET_NETWORK_Handle *fd, int level,
837                                   int option_name, const void *option_value,
838                                   socklen_t option_len)
839 {
840   int ret;
841
842   ret = setsockopt (fd->fd, level, option_name, option_value, option_len);
843 #ifdef MINGW
844   if (SOCKET_ERROR == ret)
845     SetErrnoFromWinsockError (WSAGetLastError ());
846 #endif
847   return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;
848 }
849
850
851 /**
852  * Create a new socket.  Configure it for non-blocking IO and
853  * mark it as non-inheritable to child processes (set the
854  * close-on-exec flag).
855  *
856  * @param domain domain of the socket
857  * @param type socket type
858  * @param protocol network protocol
859  * @return new socket, NULL on error
860  */
861 struct GNUNET_NETWORK_Handle *
862 GNUNET_NETWORK_socket_create (int domain, int type, int protocol)
863 {
864   struct GNUNET_NETWORK_Handle *ret;
865
866   ret = GNUNET_new (struct GNUNET_NETWORK_Handle);
867   ret->fd = socket (domain, type, protocol);
868   if (-1 == ret->fd)
869   {
870     GNUNET_free (ret);
871     return NULL;
872   }
873   if (GNUNET_OK !=
874       initialize_network_handle (ret, domain, type))
875     return NULL;
876   return ret;
877 }
878
879
880 /**
881  * Shut down socket operations
882  * @param desc socket
883  * @param how type of shutdown
884  * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
885  */
886 int
887 GNUNET_NETWORK_socket_shutdown (struct GNUNET_NETWORK_Handle *desc, int how)
888 {
889   int ret;
890
891   ret = shutdown (desc->fd, how);
892 #ifdef MINGW
893   if (ret != 0)
894     SetErrnoFromWinsockError (WSAGetLastError ());
895 #endif
896   return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;
897 }
898
899
900 /**
901  * Disable the "CORK" feature for communication with the given socket,
902  * forcing the OS to immediately flush the buffer on transmission
903  * instead of potentially buffering multiple messages.  Essentially
904  * reduces the OS send buffers to zero.
905  *
906  * @param desc socket
907  * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
908  */
909 int
910 GNUNET_NETWORK_socket_disable_corking (struct GNUNET_NETWORK_Handle *desc)
911 {
912   int ret = 0;
913
914 #if WINDOWS
915   int value = 0;
916
917   if (0 !=
918       (ret =
919        setsockopt (desc->fd, SOL_SOCKET, SO_SNDBUF, (char *) &value,
920                    sizeof (value))))
921     LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "setsockopt");
922   if (0 !=
923       (ret =
924        setsockopt (desc->fd, SOL_SOCKET, SO_RCVBUF, (char *) &value,
925                    sizeof (value))))
926     LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "setsockopt");
927 #elif LINUX
928   int value = 0;
929
930   if (0 !=
931       (ret =
932        setsockopt (desc->fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof (value))))
933     LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "setsockopt");
934   if (0 !=
935       (ret =
936        setsockopt (desc->fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof (value))))
937     LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "setsockopt");
938 #endif
939   return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;
940 }
941
942
943 /**
944  * Reset FD set
945  *
946  * @param fds fd set
947  */
948 void
949 GNUNET_NETWORK_fdset_zero (struct GNUNET_NETWORK_FDSet *fds)
950 {
951   FD_ZERO (&fds->sds);
952   fds->nsds = 0;
953 #ifdef MINGW
954   GNUNET_CONTAINER_slist_clear (fds->handles);
955 #endif
956 }
957
958
959 /**
960  * Add a socket to the FD set
961  *
962  * @param fds fd set
963  * @param desc socket to add
964  */
965 void
966 GNUNET_NETWORK_fdset_set (struct GNUNET_NETWORK_FDSet *fds,
967                           const struct GNUNET_NETWORK_Handle *desc)
968 {
969   FD_SET (desc->fd, &fds->sds);
970   if (desc->fd + 1 > fds->nsds)
971     fds->nsds = desc->fd + 1;
972 }
973
974
975 /**
976  * Check whether a socket is part of the fd set
977  *
978  * @param fds fd set
979  * @param desc socket
980  * @return 0 if the FD is not set
981  */
982 int
983 GNUNET_NETWORK_fdset_isset (const struct GNUNET_NETWORK_FDSet *fds,
984                             const struct GNUNET_NETWORK_Handle *desc)
985 {
986   return FD_ISSET (desc->fd, &fds->sds);
987 }
988
989
990 /**
991  * Add one fd set to another
992  *
993  * @param dst the fd set to add to
994  * @param src the fd set to add from
995  */
996 void
997 GNUNET_NETWORK_fdset_add (struct GNUNET_NETWORK_FDSet *dst,
998                           const struct GNUNET_NETWORK_FDSet *src)
999 {
1000 #ifndef MINGW
1001   int nfds;
1002
1003   for (nfds = src->nsds; nfds >= 0; nfds--)
1004     if (FD_ISSET (nfds, &src->sds))
1005
1006     {
1007       FD_SET (nfds, &dst->sds);
1008       if (nfds + 1 > dst->nsds)
1009         dst->nsds = nfds + 1;
1010     }
1011 #else
1012   /* This is MinGW32-specific implementation that relies on the code that
1013    * winsock2.h defines for FD_SET. Namely, it relies on FD_SET checking
1014    * that fd being added is not already in the set.
1015    * Also relies on us knowing what's inside fd_set (fd_count and fd_array).
1016    */
1017   int i;
1018   for (i = 0; i < src->sds.fd_count; i++)
1019     FD_SET (src->sds.fd_array[i], &dst->sds);
1020   if (src->nsds > dst->nsds)
1021     dst->nsds = src->nsds;
1022
1023   GNUNET_CONTAINER_slist_append (dst->handles, src->handles);
1024 #endif
1025 }
1026
1027
1028 /**
1029  * Copy one fd set to another
1030  *
1031  * @param to destination
1032  * @param from source
1033  */
1034 void
1035 GNUNET_NETWORK_fdset_copy (struct GNUNET_NETWORK_FDSet *to,
1036                            const struct GNUNET_NETWORK_FDSet *from)
1037 {
1038   FD_COPY (&from->sds, &to->sds);
1039   to->nsds = from->nsds;
1040
1041 #ifdef MINGW
1042   GNUNET_CONTAINER_slist_clear (to->handles);
1043   GNUNET_CONTAINER_slist_append (to->handles, from->handles);
1044 #endif
1045 }
1046
1047
1048 /**
1049  * Return file descriptor for this network handle
1050  *
1051  * @param desc wrapper to process
1052  * @return POSIX file descriptor
1053  */
1054 int
1055 GNUNET_NETWORK_get_fd (struct GNUNET_NETWORK_Handle *desc)
1056 {
1057   return desc->fd;
1058 }
1059
1060
1061 /**
1062  * Return sockaddr for this network handle
1063  *
1064  * @param desc wrapper to process
1065  * @return sockaddr
1066  */
1067 struct sockaddr*
1068 GNUNET_NETWORK_get_addr (struct GNUNET_NETWORK_Handle *desc)
1069 {
1070   return desc->addr;
1071 }
1072
1073
1074 /**
1075  * Return sockaddr length for this network handle
1076  *
1077  * @param desc wrapper to process
1078  * @return socklen_t for sockaddr
1079  */
1080 socklen_t
1081 GNUNET_NETWORK_get_addrlen (struct GNUNET_NETWORK_Handle *desc)
1082 {
1083   return desc->addrlen;
1084 }
1085
1086
1087 /**
1088  * Copy a native fd set
1089  *
1090  * @param to destination
1091  * @param from native source set
1092  * @param nfds the biggest socket number in from + 1
1093  */
1094 void
1095 GNUNET_NETWORK_fdset_copy_native (struct GNUNET_NETWORK_FDSet *to,
1096                                   const fd_set * from, int nfds)
1097 {
1098   FD_COPY (from, &to->sds);
1099   to->nsds = nfds;
1100 }
1101
1102
1103 /**
1104  * Set a native fd in a set
1105  *
1106  * @param to destination
1107  * @param nfd native FD to set
1108  */
1109 void
1110 GNUNET_NETWORK_fdset_set_native (struct GNUNET_NETWORK_FDSet *to, int nfd)
1111 {
1112   GNUNET_assert ((nfd >= 0) && (nfd < FD_SETSIZE));
1113   FD_SET (nfd, &to->sds);
1114   to->nsds = GNUNET_MAX (nfd + 1, to->nsds);
1115 }
1116
1117
1118 /**
1119  * Test native fd in a set
1120  *
1121  * @param to set to test, NULL for empty set
1122  * @param nfd native FD to test, or -1 for none
1123  * @return #GNUNET_YES if FD is set in the set
1124  */
1125 int
1126 GNUNET_NETWORK_fdset_test_native (const struct GNUNET_NETWORK_FDSet *to,
1127                                   int nfd)
1128 {
1129   if ((nfd == -1) || (to == NULL))
1130     return GNUNET_NO;
1131   return FD_ISSET (nfd, &to->sds) ? GNUNET_YES : GNUNET_NO;
1132 }
1133
1134
1135 /**
1136  * Add a file handle to the fd set
1137  * @param fds fd set
1138  * @param h the file handle to add
1139  */
1140 void
1141 GNUNET_NETWORK_fdset_handle_set (struct GNUNET_NETWORK_FDSet *fds,
1142                                  const struct GNUNET_DISK_FileHandle *h)
1143 {
1144 #ifdef MINGW
1145   GNUNET_CONTAINER_slist_add (fds->handles,
1146                               GNUNET_CONTAINER_SLIST_DISPOSITION_TRANSIENT, h,
1147                               sizeof (struct GNUNET_DISK_FileHandle));
1148
1149 #else
1150   int fd;
1151
1152   GNUNET_DISK_internal_file_handle_ (h, &fd, sizeof (int));
1153   FD_SET (fd, &fds->sds);
1154   if (fd + 1 > fds->nsds)
1155     fds->nsds = fd + 1;
1156
1157 #endif
1158 }
1159
1160
1161 /**
1162  * Check if a file handle is part of an fd set
1163  * @param fds fd set
1164  * @param h file handle
1165  * @return #GNUNET_YES if the file handle is part of the set
1166  */
1167 int
1168 GNUNET_NETWORK_fdset_handle_isset (const struct GNUNET_NETWORK_FDSet *fds,
1169                                    const struct GNUNET_DISK_FileHandle *h)
1170 {
1171
1172 #ifdef MINGW
1173   return GNUNET_CONTAINER_slist_contains (fds->handles, h,
1174                                           sizeof (struct
1175                                                   GNUNET_DISK_FileHandle));
1176 #else
1177   return FD_ISSET (h->fd, &fds->sds);
1178 #endif
1179 }
1180
1181
1182 /**
1183  * Checks if two fd sets overlap
1184  * @param fds1 first fd set
1185  * @param fds2 second fd set
1186  * @return #GNUNET_YES if they do overlap, #GNUNET_NO otherwise
1187  */
1188 int
1189 GNUNET_NETWORK_fdset_overlap (const struct GNUNET_NETWORK_FDSet *fds1,
1190                               const struct GNUNET_NETWORK_FDSet *fds2)
1191 {
1192 #ifndef MINGW
1193   int nfds;
1194
1195   nfds = fds1->nsds;
1196   if (nfds > fds2->nsds)
1197     nfds = fds2->nsds;
1198   while (nfds > 0)
1199   {
1200     nfds--;
1201     if (FD_ISSET (nfds, &fds1->sds) && FD_ISSET (nfds, &fds2->sds))
1202       return GNUNET_YES;
1203   }
1204 #else
1205   struct GNUNET_CONTAINER_SList_Iterator it;
1206   struct GNUNET_DISK_FileHandle *h;
1207   int i;
1208   int j;
1209
1210   /*This code is somewhat hacky, we are not supposed to know what's
1211    * inside of fd_set; also the O(n^2) is really bad... */
1212
1213   for (i = 0; i < fds1->sds.fd_count; i++)
1214   {
1215     for (j = 0; j < fds2->sds.fd_count; j++)
1216     {
1217       if (fds1->sds.fd_array[i] == fds2->sds.fd_array[j])
1218         return GNUNET_YES;
1219     }
1220   }
1221   it = GNUNET_CONTAINER_slist_begin (fds1->handles);
1222   while (GNUNET_CONTAINER_slist_end (&it) != GNUNET_YES)
1223   {
1224 #if DEBUG_NETWORK
1225     struct GNUNET_CONTAINER_SList_Iterator t;
1226 #endif
1227     h = (struct GNUNET_DISK_FileHandle *) GNUNET_CONTAINER_slist_get (&it,
1228                                                                       NULL);
1229 #if DEBUG_NETWORK
1230     LOG (GNUNET_ERROR_TYPE_DEBUG, "Checking that FD 0x%x is in another set:\n",
1231          h->h);
1232     for (t = GNUNET_CONTAINER_slist_begin (fds2->handles);
1233          GNUNET_CONTAINER_slist_end (&t) != GNUNET_YES;
1234          GNUNET_CONTAINER_slist_next (&t))
1235     {
1236       struct GNUNET_DISK_FileHandle *fh;
1237
1238       fh = (struct GNUNET_DISK_FileHandle *) GNUNET_CONTAINER_slist_get (&t,
1239                                                                          NULL);
1240       LOG (GNUNET_ERROR_TYPE_DEBUG, "0x%x\n", fh->h);
1241     }
1242 #endif
1243     if (GNUNET_CONTAINER_slist_contains
1244         (fds2->handles, h, sizeof (struct GNUNET_DISK_FileHandle)))
1245     {
1246       return GNUNET_YES;
1247     }
1248     GNUNET_CONTAINER_slist_next (&it);
1249   }
1250 #endif
1251   return GNUNET_NO;
1252 }
1253
1254
1255 /**
1256  * Creates an fd set
1257  *
1258  * @return a new fd set
1259  */
1260 struct GNUNET_NETWORK_FDSet *
1261 GNUNET_NETWORK_fdset_create ()
1262 {
1263   struct GNUNET_NETWORK_FDSet *fds;
1264
1265   fds = GNUNET_new (struct GNUNET_NETWORK_FDSet);
1266 #ifdef MINGW
1267   fds->handles = GNUNET_CONTAINER_slist_create ();
1268 #endif
1269   GNUNET_NETWORK_fdset_zero (fds);
1270   return fds;
1271 }
1272
1273
1274 /**
1275  * Releases the associated memory of an fd set
1276  *
1277  * @param fds fd set
1278  */
1279 void
1280 GNUNET_NETWORK_fdset_destroy (struct GNUNET_NETWORK_FDSet *fds)
1281 {
1282 #ifdef MINGW
1283   GNUNET_CONTAINER_slist_destroy (fds->handles);
1284 #endif
1285   GNUNET_free (fds);
1286 }
1287
1288 #if MINGW
1289 struct _select_params
1290 {
1291   fd_set *r;
1292   fd_set *w;
1293   fd_set *e;
1294   struct timeval *tv;
1295   HANDLE wakeup;
1296   HANDLE standby;
1297   SOCKET wakeup_socket;
1298   int status;
1299 };
1300
1301 static DWORD WINAPI
1302 _selector (LPVOID p)
1303 {
1304   struct _select_params *sp = p;
1305
1306   while (1)
1307   {
1308     WaitForSingleObject (sp->standby, INFINITE);
1309     ResetEvent (sp->standby);
1310     sp->status = select (1, sp->r, sp->w, sp->e, sp->tv);
1311     if (FD_ISSET (sp->wakeup_socket, sp->r))
1312     {
1313       FD_CLR (sp->wakeup_socket, sp->r);
1314       sp->status -= 1;
1315     }
1316     SetEvent (sp->wakeup);
1317   }
1318   return 0;
1319 }
1320 #endif
1321
1322
1323 #ifndef MINGW
1324 /**
1325  * Check if sockets or pipes meet certain conditions
1326  *
1327  * @param rfds set of sockets or pipes to be checked for readability
1328  * @param wfds set of sockets or pipes to be checked for writability
1329  * @param efds set of sockets or pipes to be checked for exceptions
1330  * @param timeout relative value when to return
1331  * @return number of selected sockets or pipes, #GNUNET_SYSERR on error
1332  */
1333 int
1334 GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds,
1335                               struct GNUNET_NETWORK_FDSet *wfds,
1336                               struct GNUNET_NETWORK_FDSet *efds,
1337                               const struct GNUNET_TIME_Relative timeout)
1338 {
1339   int nfds;
1340   struct timeval tv;
1341
1342   if (NULL != rfds)
1343     nfds = rfds->nsds;
1344   else
1345     nfds = 0;
1346   if (NULL != wfds)
1347     nfds = GNUNET_MAX (nfds, wfds->nsds);
1348   if (NULL != efds)
1349     nfds = GNUNET_MAX (nfds, efds->nsds);
1350   if ((nfds == 0) &&
1351       (timeout.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us))
1352   {
1353     GNUNET_break (0);
1354     LOG (GNUNET_ERROR_TYPE_ERROR,
1355          _("Fatal internal logic error, process hangs in `%s' (abort with CTRL-C)!\n"),
1356          "select");
1357   }
1358   tv.tv_sec = timeout.rel_value_us / GNUNET_TIME_UNIT_SECONDS.rel_value_us;
1359   tv.tv_usec =
1360     (timeout.rel_value_us -
1361      (tv.tv_sec * GNUNET_TIME_UNIT_SECONDS.rel_value_us));
1362   return select (nfds,
1363                  (NULL != rfds) ? &rfds->sds : NULL,
1364                  (NULL != wfds) ? &wfds->sds : NULL,
1365                  (NULL != efds) ? &efds->sds : NULL,
1366                  (timeout.rel_value_us ==
1367                   GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us) ? NULL : &tv);
1368 }
1369
1370
1371 #else
1372 /* MINGW */
1373
1374
1375 /**
1376  * Check if sockets or pipes meet certain conditions, version for W32.
1377  *
1378  * @param rfds set of sockets or pipes to be checked for readability
1379  * @param wfds set of sockets or pipes to be checked for writability
1380  * @param efds set of sockets or pipes to be checked for exceptions
1381  * @param timeout relative value when to return
1382  * @return number of selected sockets or pipes, #GNUNET_SYSERR on error
1383  */
1384 int
1385 GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds,
1386                               struct GNUNET_NETWORK_FDSet *wfds,
1387                               struct GNUNET_NETWORK_FDSet *efds,
1388                               const struct GNUNET_TIME_Relative timeout)
1389 {
1390   int nfds = 0;
1391   int handles = 0;
1392   int ex_handles = 0;
1393   int read_handles = 0;
1394   int write_handles = 0;
1395
1396   int i = 0;
1397   int retcode = 0;
1398   uint64_t mcs_total = 0;
1399   DWORD ms_rounded = 0;
1400
1401   int nhandles = 0;
1402
1403   static HANDLE hEventPipeWrite = 0;
1404   static HANDLE hEventReadReady = 0;
1405
1406   static struct _select_params sp;
1407   static HANDLE select_thread = NULL;
1408   static HANDLE select_finished_event = NULL;
1409   static HANDLE select_standby_event = NULL;
1410   static SOCKET select_wakeup_socket = -1;
1411   static SOCKET select_send_socket = -1;
1412   static struct timeval select_timeout;
1413
1414   int readPipes = 0;
1415   int writePipePos = 0;
1416
1417   HANDLE handle_array[FD_SETSIZE + 2];
1418   int returncode = -1;
1419   int returnedpos = 0;
1420
1421   struct GNUNET_CONTAINER_SList *handles_read;
1422   struct GNUNET_CONTAINER_SList *handles_write;
1423   struct GNUNET_CONTAINER_SList *handles_except;
1424
1425   int selectret = 0;
1426
1427   fd_set aread;
1428   fd_set awrite;
1429   fd_set aexcept;
1430
1431 #if DEBUG_NETWORK
1432   fd_set bread;
1433   fd_set bwrite;
1434   fd_set bexcept;
1435 #endif
1436
1437   /* TODO: Make this growable */
1438   struct GNUNET_DISK_FileHandle *readArray[50];
1439   struct timeval tv;
1440
1441   if (NULL != rfds)
1442   {
1443     nfds = rfds->nsds;
1444     handles += read_handles = GNUNET_CONTAINER_slist_count (rfds->handles);
1445 #if DEBUG_NETWORK
1446     {
1447       struct GNUNET_CONTAINER_SList_Iterator t;
1448
1449       for (t = GNUNET_CONTAINER_slist_begin (rfds->handles);
1450            GNUNET_CONTAINER_slist_end (&t) != GNUNET_YES;
1451            GNUNET_CONTAINER_slist_next (&t))
1452       {
1453         struct GNUNET_DISK_FileHandle *fh;
1454
1455         fh = (struct GNUNET_DISK_FileHandle *) GNUNET_CONTAINER_slist_get (&t,
1456                                                                            NULL);
1457         LOG (GNUNET_ERROR_TYPE_DEBUG, "FD 0x%x (0x%x) is SET in rfds\n", fh->h,
1458              fh);
1459       }
1460     }
1461 #endif
1462   }
1463   if (NULL != wfds)
1464   {
1465     nfds = GNUNET_MAX (nfds, wfds->nsds);
1466     handles += write_handles = GNUNET_CONTAINER_slist_count (wfds->handles);
1467   }
1468   if (NULL != efds)
1469   {
1470     nfds = GNUNET_MAX (nfds, efds->nsds);
1471     handles += ex_handles = GNUNET_CONTAINER_slist_count (efds->handles);
1472   }
1473
1474   if ((nfds == 0) &&
1475       (timeout.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
1476       && (handles == 0) )
1477   {
1478     GNUNET_break (0);
1479     LOG (GNUNET_ERROR_TYPE_ERROR,
1480          _("Fatal internal logic error, process hangs in `%s' (abort with CTRL-C)!\n"),
1481          "select");
1482   }
1483 #define SAFE_FD_ISSET(fd, set)  (set != NULL && FD_ISSET(fd, set))
1484   /* calculate how long we need to wait in microseconds */
1485   if (timeout.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
1486   {
1487     mcs_total = INFINITE;
1488     ms_rounded = INFINITE;
1489   }
1490   else
1491   {
1492     mcs_total = timeout.rel_value_us / GNUNET_TIME_UNIT_MICROSECONDS.rel_value_us;
1493     ms_rounded = (DWORD) (mcs_total / GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us);
1494     if (mcs_total > 0 && ms_rounded == 0)
1495       ms_rounded = 1;
1496   }
1497   /* select() may be used as a portable way to sleep */
1498   if (!(rfds || wfds || efds))
1499   {
1500     Sleep (ms_rounded);
1501     return 0;
1502   }
1503
1504   if (NULL == select_thread)
1505   {
1506     SOCKET select_listening_socket = -1;
1507     struct sockaddr_in s_in;
1508     int alen;
1509     int res;
1510     unsigned long p;
1511
1512     select_standby_event = CreateEvent (NULL, TRUE, FALSE, NULL);
1513     select_finished_event = CreateEvent (NULL, TRUE, FALSE, NULL);
1514
1515     select_wakeup_socket = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
1516
1517     select_listening_socket = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
1518
1519     p = 1;
1520     res = ioctlsocket (select_wakeup_socket, FIONBIO, &p);
1521     LOG (GNUNET_ERROR_TYPE_DEBUG, "Select thread initialization: ioctlsocket() returns %d\n", res);
1522
1523     alen = sizeof (s_in);
1524     s_in.sin_family = AF_INET;
1525     s_in.sin_port = 0;
1526     s_in.sin_addr.S_un.S_un_b.s_b1 = 127;
1527     s_in.sin_addr.S_un.S_un_b.s_b2 = 0;
1528     s_in.sin_addr.S_un.S_un_b.s_b3 = 0;
1529     s_in.sin_addr.S_un.S_un_b.s_b4 = 1;
1530     res = bind (select_listening_socket, (const struct sockaddr *) &s_in, sizeof (s_in));
1531     LOG (GNUNET_ERROR_TYPE_DEBUG, "Select thread initialization: bind() returns %d\n", res);
1532
1533     res = getsockname (select_listening_socket, (struct sockaddr *) &s_in, &alen);
1534     LOG (GNUNET_ERROR_TYPE_DEBUG, "Select thread initialization: getsockname() returns %d\n", res);
1535
1536     res = listen (select_listening_socket, SOMAXCONN);
1537     LOG (GNUNET_ERROR_TYPE_DEBUG, "Select thread initialization: listen() returns %d\n", res);
1538
1539     res = connect (select_wakeup_socket, (const struct sockaddr *) &s_in, sizeof (s_in));
1540     LOG (GNUNET_ERROR_TYPE_DEBUG, "Select thread initialization: connect() returns %d\n", res);
1541
1542     select_send_socket = accept (select_listening_socket, (struct sockaddr *) &s_in, &alen);
1543
1544     closesocket (select_listening_socket);
1545
1546     sp.wakeup = select_finished_event;
1547     sp.standby = select_standby_event;
1548     sp.wakeup_socket = select_wakeup_socket;
1549
1550     select_thread = CreateThread (NULL, 0, _selector, &sp, 0, NULL);
1551   }
1552
1553
1554   handles_read = GNUNET_CONTAINER_slist_create ();
1555   handles_write = GNUNET_CONTAINER_slist_create ();
1556   handles_except = GNUNET_CONTAINER_slist_create ();
1557   FD_ZERO (&aread);
1558   FD_ZERO (&awrite);
1559   FD_ZERO (&aexcept);
1560 #if DEBUG_NETWORK
1561   FD_ZERO (&bread);
1562   FD_ZERO (&bwrite);
1563   FD_ZERO (&bexcept);
1564 #endif
1565   if (rfds)
1566   {
1567     FD_COPY (&rfds->sds, &aread);
1568 #if DEBUG_NETWORK
1569     FD_COPY (&rfds->sds, &bread);
1570 #endif
1571   }
1572   if (wfds)
1573   {
1574     FD_COPY (&wfds->sds, &awrite);
1575 #if DEBUG_NETWORK
1576     FD_COPY (&wfds->sds, &bwrite);
1577 #endif
1578   }
1579   if (efds)
1580   {
1581     FD_COPY (&efds->sds, &aexcept);
1582 #if DEBUG_NETWORK
1583     FD_COPY (&efds->sds, &bexcept);
1584 #endif
1585   }
1586
1587   /* Start by doing a fast check on sockets and pipes (without waiting). It is cheap, and is sufficient most of the time.
1588      By profiling we detected that to be true in 90% of the cases.
1589   */
1590
1591   /* Do the select now */
1592   select_timeout.tv_sec = 0;
1593   select_timeout.tv_usec = 0;
1594
1595   /* Copy all the writes to the except, so we can detect connect() errors */
1596   for (i = 0; i < awrite.fd_count; i++)
1597     FD_SET (awrite.fd_array[i], &aexcept);
1598   if (aread.fd_count > 0 || awrite.fd_count > 0 || aexcept.fd_count > 0)
1599     selectret = select (1, (rfds != NULL) ? &aread : NULL,
1600         (wfds != NULL) ? &awrite : NULL, &aexcept, &select_timeout);
1601   else
1602     selectret = 0;
1603   if (selectret == -1)
1604   {
1605     /* Throw an error early on, while we still have the context. */
1606     LOG (GNUNET_ERROR_TYPE_ERROR, "W32 select(%d, %d, %d) failed: %lu\n",
1607         rfds ? aread.fd_count : 0, wfds ? awrite.fd_count : 0, aexcept.fd_count, GetLastError ());
1608     GNUNET_abort ();
1609   }
1610
1611   /* Check aexcept, add its contents to awrite
1612      This is technically wrong (aexcept might have its own descriptors), we should
1613      have checked that descriptors were in awrite originally before re-adding them from
1614      aexcept. Luckily, GNUnet never uses aexcept for anything, so this does not become a problem (yet). */
1615   for (i = 0; i < aexcept.fd_count; i++)
1616     FD_SET (aexcept.fd_array[i], &awrite);
1617
1618   /* If our select returned something or is a 0-timed request, then also check the pipes and get out of here! */
1619   /* Sadly, it means code duplication :( */
1620   if ((selectret > 0) || (mcs_total == 0))
1621   {
1622     /* Read Pipes */
1623     if (rfds && read_handles)
1624     {
1625       struct GNUNET_CONTAINER_SList_Iterator i;
1626       int c;
1627
1628       for (c = 0, i = GNUNET_CONTAINER_slist_begin (rfds->handles);
1629           GNUNET_CONTAINER_slist_end (&i) != GNUNET_YES;
1630           GNUNET_CONTAINER_slist_next (&i), c++)
1631       {
1632         struct GNUNET_DISK_FileHandle *fh;
1633
1634         fh = (struct GNUNET_DISK_FileHandle *) GNUNET_CONTAINER_slist_get (&i,NULL);
1635         if (fh->type == GNUNET_DISK_HANLDE_TYPE_PIPE)
1636         {
1637           DWORD error;
1638           BOOL bret;
1639
1640           SetLastError (0);
1641           DWORD waitstatus = 0;
1642           bret = PeekNamedPipe (fh->h, NULL, 0, NULL, &waitstatus, NULL);
1643           error = GetLastError ();
1644           LOG (GNUNET_ERROR_TYPE_DEBUG, "Peek at read pipe %d (0x%x) returned %d (%d bytes available) GLE %u\n",
1645               c, fh->h, bret, waitstatus, error);
1646           if (bret == 0)
1647           {
1648             /* TODO: either add more errors to this condition, or eliminate it
1649              * entirely (failed to peek -> pipe is in serious trouble, should
1650              * be selected as readable).
1651              */
1652             if (error != ERROR_BROKEN_PIPE && error != ERROR_INVALID_HANDLE)
1653               continue;
1654           }
1655           else if (waitstatus <= 0)
1656             continue;
1657           GNUNET_CONTAINER_slist_add (handles_read, GNUNET_CONTAINER_SLIST_DISPOSITION_TRANSIENT,
1658               fh, sizeof (struct GNUNET_DISK_FileHandle));
1659           retcode++;
1660           LOG (GNUNET_ERROR_TYPE_DEBUG, "Added read Pipe 0x%x (0x%x)\n",
1661               fh, fh->h);
1662         }
1663         else
1664         {
1665           GNUNET_CONTAINER_slist_add (handles_read, GNUNET_CONTAINER_SLIST_DISPOSITION_TRANSIENT,
1666               fh, sizeof (struct GNUNET_DISK_FileHandle));
1667           retcode++;
1668         }
1669       }
1670     }
1671     if (wfds && write_handles)
1672     {
1673       LOG (GNUNET_ERROR_TYPE_DEBUG,
1674           "Adding the write ready event to the array as %d\n", nhandles);
1675       GNUNET_CONTAINER_slist_append (handles_write, wfds->handles);
1676       retcode += write_handles;
1677     }
1678     if (efds && ex_handles)
1679     {
1680       struct GNUNET_CONTAINER_SList_Iterator i;
1681
1682       for (i = GNUNET_CONTAINER_slist_begin (efds->handles);
1683           GNUNET_CONTAINER_slist_end (&i) != GNUNET_YES;
1684           GNUNET_CONTAINER_slist_next (&i))
1685       {
1686         struct GNUNET_DISK_FileHandle *fh;
1687         DWORD dwBytes;
1688
1689         fh = (struct GNUNET_DISK_FileHandle *) GNUNET_CONTAINER_slist_get (&i, NULL);
1690         if (fh->type == GNUNET_DISK_HANLDE_TYPE_PIPE)
1691         {
1692           if (PeekNamedPipe (fh->h, NULL, 0, NULL, &dwBytes, NULL))
1693             continue;
1694           GNUNET_CONTAINER_slist_add (handles_except, GNUNET_CONTAINER_SLIST_DISPOSITION_TRANSIENT,
1695               fh, sizeof (struct GNUNET_DISK_FileHandle));
1696           retcode++;
1697         }
1698       }
1699     }
1700
1701     /* Add our select() result.*/
1702     if (selectret >= 0)
1703       retcode += selectret;
1704
1705     if (rfds)
1706     {
1707       GNUNET_NETWORK_fdset_zero (rfds);
1708       if (selectret != -1)
1709         GNUNET_NETWORK_fdset_copy_native (rfds, &aread, selectret);
1710       GNUNET_CONTAINER_slist_append (rfds->handles, handles_read);
1711     }
1712     if (wfds)
1713     {
1714       GNUNET_NETWORK_fdset_zero (wfds);
1715       if (selectret != -1)
1716         GNUNET_NETWORK_fdset_copy_native (wfds, &awrite, selectret);
1717       GNUNET_CONTAINER_slist_append (wfds->handles, handles_write);
1718     }
1719     if (efds)
1720     {
1721       GNUNET_NETWORK_fdset_zero (efds);
1722       if (selectret != -1)
1723         GNUNET_NETWORK_fdset_copy_native (efds, &aexcept, selectret);
1724       GNUNET_CONTAINER_slist_append (efds->handles, handles_except);
1725     }
1726     GNUNET_CONTAINER_slist_destroy (handles_read);
1727     GNUNET_CONTAINER_slist_destroy (handles_write);
1728     GNUNET_CONTAINER_slist_destroy (handles_except);
1729
1730     if (selectret == -1)
1731       return -1;
1732     return retcode;
1733   }
1734
1735   /* If we got this far, use slower implementation that is able to do a waiting select
1736      on both sockets and pipes simultaneously */
1737
1738   /* Events for pipes */
1739   if (!hEventReadReady)
1740     hEventReadReady = CreateEvent (NULL, TRUE, TRUE, NULL);
1741   if (!hEventPipeWrite)
1742     hEventPipeWrite = CreateEvent (NULL, TRUE, TRUE, NULL);
1743   readPipes = 0;
1744   writePipePos = -1;
1745
1746   retcode = 0;
1747
1748   FD_ZERO (&aread);
1749   FD_ZERO (&awrite);
1750   FD_ZERO (&aexcept);
1751 #if DEBUG_NETWORK
1752   FD_ZERO (&bread);
1753   FD_ZERO (&bwrite);
1754   FD_ZERO (&bexcept);
1755 #endif
1756   if (rfds)
1757   {
1758     FD_COPY (&rfds->sds, &aread);
1759 #if DEBUG_NETWORK
1760     FD_COPY (&rfds->sds, &bread);
1761 #endif
1762   }
1763   if (wfds)
1764   {
1765     FD_COPY (&wfds->sds, &awrite);
1766 #if DEBUG_NETWORK
1767     FD_COPY (&wfds->sds, &bwrite);
1768 #endif
1769   }
1770   if (efds)
1771   {
1772     FD_COPY (&efds->sds, &aexcept);
1773 #if DEBUG_NETWORK
1774     FD_COPY (&efds->sds, &bexcept);
1775 #endif
1776   }
1777   /* We will first Add the PIPES to the events */
1778   /* Read Pipes */
1779   if (rfds && read_handles)
1780   {
1781     struct GNUNET_CONTAINER_SList_Iterator i;
1782
1783     for (i = GNUNET_CONTAINER_slist_begin (rfds->handles);
1784          GNUNET_CONTAINER_slist_end (&i) != GNUNET_YES;
1785          GNUNET_CONTAINER_slist_next (&i))
1786     {
1787       struct GNUNET_DISK_FileHandle *fh;
1788
1789       fh = (struct GNUNET_DISK_FileHandle *) GNUNET_CONTAINER_slist_get (&i,
1790                                                                          NULL);
1791       if (fh->type == GNUNET_DISK_HANLDE_TYPE_PIPE)
1792       {
1793         /* Read zero bytes to check the status of the pipe */
1794         LOG (GNUNET_ERROR_TYPE_DEBUG, "Reading 0 bytes from the pipe 0x%x\n",
1795              fh->h);
1796         if (!ReadFile (fh->h, NULL, 0, NULL, fh->oOverlapRead))
1797         {
1798           DWORD error_code = GetLastError ();
1799
1800           if (error_code == ERROR_IO_PENDING)
1801           {
1802             LOG (GNUNET_ERROR_TYPE_DEBUG,
1803                  "Adding the pipe's 0x%x overlapped event to the array as %d\n",
1804                  fh->h, nhandles);
1805             handle_array[nhandles++] = fh->oOverlapRead->hEvent;
1806             readArray[readPipes++] = fh;
1807           }
1808           else
1809           {
1810             LOG (GNUNET_ERROR_TYPE_DEBUG,
1811                  "Read failed, adding the read ready event to the array as %d\n", nhandles);
1812             handle_array[nhandles++] = hEventReadReady;
1813             readArray[readPipes++] = fh;
1814           }
1815         }
1816         else
1817         {
1818           LOG (GNUNET_ERROR_TYPE_DEBUG,
1819                "Adding the read ready event to the array as %d\n", nhandles);
1820           handle_array[nhandles++] = hEventReadReady;
1821           readArray[readPipes++] = fh;
1822         }
1823       }
1824       else
1825       {
1826         GNUNET_CONTAINER_slist_add (handles_read,
1827                                     GNUNET_CONTAINER_SLIST_DISPOSITION_TRANSIENT,
1828                                     fh, sizeof (struct GNUNET_DISK_FileHandle));
1829       }
1830     }
1831   }
1832   if (wfds && write_handles)
1833   {
1834     LOG (GNUNET_ERROR_TYPE_DEBUG,
1835          "Adding the write ready event to the array as %d\n", nhandles);
1836     handle_array[nhandles++] = hEventPipeWrite;
1837     writePipePos = nhandles;
1838   }
1839   if (efds && ex_handles)
1840   {
1841     struct GNUNET_CONTAINER_SList_Iterator i;
1842
1843     for (i = GNUNET_CONTAINER_slist_begin (efds->handles);
1844          GNUNET_CONTAINER_slist_end (&i) != GNUNET_YES;
1845          GNUNET_CONTAINER_slist_next (&i))
1846     {
1847       struct GNUNET_DISK_FileHandle *fh;
1848       DWORD dwBytes;
1849
1850       fh = (struct GNUNET_DISK_FileHandle *) GNUNET_CONTAINER_slist_get (&i,
1851                                                                          NULL);
1852       if (fh->type == GNUNET_DISK_HANLDE_TYPE_PIPE)
1853       {
1854         if (!PeekNamedPipe (fh->h, NULL, 0, NULL, &dwBytes, NULL))
1855         {
1856           GNUNET_CONTAINER_slist_add (handles_except,
1857                                       GNUNET_CONTAINER_SLIST_DISPOSITION_TRANSIENT,
1858                                       fh,
1859                                       sizeof (struct GNUNET_DISK_FileHandle));
1860         }
1861       }
1862     }
1863   }
1864
1865   sp.status = 0;
1866
1867   if (nfds > 0)
1868   {
1869     LOG (GNUNET_ERROR_TYPE_DEBUG,
1870          "Adding the socket event to the array as %d\n",
1871          nhandles);
1872     handle_array[nhandles++] = select_finished_event;
1873     if (timeout.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
1874       sp.tv = NULL;
1875     else
1876     {
1877       select_timeout.tv_sec = timeout.rel_value_us / GNUNET_TIME_UNIT_SECONDS.rel_value_us;
1878       select_timeout.tv_usec =(timeout.rel_value_us -
1879           (select_timeout.tv_sec * GNUNET_TIME_UNIT_SECONDS.rel_value_us));
1880       sp.tv = &select_timeout;
1881     }
1882     FD_SET (select_wakeup_socket, &aread);
1883     do
1884     {
1885       i = recv (select_wakeup_socket, (char *) &returnedpos, 1, 0);
1886     } while (i == 1);
1887     sp.r = &aread;
1888     sp.w = &awrite;
1889     sp.e = &aexcept;
1890     /* Failed connections cause sockets to be set in errorfds on W32,
1891      * but on POSIX it should set them in writefds.
1892      * First copy all awrite sockets to aexcept, later we'll
1893      * check aexcept and set its contents in awrite as well
1894      * Sockets are also set in errorfds when OOB data is available,
1895      * but we don't use OOB data.
1896      */
1897     for (i = 0; i < awrite.fd_count; i++)
1898       FD_SET (awrite.fd_array[i], &aexcept);
1899     ResetEvent (select_finished_event);
1900     SetEvent (select_standby_event);
1901   }
1902
1903   handle_array[nhandles] = NULL;
1904   LOG (GNUNET_ERROR_TYPE_DEBUG, "nfds: %d, handles: %d, will wait: %llu mcs\n",
1905        nfds, nhandles, mcs_total);
1906   if (nhandles)
1907   {
1908     returncode =
1909         WaitForMultipleObjects (nhandles, handle_array, FALSE, ms_rounded);
1910     LOG (GNUNET_ERROR_TYPE_DEBUG, "WaitForMultipleObjects Returned : %d\n", returncode);
1911   }
1912   else if (nfds > 0)
1913   {
1914     GNUNET_break (0); /* This branch shouldn't actually be executed...*/
1915     i = (int) WaitForSingleObject (select_finished_event, INFINITE);
1916     returncode = WAIT_TIMEOUT;
1917   }
1918   else
1919   {
1920     /* Shouldn't come this far. If it does - investigate. */
1921     GNUNET_assert (0);
1922   }
1923
1924   if (nfds > 0)
1925   {
1926     /* Don't wake up select-thread when delay is 0, it should return immediately
1927      * and wake up by itself.
1928      */
1929     if (mcs_total != 0)
1930       i = send (select_send_socket, (const char *) &returnedpos, 1, 0);
1931     i = (int) WaitForSingleObject (select_finished_event, INFINITE);
1932     LOG (GNUNET_ERROR_TYPE_DEBUG, "Finished waiting for the select thread: %d %d\n", i, sp.status);
1933     if (mcs_total != 0)
1934     {
1935       do
1936       {
1937         i = recv (select_wakeup_socket, (char *) &returnedpos, 1, 0);
1938       } while (i == 1);
1939     }
1940     /* Check aexcept, add its contents to awrite */
1941     for (i = 0; i < aexcept.fd_count; i++)
1942       FD_SET (aexcept.fd_array[i], &awrite);
1943   }
1944
1945   returnedpos = returncode - WAIT_OBJECT_0;
1946   LOG (GNUNET_ERROR_TYPE_DEBUG, "return pos is : %d\n", returnedpos);
1947
1948   if (nhandles && (returnedpos < nhandles))
1949   {
1950     DWORD waitstatus;
1951
1952     if (sp.status > 0)
1953       retcode += sp.status;
1954
1955     if ((writePipePos != -1) && (returnedpos < writePipePos))
1956     {
1957       GNUNET_CONTAINER_slist_append (handles_write, wfds->handles);
1958       retcode += write_handles;
1959       LOG (GNUNET_ERROR_TYPE_DEBUG, "Added write pipe\n");
1960     }
1961     LOG (GNUNET_ERROR_TYPE_DEBUG, "ReadPipes is : %d\n", readPipes);
1962     /* We have some pipes ready for read. */
1963     if (returnedpos < readPipes)
1964     {
1965       for (i = 0; i < readPipes; i++)
1966       {
1967         DWORD error;
1968         BOOL bret;
1969
1970         SetLastError (0);
1971         waitstatus = 0;
1972         bret =
1973             PeekNamedPipe (readArray[i]->h, NULL, 0, NULL, &waitstatus, NULL);
1974         error = GetLastError ();
1975         LOG (GNUNET_ERROR_TYPE_DEBUG,
1976              "Peek at read pipe %d (0x%x) returned %d (%d bytes available) GLE %u\n",
1977              i, readArray[i]->h, bret, waitstatus, error);
1978         if (bret == 0)
1979         {
1980           /* TODO: either add more errors to this condition, or eliminate it
1981            * entirely (failed to peek -> pipe is in serious trouble, should
1982            * be selected as readable).
1983            */
1984           if (error != ERROR_BROKEN_PIPE && error != ERROR_INVALID_HANDLE)
1985             continue;
1986         }
1987         else if (waitstatus <= 0)
1988           continue;
1989         GNUNET_CONTAINER_slist_add (handles_read,
1990                                     GNUNET_CONTAINER_SLIST_DISPOSITION_TRANSIENT,
1991                                     readArray[i],
1992                                     sizeof (struct GNUNET_DISK_FileHandle));
1993         retcode++;
1994         LOG (GNUNET_ERROR_TYPE_DEBUG, "Added read Pipe 0x%x (0x%x)\n",
1995              readArray[i], readArray[i]->h);
1996       }
1997     }
1998   }
1999   if (!nhandles || (returnedpos >= nhandles))
2000     LOG (GNUNET_ERROR_TYPE_DEBUG, "Returning from _select() with nothing!\n");
2001   if (rfds)
2002   {
2003     struct GNUNET_CONTAINER_SList_Iterator t;
2004
2005     for (t = GNUNET_CONTAINER_slist_begin (rfds->handles);
2006          GNUNET_CONTAINER_slist_end (&t) != GNUNET_YES;
2007          GNUNET_CONTAINER_slist_next (&t))
2008     {
2009       struct GNUNET_DISK_FileHandle *fh;
2010
2011       fh = (struct GNUNET_DISK_FileHandle *) GNUNET_CONTAINER_slist_get (&t,
2012                                                                          NULL);
2013       if (fh->type == GNUNET_DISK_HANLDE_TYPE_PIPE)
2014       {
2015         CancelIo (fh->h);
2016       }
2017     }
2018     LOG (GNUNET_ERROR_TYPE_DEBUG, "Zeroing rfds%s\n", (retcode != -1 && nhandles && (returnedpos < nhandles)) ? ", copying fdset" : "");
2019     GNUNET_NETWORK_fdset_zero (rfds);
2020     if (retcode != -1 && nhandles && (returnedpos < nhandles))
2021       GNUNET_NETWORK_fdset_copy_native (rfds, &aread, retcode);
2022     GNUNET_CONTAINER_slist_append (rfds->handles, handles_read);
2023   }
2024   if (wfds)
2025   {
2026     LOG (GNUNET_ERROR_TYPE_DEBUG, "Zeroing wfds%s\n", (retcode != -1 && nhandles && (returnedpos < nhandles)) ? ", copying fdset" : "");
2027     GNUNET_NETWORK_fdset_zero (wfds);
2028     if (retcode != -1 && nhandles && (returnedpos < nhandles))
2029       GNUNET_NETWORK_fdset_copy_native (wfds, &awrite, retcode);
2030     GNUNET_CONTAINER_slist_append (wfds->handles, handles_write);
2031   }
2032   if (efds)
2033   {
2034     LOG (GNUNET_ERROR_TYPE_DEBUG, "Zeroing efds%s\n", (retcode != -1 && nhandles && (returnedpos < nhandles)) ? ", copying fdset" : "");
2035     GNUNET_NETWORK_fdset_zero (efds);
2036     if (retcode != -1 && nhandles && (returnedpos < nhandles))
2037       GNUNET_NETWORK_fdset_copy_native (efds, &aexcept, retcode);
2038     GNUNET_CONTAINER_slist_append (efds->handles, handles_except);
2039   }
2040   GNUNET_CONTAINER_slist_destroy (handles_read);
2041   GNUNET_CONTAINER_slist_destroy (handles_write);
2042   GNUNET_CONTAINER_slist_destroy (handles_except);
2043 #if DEBUG_NETWORK
2044   if (rfds)
2045   {
2046     struct GNUNET_CONTAINER_SList_Iterator t;
2047
2048     LOG (GNUNET_ERROR_TYPE_DEBUG, "rfds:\n");
2049     for (i = 0; i < rfds->sds.fd_count; i++)
2050     {
2051       LOG (GNUNET_ERROR_TYPE_DEBUG, "%d\n", rfds->sds.fd_array[i]);
2052     }
2053     for (t = GNUNET_CONTAINER_slist_begin (rfds->handles);
2054          GNUNET_CONTAINER_slist_end (&t) != GNUNET_YES;
2055          GNUNET_CONTAINER_slist_next (&t))
2056     {
2057       struct GNUNET_DISK_FileHandle *fh;
2058
2059       fh = (struct GNUNET_DISK_FileHandle *) GNUNET_CONTAINER_slist_get (&t,
2060                                                                          NULL);
2061       LOG (GNUNET_ERROR_TYPE_DEBUG, "%d\n", fh->h);
2062     }
2063   }
2064   if (wfds)
2065   {
2066     LOG (GNUNET_ERROR_TYPE_DEBUG, "wfds:\n");
2067     for (i = 0; i < wfds->sds.fd_count; i++)
2068     {
2069       LOG (GNUNET_ERROR_TYPE_DEBUG, "%d\n", wfds->sds.fd_array[i]);
2070     }
2071   }
2072   if (efds)
2073   {
2074     LOG (GNUNET_ERROR_TYPE_DEBUG, "efds:\n");
2075     for (i = 0; i < efds->sds.fd_count; i++)
2076     {
2077       LOG (GNUNET_ERROR_TYPE_DEBUG, "%d\n", efds->sds.fd_array[i]);
2078     }
2079   }
2080   LOG (GNUNET_ERROR_TYPE_DEBUG, "Returning %d or 0\n", retcode);
2081 #endif
2082   if (nhandles && (returnedpos < nhandles))
2083     return retcode;
2084   else
2085     return 0;
2086 }
2087
2088 /* MINGW */
2089 #endif
2090
2091 /* end of network.c */