Use TCP keepalives on Linux if available; if not, fallback to manual keepalives.
--- a/loudmouth/lm-connection.c Mon Oct 29 16:59:36 2007 +0100
+++ b/loudmouth/lm-connection.c Mon Oct 29 17:02:16 2007 +0100
@@ -321,6 +321,12 @@
static void
connection_start_keep_alive (LmConnection *connection)
{
+ /* try using TCP keepalives if possible */
+ if ((connection->keep_alive_rate > 0) &&
+ lm_socket_set_keepalive (connection->socket,
+ connection->keep_alive_rate))
+ return;
+
if (connection->keep_alive_source) {
connection_stop_keep_alive (connection);
}
--- a/loudmouth/lm-internals.h Mon Oct 29 16:59:36 2007 +0100
+++ b/loudmouth/lm-internals.h Mon Oct 29 17:02:16 2007 +0100
@@ -109,4 +109,8 @@
const gchar * _lm_sock_get_error_str (int err);
const gchar * _lm_sock_addrinfo_get_error_str (int err);
+#ifdef USE_TCP_KEEPALIVES
+gboolean _lm_sock_set_keepalive (LmSocketT sock, int delay);
+#endif /* USE_TCP_KEEPALIVES */
+
#endif /* __LM_INTERNALS_H__ */
--- a/loudmouth/lm-sock.c Mon Oct 29 16:59:36 2007 +0100
+++ b/loudmouth/lm-sock.c Mon Oct 29 17:02:16 2007 +0100
@@ -289,3 +289,34 @@
return _("The remote address could not be obtained ");
}
+
+#ifdef USE_TCP_KEEPALIVES
+gboolean
+_lm_sock_set_keepalive (LmSocketT sock, int delay)
+{
+ int opt;
+
+ opt = 1;
+ if (setsockopt (sock, SOL_SOCKET, SO_KEEPALIVE, &opt, sizeof (opt)) < 0) {
+ return FALSE;
+ }
+
+ opt = 3; /* 3 keepalives before considering connection dead */
+ if (setsockopt (sock, IPPROTO_TCP, TCP_KEEPCNT, &opt, sizeof (opt)) < 0) {
+ return FALSE;
+ }
+
+ opt = 30; /* start keepalives after 30s idle time */
+ if (setsockopt (sock, IPPROTO_TCP, TCP_KEEPIDLE, &opt, sizeof (opt)) < 0) {
+ return FALSE;
+ }
+
+ opt = 30; /* send keepalive every 30s */
+ if (setsockopt (sock, IPPROTO_TCP, TCP_KEEPINTVL, &opt, sizeof (opt)) < 0) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+#endif /* USE_TCP_KEEPALIVES */
+
--- a/loudmouth/lm-socket.c Mon Oct 29 16:59:36 2007 +0100
+++ b/loudmouth/lm-socket.c Mon Oct 29 17:02:16 2007 +0100
@@ -1119,3 +1119,13 @@
}
}
+gboolean
+lm_socket_set_keepalive (LmSocket *socket, int delay)
+{
+#ifdef USE_TCP_KEEPALIVES
+ return _lm_sock_set_keepalive (socket->fd, delay);
+#else
+ return FALSE;
+#endif /* USE_TCP_KEEPALIVES */
+}
+
--- a/loudmouth/lm-socket.h Mon Oct 29 16:59:36 2007 +0100
+++ b/loudmouth/lm-socket.h Mon Oct 29 17:02:16 2007 +0100
@@ -70,6 +70,7 @@
void _asyncns_cancel (LmSocket *socket);
#endif
gboolean lm_socket_starttls (LmSocket *socket);
+gboolean lm_socket_set_keepalive (LmSocket *socket, int delay);
#endif /* __LM_SOCKET_H__ */