Skip to content

Commit

Permalink
more flexible keepalive options detection + awful options documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
shripchenko committed Apr 6, 2012
1 parent 0c3d917 commit 4b30340
Show file tree
Hide file tree
Showing 6 changed files with 286 additions and 28 deletions.
112 changes: 97 additions & 15 deletions acinclude.m4
Original file line number Diff line number Diff line change
Expand Up @@ -604,10 +604,10 @@ int main (int argc, char *argv [])
}])

dnl ################################################################################
dnl # LIBZMQ_CHECK_TCP_KEEPALIVE([action-if-found], [action-if-not-found]) #
dnl # LIBZMQ_CHECK_SO_KEEPALIVE([action-if-found], [action-if-not-found]) #
dnl # Check if SO_KEEPALIVE is supported #
dnl ################################################################################
AC_DEFUN([LIBZMQ_CHECK_TCP_KEEPALIVE], [{
AC_DEFUN([LIBZMQ_CHECK_SO_KEEPALIVE], [{
AC_MSG_CHECKING(whether SO_KEEPALIVE is supported)
AC_TRY_RUN([/* SO_KEEPALIVE test */
#include <sys/types.h>
Expand All @@ -622,19 +622,75 @@ int main (int argc, char *argv [])
);
}
],
[AC_MSG_RESULT(yes) ; libzmq_cv_tcp_keepalive="yes" ; $1],
[AC_MSG_RESULT(no) ; libzmq_cv_tcp_keepalive="no" ; $2],
[AC_MSG_RESULT(not during cross-compile) ; libzmq_cv_tcp_keepalive="no"]
[AC_MSG_RESULT(yes) ; libzmq_cv_so_keepalive="yes" ; $1],
[AC_MSG_RESULT(no) ; libzmq_cv_so_keepalive="no" ; $2],
[AC_MSG_RESULT(not during cross-compile) ; libzmq_cv_so_keepalive="no"]
)
}])

dnl ################################################################################
dnl # LIBZMQ_CHECK_TCP_KEEPCNT([action-if-found], [action-if-not-found]) #
dnl # Check if TCP_KEEPCNT is supported #
dnl ################################################################################
AC_DEFUN([LIBZMQ_CHECK_TCP_KEEPCNT], [{
AC_MSG_CHECKING(whether TCP_KEEPCNT is supported)
AC_TRY_RUN([/* TCP_KEEPCNT test */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
int main (int argc, char *argv [])
{
int s, rc, opt = 1;
return (
((s = socket (PF_INET, SOCK_STREAM, 0)) == -1) ||
((rc = setsockopt (s, SOL_SOCKET, SO_KEEPALIVE, (char*) &opt, sizeof (int))) == -1) ||
((rc = setsockopt (s, IPPROTO_TCP, TCP_KEEPCNT, (char*) &opt, sizeof (int))) == -1)
);
}
],
[AC_MSG_RESULT(yes) ; libzmq_cv_tcp_keepcnt="yes" ; $1],
[AC_MSG_RESULT(no) ; libzmq_cv_tcp_keepcnt="no" ; $2],
[AC_MSG_RESULT(not during cross-compile) ; libzmq_cv_tcp_keepcnt="no"]
)
}])

dnl ################################################################################
dnl # LIBZMQ_CHECK_TCP_KEEPALIVE_OPTS([action-if-found], [action-if-not-found]) #
dnl # Check if TCP_KEEPCNT, TCP_KEEPIDLE, TCP_KEEPINTVL are supported #
dnl # LIBZMQ_CHECK_TCP_KEEPIDLE([action-if-found], [action-if-not-found]) #
dnl # Check if TCP_KEEPIDLE is supported #
dnl ################################################################################
AC_DEFUN([LIBZMQ_CHECK_TCP_KEEPALIVE_OPTS], [{
AC_MSG_CHECKING(whether TCP_KEEPCNT TCP_KEEPIDLE TCP_KEEPINTVL are supported)
AC_TRY_RUN([/* TCP_KEEPCNT TCP_KEEPIDLE TCP_KEEPINTVL test */
AC_DEFUN([LIBZMQ_CHECK_TCP_KEEPIDLE], [{
AC_MSG_CHECKING(whether TCP_KEEPIDLE is supported)
AC_TRY_RUN([/* TCP_KEEPIDLE test */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
int main (int argc, char *argv [])
{
int s, rc, opt = 1;
return (
((s = socket (PF_INET, SOCK_STREAM, 0)) == -1) ||
((rc = setsockopt (s, SOL_SOCKET, SO_KEEPALIVE, (char*) &opt, sizeof (int))) == -1) ||
((rc = setsockopt (s, IPPROTO_TCP, TCP_KEEPIDLE, (char*) &opt, sizeof (int))) == -1)
);
}
],
[AC_MSG_RESULT(yes) ; libzmq_cv_tcp_keepidle="yes" ; $1],
[AC_MSG_RESULT(no) ; libzmq_cv_tcp_keepidle="no" ; $2],
[AC_MSG_RESULT(not during cross-compile) ; libzmq_cv_tcp_keepidle="no"]
)
}])

dnl ################################################################################
dnl # LIBZMQ_CHECK_TCP_KEEPINTVL([action-if-found], [action-if-not-found]) #
dnl # Check if TCP_KEEPINTVL is supported #
dnl ################################################################################
AC_DEFUN([LIBZMQ_CHECK_TCP_KEEPINTVL], [{
AC_MSG_CHECKING(whether TCP_KEEPINTVL is supported)
AC_TRY_RUN([/* TCP_KEEPINTVL test */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
Expand All @@ -646,15 +702,41 @@ int main (int argc, char *argv [])
return (
((s = socket (PF_INET, SOCK_STREAM, 0)) == -1) ||
((rc = setsockopt (s, SOL_SOCKET, SO_KEEPALIVE, (char*) &opt, sizeof (int))) == -1) ||
((rc = setsockopt (s, IPPROTO_TCP, TCP_KEEPCNT, (char*) &opt, sizeof (int))) == -1) ||
((rc = setsockopt (s, IPPROTO_TCP, TCP_KEEPIDLE, (char*) &opt, sizeof (int))) == -1) ||
((rc = setsockopt (s, IPPROTO_TCP, TCP_KEEPINTVL, (char*) &opt, sizeof (int))) == -1)
);
}
],
[AC_MSG_RESULT(yes) ; libzmq_cv_tcp_keepalive_opts="yes" ; $1],
[AC_MSG_RESULT(no) ; libzmq_cv_tcp_keepalive_opts="no" ; $2],
[AC_MSG_RESULT(not during cross-compile) ; libzmq_cv_tcp_keepalive_opts="no"]
[AC_MSG_RESULT(yes) ; libzmq_cv_tcp_keepintvl="yes" ; $1],
[AC_MSG_RESULT(no) ; libzmq_cv_tcp_keepintvl="no" ; $2],
[AC_MSG_RESULT(not during cross-compile) ; libzmq_cv_tcp_keepintvl="no"]
)
}])

dnl ################################################################################
dnl # LIBZMQ_CHECK_TCP_KEEPALIVE([action-if-found], [action-if-not-found]) #
dnl # Check if TCP_KEEPALIVE is supported #
dnl ################################################################################
AC_DEFUN([LIBZMQ_CHECK_TCP_KEEPALIVE], [{
AC_MSG_CHECKING(whether TCP_KEEPALIVE is supported)
AC_TRY_RUN([/* TCP_KEEPALIVE test */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
int main (int argc, char *argv [])
{
int s, rc, opt = 1;
return (
((s = socket (PF_INET, SOCK_STREAM, 0)) == -1) ||
((rc = setsockopt (s, SOL_SOCKET, SO_KEEPALIVE, (char*) &opt, sizeof (int))) == -1) ||
((rc = setsockopt (s, IPPROTO_TCP, TCP_KEEPALIVE, (char*) &opt, sizeof (int))) == -1)
);
}
],
[AC_MSG_RESULT(yes) ; libzmq_cv_tcp_keepalive="yes" ; $1],
[AC_MSG_RESULT(no) ; libzmq_cv_tcp_keepalive="no" ; $2],
[AC_MSG_RESULT(not during cross-compile) ; libzmq_cv_tcp_keepalive="no"]
)
}])

Expand Down
27 changes: 22 additions & 5 deletions configure.in
Original file line number Diff line number Diff line change
Expand Up @@ -383,15 +383,32 @@ LIBZMQ_CHECK_SOCK_CLOEXEC([AC_DEFINE(
[1],
[Whether SOCK_CLOEXEC is defined and functioning.])
])
LIBZMQ_CHECK_TCP_KEEPALIVE([AC_DEFINE(
[ZMQ_HAVE_TCP_KEEPALIVE],

# TCP keep-alives Checks.
LIBZMQ_CHECK_SO_KEEPALIVE([AC_DEFINE(
[ZMQ_HAVE_SO_KEEPALIVE],
[1],
[Whether SO_KEEPALIVE is supported.])
])
LIBZMQ_CHECK_TCP_KEEPALIVE_OPTS([AC_DEFINE(
[ZMQ_HAVE_TCP_KEEPALIVE_OPTS],
LIBZMQ_CHECK_TCP_KEEPCNT([AC_DEFINE(
[ZMQ_HAVE_TCP_KEEPCNT],
[1],
[Whether TCP_KEEPCNT is supported.])
])
LIBZMQ_CHECK_TCP_KEEPIDLE([AC_DEFINE(
[ZMQ_HAVE_TCP_KEEPIDLE],
[1],
[Whether TCP_KEEPIDLE is supported.])
])
LIBZMQ_CHECK_TCP_KEEPINTVL([AC_DEFINE(
[ZMQ_HAVE_TCP_KEEPINTVL],
[1],
[Whether TCP_KEEPINTVL is supported.])
])
LIBZMQ_CHECK_TCP_KEEPALIVE([AC_DEFINE(
[ZMQ_HAVE_TCP_KEEPALIVE],
[1],
[Whether TCP_KEEPCNT, TCP_KEEPIDLE, TCP_KEEPINTVL are supported.])
[Whether TCP_KEEPALIVE is supported.])
])

# Subst LIBZMQ_EXTRA_CFLAGS & CXXFLAGS & LDFLAGS
Expand Down
63 changes: 63 additions & 0 deletions doc/zmq_getsockopt.txt
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,69 @@ Option value unit:: N/A
Default value:: NULL
Applicable socket types:: all, when binding TCP or IPC transports

ZMQ_TCP_KEEPALIVE: Retrieve override TCP keepalives flag
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Retrieve override OS TCP keepalives on/off flag (maps to SO_KEEPALIVE socket option).
When equal to `1`(or `0`) TCP keepalives will be turned on(or off) for each new TCP connection
of ZeroMQ socket, `-1` value disables TCP keepalives adjustments.
If the host OS does not support it then setsockopt() call will return `0` but leave this option equal to `-1`.

TCP keepalives are zero-length TCP packets automatically generated by OS
and transparrent to application socket, used to update state of TCP connection.
This also can be used to prevent the infrastructure (VPNs, NATs and similar) to terminate
connections with no activity.

[horizontal]
Option value type:: int
Option value unit:: -1,0,1
Default value:: -1 (leave for OS default)
Applicable socket types:: all, when using TCP transports.

ZMQ_TCP_KEEPALIVE_IDLE: <dont know how to summarize it>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Retrieve option value to override the interval between the last data packet sent over
the TCP socket and the first keepalive probe (maps to TCP_KEEPCNT or TCP_KEEPALIVE socket option).

Default value `-1` disables adjustment.
If the host OS does not support it then setsockopt() call will return `0` but leave this option equal to `-1`.

[horizontal]
Option value type:: int
Option value unit:: -1,>0
Default value:: -1 (leave for OS default)
Applicable socket types:: all, when using TCP transports.

ZMQ_TCP_KEEPALIVE_CNT: <dont know how to summarize it>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Retrieve option value to override the number of unacknowledged keepalive probes
to send over the TCP socket before considering the connection dead and notifying
the application ZeroMQ layer (maps to TCP_KEEPCNT socket option).

Default value `-1` disables adjustment.
If the host OS does not support it then setsockopt() call will return `0` but leave this option equal to `-1`.

[horizontal]
Option value type:: int
Option value unit:: -1,>0
Default value:: -1 (leave for OS default)
Applicable socket types:: all, when using TCP transports.

ZMQ_TCP_KEEPALIVE_INTVL: <dont know how to summarize it>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Retrieve option value to override the interval between subsequential keepalive probes,
regardless of what the TCP connection has exchanged in the meantime
(maps to TCP_KEEPINTVL socket option).

Default value `-1` disables adjustment.
If the host OS does not support it then setsockopt() call will return `0` but leave this option equal to `-1`.

[horizontal]
Option value type:: int
Option value unit:: -1,>0
Default value:: -1 (leave for OS default)
Applicable socket types:: all, when using TCP transports.


RETURN VALUE
------------
The _zmq_getsockopt()_ function shall return zero if successful. Otherwise it
Expand Down
66 changes: 66 additions & 0 deletions doc/zmq_setsockopt.txt
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,72 @@ Default value:: 0 (false)
Applicable socket types:: ZMQ_ROUTER


ZMQ_TCP_KEEPALIVE: Set TCP keepalives flag
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Sets the option to override TCP keepalives on/off flag (maps to SO_KEEPALIVE socket option).
When set to `1`(or `0`) TCP keepalives will be turned on(or off) for each new TCP connection
of ZeroMQ socket, `-1` value disables TCP keepalives adjustments.
If the host OS does not support it then setsockopt() call will return `0` but leave this option equal to `-1`.

TCP keepalives are zero-length TCP packets automatically generated by OS
and transparrent to application socket, used to update state of TCP connection.
This also can be used to prevent the infrastructure (VPNs, NATs and similar) to terminate
connections with no activity.

[horizontal]
Option value type:: int
Option value unit:: -1,0,1
Default value:: -1 (leave for OS default)
Applicable socket types:: all, when using TCP transports.


ZMQ_TCP_KEEPALIVE_IDLE: <dont know how to summarize it>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Sets option value to override the interval between the last data packet sent over
the TCP socket and the first keepalive probe (maps to TCP_KEEPCNT or TCP_KEEPALIVE socket option).

Default value `-1` disables adjustment.
If the host OS does not support it then setsockopt() call will return `0` but leave this option equal to `-1`.

[horizontal]
Option value type:: int
Option value unit:: -1,>0
Default value:: -1 (leave for OS default)
Applicable socket types:: all, when using TCP transports.


ZMQ_TCP_KEEPALIVE_CNT: <dont know how to summarize it>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Sets option value to override the number of unacknowledged keepalive probes
to send over the TCP socket before considering the connection dead and notifying
the application ZeroMQ layer (maps to TCP_KEEPCNT socket option).

Default value `-1` disables adjustment.
If the host OS does not support it then setsockopt() call will return `0` but leave this option equal to `-1`.

[horizontal]
Option value type:: int
Option value unit:: -1,>0
Default value:: -1 (leave for OS default)
Applicable socket types:: all, when using TCP transports.


ZMQ_TCP_KEEPALIVE_INTVL: <dont know how to summarize it>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Sets option value to override the interval between subsequential keepalive probes,
regardless of what the TCP connection has exchanged in the meantime
(maps to TCP_KEEPINTVL socket option).

Default value `-1` disables adjustment.
If the host OS does not support it then setsockopt() call will return `0` but leave this option equal to `-1`.

[horizontal]
Option value type:: int
Option value unit:: -1,>0
Default value:: -1 (leave for OS default)
Applicable socket types:: all, when using TCP transports.


RETURN VALUE
------------
The _zmq_setsockopt()_ function shall return zero if successful. Otherwise it
Expand Down
37 changes: 33 additions & 4 deletions src/ip.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ void zmq::tune_tcp_keepalives (fd_t s_, int keepalive_, int keepalive_cnt_, int
{
// Tuning TCP keep-alives if platform allows it
// All values = -1 means skip and leave it for OS
#ifdef ZMQ_HAVE_TCP_KEEPALIVE
#ifdef ZMQ_HAVE_SO_KEEPALIVE
if (keepalive_ != -1) {
int rc = setsockopt (s_, SOL_SOCKET, SO_KEEPALIVE, (char*) &keepalive_, sizeof (int));
#ifdef ZMQ_HAVE_WINDOWS
Expand All @@ -96,22 +96,51 @@ void zmq::tune_tcp_keepalives (fd_t s_, int keepalive_, int keepalive_cnt_, int
errno_assert (rc == 0);
#endif

#if defined ZMQ_HAVE_TCP_KEEPALIVE_OPTS && !defined ZMQ_HAVE_WINDOWS
#ifdef ZMQ_HAVE_TCP_KEEPCNT
if (keepalive_cnt_ != -1) {
int rc = setsockopt (s_, IPPROTO_TCP, TCP_KEEPCNT, &keepalive_cnt_, sizeof (int));
#ifdef ZMQ_HAVE_WINDOWS
wsa_assert (rc != SOCKET_ERROR);
#else
errno_assert (rc == 0);
#endif
}
#endif // ZMQ_HAVE_TCP_KEEPCNT

#ifdef ZMQ_HAVE_TCP_KEEPIDLE
if (keepalive_idle_ != -1) {
int rc = setsockopt (s_, IPPROTO_TCP, TCP_KEEPIDLE, &keepalive_idle_, sizeof (int));
#ifdef ZMQ_HAVE_WINDOWS
wsa_assert (rc != SOCKET_ERROR);
#else
errno_assert (rc == 0);
#endif
}
#else // ZMQ_HAVE_TCP_KEEPIDLE
#ifdef ZMQ_HAVE_TCP_KEEPALIVE
if (keepalive_idle_ != -1) {
int rc = setsockopt (s_, IPPROTO_TCP, TCP_KEEPALIVE, &keepalive_idle_, sizeof (int));
#ifdef ZMQ_HAVE_WINDOWS
wsa_assert (rc != SOCKET_ERROR);
#else
errno_assert (rc == 0);
#endif
}
#endif // ZMQ_HAVE_TCP_KEEPALIVE
#endif // ZMQ_HAVE_TCP_KEEPIDLE

#ifdef ZMQ_HAVE_TCP_KEEPINTVL
if (keepalive_intvl_ != -1) {
int rc = setsockopt (s_, IPPROTO_TCP, TCP_KEEPINTVL, &keepalive_intvl_, sizeof (int));
#ifdef ZMQ_HAVE_WINDOWS
wsa_assert (rc != SOCKET_ERROR);
#else
errno_assert (rc == 0);
}
#endif
}
#endif // ZMQ_HAVE_TCP_KEEPINTVL
}
#endif
#endif // ZMQ_HAVE_SO_KEEPALIVE
}

void zmq::unblock_socket (fd_t s_)
Expand Down
Loading

0 comments on commit 4b30340

Please sign in to comment.