aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/man/gnunet.conf.54
-rw-r--r--src/arm/gnunet-service-arm.c25
-rw-r--r--src/include/gnunet_network_lib.h15
-rw-r--r--src/util/network.c58
4 files changed, 88 insertions, 14 deletions
diff --git a/doc/man/gnunet.conf.5 b/doc/man/gnunet.conf.5
index 2ef88c11e..3df3b437a 100644
--- a/doc/man/gnunet.conf.5
+++ b/doc/man/gnunet.conf.5
@@ -28,6 +28,10 @@ The following options are generic and shared by all services:
28 Start the service always when the peer starts. Set to YES for services that should always be launched, even if no other service explicitly needs them. 28 Start the service always when the peer starts. Set to YES for services that should always be launched, even if no other service explicitly needs them.
29.IP AUTOSTART 29.IP AUTOSTART
30 Set to YES to automatically start the service when it is requested by another service. YES for most GNUnet services. 30 Set to YES to automatically start the service when it is requested by another service. YES for most GNUnet services.
31.IP NOARMBIND
32 Set to YES to never have ARM bind to the respective socket. This option is mostly for debugging in situations where ARM cannot pass the pre-bound socket to the child due to interference from PREFIX-commands. This option is only effective in combination with FORCESTART being YES. NO by default.
33.IP PREFIX
34 PREFIX the given command (with its arguments) to the actual BINARY to be executed. Useful to run certain services under special supervisors (like strace or valgrind). Typically used in combination with FORCESTART and NOARMBIND. Empty by default.
31.IP ACCEPT_FROM 35.IP ACCEPT_FROM
32 A semi-column separated list of IPv4 addresses that are allowed to use the service; usually 127.0.0.1. 36 A semi-column separated list of IPv4 addresses that are allowed to use the service; usually 127.0.0.1.
33.IP ACCEPT_FROM6 37.IP ACCEPT_FROM6
diff --git a/src/arm/gnunet-service-arm.c b/src/arm/gnunet-service-arm.c
index 0dffafeeb..a411546d7 100644
--- a/src/arm/gnunet-service-arm.c
+++ b/src/arm/gnunet-service-arm.c
@@ -603,7 +603,8 @@ accept_connection (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
603 * @param sl service entry for the service in question 603 * @param sl service entry for the service in question
604 */ 604 */
605static void 605static void
606create_listen_socket (struct sockaddr *sa, socklen_t addr_len, 606create_listen_socket (struct sockaddr *sa,
607 socklen_t addr_len,
607 struct ServiceList *sl) 608 struct ServiceList *sl)
608{ 609{
609 static int on = 1; 610 static int on = 1;
@@ -652,14 +653,18 @@ create_listen_socket (struct sockaddr *sa, socklen_t addr_len,
652 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 653 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
653 "setsockopt"); 654 "setsockopt");
654#endif 655#endif
655 656#ifndef WINDOWS
657 if (AF_UNIX == sa->sa_family)
658 GNUNET_NETWORK_unix_precheck ((struct sockaddr_un *) sa);
659#endif
656 if (GNUNET_OK != 660 if (GNUNET_OK !=
657 GNUNET_NETWORK_socket_bind (sock, (const struct sockaddr *) sa, addr_len)) 661 GNUNET_NETWORK_socket_bind (sock, (const struct sockaddr *) sa, addr_len))
658 { 662 {
659 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 663 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
660 _ 664 _("Unable to bind listening socket for service `%s' to address `%s': %s\n"),
661 ("Unable to bind listening socket for service `%s' to address `%s': %s\n"), 665 sl->name,
662 sl->name, GNUNET_a2s (sa, addr_len), STRERROR (errno)); 666 GNUNET_a2s (sa, addr_len),
667 STRERROR (errno));
663 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); 668 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
664 GNUNET_free (sa); 669 GNUNET_free (sa);
665 return; 670 return;
@@ -1394,11 +1399,11 @@ setup_service (void *cls,
1394 "FORCESTART")) 1399 "FORCESTART"))
1395 { 1400 {
1396 sl->force_start = GNUNET_YES; 1401 sl->force_start = GNUNET_YES;
1397 /* FIXME: we might like the pre-binding even for 1402 if (GNUNET_YES ==
1398 _certain_ services that have force_start set, 1403 GNUNET_CONFIGURATION_get_value_yesno (cfg,
1399 otherwise interdependencies may again force 1404 section,
1400 client's to retry connections during startup. */ 1405 "NOARMBIND"))
1401 return; 1406 return;
1402 } 1407 }
1403 else 1408 else
1404 { 1409 {
diff --git a/src/include/gnunet_network_lib.h b/src/include/gnunet_network_lib.h
index f70509830..83d820a5b 100644
--- a/src/include/gnunet_network_lib.h
+++ b/src/include/gnunet_network_lib.h
@@ -106,6 +106,21 @@ char *
106GNUNET_NETWORK_shorten_unixpath (char *unixpath); 106GNUNET_NETWORK_shorten_unixpath (char *unixpath);
107 107
108 108
109#ifndef WINDOWS
110/**
111 * If services crash, they can leave a unix domain socket file on the
112 * disk. This needs to be manually removed, because otherwise both
113 * bind() and connect() for the respective address will fail. In this
114 * function, we test if such a left-over file exists, and if so,
115 * remove it (unless there is a listening service at the address).
116 *
117 * @param un unix domain socket address to check
118 */
119void
120GNUNET_NETWORK_unix_precheck (const struct sockaddr_un *un);
121#endif
122
123
109/** 124/**
110 * Accept a new connection on a socket. Configure it for non-blocking 125 * Accept a new connection on a socket. Configure it for non-blocking
111 * IO and mark it as non-inheritable to child processes (set the 126 * IO and mark it as non-inheritable to child processes (set the
diff --git a/src/util/network.c b/src/util/network.c
index d141732c2..489966426 100644
--- a/src/util/network.c
+++ b/src/util/network.c
@@ -147,6 +147,53 @@ GNUNET_NETWORK_shorten_unixpath (char *unixpath)
147} 147}
148 148
149 149
150#ifndef WINDOWS
151/**
152 * If services crash, they can leave a unix domain socket file on the
153 * disk. This needs to be manually removed, because otherwise both
154 * bind() and connect() for the respective address will fail. In this
155 * function, we test if such a left-over file exists, and if so,
156 * remove it (unless there is a listening service at the address).
157 *
158 * @param un unix domain socket address to check
159 */
160void
161GNUNET_NETWORK_unix_precheck (const struct sockaddr_un *un)
162{
163 int s;
164 int eno;
165 struct stat sbuf;
166 int ret;
167
168 s = socket (AF_UNIX, SOCK_STREAM, 0);
169 ret = connect (s,
170 (struct sockaddr *) un,
171 sizeof (struct sockaddr_un));
172 eno = errno;
173 GNUNET_break (0 == close (s));
174 if (0 == ret)
175 return; /* another process is listening, do not remove! */
176 if (ECONNREFUSED != eno)
177 return; /* some other error, likely "no such file or directory" -- all well */
178 /* should unlink, but sanity checks first */
179 if (0 != stat (un->sun_path,
180 &sbuf))
181 return; /* failed to 'stat', likely does not exist after all */
182 if (S_IFSOCK != (S_IFMT & sbuf.st_mode))
183 return; /* refuse to unlink anything except sockets */
184 /* finally, really unlink */
185 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
186 "Removing left-over `%s' from previous exeuction\n",
187 un->sun_path);
188 if (0 != unlink (un->sun_path))
189 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
190 "unlink",
191 un->sun_path);
192}
193#endif
194
195
196
150#ifndef FD_COPY 197#ifndef FD_COPY
151#define FD_COPY(s, d) (memcpy ((d), (s), sizeof (fd_set))) 198#define FD_COPY(s, d) (memcpy ((d), (s), sizeof (fd_set)))
152#endif 199#endif
@@ -447,6 +494,8 @@ GNUNET_NETWORK_socket_bind (struct GNUNET_NETWORK_Handle *desc,
447#endif 494#endif
448#endif 495#endif
449#ifndef WINDOWS 496#ifndef WINDOWS
497 if (AF_UNIX == address->sa_family)
498 GNUNET_NETWORK_unix_precheck ((const struct sockaddr_un *) address);
450 { 499 {
451 const int on = 1; 500 const int on = 1;
452 501
@@ -459,8 +508,6 @@ GNUNET_NETWORK_socket_bind (struct GNUNET_NETWORK_Handle *desc,
459 LOG_STRERROR (GNUNET_ERROR_TYPE_DEBUG, 508 LOG_STRERROR (GNUNET_ERROR_TYPE_DEBUG,
460 "setsockopt"); 509 "setsockopt");
461 } 510 }
462#endif
463#ifndef WINDOWS
464 { 511 {
465 /* set permissions of newly created non-abstract UNIX domain socket to 512 /* set permissions of newly created non-abstract UNIX domain socket to
466 "user-only"; applications can choose to relax this later */ 513 "user-only"; applications can choose to relax this later */
@@ -476,7 +523,10 @@ GNUNET_NETWORK_socket_bind (struct GNUNET_NETWORK_Handle *desc,
476 old_mask = umask (S_IWGRP | S_IRGRP | S_IXGRP | S_IWOTH | S_IROTH | S_IXOTH); 523 old_mask = umask (S_IWGRP | S_IRGRP | S_IXGRP | S_IWOTH | S_IROTH | S_IXOTH);
477#endif 524#endif
478 525
479 ret = bind (desc->fd, address, address_len); 526 ret = bind (desc->fd,
527 address,
528 address_len);
529
480#ifndef WINDOWS 530#ifndef WINDOWS
481 if (not_abstract) 531 if (not_abstract)
482 (void) umask (old_mask); 532 (void) umask (old_mask);
@@ -486,7 +536,7 @@ GNUNET_NETWORK_socket_bind (struct GNUNET_NETWORK_Handle *desc,
486 if (SOCKET_ERROR == ret) 536 if (SOCKET_ERROR == ret)
487 SetErrnoFromWinsockError (WSAGetLastError ()); 537 SetErrnoFromWinsockError (WSAGetLastError ());
488#endif 538#endif
489 if (ret != 0) 539 if (0 != ret)
490 return GNUNET_SYSERR; 540 return GNUNET_SYSERR;
491#ifndef MINGW 541#ifndef MINGW
492 desc->addr = GNUNET_malloc (address_len); 542 desc->addr = GNUNET_malloc (address_len);