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