GNUnet  0.10.x
network.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2009-2013 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19 */
20 
27 #include "platform.h"
28 #include "gnunet_util_lib.h"
29 #include "disk.h"
30 
31 #define LOG(kind,...) GNUNET_log_from (kind, "util-network", __VA_ARGS__)
32 #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util-network", syscall, filename)
33 #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util-network", syscall)
34 
35 #define DEBUG_NETWORK GNUNET_EXTRA_LOGGING
36 
37 
38 #ifndef INVALID_SOCKET
39 #define INVALID_SOCKET -1
40 #endif
41 
42 
47 {
48 #ifndef MINGW
49  int fd;
50 #else
51  SOCKET fd;
52 #endif
53 
57  int af;
58 
62  int type;
63 
67  socklen_t addrlen;
68 
72  struct sockaddr *addr;
73 
74 };
75 
76 
83 int
85 {
86  static int cache_v4 = -1;
87  static int cache_v6 = -1;
88  static int cache_un = -1;
89  int s;
90  int ret;
91 
92  switch (pf)
93  {
94  case PF_INET:
95  if (-1 != cache_v4)
96  return cache_v4;
97  break;
98  case PF_INET6:
99  if (-1 != cache_v6)
100  return cache_v6;
101  break;
102 #ifdef PF_UNIX
103  case PF_UNIX:
104  if (-1 != cache_un)
105  return cache_un;
106  break;
107 #endif
108  }
109  s = socket (pf, SOCK_STREAM, 0);
110  if (-1 == s)
111  {
112  if (EAFNOSUPPORT != errno)
113  {
115  "socket");
116  return GNUNET_SYSERR;
117  }
118  ret = GNUNET_NO;
119  }
120  else
121  {
122 #if WINDOWS
123  closesocket (s);
124 #else
125  close (s);
126 #endif
127  ret = GNUNET_OK;
128  }
129  switch (pf)
130  {
131  case PF_INET:
132  cache_v4 = ret;
133  break;
134  case PF_INET6:
135  cache_v6 = ret;
136  break;
137 #ifdef PF_UNIX
138  case PF_UNIX:
139  cache_un = ret;
140  break;
141 #endif
142  }
143  return ret;
144 }
145 
146 
156 char *
158 {
159  struct sockaddr_un dummy;
160  size_t slen;
161  char *end;
162  struct GNUNET_HashCode sh;
164  size_t upm;
165 
166  upm = sizeof (dummy.sun_path);
167  slen = strlen (unixpath);
168  if (slen < upm)
169  return unixpath; /* no shortening required */
170  GNUNET_CRYPTO_hash (unixpath, slen, &sh);
171  while (16 + strlen (unixpath) >= upm)
172  {
173  if (NULL == (end = strrchr (unixpath, '/')))
174  {
176  _("Unable to shorten unix path `%s' while keeping name unique\n"),
177  unixpath);
178  GNUNET_free (unixpath);
179  return NULL;
180  }
181  *end = '\0';
182  }
183  GNUNET_CRYPTO_hash_to_enc (&sh, &ae);
184  ae.encoding[16] = '\0';
185  strcat (unixpath, (char *) ae.encoding);
186  return unixpath;
187 }
188 
189 
190 #ifndef WINDOWS
191 
200 void
201 GNUNET_NETWORK_unix_precheck (const struct sockaddr_un *un)
202 {
203  int s;
204  int eno;
205  struct stat sbuf;
206  int ret;
207 
208  s = socket (AF_UNIX, SOCK_STREAM, 0);
209  if (-1 == s)
210  {
212  "Failed to open AF_UNIX socket");
213  return;
214  }
215  ret = connect (s,
216  (struct sockaddr *) un,
217  sizeof (struct sockaddr_un));
218  eno = errno;
219  GNUNET_break (0 == close (s));
220  if (0 == ret)
221  return; /* another process is listening, do not remove! */
222  if (ECONNREFUSED != eno)
223  return; /* some other error, likely "no such file or directory" -- all well */
224  /* should unlink, but sanity checks first */
225  if (0 != stat (un->sun_path,
226  &sbuf))
227  return; /* failed to 'stat', likely does not exist after all */
228  if (S_IFSOCK != (S_IFMT & sbuf.st_mode))
229  return; /* refuse to unlink anything except sockets */
230  /* finally, really unlink */
232  "Removing left-over `%s' from previous exeuction\n",
233  un->sun_path);
234  if (0 != unlink (un->sun_path))
236  "unlink",
237  un->sun_path);
238 }
239 #endif
240 
241 
242 
243 #ifndef FD_COPY
244 #define FD_COPY(s, d) do { GNUNET_memcpy ((d), (s), sizeof (fd_set)); } while (0)
245 #endif
246 
247 
255 int
257  int doBlock)
258 {
259 
260 #if MINGW
261  u_long mode;
262 
263  mode = !doBlock;
264  if (SOCKET_ERROR ==
265  ioctlsocket (fd->fd,
266  FIONBIO,
267  &mode))
268 
269  {
270  SetErrnoFromWinsockError (WSAGetLastError ());
272  "ioctlsocket");
273  return GNUNET_SYSERR;
274  }
275  return GNUNET_OK;
276 
277 #else
278  /* not MINGW */
279  int flags = fcntl (fd->fd, F_GETFL);
280 
281  if (flags == -1)
282  {
284  "fcntl");
285  return GNUNET_SYSERR;
286  }
287  if (doBlock)
288  flags &= ~O_NONBLOCK;
289 
290  else
291  flags |= O_NONBLOCK;
292  if (0 != fcntl (fd->fd,
293  F_SETFL,
294  flags))
295 
296  {
298  "fcntl");
299  return GNUNET_SYSERR;
300  }
301  return GNUNET_OK;
302 #endif
303 }
304 
305 
313 static int
315 {
316 #ifndef MINGW
317  int i;
318  i = fcntl (h->fd, F_GETFD);
319  if (i < 0)
320  return GNUNET_SYSERR;
321  if (i == (i | FD_CLOEXEC))
322  return GNUNET_OK;
323  i |= FD_CLOEXEC;
324  if (fcntl (h->fd, F_SETFD, i) < 0)
325  return GNUNET_SYSERR;
326 #else
327  BOOL b;
328  SetLastError (0);
329  b = SetHandleInformation ((HANDLE) h->fd, HANDLE_FLAG_INHERIT, 0);
330  if (!b)
331  {
332  SetErrnoFromWinsockError (WSAGetLastError ());
333  return GNUNET_SYSERR;
334  }
335 #endif
336  return GNUNET_OK;
337 }
338 
339 
340 #ifdef DARWIN
341 
346 static void
347 socket_set_nosigpipe (const struct GNUNET_NETWORK_Handle *h)
348 {
349  int abs_value = 1;
350 
351  if (0 !=
352  setsockopt (h->fd, SOL_SOCKET, SO_NOSIGPIPE,
353  (const void *) &abs_value,
354  sizeof (abs_value)))
355  LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "setsockopt");
356 }
357 #endif
358 
359 
367 static void
369 {
370 #ifndef WINDOWS
371  int value = 1;
372 
373  if (0 !=
374  setsockopt (h->fd,
375  IPPROTO_TCP,
376  TCP_NODELAY,
377  &value, sizeof (value)))
379  "setsockopt");
380 #else
381  const char *abs_value = "1";
382 
383  if (0 !=
384  setsockopt (h->fd,
385  IPPROTO_TCP,
386  TCP_NODELAY,
387  (const void *) abs_value,
388  sizeof (abs_value)))
390  "setsockopt");
391 #endif
392 }
393 
394 
407 static int
409  int af,
410  int type)
411 {
412  int eno;
413 
414  h->af = af;
415  h->type = type;
416  if (h->fd == INVALID_SOCKET)
417  {
418 #ifdef MINGW
419  SetErrnoFromWinsockError (WSAGetLastError ());
420 #endif
421  eno = errno;
422  GNUNET_free (h);
423  errno = eno;
424  return GNUNET_SYSERR;
425  }
426 #ifndef MINGW
427  if (h->fd >= FD_SETSIZE)
428  {
430  errno = EMFILE;
431  return GNUNET_SYSERR;
432  }
433 #endif
436  "socket_set_inheritable");
437 
439  {
440  eno = errno;
441  GNUNET_break (0);
443  errno = eno;
444  return GNUNET_SYSERR;
445  }
446 #ifdef DARWIN
447  socket_set_nosigpipe (h);
448 #endif
449  if ( (type == SOCK_STREAM)
450 #ifdef AF_UNIX
451  && (af != AF_UNIX)
452 #endif
453  )
454  socket_set_nodelay (h);
455  return GNUNET_OK;
456 }
457 
458 
467 struct GNUNET_NETWORK_Handle *
469  struct sockaddr *address,
470  socklen_t *address_len)
471 {
472  struct GNUNET_NETWORK_Handle *ret;
473  int eno;
474 
475  ret = GNUNET_new (struct GNUNET_NETWORK_Handle);
476 #if DEBUG_NETWORK
477  {
478  struct sockaddr_storage name;
479  socklen_t namelen = sizeof (name);
480 
481  int gsn = getsockname (desc->fd,
482  (struct sockaddr *) &name,
483  &namelen);
484 
485  if (0 == gsn)
487  "Accepting connection on `%s'\n",
488  GNUNET_a2s ((const struct sockaddr *) &name,
489  namelen));
490  }
491 #endif
492  ret->fd = accept (desc->fd,
493  address,
494  address_len);
495  if (-1 == ret->fd)
496  {
497  eno = errno;
498  GNUNET_free (ret);
499  errno = eno;
500  return NULL;
501  }
502  if (GNUNET_OK !=
504  (NULL != address) ? address->sa_family : desc->af,
505  SOCK_STREAM))
506  {
507  return NULL;
508  }
509  return ret;
510 }
511 
512 
521 int
523  const struct sockaddr *address,
524  socklen_t address_len)
525 {
526  int ret;
527 
528 #ifdef IPV6_V6ONLY
529 #ifdef IPPROTO_IPV6
530  {
531  const int on = 1;
532 
533  if (AF_INET6 == desc->af)
534  if (setsockopt (desc->fd,
535  IPPROTO_IPV6,
536  IPV6_V6ONLY,
537  (const void *) &on,
538  sizeof (on)))
540  "setsockopt");
541  }
542 #endif
543 #endif
544 #ifndef WINDOWS
545  if (AF_UNIX == address->sa_family)
546  GNUNET_NETWORK_unix_precheck ((const struct sockaddr_un *) address);
547  {
548  const int on = 1;
549 
550  /* This is required here for TCP sockets, but only on UNIX */
551  if ( (SOCK_STREAM == desc->type) &&
552  (0 != setsockopt (desc->fd,
553  SOL_SOCKET,
554  SO_REUSEADDR,
555  &on, sizeof (on))))
557  "setsockopt");
558  }
559  {
560  /* set permissions of newly created non-abstract UNIX domain socket to
561  "user-only"; applications can choose to relax this later */
562  mode_t old_mask = 0; /* assigned to make compiler happy */
563  const struct sockaddr_un *un = (const struct sockaddr_un *) address;
564  int not_abstract = 0;
565 
566  if ((AF_UNIX == address->sa_family)
567  && ('\0' != un->sun_path[0]) ) /* Not an abstract socket */
568  not_abstract = 1;
569  if (not_abstract)
570  old_mask = umask (S_IWGRP | S_IRGRP | S_IXGRP | S_IWOTH | S_IROTH | S_IXOTH);
571 #endif
572 
573  ret = bind (desc->fd,
574  address,
575  address_len);
576 
577 #ifndef WINDOWS
578  if (not_abstract)
579  (void) umask (old_mask);
580  }
581 #endif
582 #ifdef MINGW
583  if (SOCKET_ERROR == ret)
584  SetErrnoFromWinsockError (WSAGetLastError ());
585 #endif
586  if (0 != ret)
587  return GNUNET_SYSERR;
588 #ifndef MINGW
589  desc->addr = GNUNET_malloc (address_len);
590  GNUNET_memcpy (desc->addr, address, address_len);
591  desc->addrlen = address_len;
592 #endif
593  return GNUNET_OK;
594 }
595 
596 
603 int
605 {
606  int ret;
607 
608 #ifdef WINDOWS
609  DWORD error = 0;
610 
611  SetLastError (0);
612  ret = closesocket (desc->fd);
613  error = WSAGetLastError ();
614  SetErrnoFromWinsockError (error);
616  "Closed 0x%x, closesocket() returned %d, GLE is %u\n",
617  desc->fd,
618  ret,
619  error);
620 #else
621  ret = close (desc->fd);
622 #endif
623 #ifndef WINDOWS
624  const struct sockaddr_un *un = (const struct sockaddr_un *) desc->addr;
625 
626  /* Cleanup the UNIX domain socket and its parent directories in case of non
627  abstract sockets */
628  if ( (AF_UNIX == desc->af) &&
629  (NULL != desc->addr) &&
630  ('\0' != un->sun_path[0]) )
631  {
632  char *dirname = GNUNET_strndup (un->sun_path,
633  sizeof (un->sun_path));
634 
635  if (0 != unlink (dirname))
636  {
638  "unlink",
639  dirname);
640  }
641  else
642  {
643  size_t len;
644 
645  len = strlen (dirname);
646  while ((len > 0) && (dirname[len] != DIR_SEPARATOR))
647  len--;
648  dirname[len] = '\0';
649  if ((0 != len) && (0 != rmdir (dirname)))
650  {
651  switch (errno)
652  {
653  case EACCES:
654  case ENOTEMPTY:
655  case EPERM:
656  /* these are normal and can just be ignored */
657  break;
658  default:
660  "rmdir",
661  dirname);
662  break;
663  }
664  }
665  }
666  GNUNET_free (dirname);
667  }
668 #endif
670  return (ret == 0) ? GNUNET_OK : GNUNET_SYSERR;
671 }
672 
673 
679 void
681 {
682  GNUNET_free_non_null (desc->addr);
683  GNUNET_free (desc);
684 }
685 
686 
693 struct GNUNET_NETWORK_Handle *
695 {
696  struct GNUNET_NETWORK_Handle *ret;
697 #if MINGW
698  unsigned long i;
699  DWORD d;
700  /* FIXME: Find a better call to check that FD is valid */
701  if (0 !=
702  WSAIoctl (fd, FIONBIO,
703  (void *) &i, sizeof (i),
704  NULL, 0, &d,
705  NULL, NULL))
706  return NULL; /* invalid FD */
707  ret = GNUNET_new (struct GNUNET_NETWORK_Handle);
708  ret->fd = fd;
709  ret->af = AF_UNSPEC;
710  return ret;
711 #else
712  if (fcntl (fd, F_GETFD) < 0)
713  return NULL; /* invalid FD */
714  ret = GNUNET_new (struct GNUNET_NETWORK_Handle);
715  ret->fd = fd;
716  ret->af = AF_UNSPEC;
717  return ret;
718 #endif
719 }
720 
721 
730 int
732  const struct sockaddr *address,
733  socklen_t address_len)
734 {
735  int ret;
736 
737  ret = connect (desc->fd,
738  address,
739  address_len);
740 #ifdef MINGW
741  if (SOCKET_ERROR == ret)
742  {
743  SetErrnoFromWinsockError (WSAGetLastError ());
744  if (errno == EWOULDBLOCK)
745  errno = EINPROGRESS;
746  }
747 #endif
748  return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;
749 }
750 
751 
762 int
764  int level,
765  int optname,
766  void *optval,
767  socklen_t *optlen)
768 {
769  int ret;
770 
771  ret = getsockopt (desc->fd,
772  level,
773  optname,
774  optval, optlen);
775 
776 #ifdef MINGW
777  if ( (0 == ret) &&
778  (SOL_SOCKET == level) &&
779  (SO_ERROR == optname) )
780  *((int *) optval) = GetErrnoFromWinsockError (*((int *) optval));
781  else if (SOCKET_ERROR == ret)
782  SetErrnoFromWinsockError (WSAGetLastError ());
783 #endif
784  return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;
785 }
786 
787 
795 int
797  int backlog)
798 {
799  int ret;
800 
801  ret = listen (desc->fd,
802  backlog);
803 #ifdef MINGW
804  if (SOCKET_ERROR == ret)
805  SetErrnoFromWinsockError (WSAGetLastError ());
806 #endif
807  return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;
808 }
809 
810 
817 ssize_t
819 {
820  int error;
821 
822  /* How much is there to be read? */
823 #ifndef WINDOWS
824  int pending;
825 
826  error = ioctl (desc->fd,
827  FIONREAD,
828  &pending);
829  if (0 == error)
830  return (ssize_t) pending;
831  return GNUNET_SYSERR;
832 #else
833  u_long pending;
834 
835  error = ioctlsocket (desc->fd,
836  FIONREAD,
837  &pending);
838  if (error != SOCKET_ERROR)
839  return (ssize_t) pending;
840  return GNUNET_SYSERR;
841 #endif
842 }
843 
844 
855 ssize_t
857  void *buffer,
858  size_t length,
859  struct sockaddr *src_addr,
860  socklen_t *addrlen)
861 {
862  int ret;
863  int flags;
864 
865  flags = 0;
866 
867 #ifdef MSG_DONTWAIT
868  flags |= MSG_DONTWAIT;
869 
870 #endif
871  ret = recvfrom (desc->fd,
872  buffer,
873  length,
874  flags,
875  src_addr,
876  addrlen);
877 #ifdef MINGW
878  if (SOCKET_ERROR == ret)
879  SetErrnoFromWinsockError (WSAGetLastError ());
880 #endif
881  return ret;
882 }
883 
884 
893 ssize_t
895  void *buffer,
896  size_t length)
897 {
898  int ret;
899  int flags;
900 
901  flags = 0;
902 
903 #ifdef MSG_DONTWAIT
904  flags |= MSG_DONTWAIT;
905 #endif
906  ret = recv (desc->fd,
907  buffer,
908  length,
909  flags);
910 #ifdef MINGW
911  if (SOCKET_ERROR == ret)
912  SetErrnoFromWinsockError (WSAGetLastError ());
913 #endif
914  return ret;
915 }
916 
917 
926 ssize_t
928  const void *buffer,
929  size_t length)
930 {
931  int ret;
932  int flags;
933 
934  flags = 0;
935 #ifdef MSG_DONTWAIT
936  flags |= MSG_DONTWAIT;
937 
938 #endif
939 #ifdef MSG_NOSIGNAL
940  flags |= MSG_NOSIGNAL;
941 
942 #endif
943  ret = send (desc->fd,
944  buffer,
945  length,
946  flags);
947 #ifdef MINGW
948  if (SOCKET_ERROR == ret)
949  SetErrnoFromWinsockError (WSAGetLastError ());
950 
951 #endif
952  return ret;
953 }
954 
955 
967 ssize_t
969  const void *message,
970  size_t length,
971  const struct sockaddr *dest_addr,
972  socklen_t dest_len)
973 {
974  int ret;
975  int flags;
976 
977  flags = 0;
978 
979 #ifdef MSG_DONTWAIT
980  flags |= MSG_DONTWAIT;
981 #endif
982 #ifdef MSG_NOSIGNAL
983  flags |= MSG_NOSIGNAL;
984 #endif
985  ret = sendto (desc->fd, message, length, flags, dest_addr, dest_len);
986 #ifdef MINGW
987  if (SOCKET_ERROR == ret)
988  SetErrnoFromWinsockError (WSAGetLastError ());
989 #endif
990  return ret;
991 }
992 
993 
1004 int
1006  int level,
1007  int option_name,
1008  const void *option_value,
1009  socklen_t option_len)
1010 {
1011  int ret;
1012 
1013  ret = setsockopt (fd->fd,
1014  level,
1015  option_name,
1016  option_value,
1017  option_len);
1018 #ifdef MINGW
1019  if (SOCKET_ERROR == ret)
1020  SetErrnoFromWinsockError (WSAGetLastError ());
1021 #endif
1022  return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;
1023 }
1024 
1025 
1036 struct GNUNET_NETWORK_Handle *
1038  int type,
1039  int protocol)
1040 {
1041  struct GNUNET_NETWORK_Handle *ret;
1042  int fd;
1043 
1044  fd = socket (domain, type, protocol);
1045  if (-1 == fd)
1046  return NULL;
1047  ret = GNUNET_new (struct GNUNET_NETWORK_Handle);
1048  ret->fd = fd;
1049  if (GNUNET_OK !=
1051  domain,
1052  type))
1053  return NULL;
1054  return ret;
1055 }
1056 
1057 
1064 int
1066  int how)
1067 {
1068  int ret;
1069 
1070  ret = shutdown (desc->fd, how);
1071 #ifdef MINGW
1072  if (0 != ret)
1073  SetErrnoFromWinsockError (WSAGetLastError ());
1074 #endif
1075  return (0 == ret) ? GNUNET_OK : GNUNET_SYSERR;
1076 }
1077 
1078 
1088 int
1090 {
1091  int ret = 0;
1092 
1093 #if WINDOWS
1094  int value = 0;
1095 
1096  if (0 !=
1097  (ret =
1098  setsockopt (desc->fd,
1099  SOL_SOCKET,
1100  SO_SNDBUF,
1101  (char *) &value,
1102  sizeof (value))))
1104  "setsockopt");
1105  if (0 !=
1106  (ret =
1107  setsockopt (desc->fd,
1108  SOL_SOCKET,
1109  SO_RCVBUF,
1110  (char *) &value,
1111  sizeof (value))))
1113  "setsockopt");
1114 #elif LINUX
1115  int value = 0;
1116 
1117  if (0 !=
1118  (ret =
1119  setsockopt (desc->fd,
1120  SOL_SOCKET,
1121  SO_SNDBUF,
1122  &value,
1123  sizeof (value))))
1125  "setsockopt");
1126  if (0 !=
1127  (ret =
1128  setsockopt (desc->fd,
1129  SOL_SOCKET,
1130  SO_RCVBUF,
1131  &value,
1132  sizeof (value))))
1134  "setsockopt");
1135 #endif
1136  return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;
1137 }
1138 
1139 
1145 void
1147 {
1148  FD_ZERO (&fds->sds);
1149  fds->nsds = 0;
1150 #ifdef MINGW
1151  fds->handles_pos = 0;
1152 #endif
1153 }
1154 
1155 
1162 void
1164  const struct GNUNET_NETWORK_Handle *desc)
1165 {
1166  FD_SET (desc->fd,
1167  &fds->sds);
1168  fds->nsds = GNUNET_MAX (fds->nsds,
1169  desc->fd + 1);
1170 }
1171 
1172 
1180 int
1182  const struct GNUNET_NETWORK_Handle *desc)
1183 {
1184  return FD_ISSET (desc->fd,
1185  &fds->sds);
1186 }
1187 
1188 
1195 void
1197  const struct GNUNET_NETWORK_FDSet *src)
1198 {
1199 #ifndef MINGW
1200  int nfds;
1201 
1202  for (nfds = src->nsds; nfds >= 0; nfds--)
1203  if (FD_ISSET (nfds, &src->sds))
1204  FD_SET (nfds, &dst->sds);
1205  dst->nsds = GNUNET_MAX (dst->nsds,
1206  src->nsds);
1207 #else
1208  /* This is MinGW32-specific implementation that relies on the code that
1209  * winsock2.h defines for FD_SET. Namely, it relies on FD_SET checking
1210  * that fd being added is not already in the set.
1211  * Also relies on us knowing what's inside fd_set (fd_count and fd_array).
1212  *
1213  * NOTE: I don't understand why the UNIX-logic wouldn't work
1214  * for the first part here as well. -CG
1215  */
1216  unsigned int i;
1217 
1218  for (i = 0; i < src->sds.fd_count; i++)
1219  FD_SET (src->sds.fd_array[i],
1220  &dst->sds);
1221  dst->nsds = GNUNET_MAX (src->nsds,
1222  dst->nsds);
1223 
1224  /* also copy over `struct GNUNET_DISK_FileHandle` array */
1225  if (dst->handles_pos + src->handles_pos > dst->handles_size)
1226  GNUNET_array_grow (dst->handles,
1227  dst->handles_size,
1228  ((dst->handles_pos + src->handles_pos) << 1));
1229  for (i = 0; i < src->handles_pos; i++)
1230  dst->handles[dst->handles_pos++] = src->handles[i];
1231 #endif
1232 }
1233 
1234 
1241 void
1243  const struct GNUNET_NETWORK_FDSet *from)
1244 {
1245  FD_COPY (&from->sds,
1246  &to->sds);
1247  to->nsds = from->nsds;
1248 #ifdef MINGW
1249  if (from->handles_pos > to->handles_size)
1250  GNUNET_array_grow (to->handles,
1251  to->handles_size,
1252  from->handles_pos * 2);
1253  GNUNET_memcpy (to->handles,
1254  from->handles,
1255  from->handles_pos * sizeof (struct GNUNET_NETWORK_Handle *));
1256  to->handles_pos = from->handles_pos;
1257 #endif
1258 }
1259 
1260 
1267 int
1269 {
1270  return desc->fd;
1271 }
1272 
1273 
1280 struct sockaddr*
1282 {
1283  return desc->addr;
1284 }
1285 
1286 
1293 socklen_t
1295 {
1296  return desc->addrlen;
1297 }
1298 
1299 
1307 void
1309  const fd_set *from,
1310  int nfds)
1311 {
1312  FD_COPY (from,
1313  &to->sds);
1314  to->nsds = nfds;
1315 }
1316 
1317 
1324 void
1326  int nfd)
1327 {
1328  GNUNET_assert ((nfd >= 0) && (nfd < FD_SETSIZE));
1329  FD_SET (nfd, &to->sds);
1330  to->nsds = GNUNET_MAX (nfd + 1,
1331  to->nsds);
1332 }
1333 
1334 
1342 int
1344  int nfd)
1345 {
1346  if ( (-1 == nfd) ||
1347  (NULL == to) )
1348  return GNUNET_NO;
1349  return FD_ISSET (nfd, &to->sds) ? GNUNET_YES : GNUNET_NO;
1350 }
1351 
1352 
1358 void
1360  const struct GNUNET_DISK_FileHandle *h)
1361 {
1362 #ifdef MINGW
1363  if (fds->handles_pos == fds->handles_size)
1364  GNUNET_array_grow (fds->handles,
1365  fds->handles_size,
1366  fds->handles_size * 2 + 2);
1367  fds->handles[fds->handles_pos++] = h;
1368 #else
1369  int fd;
1370 
1373  &fd,
1374  sizeof (int)));
1375  FD_SET (fd,
1376  &fds->sds);
1377  fds->nsds = GNUNET_MAX (fd + 1,
1378  fds->nsds);
1379 #endif
1380 }
1381 
1382 
1388 void
1390  const struct GNUNET_DISK_FileHandle *h)
1391 {
1392 #ifdef MINGW
1393  if (fds->handles_pos == fds->handles_size)
1394  GNUNET_array_grow (fds->handles,
1395  fds->handles_size,
1396  fds->handles_size * 2 + 2);
1397  fds->handles[fds->handles_pos] = h;
1398  if (fds->handles[0] != h)
1399  {
1400  const struct GNUNET_DISK_FileHandle *bak = fds->handles[0];
1401  fds->handles[0] = h;
1402  fds->handles[fds->handles_pos] = bak;
1403  }
1404  fds->handles_pos++;
1405 #else
1407 #endif
1408 }
1409 
1410 
1418 int
1420  const struct GNUNET_DISK_FileHandle *h)
1421 {
1422 #ifdef MINGW
1423  unsigned int i;
1424 
1425  for (i=0;i<fds->handles_pos;i++)
1426  if (fds->handles[i] == h)
1427  return GNUNET_YES;
1428  return GNUNET_NO;
1429 #else
1430  return FD_ISSET (h->fd,
1431  &fds->sds);
1432 #endif
1433 }
1434 
1435 
1436 #ifdef MINGW
1437 
1445 static int
1446 ptr_cmp (const void *p1,
1447  const void *p2)
1448 {
1449  if (p1 == p2)
1450  return 0;
1451  if ((intptr_t) p1 < (intptr_t) p2)
1452  return -1;
1453  return 1;
1454 }
1455 #endif
1456 
1457 
1465 int
1467  const struct GNUNET_NETWORK_FDSet *fds2)
1468 {
1469 #ifndef MINGW
1470  int nfds;
1471 
1472  nfds = GNUNET_MIN (fds1->nsds,
1473  fds2->nsds);
1474  while (nfds > 0)
1475  {
1476  nfds--;
1477  if ( (FD_ISSET (nfds,
1478  &fds1->sds)) &&
1479  (FD_ISSET (nfds,
1480  &fds2->sds)) )
1481  return GNUNET_YES;
1482  }
1483  return GNUNET_NO;
1484 #else
1485  unsigned int i;
1486  unsigned int j;
1487 
1488  /* This code is somewhat hacky, we are not supposed to know what's
1489  * inside of fd_set; also the O(n^2) is really bad... */
1490  for (i = 0; i < fds1->sds.fd_count; i++)
1491  for (j = 0; j < fds2->sds.fd_count; j++)
1492  if (fds1->sds.fd_array[i] == fds2->sds.fd_array[j])
1493  return GNUNET_YES;
1494 
1495  /* take a short cut if possible */
1496  if ( (0 == fds1->handles_pos) ||
1497  (0 == fds2->handles_pos) )
1498  return GNUNET_NO;
1499 
1500  /* Sort file handles array to avoid quadratic complexity when
1501  checking for overlap */
1502  qsort (fds1->handles,
1503  fds1->handles_pos,
1504  sizeof (void *),
1505  &ptr_cmp);
1506  qsort (fds2->handles,
1507  fds2->handles_pos,
1508  sizeof (void *),
1509  &ptr_cmp);
1510  i = 0;
1511  j = 0;
1512  while ( (i < fds1->handles_pos) &&
1513  (j < fds2->handles_pos) )
1514  {
1515  switch (ptr_cmp (fds1->handles[i],
1516  fds2->handles[j]))
1517  {
1518  case -1:
1519  i++;
1520  break;
1521  case 0:
1522  return GNUNET_YES;
1523  case 1:
1524  j++;
1525  }
1526  }
1527  return GNUNET_NO;
1528 #endif
1529 }
1530 
1531 
1537 struct GNUNET_NETWORK_FDSet *
1539 {
1540  struct GNUNET_NETWORK_FDSet *fds;
1541 
1542  fds = GNUNET_new (struct GNUNET_NETWORK_FDSet);
1544  return fds;
1545 }
1546 
1547 
1553 void
1555 {
1556 #ifdef MINGW
1557  GNUNET_array_grow (fds->handles,
1558  fds->handles_size,
1559  0);
1560 #endif
1561  GNUNET_free (fds);
1562 }
1563 
1564 
1565 #if MINGW
1566 
1569 struct _select_params
1570 {
1574  fd_set *r;
1575 
1579  fd_set *w;
1580 
1584  fd_set *e;
1585 
1589  struct timeval *tv;
1590 
1594  HANDLE wakeup;
1595 
1599  HANDLE standby;
1600 
1604  SOCKET wakeup_socket;
1605 
1609  int status;
1610 };
1611 
1612 
1616 static DWORD WINAPI
1617 _selector (LPVOID p)
1618 {
1619  struct _select_params *sp = p;
1620 
1621  while (1)
1622  {
1623  WaitForSingleObject (sp->standby,
1624  INFINITE);
1625  ResetEvent (sp->standby);
1626  sp->status = select (1,
1627  sp->r,
1628  sp->w,
1629  sp->e,
1630  sp->tv);
1631  if (FD_ISSET (sp->wakeup_socket,
1632  sp->r))
1633  {
1634  FD_CLR (sp->wakeup_socket,
1635  sp->r);
1636  sp->status -= 1;
1637  }
1638  SetEvent (sp->wakeup);
1639  }
1640  return 0;
1641 }
1642 
1643 
1644 static HANDLE hEventPipeWrite;
1645 
1646 static HANDLE hEventReadReady;
1647 
1648 static struct _select_params sp;
1649 
1650 static HANDLE select_thread;
1651 
1652 static HANDLE select_finished_event;
1653 
1654 static HANDLE select_standby_event;
1655 
1656 static SOCKET select_wakeup_socket = -1;
1657 
1658 static SOCKET select_send_socket = -1;
1659 
1660 static struct timeval select_timeout;
1661 
1662 
1668 static void
1669 initialize_select_thread ()
1670 {
1671  SOCKET select_listening_socket = -1;
1672  struct sockaddr_in s_in;
1673  int alen;
1674  int res;
1675  unsigned long p;
1676 
1677  select_standby_event = CreateEvent (NULL, TRUE, FALSE, NULL);
1678  select_finished_event = CreateEvent (NULL, TRUE, FALSE, NULL);
1679 
1680  select_wakeup_socket = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
1681 
1682  select_listening_socket = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
1683 
1684  p = 1;
1685  res = ioctlsocket (select_wakeup_socket, FIONBIO, &p);
1687  "Select thread initialization: ioctlsocket() returns %d\n",
1688  res);
1689 
1690  alen = sizeof (s_in);
1691  s_in.sin_family = AF_INET;
1692  s_in.sin_port = 0;
1693  s_in.sin_addr.S_un.S_un_b.s_b1 = 127;
1694  s_in.sin_addr.S_un.S_un_b.s_b2 = 0;
1695  s_in.sin_addr.S_un.S_un_b.s_b3 = 0;
1696  s_in.sin_addr.S_un.S_un_b.s_b4 = 1;
1697  res = bind (select_listening_socket,
1698  (const struct sockaddr *) &s_in,
1699  sizeof (s_in));
1701  "Select thread initialization: bind() returns %d\n",
1702  res);
1703 
1704  res = getsockname (select_listening_socket,
1705  (struct sockaddr *) &s_in,
1706  &alen);
1708  "Select thread initialization: getsockname() returns %d\n",
1709  res);
1710 
1711  res = listen (select_listening_socket,
1712  SOMAXCONN);
1714  "Select thread initialization: listen() returns %d\n",
1715  res);
1716  res = connect (select_wakeup_socket,
1717  (const struct sockaddr *) &s_in,
1718  sizeof (s_in));
1720  "Select thread initialization: connect() returns %d\n",
1721  res);
1722 
1723  select_send_socket = accept (select_listening_socket,
1724  (struct sockaddr *) &s_in,
1725  &alen);
1726 
1727  closesocket (select_listening_socket);
1728 
1729  sp.wakeup = select_finished_event;
1730  sp.standby = select_standby_event;
1731  sp.wakeup_socket = select_wakeup_socket;
1732 
1733  select_thread = CreateThread (NULL,
1734  0,
1735  _selector,
1736  &sp,
1737  0, NULL);
1738 }
1739 
1740 
1741 #endif
1742 
1750 int
1752  uint16_t port)
1753 {
1754  struct GNUNET_NETWORK_Handle *socket;
1755  int bind_status;
1756  int socktype;
1757  char open_port_str[6];
1758  struct addrinfo hint;
1759  struct addrinfo *ret;
1760  struct addrinfo *ai;
1761 
1762  GNUNET_snprintf (open_port_str,
1763  sizeof (open_port_str),
1764  "%u",
1765  (unsigned int) port);
1766  socktype = (IPPROTO_TCP == ipproto) ? SOCK_STREAM : SOCK_DGRAM;
1767  ret = NULL;
1768  memset (&hint, 0, sizeof (hint));
1769  hint.ai_family = AF_UNSPEC; /* IPv4 and IPv6 */
1770  hint.ai_socktype = socktype;
1771  hint.ai_protocol = ipproto;
1772  hint.ai_addrlen = 0;
1773  hint.ai_addr = NULL;
1774  hint.ai_canonname = NULL;
1775  hint.ai_next = NULL;
1776  hint.ai_flags = AI_PASSIVE | AI_NUMERICSERV; /* Wild card address */
1777  GNUNET_assert (0 == getaddrinfo (NULL,
1778  open_port_str,
1779  &hint,
1780  &ret));
1781  bind_status = GNUNET_NO;
1782  for (ai = ret; NULL != ai; ai = ai->ai_next)
1783  {
1784  socket = GNUNET_NETWORK_socket_create (ai->ai_family,
1785  ai->ai_socktype,
1786  ai->ai_protocol);
1787  if (NULL == socket)
1788  continue;
1789  bind_status = GNUNET_NETWORK_socket_bind (socket,
1790  ai->ai_addr,
1791  ai->ai_addrlen);
1792  GNUNET_NETWORK_socket_close (socket);
1793  if (GNUNET_OK != bind_status)
1794  break;
1795  }
1796  freeaddrinfo (ret);
1797  return bind_status;
1798 }
1799 
1800 
1801 #ifndef MINGW
1802 
1811 int
1813  struct GNUNET_NETWORK_FDSet *wfds,
1814  struct GNUNET_NETWORK_FDSet *efds,
1815  const struct GNUNET_TIME_Relative timeout)
1816 {
1817  int nfds;
1818  struct timeval tv;
1819 
1820  if (NULL != rfds)
1821  nfds = rfds->nsds;
1822  else
1823  nfds = 0;
1824  if (NULL != wfds)
1825  nfds = GNUNET_MAX (nfds,
1826  wfds->nsds);
1827  if (NULL != efds)
1828  nfds = GNUNET_MAX (nfds,
1829  efds->nsds);
1830  if ((0 == nfds) &&
1831  (timeout.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us))
1832  {
1833  GNUNET_break (0);
1835  _("Fatal internal logic error, process hangs in `%s' (abort with CTRL-C)!\n"),
1836  "select");
1837  }
1838  if (timeout.rel_value_us / GNUNET_TIME_UNIT_SECONDS.rel_value_us > (unsigned long long) LONG_MAX)
1839  {
1840  tv.tv_sec = LONG_MAX;
1841  tv.tv_usec = 999999L;
1842  }
1843  else
1844  {
1845  tv.tv_sec = (long) (timeout.rel_value_us / GNUNET_TIME_UNIT_SECONDS.rel_value_us);
1846  tv.tv_usec =
1847  (timeout.rel_value_us -
1848  (tv.tv_sec * GNUNET_TIME_UNIT_SECONDS.rel_value_us));
1849  }
1850  return select (nfds,
1851  (NULL != rfds) ? &rfds->sds : NULL,
1852  (NULL != wfds) ? &wfds->sds : NULL,
1853  (NULL != efds) ? &efds->sds : NULL,
1854  (timeout.rel_value_us ==
1855  GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us) ? NULL : &tv);
1856 }
1857 
1858 
1859 #else
1860 /* MINGW */
1861 
1862 
1869 static int
1870 pipe_read_ready (const struct GNUNET_DISK_FileHandle *fh)
1871 {
1872  DWORD error;
1873  BOOL bret;
1874  DWORD waitstatus = 0;
1875 
1876  SetLastError (0);
1877  bret = PeekNamedPipe (fh->h, NULL, 0, NULL, &waitstatus, NULL);
1878  error = GetLastError ();
1879  if (0 == bret)
1880  {
1881  /* TODO: either add more errors to this condition, or eliminate it
1882  * entirely (failed to peek -> pipe is in serious trouble, should
1883  * be selected as readable).
1884  */
1885  if ( (error != ERROR_BROKEN_PIPE) &&
1886  (error != ERROR_INVALID_HANDLE) )
1887  return GNUNET_NO;
1888  }
1889  else if (waitstatus <= 0)
1890  return GNUNET_NO;
1891  return GNUNET_YES;
1892 }
1893 
1894 
1901 static int
1902 pipe_except_ready (const struct GNUNET_DISK_FileHandle *fh)
1903 {
1904  DWORD dwBytes;
1905 
1906  if (PeekNamedPipe (fh->h, NULL, 0, NULL, &dwBytes, NULL))
1907  return GNUNET_NO;
1908  return GNUNET_YES;
1909 }
1910 
1911 
1925 static int
1926 check_handles_status (struct GNUNET_NETWORK_FDSet *fds,
1927  int except,
1928  HANDLE set_for_sure)
1929 {
1930  const struct GNUNET_DISK_FileHandle *fh;
1931  unsigned int roff;
1932  unsigned int woff;
1933 
1934  for (woff = 0, roff = 0; roff < fds->handles_pos; roff++)
1935  {
1936  fh = fds->handles[roff];
1937  if (fh == set_for_sure)
1938  {
1939  fds->handles[woff++] = fh;
1940  }
1941  else if (fh->type == GNUNET_DISK_HANLDE_TYPE_PIPE)
1942  {
1943  if ((except && pipe_except_ready (fh)) ||
1944  (!except && pipe_read_ready (fh)))
1945  fds->handles[woff++] = fh;
1946  }
1947  else if (fh->type == GNUNET_DISK_HANLDE_TYPE_FILE)
1948  {
1949  if (!except)
1950  fds->handles[woff++] = fh;
1951  }
1952  else
1953  {
1954  if (WAIT_OBJECT_0 == WaitForSingleObject (fh->h, 0))
1955  fds->handles[woff++] = fh;
1956  }
1957  }
1958  fds->handles_pos = woff;
1959  return woff;
1960 }
1961 
1962 
1972 int
1974  struct GNUNET_NETWORK_FDSet *wfds,
1975  struct GNUNET_NETWORK_FDSet *efds,
1976  const struct GNUNET_TIME_Relative timeout)
1977 {
1978  const struct GNUNET_DISK_FileHandle *fh;
1979  int nfds;
1980  int handles;
1981  unsigned int i;
1982  int retcode;
1983  uint64_t mcs_total;
1984  DWORD ms_rounded;
1985  int nhandles = 0;
1986  int read_pipes_off;
1987  HANDLE handle_array[FD_SETSIZE + 2];
1988  int returncode;
1989  int returnedpos = 0;
1990  int selectret;
1991  fd_set aread;
1992  fd_set awrite;
1993  fd_set aexcept;
1994 
1995  nfds = 0;
1996  handles = 0;
1997  if (NULL != rfds)
1998  {
1999  nfds = GNUNET_MAX (nfds, rfds->nsds);
2000  handles += rfds->handles_pos;
2001  }
2002  if (NULL != wfds)
2003  {
2004  nfds = GNUNET_MAX (nfds, wfds->nsds);
2005  handles += wfds->handles_pos;
2006  }
2007  if (NULL != efds)
2008  {
2009  nfds = GNUNET_MAX (nfds, efds->nsds);
2010  handles += efds->handles_pos;
2011  }
2012 
2013  if ((0 == nfds) &&
2014  (GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us == timeout.rel_value_us) &&
2015  (0 == handles) )
2016  {
2017  GNUNET_break (0);
2019  _("Fatal internal logic error, process hangs in `%s' (abort with CTRL-C)!\n"),
2020  "select");
2021  }
2022 #define SAFE_FD_ISSET(fd, set) (set != NULL && FD_ISSET(fd, set))
2023  /* calculate how long we need to wait in microseconds */
2024  if (timeout.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
2025  {
2026  mcs_total = INFINITE;
2027  ms_rounded = INFINITE;
2028  }
2029  else
2030  {
2031  mcs_total = timeout.rel_value_us / GNUNET_TIME_UNIT_MICROSECONDS.rel_value_us;
2032  ms_rounded = (DWORD) (mcs_total / GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us);
2033  if (mcs_total > 0 && ms_rounded == 0)
2034  ms_rounded = 1;
2035  }
2036  /* select() may be used as a portable way to sleep */
2037  if (! (rfds || wfds || efds))
2038  {
2039  Sleep (ms_rounded);
2040  return 0;
2041  }
2042 
2043  if (NULL == select_thread)
2044  initialize_select_thread ();
2045 
2046  FD_ZERO (&aread);
2047  FD_ZERO (&awrite);
2048  FD_ZERO (&aexcept);
2049  if (rfds)
2050  FD_COPY (&rfds->sds, &aread);
2051  if (wfds)
2052  FD_COPY (&wfds->sds, &awrite);
2053  if (efds)
2054  FD_COPY (&efds->sds, &aexcept);
2055 
2056  /* Start by doing a fast check on sockets and pipes (without
2057  waiting). It is cheap, and is sufficient most of the time. By
2058  profiling we detected that to be true in 90% of the cases.
2059  */
2060 
2061  /* Do the select now */
2062  select_timeout.tv_sec = 0;
2063  select_timeout.tv_usec = 0;
2064 
2065  /* Copy all the writes to the except, so we can detect connect() errors */
2066  for (i = 0; i < awrite.fd_count; i++)
2067  FD_SET (awrite.fd_array[i],
2068  &aexcept);
2069  if ( (aread.fd_count > 0) ||
2070  (awrite.fd_count > 0) ||
2071  (aexcept.fd_count > 0) )
2072  selectret = select (1,
2073  (NULL != rfds) ? &aread : NULL,
2074  (NULL != wfds) ? &awrite : NULL,
2075  &aexcept,
2076  &select_timeout);
2077  else
2078  selectret = 0;
2079  if (-1 == selectret)
2080  {
2081  /* Throw an error early on, while we still have the context. */
2083  "W32 select(%d, %d, %d) failed: %lu\n",
2084  rfds ? aread.fd_count : 0,
2085  wfds ? awrite.fd_count : 0,
2086  aexcept.fd_count,
2087  GetLastError ());
2088  GNUNET_assert (0);
2089  }
2090 
2091  /* Check aexcept, if something is in there and we copied that
2092  FD before to detect connect() errors, add it back to the
2093  write set to report errors. */
2094  if (NULL != wfds)
2095  for (i = 0; i < aexcept.fd_count; i++)
2096  if (FD_ISSET (aexcept.fd_array[i],
2097  &wfds->sds))
2098  FD_SET (aexcept.fd_array[i],
2099  &awrite);
2100 
2101 
2102  /* If our select returned something or is a 0-timed request, then
2103  also check the pipes and get out of here! */
2104  /* Sadly, it means code duplication :( */
2105  if ( (selectret > 0) || (0 == mcs_total) )
2106  {
2107  retcode = 0;
2108 
2109  /* Read Pipes */
2110  if (rfds && (rfds->handles_pos > 0))
2111  retcode += check_handles_status (rfds, GNUNET_NO, NULL);
2112 
2113  /* wfds handles remain untouched, on W32
2114  we pretend our pipes are "always" write-ready */
2115 
2116  /* except pipes */
2117  if (efds && (efds->handles_pos > 0))
2118  retcode += check_handles_status (efds, GNUNET_YES, NULL);
2119 
2120  if (rfds)
2121  {
2123  if (selectret != -1)
2124  GNUNET_NETWORK_fdset_copy_native (rfds, &aread, selectret);
2125  }
2126  if (wfds)
2127  {
2129  if (selectret != -1)
2130  GNUNET_NETWORK_fdset_copy_native (wfds, &awrite, selectret);
2131  }
2132  if (efds)
2133  {
2135  if (selectret != -1)
2136  GNUNET_NETWORK_fdset_copy_native (efds, &aexcept, selectret);
2137  }
2138  if (-1 == selectret)
2139  return -1;
2140  /* Add our select() FDs to the total return value */
2141  retcode += selectret;
2142  return retcode;
2143  }
2144 
2145  /* If we got this far, use slower implementation that is able to do a waiting select
2146  on both sockets and pipes simultaneously */
2147 
2148  /* Events for pipes */
2149  if (! hEventReadReady)
2150  hEventReadReady = CreateEvent (NULL, TRUE, TRUE, NULL);
2151  if (! hEventPipeWrite)
2152  hEventPipeWrite = CreateEvent (NULL, TRUE, TRUE, NULL);
2153  retcode = 0;
2154 
2155  FD_ZERO (&aread);
2156  FD_ZERO (&awrite);
2157  FD_ZERO (&aexcept);
2158  if (rfds)
2159  FD_COPY (&rfds->sds, &aread);
2160  if (wfds)
2161  FD_COPY (&wfds->sds, &awrite);
2162  if (efds)
2163  FD_COPY (&efds->sds, &aexcept);
2164  /* We will first Add the PIPES to the events */
2165  /* Track how far in `handle_array` the read pipes go,
2166  so we may by-pass them quickly if none of them
2167  are selected. */
2168  read_pipes_off = 0;
2169  if (rfds && (rfds->handles_pos > 0))
2170  {
2171  for (i = 0; i <rfds->handles_pos; i++)
2172  {
2173  fh = rfds->handles[i];
2174  if (fh->type == GNUNET_DISK_HANLDE_TYPE_EVENT)
2175  {
2176  handle_array[nhandles++] = fh->h;
2177  continue;
2178  }
2179  if (fh->type != GNUNET_DISK_HANLDE_TYPE_PIPE)
2180  continue;
2181  /* Read zero bytes to check the status of the pipe */
2182  if (! ReadFile (fh->h, NULL, 0, NULL, fh->oOverlapRead))
2183  {
2184  DWORD error_code = GetLastError ();
2185 
2186  if (error_code == ERROR_IO_PENDING)
2187  {
2188  /* add as unready */
2189  handle_array[nhandles++] = fh->oOverlapRead->hEvent;
2190  read_pipes_off++;
2191  }
2192  else
2193  {
2194  /* add as ready */
2195  handle_array[nhandles++] = hEventReadReady;
2196  read_pipes_off++;
2197  }
2198  }
2199  else
2200  {
2201  /* error also counts as ready */
2202  handle_array[nhandles++] = hEventReadReady;
2203  read_pipes_off++;
2204  }
2205  }
2206  }
2207 
2208  if (wfds && (wfds->handles_pos > 0))
2209  {
2211  "Adding the write ready event to the array as %d\n",
2212  nhandles);
2213  handle_array[nhandles++] = hEventPipeWrite;
2214  }
2215 
2216  sp.status = 0;
2217  if (nfds > 0)
2218  {
2220  "Adding the socket event to the array as %d\n",
2221  nhandles);
2222  handle_array[nhandles++] = select_finished_event;
2223  if (timeout.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
2224  {
2225  sp.tv = NULL;
2226  }
2227  else
2228  {
2229  select_timeout.tv_sec = timeout.rel_value_us / GNUNET_TIME_UNIT_SECONDS.rel_value_us;
2230  select_timeout.tv_usec = (timeout.rel_value_us -
2231  (select_timeout.tv_sec *
2232  GNUNET_TIME_UNIT_SECONDS.rel_value_us));
2233  sp.tv = &select_timeout;
2234  }
2235  FD_SET (select_wakeup_socket, &aread);
2236  do
2237  {
2238  i = recv (select_wakeup_socket,
2239  (char *) &returnedpos,
2240  1,
2241  0);
2242  } while (i == 1);
2243  sp.r = &aread;
2244  sp.w = &awrite;
2245  sp.e = &aexcept;
2246  /* Failed connections cause sockets to be set in errorfds on W32,
2247  * but on POSIX it should set them in writefds.
2248  * First copy all awrite sockets to aexcept, later we'll
2249  * check aexcept and set its contents in awrite as well
2250  * Sockets are also set in errorfds when OOB data is available,
2251  * but we don't use OOB data.
2252  */
2253  for (i = 0; i < awrite.fd_count; i++)
2254  FD_SET (awrite.fd_array[i],
2255  &aexcept);
2256  ResetEvent (select_finished_event);
2257  SetEvent (select_standby_event);
2258  }
2259 
2260  /* NULL-terminate array */
2261  handle_array[nhandles] = NULL;
2263  "nfds: %d, handles: %d, will wait: %llu mcs\n",
2264  nfds,
2265  nhandles,
2266  mcs_total);
2267  if (nhandles)
2268  {
2269  returncode
2270  = WaitForMultipleObjects (nhandles,
2271  handle_array,
2272  FALSE,
2273  ms_rounded);
2275  "WaitForMultipleObjects Returned: %d\n",
2276  returncode);
2277  }
2278  else if (nfds > 0)
2279  {
2280  GNUNET_break (0); /* This branch shouldn't actually be executed...*/
2281  i = (int) WaitForSingleObject (select_finished_event,
2282  INFINITE);
2283  returncode = WAIT_TIMEOUT;
2284  }
2285  else
2286  {
2287  /* Shouldn't come this far. If it does - investigate. */
2288  GNUNET_assert (0);
2289  }
2290 
2291  if (nfds > 0)
2292  {
2293  /* Don't wake up select-thread when delay is 0, it should return immediately
2294  * and wake up by itself.
2295  */
2296  if (0 != mcs_total)
2297  i = send (select_send_socket,
2298  (const char *) &returnedpos,
2299  1,
2300  0);
2301  i = (int) WaitForSingleObject (select_finished_event,
2302  INFINITE);
2304  "Finished waiting for the select thread: %d %d\n",
2305  i,
2306  sp.status);
2307  if (0 != mcs_total)
2308  {
2309  do
2310  {
2311  i = recv (select_wakeup_socket,
2312  (char *) &returnedpos,
2313  1, 0);
2314  } while (1 == i);
2315  }
2316  /* Check aexcept, add its contents to awrite */
2317  for (i = 0; i < aexcept.fd_count; i++)
2318  FD_SET (aexcept.fd_array[i], &awrite);
2319  }
2320 
2321  returnedpos = returncode - WAIT_OBJECT_0;
2323  "return pos is: %d\n",
2324  returnedpos);
2325 
2326  if (rfds)
2327  {
2328  /* We queued a zero-long read on each pipe to check
2329  * its state, now we must cancel these read operations.
2330  * This must be done while rfds->handles_pos is still
2331  * intact and matches the number of read handles that we
2332  * got from the caller.
2333  */
2334  for (i = 0; i < rfds->handles_pos; i++)
2335  {
2336  fh = rfds->handles[i];
2337  if (GNUNET_DISK_HANLDE_TYPE_PIPE == fh->type)
2338  CancelIo (fh->h);
2339  }
2340 
2341  /* We may have some pipes ready for reading. */
2342  if (returnedpos < read_pipes_off)
2343  retcode += check_handles_status (rfds, GNUNET_NO, handle_array[returnedpos]);
2344  else
2345  rfds->handles_pos = 0;
2346 
2347  if (-1 != sp.status)
2348  GNUNET_NETWORK_fdset_copy_native (rfds, &aread, retcode);
2349  }
2350  if (wfds)
2351  {
2352  retcode += wfds->handles_pos;
2353  /* wfds handles remain untouched */
2354  if (-1 != sp.status)
2355  GNUNET_NETWORK_fdset_copy_native (wfds, &awrite, retcode);
2356  }
2357  if (efds)
2358  {
2359  retcode += check_handles_status (rfds,
2360  GNUNET_YES,
2361  returnedpos < nhandles ? handle_array[returnedpos] : NULL);
2362  if (-1 != sp.status)
2363  GNUNET_NETWORK_fdset_copy_native (efds, &aexcept, retcode);
2364  }
2365 
2366  if (sp.status > 0)
2367  retcode += sp.status;
2368 
2369  return retcode;
2370 }
2371 
2372 /* MINGW */
2373 #endif
2374 
2375 /* end of network.c */
int GNUNET_NETWORK_socket_listen(const struct GNUNET_NETWORK_Handle *desc, int backlog)
Listen on a socket.
Definition: network.c:796
int GNUNET_NETWORK_socket_setsockopt(struct GNUNET_NETWORK_Handle *fd, int level, int option_name, const void *option_value, socklen_t option_len)
Set socket option.
Definition: network.c:1005
int GNUNET_NETWORK_get_fd(const struct GNUNET_NETWORK_Handle *desc)
Return file descriptor for this network handle.
Definition: network.c:1268
int GNUNET_NETWORK_fdset_overlap(const struct GNUNET_NETWORK_FDSet *fds1, const struct GNUNET_NETWORK_FDSet *fds2)
Checks if two fd sets overlap.
Definition: network.c:1466
int GNUNET_NETWORK_socket_set_blocking(struct GNUNET_NETWORK_Handle *fd, int doBlock)
Set if a socket should use blocking or non-blocking IO.
Definition: network.c:256
struct sockaddr * GNUNET_NETWORK_get_addr(const struct GNUNET_NETWORK_Handle *desc)
Return sockaddr for this network handle.
Definition: network.c:1281
int nsds
Maximum number of any socket descriptor in the set (plus one)
static int initialize_network_handle(struct GNUNET_NETWORK_Handle *h, int af, int type)
Perform proper canonical initialization for a network handle.
Definition: network.c:408
uint64_t rel_value_us
The actual value.
#define AI_NUMERICSERV
AI_NUMERICSERV not defined in windows.
Definition: platform.h:261
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:34
ssize_t GNUNET_NETWORK_socket_send(const struct GNUNET_NETWORK_Handle *desc, const void *buffer, size_t length)
Send data (always non-blocking).
Definition: network.c:927
#define SOCKTYPE
Definition: platform.h:276
socklen_t GNUNET_NETWORK_get_addrlen(const struct GNUNET_NETWORK_Handle *desc)
Return sockaddr length for this network handle.
Definition: network.c:1294
int GNUNET_snprintf(char *buf, size_t size, const char *format,...)
Like snprintf, just aborts if the buffer is of insufficient size.
void GNUNET_NETWORK_fdset_set_native(struct GNUNET_NETWORK_FDSet *to, int nfd)
Set a native fd in a set.
Definition: network.c:1325
ssize_t GNUNET_NETWORK_socket_recv(const struct GNUNET_NETWORK_Handle *desc, void *buffer, size_t length)
Read data from a connected socket (always non-blocking).
Definition: network.c:894
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_TIME_UNIT_SECONDS
One second.
int GNUNET_NETWORK_socket_getsockopt(const struct GNUNET_NETWORK_Handle *desc, int level, int optname, void *optval, socklen_t *optlen)
Get socket options.
Definition: network.c:763
int GNUNET_NETWORK_socket_disable_corking(struct GNUNET_NETWORK_Handle *desc)
Disable the "CORK" feature for communication with the given socket, forcing the OS to immediately flu...
Definition: network.c:1089
int GNUNET_NETWORK_socket_bind(struct GNUNET_NETWORK_Handle *desc, const struct sockaddr *address, socklen_t address_len)
Bind a socket to a particular address.
Definition: network.c:522
Handle represents a file.
int GNUNET_NETWORK_fdset_test_native(const struct GNUNET_NETWORK_FDSet *to, int nfd)
Test native fd in a set.
Definition: network.c:1343
static struct Experiment * e
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
int GNUNET_NETWORK_socket_shutdown(struct GNUNET_NETWORK_Handle *desc, int how)
Shut down socket operations.
Definition: network.c:1065
static int ret
Final status code.
Definition: gnunet-arm.c:89
static int socket_set_inheritable(const struct GNUNET_NETWORK_Handle *h)
Make a socket non-inheritable to child processes.
Definition: network.c:314
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:94
void GNUNET_NETWORK_fdset_copy_native(struct GNUNET_NETWORK_FDSet *to, const fd_set *from, int nfds)
Copy a native fd set.
Definition: network.c:1308
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
static void socket_set_nodelay(const struct GNUNET_NETWORK_Handle *h)
Disable delays when sending data via the socket.
Definition: network.c:368
void GNUNET_NETWORK_socket_free_memory_only_(struct GNUNET_NETWORK_Handle *desc)
Only free memory of a socket, keep the file descriptor untouched.
Definition: network.c:680
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_accept(const struct GNUNET_NETWORK_Handle *desc, struct sockaddr *address, socklen_t *address_len)
accept a new connection on a socket
Definition: network.c:468
#define FD_SETSIZE
Definition: winproc.h:39
void GNUNET_NETWORK_fdset_destroy(struct GNUNET_NETWORK_FDSet *fds)
Releases the associated memory of an fd set.
Definition: network.c:1554
#define GNUNET_log_strerror(level, cmd)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
struct GNUNET_NETWORK_FDSet * GNUNET_NETWORK_fdset_create()
Creates an fd set.
Definition: network.c:1538
int GNUNET_NETWORK_socket_connect(const struct GNUNET_NETWORK_Handle *desc, const struct sockaddr *address, socklen_t address_len)
Connect a socket to some remote address.
Definition: network.c:731
#define GNUNET_array_grow(arr, size, tsize)
Grow a well-typed (!) array.
static struct GNUNET_TIME_Relative timeout
User defined timestamp for completing operations.
Definition: gnunet-arm.c:114
#define GNUNET_memcpy(dst, src, n)
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-qr.c:59
static char * value
Value of the record to add/remove.
#define INVALID_SOCKET
Definition: network.c:39
#define SOCKET(a, t, p)
Definition: plibc.h:711
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:44
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_box_native(SOCKTYPE fd)
Box a native socket (and check that it is a socket).
Definition: network.c:694
#define LOG_STRERROR_FILE(kind, syscall, filename)
Definition: network.c:32
#define GNUNET_MAX(a, b)
Definition: gnunet_common.h:85
#define GNUNET_MIN(a, b)
Definition: gnunet_common.h:83
ssize_t GNUNET_NETWORK_socket_sendto(const struct GNUNET_NETWORK_Handle *desc, const void *message, size_t length, const struct sockaddr *dest_addr, socklen_t dest_len)
Send data to a particular destination (always non-blocking).
Definition: network.c:968
collection of IO descriptors
uint16_t status
See PRISM_STATUS_*-constants.
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
const char * GNUNET_a2s(const struct sockaddr *addr, socklen_t addrlen)
Convert a "struct sockaddr*" (IPv4 or IPv6 address) to a string (for printing debug messages)...
static int fh
Handle to the unique file.
#define DIR_SEPARATOR
Definition: plibc.h:631
A 512-bit hashcode.
#define GNUNET_TIME_UNIT_MILLISECONDS
One millisecond.
static int res
Handle represents a pipe.
struct sockaddr * addr
Address we were bound to, or NULL.
Definition: network.c:72
int GNUNET_NETWORK_socket_select(struct GNUNET_NETWORK_FDSet *rfds, struct GNUNET_NETWORK_FDSet *wfds, struct GNUNET_NETWORK_FDSet *efds, const struct GNUNET_TIME_Relative timeout)
Check if sockets or pipes meet certain conditions.
Definition: network.c:1812
void GNUNET_CRYPTO_hash_to_enc(const struct GNUNET_HashCode *block, struct GNUNET_CRYPTO_HashAsciiEncoded *result)
Convert hash to ASCII encoding.
Definition: crypto_hash.c:69
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
static struct GNUNET_TRANSPORT_AddressIdentifier * ai
Handle to the operation that publishes our address.
int GNUNET_DISK_internal_file_handle_(const struct GNUNET_DISK_FileHandle *fh, void *dst, size_t dst_len)
Retrieve OS file handle.
Definition: disk.c:2665
const char * name
void GNUNET_NETWORK_fdset_zero(struct GNUNET_NETWORK_FDSet *fds)
Reset FD set.
Definition: network.c:1146
static unsigned int pending
The number of queries that are outstanding.
fd_set sds
Bitset with the descriptors.
void GNUNET_NETWORK_fdset_handle_set(struct GNUNET_NETWORK_FDSet *fds, const struct GNUNET_DISK_FileHandle *h)
Add a file handle to the fd set.
Definition: network.c:1359
void GNUNET_NETWORK_fdset_set(struct GNUNET_NETWORK_FDSet *fds, const struct GNUNET_NETWORK_Handle *desc)
Add a socket to the FD set.
Definition: network.c:1163
int GNUNET_NETWORK_fdset_handle_isset(const struct GNUNET_NETWORK_FDSet *fds, const struct GNUNET_DISK_FileHandle *h)
Check if a file handle is part of an fd set.
Definition: network.c:1419
0-terminated ASCII encoding of a struct GNUNET_HashCode.
#define GNUNET_strndup(a, length)
Wrapper around GNUNET_xstrndup_.
static uint16_t port
Port number.
Definition: gnunet-bcd.c:79
void GNUNET_NETWORK_fdset_copy(struct GNUNET_NETWORK_FDSet *to, const struct GNUNET_NETWORK_FDSet *from)
Copy one fd set to another.
Definition: network.c:1242
socklen_t addrlen
Number of bytes in addr.
Definition: network.c:67
#define FD_COPY(s, d)
Definition: network.c:244
int GNUNET_NETWORK_test_port_free(int ipproto, uint16_t port)
Test if the given port is available.
Definition: network.c:1751
#define LOG_STRERROR(kind, syscall)
Definition: network.c:33
#define LOG(kind,...)
Definition: network.c:31
#define GNUNET_log(kind,...)
Handle represents an event.
handle to a socket
Definition: network.c:46
char * GNUNET_NETWORK_shorten_unixpath(char *unixpath)
Given a unixpath that is too long (larger than UNIX_PATH_MAX), shorten it to an acceptable length whi...
Definition: network.c:157
int af
Address family / domain.
Definition: network.c:57
ssize_t GNUNET_NETWORK_socket_recvfrom_amount(const struct GNUNET_NETWORK_Handle *desc)
How much data is available to be read on this descriptor?
Definition: network.c:818
#define GNUNET_YES
Definition: gnunet_common.h:80
int fd
File handle on other OSes.
void GNUNET_NETWORK_unix_precheck(const struct sockaddr_un *un)
If services crash, they can leave a unix domain socket file on the disk.
Definition: network.c:201
int GNUNET_NETWORK_fdset_isset(const struct GNUNET_NETWORK_FDSet *fds, const struct GNUNET_NETWORK_Handle *desc)
Check whether a socket is part of the fd set.
Definition: network.c:1181
ssize_t GNUNET_NETWORK_socket_recvfrom(const struct GNUNET_NETWORK_Handle *desc, void *buffer, size_t length, struct sockaddr *src_addr, socklen_t *addrlen)
Read data from a socket (always non-blocking).
Definition: network.c:856
void GNUNET_NETWORK_fdset_add(struct GNUNET_NETWORK_FDSet *dst, const struct GNUNET_NETWORK_FDSet *src)
Add one fd set to another.
Definition: network.c:1196
static char * address
GNS address for this phone.
#define GNUNET_TIME_UNIT_MICROSECONDS
One microsecond, our basic time unit.
Handle used to access files (and pipes).
int GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:604
int type
Type of the socket.
Definition: network.c:62
#define GNUNET_malloc(size)
Wrapper around malloc.
int GNUNET_NETWORK_test_pf(int pf)
Test if the given protocol family is supported by this system.
Definition: network.c:84
static enum @11 mode
Should we do a PUT (mode = 0) or GET (mode = 1);.
Internal DISK related helper functions.
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:1037
void GNUNET_NETWORK_fdset_handle_set_first(struct GNUNET_NETWORK_FDSet *fds, const struct GNUNET_DISK_FileHandle *h)
Add a file handle to the fd set.
Definition: network.c:1389