use NULL value in load_path_suffix to NOT load any files
[oweals/gnunet.git] / src / util / network.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2009-2013 GNUnet e.V.
4
5      GNUnet is free software: you can redistribute it and/or modify it
6      under the terms of the GNU Affero General Public License as published
7      by the Free Software Foundation, either version 3 of the License,
8      or (at your option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      Affero General Public License for more details.
14
15      You should have received a copy of the GNU Affero General Public License
16      along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18      SPDX-License-Identifier: AGPL3.0-or-later
19  */
20
21 /**
22  * @file util/network.c
23  * @brief basic, low-level networking interface
24  * @author Nils Durner
25  * @author Christian Grothoff
26  */
27 #include "platform.h"
28 #include "gnunet_util_lib.h"
29 #include "disk.h"
30
31 #define LOG(kind, ...) GNUNET_log_from (kind, "util-network", __VA_ARGS__)
32 #define LOG_STRERROR_FILE(kind, syscall, \
33                           filename) GNUNET_log_from_strerror_file (kind, \
34                                                                    "util-network", \
35                                                                    syscall, \
36                                                                    filename)
37 #define LOG_STRERROR(kind, syscall) GNUNET_log_from_strerror (kind, \
38                                                               "util-network", \
39                                                               syscall)
40
41 #define DEBUG_NETWORK GNUNET_EXTRA_LOGGING
42
43
44 #ifndef INVALID_SOCKET
45 #define INVALID_SOCKET -1
46 #endif
47
48
49 /**
50  * @brief handle to a socket
51  */
52 struct GNUNET_NETWORK_Handle
53 {
54   int fd;
55
56   /**
57    * Address family / domain.
58    */
59   int af;
60
61   /**
62    * Type of the socket
63    */
64   int type;
65
66   /**
67    * Number of bytes in addr.
68    */
69   socklen_t addrlen;
70
71   /**
72    * Address we were bound to, or NULL.
73    */
74   struct sockaddr *addr;
75 };
76
77
78 /**
79  * Test if the given protocol family is supported by this system.
80  *
81  * @param pf protocol family to test (PF_INET, PF_INET6, PF_UNIX)
82  * @return #GNUNET_OK if the PF is supported
83  */
84 int
85 GNUNET_NETWORK_test_pf (int pf)
86 {
87   static int cache_v4 = -1;
88   static int cache_v6 = -1;
89   static int cache_un = -1;
90   int s;
91   int ret;
92
93   switch (pf)
94   {
95   case PF_INET:
96     if (-1 != cache_v4)
97       return cache_v4;
98     break;
99
100   case PF_INET6:
101     if (-1 != cache_v6)
102       return cache_v6;
103     break;
104
105 #ifdef PF_UNIX
106   case PF_UNIX:
107     if (-1 != cache_un)
108       return cache_un;
109     break;
110 #endif
111   }
112   s = socket (pf, SOCK_STREAM, 0);
113   if (-1 == s)
114   {
115     if (EAFNOSUPPORT != errno)
116     {
117       GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
118                            "socket");
119       return GNUNET_SYSERR;
120     }
121     ret = GNUNET_NO;
122   }
123   else
124   {
125     close (s);
126     ret = GNUNET_OK;
127   }
128   switch (pf)
129   {
130   case PF_INET:
131     cache_v4 = ret;
132     break;
133
134   case PF_INET6:
135     cache_v6 = ret;
136     break;
137
138 #ifdef PF_UNIX
139   case PF_UNIX:
140     cache_un = ret;
141     break;
142 #endif
143   }
144   return ret;
145 }
146
147
148 /**
149  * Given a unixpath that is too long (larger than UNIX_PATH_MAX),
150  * shorten it to an acceptable length while keeping it unique
151  * and making sure it remains a valid filename (if possible).
152  *
153  * @param unixpath long path, will be freed (or same pointer returned
154  *        with moved 0-termination).
155  * @return shortened unixpath, NULL on error
156  */
157 char *
158 GNUNET_NETWORK_shorten_unixpath (char *unixpath)
159 {
160   struct sockaddr_un dummy;
161   size_t slen;
162   char *end;
163   struct GNUNET_HashCode sh;
164   struct GNUNET_CRYPTO_HashAsciiEncoded ae;
165   size_t upm;
166
167   upm = sizeof(dummy.sun_path);
168   slen = strlen (unixpath);
169   if (slen < upm)
170     return unixpath; /* no shortening required */
171   GNUNET_CRYPTO_hash (unixpath, slen, &sh);
172   while (16 + strlen (unixpath) >= upm)
173   {
174     if (NULL == (end = strrchr (unixpath, '/')))
175     {
176       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
177                   _ (
178                     "Unable to shorten unix path `%s' while keeping name unique\n"),
179                   unixpath);
180       GNUNET_free (unixpath);
181       return NULL;
182     }
183     *end = '\0';
184   }
185   GNUNET_CRYPTO_hash_to_enc (&sh, &ae);
186   ae.encoding[16] = '\0';
187   strcat (unixpath, (char *) ae.encoding);
188   return unixpath;
189 }
190
191
192 /**
193  * If services crash, they can leave a unix domain socket file on the
194  * disk. This needs to be manually removed, because otherwise both
195  * bind() and connect() for the respective address will fail.  In this
196  * function, we test if such a left-over file exists, and if so,
197  * remove it (unless there is a listening service at the address).
198  *
199  * @param un unix domain socket address to check
200  */
201 void
202 GNUNET_NETWORK_unix_precheck (const struct sockaddr_un *un)
203 {
204   int s;
205   int eno;
206   struct stat sbuf;
207   int ret;
208
209   s = socket (AF_UNIX, SOCK_STREAM, 0);
210   if (-1 == s)
211   {
212     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
213                          "Failed to open AF_UNIX socket");
214     return;
215   }
216   ret = connect (s,
217                  (struct sockaddr *) un,
218                  sizeof(struct sockaddr_un));
219   eno = errno;
220   GNUNET_break (0 == close (s));
221   if (0 == ret)
222     return; /* another process is listening, do not remove! */
223   if (ECONNREFUSED != eno)
224     return; /* some other error, likely "no such file or directory" -- all well */
225   /* should unlink, but sanity checks first */
226   if (0 != stat (un->sun_path,
227                  &sbuf))
228     return; /* failed to 'stat', likely does not exist after all */
229   if (S_IFSOCK != (S_IFMT & sbuf.st_mode))
230     return; /* refuse to unlink anything except sockets */
231   /* finally, really unlink */
232   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
233               "Removing left-over `%s' from previous exeuction\n",
234               un->sun_path);
235   if (0 != unlink (un->sun_path))
236     GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
237                               "unlink",
238                               un->sun_path);
239 }
240
241
242 #ifndef FD_COPY
243 #define FD_COPY(s, d) do { GNUNET_memcpy ((d), (s), sizeof(fd_set)); } while (0)
244 #endif
245
246
247 /**
248  * Set if a socket should use blocking or non-blocking IO.
249  *
250  * @param fd socket
251  * @param doBlock blocking mode
252  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
253  */
254 int
255 GNUNET_NETWORK_socket_set_blocking (struct GNUNET_NETWORK_Handle *fd,
256                                     int doBlock)
257 {
258   int flags = fcntl (fd->fd, F_GETFL);
259
260   if (flags == -1)
261   {
262     LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING,
263                   "fcntl");
264     return GNUNET_SYSERR;
265   }
266   if (doBlock)
267     flags &= ~O_NONBLOCK;
268
269   else
270     flags |= O_NONBLOCK;
271   if (0 != fcntl (fd->fd,
272                   F_SETFL,
273                   flags))
274
275   {
276     LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING,
277                   "fcntl");
278     return GNUNET_SYSERR;
279   }
280   return GNUNET_OK;
281 }
282
283
284 /**
285  * Make a socket non-inheritable to child processes
286  *
287  * @param h the socket to make non-inheritable
288  * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
289  * @warning Not implemented on Windows
290  */
291 static int
292 socket_set_inheritable (const struct GNUNET_NETWORK_Handle *h)
293 {
294   int i;
295   i = fcntl (h->fd, F_GETFD);
296   if (i < 0)
297     return GNUNET_SYSERR;
298   if (i == (i | FD_CLOEXEC))
299     return GNUNET_OK;
300   i |= FD_CLOEXEC;
301   if (fcntl (h->fd, F_SETFD, i) < 0)
302     return GNUNET_SYSERR;
303
304   return GNUNET_OK;
305 }
306
307
308 #ifdef DARWIN
309 /**
310  * The MSG_NOSIGNAL equivalent on Mac OS X
311  *
312  * @param h the socket to make non-delaying
313  */
314 static int
315 socket_set_nosigpipe (const struct GNUNET_NETWORK_Handle *h)
316 {
317   int abs_value = 1;
318
319   if (0 !=
320       setsockopt (h->fd, SOL_SOCKET, SO_NOSIGPIPE,
321                   (const void *) &abs_value,
322                   sizeof(abs_value)))
323     return GNUNET_SYSERR;
324   return GNUNET_OK;
325 }
326
327
328 #endif
329
330
331 /**
332  * Disable delays when sending data via the socket.
333  * (GNUnet makes sure that messages are as big as
334  * possible already).
335  *
336  * @param h the socket to make non-delaying
337  */
338 static void
339 socket_set_nodelay (const struct GNUNET_NETWORK_Handle *h)
340 {
341   int value = 1;
342
343   if (0 !=
344       setsockopt (h->fd,
345                   IPPROTO_TCP,
346                   TCP_NODELAY,
347                   &value, sizeof(value)))
348     LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING,
349                   "setsockopt");
350 }
351
352
353 /**
354  * Perform proper canonical initialization for a network handle.
355  * Set it to non-blocking, make it non-inheritable to child
356  * processes, disable SIGPIPE, enable "nodelay" (if non-UNIX
357  * stream socket) and check that it is smaller than FD_SETSIZE.
358  *
359  * @param h socket to initialize
360  * @param af address family of the socket
361  * @param type socket type
362  * @return #GNUNET_OK on success, #GNUNET_SYSERR if initialization
363  *         failed and the handle was destroyed
364  */
365 static int
366 initialize_network_handle (struct GNUNET_NETWORK_Handle *h,
367                            int af,
368                            int type)
369 {
370   int eno;
371
372   h->af = af;
373   h->type = type;
374   if (h->fd == INVALID_SOCKET)
375   {
376     eno = errno;
377     GNUNET_free (h);
378     errno = eno;
379     return GNUNET_SYSERR;
380   }
381
382   if (h->fd >= FD_SETSIZE)
383   {
384     GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (h));
385     errno = EMFILE;
386     return GNUNET_SYSERR;
387   }
388
389   if (GNUNET_OK != socket_set_inheritable (h))
390     LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
391                   "socket_set_inheritable");
392
393   if (GNUNET_SYSERR == GNUNET_NETWORK_socket_set_blocking (h, GNUNET_NO))
394   {
395     eno = errno;
396     GNUNET_break (0);
397     GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (h));
398     errno = eno;
399     return GNUNET_SYSERR;
400   }
401 #ifdef DARWIN
402   if (GNUNET_SYSERR == socket_set_nosigpipe (h))
403   {
404     eno = errno;
405     GNUNET_break (0);
406     GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (h));
407     errno = eno;
408     return GNUNET_SYSERR;
409   }
410 #endif
411   if ((type == SOCK_STREAM)
412 #ifdef AF_UNIX
413       && (af != AF_UNIX)
414 #endif
415       )
416     socket_set_nodelay (h);
417   return GNUNET_OK;
418 }
419
420
421 /**
422  * accept a new connection on a socket
423  *
424  * @param desc bound socket
425  * @param address address of the connecting peer, may be NULL
426  * @param address_len length of @a address
427  * @return client socket
428  */
429 struct GNUNET_NETWORK_Handle *
430 GNUNET_NETWORK_socket_accept (const struct GNUNET_NETWORK_Handle *desc,
431                               struct sockaddr *address,
432                               socklen_t *address_len)
433 {
434   struct GNUNET_NETWORK_Handle *ret;
435   int eno;
436
437   ret = GNUNET_new (struct GNUNET_NETWORK_Handle);
438 #if DEBUG_NETWORK
439   {
440     struct sockaddr_storage name;
441     socklen_t namelen = sizeof(name);
442
443     int gsn = getsockname (desc->fd,
444                            (struct sockaddr *) &name,
445                            &namelen);
446
447     if (0 == gsn)
448       LOG (GNUNET_ERROR_TYPE_DEBUG,
449            "Accepting connection on `%s'\n",
450            GNUNET_a2s ((const struct sockaddr *) &name,
451                        namelen));
452   }
453 #endif
454   ret->fd = accept (desc->fd,
455                     address,
456                     address_len);
457   if (-1 == ret->fd)
458   {
459     eno = errno;
460     GNUNET_free (ret);
461     errno = eno;
462     return NULL;
463   }
464   if (GNUNET_OK !=
465       initialize_network_handle (ret,
466                                  (NULL != address) ? address->sa_family :
467                                  desc->af,
468                                  SOCK_STREAM))
469   {
470     return NULL;
471   }
472   return ret;
473 }
474
475
476 /**
477  * Bind a socket to a particular address.
478  *
479  * @param desc socket to bind
480  * @param address address to be bound
481  * @param address_len length of @a address
482  * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
483  */
484 int
485 GNUNET_NETWORK_socket_bind (struct GNUNET_NETWORK_Handle *desc,
486                             const struct sockaddr *address,
487                             socklen_t address_len)
488 {
489   int ret;
490
491 #ifdef IPV6_V6ONLY
492 #ifdef IPPROTO_IPV6
493   {
494     const int on = 1;
495
496     if (AF_INET6 == desc->af)
497       if (setsockopt (desc->fd,
498                       IPPROTO_IPV6,
499                       IPV6_V6ONLY,
500                       (const void *) &on,
501                       sizeof(on)))
502         LOG_STRERROR (GNUNET_ERROR_TYPE_DEBUG,
503                       "setsockopt");
504   }
505 #endif
506 #endif
507   if (AF_UNIX == address->sa_family)
508     GNUNET_NETWORK_unix_precheck ((const struct sockaddr_un *) address);
509   {
510     const int on = 1;
511
512     /* This is required here for TCP sockets, but only on UNIX */
513     if ((SOCK_STREAM == desc->type) &&
514         (0 != setsockopt (desc->fd,
515                           SOL_SOCKET,
516                           SO_REUSEADDR,
517                           &on, sizeof(on))))
518       LOG_STRERROR (GNUNET_ERROR_TYPE_DEBUG,
519                     "setsockopt");
520   }
521   {
522     /* set permissions of newly created non-abstract UNIX domain socket to
523        "user-only"; applications can choose to relax this later */
524     mode_t old_mask = 0; /* assigned to make compiler happy */
525     const struct sockaddr_un *un = (const struct sockaddr_un *) address;
526     int not_abstract = 0;
527
528     if ((AF_UNIX == address->sa_family)
529         && ('\0' != un->sun_path[0]))  /* Not an abstract socket */
530       not_abstract = 1;
531     if (not_abstract)
532       old_mask = umask (S_IWGRP | S_IRGRP | S_IXGRP | S_IWOTH | S_IROTH
533                         | S_IXOTH);
534
535     ret = bind (desc->fd,
536                 address,
537                 address_len);
538
539     if (not_abstract)
540       (void) umask (old_mask);
541   }
542   if (0 != ret)
543     return GNUNET_SYSERR;
544
545   desc->addr = GNUNET_malloc (address_len);
546   GNUNET_memcpy (desc->addr, address, address_len);
547   desc->addrlen = address_len;
548
549   return GNUNET_OK;
550 }
551
552
553 /**
554  * Close a socket
555  *
556  * @param desc socket
557  * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
558  */
559 int
560 GNUNET_NETWORK_socket_close (struct GNUNET_NETWORK_Handle *desc)
561 {
562   int ret;
563
564   ret = close (desc->fd);
565
566   const struct sockaddr_un *un = (const struct sockaddr_un *) desc->addr;
567
568   /* Cleanup the UNIX domain socket and its parent directories in case of non
569      abstract sockets */
570   if ((AF_UNIX == desc->af) &&
571       (NULL != desc->addr) &&
572       ('\0' != un->sun_path[0]))
573   {
574     char *dirname = GNUNET_strndup (un->sun_path,
575                                     sizeof(un->sun_path));
576
577     if (0 != unlink (dirname))
578     {
579       LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING,
580                          "unlink",
581                          dirname);
582     }
583     else
584     {
585       size_t len;
586
587       len = strlen (dirname);
588       while ((len > 0) && (dirname[len] != DIR_SEPARATOR))
589         len--;
590       dirname[len] = '\0';
591       if ((0 != len) && (0 != rmdir (dirname)))
592       {
593         switch (errno)
594         {
595         case EACCES:
596         case ENOTEMPTY:
597         case EPERM:
598           /* these are normal and can just be ignored */
599           break;
600
601         default:
602           GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
603                                     "rmdir",
604                                     dirname);
605           break;
606         }
607       }
608     }
609     GNUNET_free (dirname);
610   }
611   GNUNET_NETWORK_socket_free_memory_only_ (desc);
612   return (ret == 0) ? GNUNET_OK : GNUNET_SYSERR;
613 }
614
615
616 /**
617  * Only free memory of a socket, keep the file descriptor untouched.
618  *
619  * @param desc socket
620  */
621 void
622 GNUNET_NETWORK_socket_free_memory_only_ (struct GNUNET_NETWORK_Handle *desc)
623 {
624   GNUNET_free_non_null (desc->addr);
625   GNUNET_free (desc);
626 }
627
628
629 /**
630  * Box a native socket (and check that it is a socket).
631  *
632  * @param fd socket to box
633  * @return NULL on error (including not supported on target platform)
634  */
635 struct GNUNET_NETWORK_Handle *
636 GNUNET_NETWORK_socket_box_native (int fd)
637 {
638   struct GNUNET_NETWORK_Handle *ret;
639
640   if (fcntl (fd, F_GETFD) < 0)
641     return NULL;                /* invalid FD */
642   ret = GNUNET_new (struct GNUNET_NETWORK_Handle);
643   ret->fd = fd;
644   ret->af = AF_UNSPEC;
645   return ret;
646 }
647
648
649 /**
650  * Connect a socket to some remote address.
651  *
652  * @param desc socket
653  * @param address peer address
654  * @param address_len length of @a address
655  * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
656  */
657 int
658 GNUNET_NETWORK_socket_connect (const struct GNUNET_NETWORK_Handle *desc,
659                                const struct sockaddr *address,
660                                socklen_t address_len)
661 {
662   int ret;
663
664   ret = connect (desc->fd,
665                  address,
666                  address_len);
667
668   return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;
669 }
670
671
672 /**
673  * Get socket options
674  *
675  * @param desc socket
676  * @param level protocol level of the option
677  * @param optname identifier of the option
678  * @param optval options
679  * @param optlen length of @a optval
680  * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
681  */
682 int
683 GNUNET_NETWORK_socket_getsockopt (const struct GNUNET_NETWORK_Handle *desc,
684                                   int level,
685                                   int optname,
686                                   void *optval,
687                                   socklen_t *optlen)
688 {
689   int ret;
690
691   ret = getsockopt (desc->fd,
692                     level,
693                     optname,
694                     optval, optlen);
695
696   return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;
697 }
698
699
700 /**
701  * Listen on a socket
702  *
703  * @param desc socket
704  * @param backlog length of the listen queue
705  * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
706  */
707 int
708 GNUNET_NETWORK_socket_listen (const struct GNUNET_NETWORK_Handle *desc,
709                               int backlog)
710 {
711   int ret;
712
713   ret = listen (desc->fd,
714                 backlog);
715
716   return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;
717 }
718
719
720 /**
721  * How much data is available to be read on this descriptor?
722  *
723  * @param desc socket
724  * @returns #GNUNET_SYSERR if no data is available, or on error!
725  */
726 ssize_t
727 GNUNET_NETWORK_socket_recvfrom_amount (const struct GNUNET_NETWORK_Handle *desc)
728 {
729   int error;
730
731   /* How much is there to be read? */
732   int pending;
733
734   error = ioctl (desc->fd,
735                  FIONREAD,
736                  &pending);
737   if (0 == error)
738     return (ssize_t) pending;
739   return GNUNET_SYSERR;
740 }
741
742
743 /**
744  * Read data from a socket (always non-blocking).
745  *
746  * @param desc socket
747  * @param buffer buffer
748  * @param length length of @a buffer
749  * @param src_addr either the source to recv from, or all zeroes
750  *        to be filled in by recvfrom
751  * @param addrlen length of the @a src_addr
752  */
753 ssize_t
754 GNUNET_NETWORK_socket_recvfrom (const struct GNUNET_NETWORK_Handle *desc,
755                                 void *buffer,
756                                 size_t length,
757                                 struct sockaddr *src_addr,
758                                 socklen_t *addrlen)
759 {
760   int ret;
761   int flags;
762
763   flags = 0;
764
765 #ifdef MSG_DONTWAIT
766   flags |= MSG_DONTWAIT;
767 #endif
768   ret = recvfrom (desc->fd,
769                   buffer,
770                   length,
771                   flags,
772                   src_addr,
773                   addrlen);
774   return ret;
775 }
776
777
778 /**
779  * Read data from a connected socket (always non-blocking).
780  *
781  * @param desc socket
782  * @param buffer buffer
783  * @param length length of @a buffer
784  * @return number of bytes received, -1 on error
785  */
786 ssize_t
787 GNUNET_NETWORK_socket_recv (const struct GNUNET_NETWORK_Handle *desc,
788                             void *buffer,
789                             size_t length)
790 {
791   int ret;
792   int flags;
793
794   flags = 0;
795
796 #ifdef MSG_DONTWAIT
797   flags |= MSG_DONTWAIT;
798 #endif
799   ret = recv (desc->fd,
800               buffer,
801               length,
802               flags);
803   return ret;
804 }
805
806
807 /**
808  * Send data (always non-blocking).
809  *
810  * @param desc socket
811  * @param buffer data to send
812  * @param length size of the @a buffer
813  * @return number of bytes sent, #GNUNET_SYSERR on error
814  */
815 ssize_t
816 GNUNET_NETWORK_socket_send (const struct GNUNET_NETWORK_Handle *desc,
817                             const void *buffer,
818                             size_t length)
819 {
820   int ret;
821   int flags;
822
823   flags = 0;
824 #ifdef MSG_DONTWAIT
825   flags |= MSG_DONTWAIT;
826 #endif
827 #ifdef MSG_NOSIGNAL
828   flags |= MSG_NOSIGNAL;
829 #endif
830   ret = send (desc->fd,
831               buffer,
832               length,
833               flags);
834   return ret;
835 }
836
837
838 /**
839  * Send data to a particular destination (always non-blocking).
840  * This function only works for UDP sockets.
841  *
842  * @param desc socket
843  * @param message data to send
844  * @param length size of the @a message
845  * @param dest_addr destination address
846  * @param dest_len length of @a address
847  * @return number of bytes sent, #GNUNET_SYSERR on error
848  */
849 ssize_t
850 GNUNET_NETWORK_socket_sendto (const struct GNUNET_NETWORK_Handle *desc,
851                               const void *message,
852                               size_t length,
853                               const struct sockaddr *dest_addr,
854                               socklen_t dest_len)
855 {
856   int ret;
857   int flags;
858
859   flags = 0;
860
861 #ifdef MSG_DONTWAIT
862   flags |= MSG_DONTWAIT;
863 #endif
864 #ifdef MSG_NOSIGNAL
865   flags |= MSG_NOSIGNAL;
866 #endif
867   ret = sendto (desc->fd, message, length, flags, dest_addr, dest_len);
868   return ret;
869 }
870
871
872 /**
873  * Set socket option
874  *
875  * @param fd socket
876  * @param level protocol level of the option
877  * @param option_name option identifier
878  * @param option_value value to set
879  * @param option_len size of @a option_value
880  * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
881  */
882 int
883 GNUNET_NETWORK_socket_setsockopt (struct GNUNET_NETWORK_Handle *fd,
884                                   int level,
885                                   int option_name,
886                                   const void *option_value,
887                                   socklen_t option_len)
888 {
889   int ret;
890
891   ret = setsockopt (fd->fd,
892                     level,
893                     option_name,
894                     option_value,
895                     option_len);
896
897   return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;
898 }
899
900
901 /**
902  * Create a new socket.  Configure it for non-blocking IO and
903  * mark it as non-inheritable to child processes (set the
904  * close-on-exec flag).
905  *
906  * @param domain domain of the socket
907  * @param type socket type
908  * @param protocol network protocol
909  * @return new socket, NULL on error
910  */
911 struct GNUNET_NETWORK_Handle *
912 GNUNET_NETWORK_socket_create (int domain,
913                               int type,
914                               int protocol)
915 {
916   struct GNUNET_NETWORK_Handle *ret;
917   int fd;
918
919   fd = socket (domain, type, protocol);
920   if (-1 == fd)
921     return NULL;
922   ret = GNUNET_new (struct GNUNET_NETWORK_Handle);
923   ret->fd = fd;
924   if (GNUNET_OK !=
925       initialize_network_handle (ret,
926                                  domain,
927                                  type))
928     return NULL;
929   return ret;
930 }
931
932
933 /**
934  * Shut down socket operations
935  * @param desc socket
936  * @param how type of shutdown
937  * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
938  */
939 int
940 GNUNET_NETWORK_socket_shutdown (struct GNUNET_NETWORK_Handle *desc,
941                                 int how)
942 {
943   int ret;
944
945   ret = shutdown (desc->fd, how);
946
947   return (0 == ret) ? GNUNET_OK : GNUNET_SYSERR;
948 }
949
950
951 /**
952  * Disable the "CORK" feature for communication with the given socket,
953  * forcing the OS to immediately flush the buffer on transmission
954  * instead of potentially buffering multiple messages.  Essentially
955  * reduces the OS send buffers to zero.
956  *
957  * @param desc socket
958  * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
959  */
960 int
961 GNUNET_NETWORK_socket_disable_corking (struct GNUNET_NETWORK_Handle *desc)
962 {
963   int ret = 0;
964
965 #ifdef __linux__
966   int value = 0;
967
968   if (0 !=
969       (ret =
970          setsockopt (desc->fd,
971                      SOL_SOCKET,
972                      SO_SNDBUF,
973                      &value,
974                      sizeof(value))))
975     LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING,
976                   "setsockopt");
977   if (0 !=
978       (ret =
979          setsockopt (desc->fd,
980                      SOL_SOCKET,
981                      SO_RCVBUF,
982                      &value,
983                      sizeof(value))))
984     LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING,
985                   "setsockopt");
986 #endif
987   return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;
988 }
989
990
991 /**
992  * Reset FD set
993  *
994  * @param fds fd set
995  */
996 void
997 GNUNET_NETWORK_fdset_zero (struct GNUNET_NETWORK_FDSet *fds)
998 {
999   FD_ZERO (&fds->sds);
1000   fds->nsds = 0;
1001 }
1002
1003
1004 /**
1005  * Add a socket to the FD set
1006  *
1007  * @param fds fd set
1008  * @param desc socket to add
1009  */
1010 void
1011 GNUNET_NETWORK_fdset_set (struct GNUNET_NETWORK_FDSet *fds,
1012                           const struct GNUNET_NETWORK_Handle *desc)
1013 {
1014   FD_SET (desc->fd,
1015           &fds->sds);
1016   fds->nsds = GNUNET_MAX (fds->nsds,
1017                           desc->fd + 1);
1018 }
1019
1020
1021 /**
1022  * Check whether a socket is part of the fd set
1023  *
1024  * @param fds fd set
1025  * @param desc socket
1026  * @return 0 if the FD is not set
1027  */
1028 int
1029 GNUNET_NETWORK_fdset_isset (const struct GNUNET_NETWORK_FDSet *fds,
1030                             const struct GNUNET_NETWORK_Handle *desc)
1031 {
1032   return FD_ISSET (desc->fd,
1033                    &fds->sds);
1034 }
1035
1036
1037 /**
1038  * Add one fd set to another
1039  *
1040  * @param dst the fd set to add to
1041  * @param src the fd set to add from
1042  */
1043 void
1044 GNUNET_NETWORK_fdset_add (struct GNUNET_NETWORK_FDSet *dst,
1045                           const struct GNUNET_NETWORK_FDSet *src)
1046 {
1047   int nfds;
1048
1049   for (nfds = src->nsds; nfds >= 0; nfds--)
1050     if (FD_ISSET (nfds, &src->sds))
1051       FD_SET (nfds, &dst->sds);
1052   dst->nsds = GNUNET_MAX (dst->nsds,
1053                           src->nsds);
1054 }
1055
1056
1057 /**
1058  * Copy one fd set to another
1059  *
1060  * @param to destination
1061  * @param from source
1062  */
1063 void
1064 GNUNET_NETWORK_fdset_copy (struct GNUNET_NETWORK_FDSet *to,
1065                            const struct GNUNET_NETWORK_FDSet *from)
1066 {
1067   FD_COPY (&from->sds,
1068            &to->sds);
1069   to->nsds = from->nsds;
1070 }
1071
1072
1073 /**
1074  * Return file descriptor for this network handle
1075  *
1076  * @param desc wrapper to process
1077  * @return POSIX file descriptor
1078  */
1079 int
1080 GNUNET_NETWORK_get_fd (const struct GNUNET_NETWORK_Handle *desc)
1081 {
1082   return desc->fd;
1083 }
1084
1085
1086 /**
1087  * Return sockaddr for this network handle
1088  *
1089  * @param desc wrapper to process
1090  * @return sockaddr
1091  */
1092 struct sockaddr*
1093 GNUNET_NETWORK_get_addr (const struct GNUNET_NETWORK_Handle *desc)
1094 {
1095   return desc->addr;
1096 }
1097
1098
1099 /**
1100  * Return sockaddr length for this network handle
1101  *
1102  * @param desc wrapper to process
1103  * @return socklen_t for sockaddr
1104  */
1105 socklen_t
1106 GNUNET_NETWORK_get_addrlen (const struct GNUNET_NETWORK_Handle *desc)
1107 {
1108   return desc->addrlen;
1109 }
1110
1111
1112 /**
1113  * Copy a native fd set
1114  *
1115  * @param to destination
1116  * @param from native source set
1117  * @param nfds the biggest socket number in from + 1
1118  */
1119 void
1120 GNUNET_NETWORK_fdset_copy_native (struct GNUNET_NETWORK_FDSet *to,
1121                                   const fd_set *from,
1122                                   int nfds)
1123 {
1124   FD_COPY (from,
1125            &to->sds);
1126   to->nsds = nfds;
1127 }
1128
1129
1130 /**
1131  * Set a native fd in a set
1132  *
1133  * @param to destination
1134  * @param nfd native FD to set
1135  */
1136 void
1137 GNUNET_NETWORK_fdset_set_native (struct GNUNET_NETWORK_FDSet *to,
1138                                  int nfd)
1139 {
1140   GNUNET_assert ((nfd >= 0) && (nfd < FD_SETSIZE));
1141   FD_SET (nfd, &to->sds);
1142   to->nsds = GNUNET_MAX (nfd + 1,
1143                          to->nsds);
1144 }
1145
1146
1147 /**
1148  * Test native fd in a set
1149  *
1150  * @param to set to test, NULL for empty set
1151  * @param nfd native FD to test, or -1 for none
1152  * @return #GNUNET_YES if FD is set in the set
1153  */
1154 int
1155 GNUNET_NETWORK_fdset_test_native (const struct GNUNET_NETWORK_FDSet *to,
1156                                   int nfd)
1157 {
1158   if ((-1 == nfd) ||
1159       (NULL == to))
1160     return GNUNET_NO;
1161   return FD_ISSET (nfd, &to->sds) ? GNUNET_YES : GNUNET_NO;
1162 }
1163
1164
1165 /**
1166  * Add a file handle to the fd set
1167  * @param fds fd set
1168  * @param h the file handle to add
1169  */
1170 void
1171 GNUNET_NETWORK_fdset_handle_set (struct GNUNET_NETWORK_FDSet *fds,
1172                                  const struct GNUNET_DISK_FileHandle *h)
1173 {
1174   int fd;
1175
1176   GNUNET_assert (GNUNET_OK ==
1177                  GNUNET_DISK_internal_file_handle_ (h,
1178                                                     &fd,
1179                                                     sizeof(int)));
1180   FD_SET (fd,
1181           &fds->sds);
1182   fds->nsds = GNUNET_MAX (fd + 1,
1183                           fds->nsds);
1184 }
1185
1186
1187 /**
1188  * Add a file handle to the fd set
1189  * @param fds fd set
1190  * @param h the file handle to add
1191  */
1192 void
1193 GNUNET_NETWORK_fdset_handle_set_first (struct GNUNET_NETWORK_FDSet *fds,
1194                                        const struct GNUNET_DISK_FileHandle *h)
1195 {
1196   GNUNET_NETWORK_fdset_handle_set (fds, h);
1197 }
1198
1199
1200 /**
1201  * Check if a file handle is part of an fd set
1202  *
1203  * @param fds fd set
1204  * @param h file handle
1205  * @return #GNUNET_YES if the file handle is part of the set
1206  */
1207 int
1208 GNUNET_NETWORK_fdset_handle_isset (const struct GNUNET_NETWORK_FDSet *fds,
1209                                    const struct GNUNET_DISK_FileHandle *h)
1210 {
1211   return FD_ISSET (h->fd,
1212                    &fds->sds);
1213 }
1214
1215
1216 /**
1217  * Checks if two fd sets overlap
1218  *
1219  * @param fds1 first fd set
1220  * @param fds2 second fd set
1221  * @return #GNUNET_YES if they do overlap, #GNUNET_NO otherwise
1222  */
1223 int
1224 GNUNET_NETWORK_fdset_overlap (const struct GNUNET_NETWORK_FDSet *fds1,
1225                               const struct GNUNET_NETWORK_FDSet *fds2)
1226 {
1227   int nfds;
1228
1229   nfds = GNUNET_MIN (fds1->nsds,
1230                      fds2->nsds);
1231   while (nfds > 0)
1232   {
1233     nfds--;
1234     if ((FD_ISSET (nfds,
1235                    &fds1->sds)) &&
1236         (FD_ISSET (nfds,
1237                    &fds2->sds)))
1238       return GNUNET_YES;
1239   }
1240   return GNUNET_NO;
1241 }
1242
1243
1244 /**
1245  * Creates an fd set
1246  *
1247  * @return a new fd set
1248  */
1249 struct GNUNET_NETWORK_FDSet *
1250 GNUNET_NETWORK_fdset_create ()
1251 {
1252   struct GNUNET_NETWORK_FDSet *fds;
1253
1254   fds = GNUNET_new (struct GNUNET_NETWORK_FDSet);
1255   GNUNET_NETWORK_fdset_zero (fds);
1256   return fds;
1257 }
1258
1259
1260 /**
1261  * Releases the associated memory of an fd set
1262  *
1263  * @param fds fd set
1264  */
1265 void
1266 GNUNET_NETWORK_fdset_destroy (struct GNUNET_NETWORK_FDSet *fds)
1267 {
1268   GNUNET_free (fds);
1269 }
1270
1271
1272 /**
1273  * Test if the given @a port is available.
1274  *
1275  * @param ipproto transport protocol to test (i.e. IPPROTO_TCP)
1276  * @param port port number to test
1277  * @return #GNUNET_OK if the port is available, #GNUNET_NO if not
1278  */
1279 int
1280 GNUNET_NETWORK_test_port_free (int ipproto,
1281                                uint16_t port)
1282 {
1283   struct GNUNET_NETWORK_Handle *socket;
1284   int bind_status;
1285   int socktype;
1286   char open_port_str[6];
1287   struct addrinfo hint;
1288   struct addrinfo *ret;
1289   struct addrinfo *ai;
1290
1291   GNUNET_snprintf (open_port_str,
1292                    sizeof(open_port_str),
1293                    "%u",
1294                    (unsigned int) port);
1295   socktype = (IPPROTO_TCP == ipproto) ? SOCK_STREAM : SOCK_DGRAM;
1296   ret = NULL;
1297   memset (&hint, 0, sizeof(hint));
1298   hint.ai_family = AF_UNSPEC; /* IPv4 and IPv6 */
1299   hint.ai_socktype = socktype;
1300   hint.ai_protocol = ipproto;
1301   hint.ai_addrlen = 0;
1302   hint.ai_addr = NULL;
1303   hint.ai_canonname = NULL;
1304   hint.ai_next = NULL;
1305   hint.ai_flags = AI_PASSIVE | AI_NUMERICSERV; /* Wild card address */
1306   GNUNET_assert (0 == getaddrinfo (NULL,
1307                                    open_port_str,
1308                                    &hint,
1309                                    &ret));
1310   bind_status = GNUNET_NO;
1311   for (ai = ret; NULL != ai; ai = ai->ai_next)
1312   {
1313     socket = GNUNET_NETWORK_socket_create (ai->ai_family,
1314                                            ai->ai_socktype,
1315                                            ai->ai_protocol);
1316     if (NULL == socket)
1317       continue;
1318     bind_status = GNUNET_NETWORK_socket_bind (socket,
1319                                               ai->ai_addr,
1320                                               ai->ai_addrlen);
1321     GNUNET_NETWORK_socket_close (socket);
1322     if (GNUNET_OK != bind_status)
1323       break;
1324   }
1325   freeaddrinfo (ret);
1326   return bind_status;
1327 }
1328
1329
1330 /**
1331  * Check if sockets or pipes meet certain conditions
1332  *
1333  * @param rfds set of sockets or pipes to be checked for readability
1334  * @param wfds set of sockets or pipes to be checked for writability
1335  * @param efds set of sockets or pipes to be checked for exceptions
1336  * @param timeout relative value when to return
1337  * @return number of selected sockets or pipes, #GNUNET_SYSERR on error
1338  */
1339 int
1340 GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds,
1341                               struct GNUNET_NETWORK_FDSet *wfds,
1342                               struct GNUNET_NETWORK_FDSet *efds,
1343                               const struct GNUNET_TIME_Relative timeout)
1344 {
1345   int nfds;
1346   struct timeval tv;
1347
1348   if (NULL != rfds)
1349     nfds = rfds->nsds;
1350   else
1351     nfds = 0;
1352   if (NULL != wfds)
1353     nfds = GNUNET_MAX (nfds,
1354                        wfds->nsds);
1355   if (NULL != efds)
1356     nfds = GNUNET_MAX (nfds,
1357                        efds->nsds);
1358   if ((0 == nfds) &&
1359       (timeout.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us))
1360   {
1361     GNUNET_break (0);
1362     LOG (GNUNET_ERROR_TYPE_ERROR,
1363          _ (
1364            "Fatal internal logic error, process hangs in `%s' (abort with CTRL-C)!\n"),
1365          "select");
1366   }
1367   if (timeout.rel_value_us / GNUNET_TIME_UNIT_SECONDS.rel_value_us > (unsigned
1368                                                                       long long)
1369       LONG_MAX)
1370   {
1371     tv.tv_sec = LONG_MAX;
1372     tv.tv_usec = 999999L;
1373   }
1374   else
1375   {
1376     tv.tv_sec = (long) (timeout.rel_value_us
1377                         / GNUNET_TIME_UNIT_SECONDS.rel_value_us);
1378     tv.tv_usec =
1379       (timeout.rel_value_us
1380        - (tv.tv_sec * GNUNET_TIME_UNIT_SECONDS.rel_value_us));
1381   }
1382   return select (nfds,
1383                  (NULL != rfds) ? &rfds->sds : NULL,
1384                  (NULL != wfds) ? &wfds->sds : NULL,
1385                  (NULL != efds) ? &efds->sds : NULL,
1386                  (timeout.rel_value_us ==
1387                   GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us) ? NULL : &tv);
1388 }
1389
1390
1391 /* end of network.c */