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