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