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