aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--socket.c25
-rw-r--r--socket.h3
2 files changed, 28 insertions, 0 deletions
diff --git a/socket.c b/socket.c
index d48a6369..930e1b0d 100644
--- a/socket.c
+++ b/socket.c
@@ -200,6 +200,31 @@ static int handle_plugin(const char *host,
}
#endif /* HAVE_SOCKETPAIR */
+static int setsocktimeout(int sock, int which, int timeout) {
+ struct timeval tv;
+ int rc;
+
+ tv.tv_sec = timeout;
+ tv.tv_usec = 0;
+ rc = setsockopt(sock, SOL_SOCKET, which, &tv, sizeof(tv));
+ if (rc) {
+ report(stderr, GT_("setsockopt(%d, SOL_SOCKET) failed: %s"), sock, strerror(errno));
+ }
+ return rc;
+}
+
+/** Configure socket options such as send/receive timeout at the socket
+ * level, to avoid network-induced stalls.
+ */
+int SockTimeout(int sock, int timeout)
+{
+ int err = 0;
+
+ if (setsocktimeout(sock, SO_RCVTIMEO, timeout)) err = 1;
+ if (setsocktimeout(sock, SO_SNDTIMEO, timeout)) err = 1;
+ return err;
+}
+
int UnixOpen(const char *path)
{
int sock = -1;
diff --git a/socket.h b/socket.h
index 0c4ac001..cbdeec06 100644
--- a/socket.h
+++ b/socket.h
@@ -20,6 +20,9 @@ struct addrinfo;
/** Create a new client socket; returns -1 on error */
int SockOpen(const char *host, const char *service, const char *plugin, struct addrinfo **);
+/** Sets the send/receive timeouts for socket \a sock to \a timeout
+ * seconds. \return zero on success. */
+int SockTimeout(int sock, int timeout);
/**
Get a string terminated by an '\n' (matches interface of fgets).