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  int fd;
48 
52  int af;
53 
57  int type;
58 
62  socklen_t addrlen;
63 
67  struct sockaddr *addr;
68 };
69 
70 
77 int
79 {
80  static int cache_v4 = -1;
81  static int cache_v6 = -1;
82  static int cache_un = -1;
83  int s;
84  int ret;
85 
86  switch (pf)
87  {
88  case PF_INET:
89  if (-1 != cache_v4)
90  return cache_v4;
91  break;
92 
93  case PF_INET6:
94  if (-1 != cache_v6)
95  return cache_v6;
96  break;
97 
98 #ifdef PF_UNIX
99  case PF_UNIX:
100  if (-1 != cache_un)
101  return cache_un;
102  break;
103 #endif
104  }
105  s = socket(pf, SOCK_STREAM, 0);
106  if (-1 == s)
107  {
108  if (EAFNOSUPPORT != errno)
109  {
111  "socket");
112  return GNUNET_SYSERR;
113  }
114  ret = GNUNET_NO;
115  }
116  else
117  {
118  close(s);
119  ret = GNUNET_OK;
120  }
121  switch (pf)
122  {
123  case PF_INET:
124  cache_v4 = ret;
125  break;
126 
127  case PF_INET6:
128  cache_v6 = ret;
129  break;
130 
131 #ifdef PF_UNIX
132  case PF_UNIX:
133  cache_un = ret;
134  break;
135 #endif
136  }
137  return ret;
138 }
139 
140 
150 char *
152 {
153  struct sockaddr_un dummy;
154  size_t slen;
155  char *end;
156  struct GNUNET_HashCode sh;
158  size_t upm;
159 
160  upm = sizeof(dummy.sun_path);
161  slen = strlen(unixpath);
162  if (slen < upm)
163  return unixpath; /* no shortening required */
164  GNUNET_CRYPTO_hash(unixpath, slen, &sh);
165  while (16 + strlen(unixpath) >= upm)
166  {
167  if (NULL == (end = strrchr(unixpath, '/')))
168  {
170  _("Unable to shorten unix path `%s' while keeping name unique\n"),
171  unixpath);
172  GNUNET_free(unixpath);
173  return NULL;
174  }
175  *end = '\0';
176  }
177  GNUNET_CRYPTO_hash_to_enc(&sh, &ae);
178  ae.encoding[16] = '\0';
179  strcat(unixpath, (char *)ae.encoding);
180  return unixpath;
181 }
182 
183 
193 void
194 GNUNET_NETWORK_unix_precheck(const struct sockaddr_un *un)
195 {
196  int s;
197  int eno;
198  struct stat sbuf;
199  int ret;
200 
201  s = socket(AF_UNIX, SOCK_STREAM, 0);
202  if (-1 == s)
203  {
205  "Failed to open AF_UNIX socket");
206  return;
207  }
208  ret = connect(s,
209  (struct sockaddr *)un,
210  sizeof(struct sockaddr_un));
211  eno = errno;
212  GNUNET_break(0 == close(s));
213  if (0 == ret)
214  return; /* another process is listening, do not remove! */
215  if (ECONNREFUSED != eno)
216  return; /* some other error, likely "no such file or directory" -- all well */
217  /* should unlink, but sanity checks first */
218  if (0 != stat(un->sun_path,
219  &sbuf))
220  return; /* failed to 'stat', likely does not exist after all */
221  if (S_IFSOCK != (S_IFMT & sbuf.st_mode))
222  return; /* refuse to unlink anything except sockets */
223  /* finally, really unlink */
225  "Removing left-over `%s' from previous exeuction\n",
226  un->sun_path);
227  if (0 != unlink(un->sun_path))
229  "unlink",
230  un->sun_path);
231 }
232 
233 
234 #ifndef FD_COPY
235 #define FD_COPY(s, d) do { GNUNET_memcpy((d), (s), sizeof(fd_set)); } while (0)
236 #endif
237 
238 
246 int
248  int doBlock)
249 {
250  int flags = fcntl(fd->fd, F_GETFL);
251 
252  if (flags == -1)
253  {
255  "fcntl");
256  return GNUNET_SYSERR;
257  }
258  if (doBlock)
259  flags &= ~O_NONBLOCK;
260 
261  else
262  flags |= O_NONBLOCK;
263  if (0 != fcntl(fd->fd,
264  F_SETFL,
265  flags))
266 
267  {
269  "fcntl");
270  return GNUNET_SYSERR;
271  }
272  return GNUNET_OK;
273 }
274 
275 
283 static int
285 {
286  int i;
287  i = fcntl(h->fd, F_GETFD);
288  if (i < 0)
289  return GNUNET_SYSERR;
290  if (i == (i | FD_CLOEXEC))
291  return GNUNET_OK;
292  i |= FD_CLOEXEC;
293  if (fcntl(h->fd, F_SETFD, i) < 0)
294  return GNUNET_SYSERR;
295 
296  return GNUNET_OK;
297 }
298 
299 
300 #ifdef DARWIN
301 
306 static int
307 socket_set_nosigpipe(const struct GNUNET_NETWORK_Handle *h)
308 {
309  int abs_value = 1;
310 
311  if (0 !=
312  setsockopt(h->fd, SOL_SOCKET, SO_NOSIGPIPE,
313  (const void *)&abs_value,
314  sizeof(abs_value)))
315  return GNUNET_SYSERR;
316  return GNUNET_OK;
317 }
318 #endif
319 
320 
328 static void
330 {
331  int value = 1;
332 
333  if (0 !=
334  setsockopt(h->fd,
335  IPPROTO_TCP,
336  TCP_NODELAY,
337  &value, sizeof(value)))
339  "setsockopt");
340 }
341 
342 
355 static int
357  int af,
358  int type)
359 {
360  int eno;
361 
362  h->af = af;
363  h->type = type;
364  if (h->fd == INVALID_SOCKET)
365  {
366  eno = errno;
367  GNUNET_free(h);
368  errno = eno;
369  return GNUNET_SYSERR;
370  }
371 
372  if (h->fd >= FD_SETSIZE)
373  {
375  errno = EMFILE;
376  return GNUNET_SYSERR;
377  }
378 
381  "socket_set_inheritable");
382 
384  {
385  eno = errno;
386  GNUNET_break(0);
388  errno = eno;
389  return GNUNET_SYSERR;
390  }
391 #ifdef DARWIN
392  if (GNUNET_SYSERR == socket_set_nosigpipe(h))
393  {
394  eno = errno;
395  GNUNET_break(0);
397  errno = eno;
398  return GNUNET_SYSERR;
399  }
400 #endif
401  if ((type == SOCK_STREAM)
402 #ifdef AF_UNIX
403  && (af != AF_UNIX)
404 #endif
405  )
407  return GNUNET_OK;
408 }
409 
410 
419 struct GNUNET_NETWORK_Handle *
421  struct sockaddr *address,
422  socklen_t *address_len)
423 {
424  struct GNUNET_NETWORK_Handle *ret;
425  int eno;
426 
427  ret = GNUNET_new(struct GNUNET_NETWORK_Handle);
428 #if DEBUG_NETWORK
429  {
430  struct sockaddr_storage name;
431  socklen_t namelen = sizeof(name);
432 
433  int gsn = getsockname(desc->fd,
434  (struct sockaddr *)&name,
435  &namelen);
436 
437  if (0 == gsn)
439  "Accepting connection on `%s'\n",
440  GNUNET_a2s((const struct sockaddr *)&name,
441  namelen));
442  }
443 #endif
444  ret->fd = accept(desc->fd,
445  address,
446  address_len);
447  if (-1 == ret->fd)
448  {
449  eno = errno;
450  GNUNET_free(ret);
451  errno = eno;
452  return NULL;
453  }
454  if (GNUNET_OK !=
456  (NULL != address) ? address->sa_family : desc->af,
457  SOCK_STREAM))
458  {
459  return NULL;
460  }
461  return ret;
462 }
463 
464 
473 int
475  const struct sockaddr *address,
476  socklen_t address_len)
477 {
478  int ret;
479 
480 #ifdef IPV6_V6ONLY
481 #ifdef IPPROTO_IPV6
482  {
483  const int on = 1;
484 
485  if (AF_INET6 == desc->af)
486  if (setsockopt(desc->fd,
487  IPPROTO_IPV6,
488  IPV6_V6ONLY,
489  (const void *)&on,
490  sizeof(on)))
492  "setsockopt");
493  }
494 #endif
495 #endif
496  if (AF_UNIX == address->sa_family)
497  GNUNET_NETWORK_unix_precheck((const struct sockaddr_un *)address);
498  {
499  const int on = 1;
500 
501  /* This is required here for TCP sockets, but only on UNIX */
502  if ((SOCK_STREAM == desc->type) &&
503  (0 != setsockopt(desc->fd,
504  SOL_SOCKET,
505  SO_REUSEADDR,
506  &on, sizeof(on))))
508  "setsockopt");
509  }
510  {
511  /* set permissions of newly created non-abstract UNIX domain socket to
512  "user-only"; applications can choose to relax this later */
513  mode_t old_mask = 0; /* assigned to make compiler happy */
514  const struct sockaddr_un *un = (const struct sockaddr_un *)address;
515  int not_abstract = 0;
516 
517  if ((AF_UNIX == address->sa_family)
518  && ('\0' != un->sun_path[0])) /* Not an abstract socket */
519  not_abstract = 1;
520  if (not_abstract)
521  old_mask = umask(S_IWGRP | S_IRGRP | S_IXGRP | S_IWOTH | S_IROTH | S_IXOTH);
522 
523  ret = bind(desc->fd,
524  address,
525  address_len);
526 
527  if (not_abstract)
528  (void)umask(old_mask);
529 }
530  if (0 != ret)
531  return GNUNET_SYSERR;
532 
533  desc->addr = GNUNET_malloc(address_len);
534  GNUNET_memcpy(desc->addr, address, address_len);
535  desc->addrlen = address_len;
536 
537  return GNUNET_OK;
538 }
539 
540 
547 int
549 {
550  int ret;
551 
552  ret = close(desc->fd);
553 
554  const struct sockaddr_un *un = (const struct sockaddr_un *)desc->addr;
555 
556  /* Cleanup the UNIX domain socket and its parent directories in case of non
557  abstract sockets */
558  if ((AF_UNIX == desc->af) &&
559  (NULL != desc->addr) &&
560  ('\0' != un->sun_path[0]))
561  {
562  char *dirname = GNUNET_strndup(un->sun_path,
563  sizeof(un->sun_path));
564 
565  if (0 != unlink(dirname))
566  {
568  "unlink",
569  dirname);
570  }
571  else
572  {
573  size_t len;
574 
575  len = strlen(dirname);
576  while ((len > 0) && (dirname[len] != DIR_SEPARATOR))
577  len--;
578  dirname[len] = '\0';
579  if ((0 != len) && (0 != rmdir(dirname)))
580  {
581  switch (errno)
582  {
583  case EACCES:
584  case ENOTEMPTY:
585  case EPERM:
586  /* these are normal and can just be ignored */
587  break;
588 
589  default:
591  "rmdir",
592  dirname);
593  break;
594  }
595  }
596  }
597  GNUNET_free(dirname);
598  }
600  return (ret == 0) ? GNUNET_OK : GNUNET_SYSERR;
601 }
602 
603 
609 void
611 {
612  GNUNET_free_non_null(desc->addr);
613  GNUNET_free(desc);
614 }
615 
616 
623 struct GNUNET_NETWORK_Handle *
625 {
626  struct GNUNET_NETWORK_Handle *ret;
627 
628  if (fcntl(fd, F_GETFD) < 0)
629  return NULL; /* invalid FD */
630  ret = GNUNET_new(struct GNUNET_NETWORK_Handle);
631  ret->fd = fd;
632  ret->af = AF_UNSPEC;
633  return ret;
634 }
635 
636 
645 int
647  const struct sockaddr *address,
648  socklen_t address_len)
649 {
650  int ret;
651 
652  ret = connect(desc->fd,
653  address,
654  address_len);
655 
656  return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;
657 }
658 
659 
670 int
672  int level,
673  int optname,
674  void *optval,
675  socklen_t *optlen)
676 {
677  int ret;
678 
679  ret = getsockopt(desc->fd,
680  level,
681  optname,
682  optval, optlen);
683 
684  return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;
685 }
686 
687 
695 int
697  int backlog)
698 {
699  int ret;
700 
701  ret = listen(desc->fd,
702  backlog);
703 
704  return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;
705 }
706 
707 
714 ssize_t
716 {
717  int error;
718 
719  /* How much is there to be read? */
720  int pending;
721 
722  error = ioctl(desc->fd,
723  FIONREAD,
724  &pending);
725  if (0 == error)
726  return (ssize_t)pending;
727  return GNUNET_SYSERR;
728 }
729 
730 
741 ssize_t
743  void *buffer,
744  size_t length,
745  struct sockaddr *src_addr,
746  socklen_t *addrlen)
747 {
748  int ret;
749  int flags;
750 
751  flags = 0;
752 
753 #ifdef MSG_DONTWAIT
754  flags |= MSG_DONTWAIT;
755 #endif
756  ret = recvfrom(desc->fd,
757  buffer,
758  length,
759  flags,
760  src_addr,
761  addrlen);
762  return ret;
763 }
764 
765 
774 ssize_t
776  void *buffer,
777  size_t length)
778 {
779  int ret;
780  int flags;
781 
782  flags = 0;
783 
784 #ifdef MSG_DONTWAIT
785  flags |= MSG_DONTWAIT;
786 #endif
787  ret = recv(desc->fd,
788  buffer,
789  length,
790  flags);
791  return ret;
792 }
793 
794 
803 ssize_t
805  const void *buffer,
806  size_t length)
807 {
808  int ret;
809  int flags;
810 
811  flags = 0;
812 #ifdef MSG_DONTWAIT
813  flags |= MSG_DONTWAIT;
814 #endif
815 #ifdef MSG_NOSIGNAL
816  flags |= MSG_NOSIGNAL;
817 #endif
818  ret = send(desc->fd,
819  buffer,
820  length,
821  flags);
822  return ret;
823 }
824 
825 
837 ssize_t
839  const void *message,
840  size_t length,
841  const struct sockaddr *dest_addr,
842  socklen_t dest_len)
843 {
844  int ret;
845  int flags;
846 
847  flags = 0;
848 
849 #ifdef MSG_DONTWAIT
850  flags |= MSG_DONTWAIT;
851 #endif
852 #ifdef MSG_NOSIGNAL
853  flags |= MSG_NOSIGNAL;
854 #endif
855  ret = sendto(desc->fd, message, length, flags, dest_addr, dest_len);
856  return ret;
857 }
858 
859 
870 int
872  int level,
873  int option_name,
874  const void *option_value,
875  socklen_t option_len)
876 {
877  int ret;
878 
879  ret = setsockopt(fd->fd,
880  level,
881  option_name,
882  option_value,
883  option_len);
884 
885  return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;
886 }
887 
888 
899 struct GNUNET_NETWORK_Handle *
901  int type,
902  int protocol)
903 {
904  struct GNUNET_NETWORK_Handle *ret;
905  int fd;
906 
907  fd = socket(domain, type, protocol);
908  if (-1 == fd)
909  return NULL;
910  ret = GNUNET_new(struct GNUNET_NETWORK_Handle);
911  ret->fd = fd;
912  if (GNUNET_OK !=
914  domain,
915  type))
916  return NULL;
917  return ret;
918 }
919 
920 
927 int
929  int how)
930 {
931  int ret;
932 
933  ret = shutdown(desc->fd, how);
934 
935  return (0 == ret) ? GNUNET_OK : GNUNET_SYSERR;
936 }
937 
938 
948 int
950 {
951  int ret = 0;
952 
953 #if LINUX
954  int value = 0;
955 
956  if (0 !=
957  (ret =
958  setsockopt(desc->fd,
959  SOL_SOCKET,
960  SO_SNDBUF,
961  &value,
962  sizeof(value))))
964  "setsockopt");
965  if (0 !=
966  (ret =
967  setsockopt(desc->fd,
968  SOL_SOCKET,
969  SO_RCVBUF,
970  &value,
971  sizeof(value))))
973  "setsockopt");
974 #endif
975  return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;
976 }
977 
978 
984 void
986 {
987  FD_ZERO(&fds->sds);
988  fds->nsds = 0;
989 }
990 
991 
998 void
1000  const struct GNUNET_NETWORK_Handle *desc)
1001 {
1002  FD_SET(desc->fd,
1003  &fds->sds);
1004  fds->nsds = GNUNET_MAX(fds->nsds,
1005  desc->fd + 1);
1006 }
1007 
1008 
1016 int
1018  const struct GNUNET_NETWORK_Handle *desc)
1019 {
1020  return FD_ISSET(desc->fd,
1021  &fds->sds);
1022 }
1023 
1024 
1031 void
1033  const struct GNUNET_NETWORK_FDSet *src)
1034 {
1035  int nfds;
1036 
1037  for (nfds = src->nsds; nfds >= 0; nfds--)
1038  if (FD_ISSET(nfds, &src->sds))
1039  FD_SET(nfds, &dst->sds);
1040  dst->nsds = GNUNET_MAX(dst->nsds,
1041  src->nsds);
1042 }
1043 
1044 
1051 void
1053  const struct GNUNET_NETWORK_FDSet *from)
1054 {
1055  FD_COPY(&from->sds,
1056  &to->sds);
1057  to->nsds = from->nsds;
1058 }
1059 
1060 
1067 int
1069 {
1070  return desc->fd;
1071 }
1072 
1073 
1080 struct sockaddr*
1082 {
1083  return desc->addr;
1084 }
1085 
1086 
1093 socklen_t
1095 {
1096  return desc->addrlen;
1097 }
1098 
1099 
1107 void
1109  const fd_set *from,
1110  int nfds)
1111 {
1112  FD_COPY(from,
1113  &to->sds);
1114  to->nsds = nfds;
1115 }
1116 
1117 
1124 void
1126  int nfd)
1127 {
1128  GNUNET_assert((nfd >= 0) && (nfd < FD_SETSIZE));
1129  FD_SET(nfd, &to->sds);
1130  to->nsds = GNUNET_MAX(nfd + 1,
1131  to->nsds);
1132 }
1133 
1134 
1142 int
1144  int nfd)
1145 {
1146  if ((-1 == nfd) ||
1147  (NULL == to))
1148  return GNUNET_NO;
1149  return FD_ISSET(nfd, &to->sds) ? GNUNET_YES : GNUNET_NO;
1150 }
1151 
1152 
1158 void
1160  const struct GNUNET_DISK_FileHandle *h)
1161 {
1162  int fd;
1163 
1166  &fd,
1167  sizeof(int)));
1168  FD_SET(fd,
1169  &fds->sds);
1170  fds->nsds = GNUNET_MAX(fd + 1,
1171  fds->nsds);
1172 }
1173 
1174 
1180 void
1182  const struct GNUNET_DISK_FileHandle *h)
1183 {
1185 }
1186 
1187 
1195 int
1197  const struct GNUNET_DISK_FileHandle *h)
1198 {
1199  return FD_ISSET(h->fd,
1200  &fds->sds);
1201 }
1202 
1203 
1211 int
1213  const struct GNUNET_NETWORK_FDSet *fds2)
1214 {
1215  int nfds;
1216 
1217  nfds = GNUNET_MIN(fds1->nsds,
1218  fds2->nsds);
1219  while (nfds > 0)
1220  {
1221  nfds--;
1222  if ((FD_ISSET(nfds,
1223  &fds1->sds)) &&
1224  (FD_ISSET(nfds,
1225  &fds2->sds)))
1226  return GNUNET_YES;
1227  }
1228  return GNUNET_NO;
1229 }
1230 
1231 
1237 struct GNUNET_NETWORK_FDSet *
1239 {
1240  struct GNUNET_NETWORK_FDSet *fds;
1241 
1242  fds = GNUNET_new(struct GNUNET_NETWORK_FDSet);
1244  return fds;
1245 }
1246 
1247 
1253 void
1255 {
1256  GNUNET_free(fds);
1257 }
1258 
1259 
1267 int
1269  uint16_t port)
1270 {
1271  struct GNUNET_NETWORK_Handle *socket;
1272  int bind_status;
1273  int socktype;
1274  char open_port_str[6];
1275  struct addrinfo hint;
1276  struct addrinfo *ret;
1277  struct addrinfo *ai;
1278 
1279  GNUNET_snprintf(open_port_str,
1280  sizeof(open_port_str),
1281  "%u",
1282  (unsigned int)port);
1283  socktype = (IPPROTO_TCP == ipproto) ? SOCK_STREAM : SOCK_DGRAM;
1284  ret = NULL;
1285  memset(&hint, 0, sizeof(hint));
1286  hint.ai_family = AF_UNSPEC; /* IPv4 and IPv6 */
1287  hint.ai_socktype = socktype;
1288  hint.ai_protocol = ipproto;
1289  hint.ai_addrlen = 0;
1290  hint.ai_addr = NULL;
1291  hint.ai_canonname = NULL;
1292  hint.ai_next = NULL;
1293  hint.ai_flags = AI_PASSIVE | AI_NUMERICSERV; /* Wild card address */
1294  GNUNET_assert(0 == getaddrinfo(NULL,
1295  open_port_str,
1296  &hint,
1297  &ret));
1298  bind_status = GNUNET_NO;
1299  for (ai = ret; NULL != ai; ai = ai->ai_next)
1300  {
1301  socket = GNUNET_NETWORK_socket_create(ai->ai_family,
1302  ai->ai_socktype,
1303  ai->ai_protocol);
1304  if (NULL == socket)
1305  continue;
1306  bind_status = GNUNET_NETWORK_socket_bind(socket,
1307  ai->ai_addr,
1308  ai->ai_addrlen);
1310  if (GNUNET_OK != bind_status)
1311  break;
1312  }
1313  freeaddrinfo(ret);
1314  return bind_status;
1315 }
1316 
1317 
1327 int
1329  struct GNUNET_NETWORK_FDSet *wfds,
1330  struct GNUNET_NETWORK_FDSet *efds,
1331  const struct GNUNET_TIME_Relative timeout)
1332 {
1333  int nfds;
1334  struct timeval tv;
1335 
1336  if (NULL != rfds)
1337  nfds = rfds->nsds;
1338  else
1339  nfds = 0;
1340  if (NULL != wfds)
1341  nfds = GNUNET_MAX(nfds,
1342  wfds->nsds);
1343  if (NULL != efds)
1344  nfds = GNUNET_MAX(nfds,
1345  efds->nsds);
1346  if ((0 == nfds) &&
1347  (timeout.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us))
1348  {
1349  GNUNET_break(0);
1351  _("Fatal internal logic error, process hangs in `%s' (abort with CTRL-C)!\n"),
1352  "select");
1353  }
1354  if (timeout.rel_value_us / GNUNET_TIME_UNIT_SECONDS.rel_value_us > (unsigned long long)LONG_MAX)
1355  {
1356  tv.tv_sec = LONG_MAX;
1357  tv.tv_usec = 999999L;
1358  }
1359  else
1360  {
1361  tv.tv_sec = (long)(timeout.rel_value_us / GNUNET_TIME_UNIT_SECONDS.rel_value_us);
1362  tv.tv_usec =
1363  (timeout.rel_value_us -
1364  (tv.tv_sec * GNUNET_TIME_UNIT_SECONDS.rel_value_us));
1365  }
1366  return select(nfds,
1367  (NULL != rfds) ? &rfds->sds : NULL,
1368  (NULL != wfds) ? &wfds->sds : NULL,
1369  (NULL != efds) ? &efds->sds : NULL,
1370  (timeout.rel_value_us ==
1371  GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us) ? NULL : &tv);
1372 }
1373 
1374 /* end of network.c */
int GNUNET_NETWORK_socket_listen(const struct GNUNET_NETWORK_Handle *desc, int backlog)
Listen on a socket.
Definition: network.c:696
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:871
int GNUNET_NETWORK_get_fd(const struct GNUNET_NETWORK_Handle *desc)
Return file descriptor for this network handle.
Definition: network.c:1068
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:1212
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:247
struct sockaddr * GNUNET_NETWORK_get_addr(const struct GNUNET_NETWORK_Handle *desc)
Return sockaddr for this network handle.
Definition: network.c:1081
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:356
uint64_t rel_value_us
The actual value.
#define AI_NUMERICSERV
AI_NUMERICSERV not defined in windows.
Definition: platform.h:226
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:804
#define SOCKTYPE
Definition: platform.h:237
socklen_t GNUNET_NETWORK_get_addrlen(const struct GNUNET_NETWORK_Handle *desc)
Return sockaddr length for this network handle.
Definition: network.c:1094
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:1125
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:775
#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:671
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:949
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:474
int GNUNET_NETWORK_fdset_test_native(const struct GNUNET_NETWORK_FDSet *to, int nfd)
Test native fd in a set.
Definition: network.c:1143
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#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:928
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:284
#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:1108
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
static void socket_set_nodelay(const struct GNUNET_NETWORK_Handle *h)
Disable delays when sending data via the socket.
Definition: network.c:329
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:610
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:420
void GNUNET_NETWORK_fdset_destroy(struct GNUNET_NETWORK_FDSet *fds)
Releases the associated memory of an fd set.
Definition: network.c:1254
#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:1238
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:646
static struct GNUNET_TIME_Relative timeout
User defined timestamp for completing operations.
Definition: gnunet-arm.c:114
static char * value
Value of the record to add/remove.
#define INVALID_SOCKET
Definition: network.c:39
#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:624
#define LOG_STRERROR_FILE(kind, syscall, filename)
Definition: network.c:32
#define GNUNET_MAX(a, b)
Definition: gnunet_common.h:82
#define GNUNET_MIN(a, b)
Definition: gnunet_common.h:80
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:838
collection of IO descriptors
#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)...
A 512-bit hashcode.
struct sockaddr * addr
Address we were bound to, or NULL.
Definition: network.c:67
#define DIR_SEPARATOR
Definition: platform.h:167
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:1328
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:76
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:1769
const char * name
void GNUNET_NETWORK_fdset_zero(struct GNUNET_NETWORK_FDSet *fds)
Reset FD set.
Definition: network.c:985
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:1159
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:999
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:1196
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:81
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:1052
socklen_t addrlen
Number of bytes in addr.
Definition: network.c:62
#define FD_COPY(s, d)
Definition: network.c:235
int GNUNET_NETWORK_test_port_free(int ipproto, uint16_t port)
Test if the given port is available.
Definition: network.c:1268
#define LOG_STRERROR(kind, syscall)
Definition: network.c:33
#define LOG(kind,...)
Definition: network.c:31
#define GNUNET_log(kind,...)
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:151
int af
Address family / domain.
Definition: network.c:52
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:715
#define GNUNET_YES
Definition: gnunet_common.h:77
int fd
File handle on Unix-like systems.
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:194
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:1017
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:742
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:1032
static char * address
GNS address for this phone.
Handle used to access files (and pipes).
int GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:548
int type
Type of the socket.
Definition: network.c:57
#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:78
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:900
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:1181