aboutsummaryrefslogtreecommitdiff
path: root/src/util/network.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2015-07-13 14:53:30 +0000
committerChristian Grothoff <christian@grothoff.org>2015-07-13 14:53:30 +0000
commit3104aa430ae360599dd54369a8cb1fd61f07894c (patch)
tree6b8d87ddc782d50e51d1107bb13597218b5e9a1f /src/util/network.c
parent13a3089d561ed7332da25a7c461cdcc633c6b855 (diff)
downloadgnunet-3104aa430ae360599dd54369a8cb1fd61f07894c.tar.gz
gnunet-3104aa430ae360599dd54369a8cb1fd61f07894c.zip
automatically clean up left-over Unix domain socket files when trying to bind (fixes #3723)
Diffstat (limited to 'src/util/network.c')
-rw-r--r--src/util/network.c58
1 files changed, 54 insertions, 4 deletions
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);