[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r36065 - in gnunet: doc/man src/arm src/include src/util
From: |
gnunet |
Subject: |
[GNUnet-SVN] r36065 - in gnunet: doc/man src/arm src/include src/util |
Date: |
Mon, 13 Jul 2015 16:53:30 +0200 |
Author: grothoff
Date: 2015-07-13 16:53:30 +0200 (Mon, 13 Jul 2015)
New Revision: 36065
Modified:
gnunet/doc/man/gnunet.conf.5
gnunet/src/arm/gnunet-service-arm.c
gnunet/src/include/gnunet_network_lib.h
gnunet/src/util/network.c
Log:
automatically clean up left-over Unix domain socket files when trying to bind
(fixes #3723)
Modified: gnunet/doc/man/gnunet.conf.5
===================================================================
--- gnunet/doc/man/gnunet.conf.5 2015-07-13 14:07:08 UTC (rev 36064)
+++ gnunet/doc/man/gnunet.conf.5 2015-07-13 14:53:30 UTC (rev 36065)
@@ -28,6 +28,10 @@
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.
.IP AUTOSTART
Set to YES to automatically start the service when it is requested by
another service. YES for most GNUnet services.
+.IP NOARMBIND
+ 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.
+.IP PREFIX
+ 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.
.IP ACCEPT_FROM
A semi-column separated list of IPv4 addresses that are allowed to use the
service; usually 127.0.0.1.
.IP ACCEPT_FROM6
Modified: gnunet/src/arm/gnunet-service-arm.c
===================================================================
--- gnunet/src/arm/gnunet-service-arm.c 2015-07-13 14:07:08 UTC (rev 36064)
+++ gnunet/src/arm/gnunet-service-arm.c 2015-07-13 14:53:30 UTC (rev 36065)
@@ -603,7 +603,8 @@
* @param sl service entry for the service in question
*/
static void
-create_listen_socket (struct sockaddr *sa, socklen_t addr_len,
+create_listen_socket (struct sockaddr *sa,
+ socklen_t addr_len,
struct ServiceList *sl)
{
static int on = 1;
@@ -652,14 +653,18 @@
GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
"setsockopt");
#endif
-
+#ifndef WINDOWS
+ if (AF_UNIX == sa->sa_family)
+ GNUNET_NETWORK_unix_precheck ((struct sockaddr_un *) sa);
+#endif
if (GNUNET_OK !=
GNUNET_NETWORK_socket_bind (sock, (const struct sockaddr *) sa,
addr_len))
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- _
- ("Unable to bind listening socket for service `%s' to address
`%s': %s\n"),
- sl->name, GNUNET_a2s (sa, addr_len), STRERROR (errno));
+ _("Unable to bind listening socket for service `%s' to address
`%s': %s\n"),
+ sl->name,
+ GNUNET_a2s (sa, addr_len),
+ STRERROR (errno));
GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
GNUNET_free (sa);
return;
@@ -1394,11 +1399,11 @@
"FORCESTART"))
{
sl->force_start = GNUNET_YES;
- /* FIXME: we might like the pre-binding even for
- _certain_ services that have force_start set,
- otherwise interdependencies may again force
- client's to retry connections during startup. */
- return;
+ if (GNUNET_YES ==
+ GNUNET_CONFIGURATION_get_value_yesno (cfg,
+ section,
+ "NOARMBIND"))
+ return;
}
else
{
Modified: gnunet/src/include/gnunet_network_lib.h
===================================================================
--- gnunet/src/include/gnunet_network_lib.h 2015-07-13 14:07:08 UTC (rev
36064)
+++ gnunet/src/include/gnunet_network_lib.h 2015-07-13 14:53:30 UTC (rev
36065)
@@ -106,7 +106,22 @@
GNUNET_NETWORK_shorten_unixpath (char *unixpath);
+#ifndef WINDOWS
/**
+ * If services crash, they can leave a unix domain socket file on the
+ * disk. This needs to be manually removed, because otherwise both
+ * bind() and connect() for the respective address will fail. In this
+ * function, we test if such a left-over file exists, and if so,
+ * remove it (unless there is a listening service at the address).
+ *
+ * @param un unix domain socket address to check
+ */
+void
+GNUNET_NETWORK_unix_precheck (const struct sockaddr_un *un);
+#endif
+
+
+/**
* Accept a new connection on a socket. Configure it for non-blocking
* IO and mark it as non-inheritable to child processes (set the
* close-on-exec flag).
Modified: gnunet/src/util/network.c
===================================================================
--- gnunet/src/util/network.c 2015-07-13 14:07:08 UTC (rev 36064)
+++ gnunet/src/util/network.c 2015-07-13 14:53:30 UTC (rev 36065)
@@ -147,6 +147,53 @@
}
+#ifndef WINDOWS
+/**
+ * If services crash, they can leave a unix domain socket file on the
+ * disk. This needs to be manually removed, because otherwise both
+ * bind() and connect() for the respective address will fail. In this
+ * function, we test if such a left-over file exists, and if so,
+ * remove it (unless there is a listening service at the address).
+ *
+ * @param un unix domain socket address to check
+ */
+void
+GNUNET_NETWORK_unix_precheck (const struct sockaddr_un *un)
+{
+ int s;
+ int eno;
+ struct stat sbuf;
+ int ret;
+
+ s = socket (AF_UNIX, SOCK_STREAM, 0);
+ ret = connect (s,
+ (struct sockaddr *) un,
+ sizeof (struct sockaddr_un));
+ eno = errno;
+ GNUNET_break (0 == close (s));
+ if (0 == ret)
+ return; /* another process is listening, do not remove! */
+ if (ECONNREFUSED != eno)
+ return; /* some other error, likely "no such file or directory" -- all
well */
+ /* should unlink, but sanity checks first */
+ if (0 != stat (un->sun_path,
+ &sbuf))
+ return; /* failed to 'stat', likely does not exist after all */
+ if (S_IFSOCK != (S_IFMT & sbuf.st_mode))
+ return; /* refuse to unlink anything except sockets */
+ /* finally, really unlink */
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Removing left-over `%s' from previous exeuction\n",
+ un->sun_path);
+ if (0 != unlink (un->sun_path))
+ GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
+ "unlink",
+ un->sun_path);
+}
+#endif
+
+
+
#ifndef FD_COPY
#define FD_COPY(s, d) (memcpy ((d), (s), sizeof (fd_set)))
#endif
@@ -447,6 +494,8 @@
#endif
#endif
#ifndef WINDOWS
+ if (AF_UNIX == address->sa_family)
+ GNUNET_NETWORK_unix_precheck ((const struct sockaddr_un *) address);
{
const int on = 1;
@@ -459,8 +508,6 @@
LOG_STRERROR (GNUNET_ERROR_TYPE_DEBUG,
"setsockopt");
}
-#endif
-#ifndef WINDOWS
{
/* set permissions of newly created non-abstract UNIX domain socket to
"user-only"; applications can choose to relax this later */
@@ -476,7 +523,10 @@
old_mask = umask (S_IWGRP | S_IRGRP | S_IXGRP | S_IWOTH | S_IROTH |
S_IXOTH);
#endif
- ret = bind (desc->fd, address, address_len);
+ ret = bind (desc->fd,
+ address,
+ address_len);
+
#ifndef WINDOWS
if (not_abstract)
(void) umask (old_mask);
@@ -486,7 +536,7 @@
if (SOCKET_ERROR == ret)
SetErrnoFromWinsockError (WSAGetLastError ());
#endif
- if (ret != 0)
+ if (0 != ret)
return GNUNET_SYSERR;
#ifndef MINGW
desc->addr = GNUNET_malloc (address_len);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r36065 - in gnunet: doc/man src/arm src/include src/util,
gnunet <=