Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use TCP keepalive to detect broken sockets #681

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 58 additions & 1 deletion implementation/endpoints/src/tcp_server_endpoint_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include <iomanip>

#include <netinet/tcp.h>
#include <boost/asio/write.hpp>

#include <vsomeip/constants.hpp>
Expand Down Expand Up @@ -272,6 +272,63 @@ void tcp_server_endpoint_impl::accept_cbk(const connection::ptr& _connection,
VSOMEIP_WARNING << "tcp_server_endpoint::connect: couldn't enable "
<< "keep_alive: " << its_error.message();
}

// Enable sending of keep-alive messages on connection-oriented sockets
// Enables (nonzero) or disables (zero) the periodic transmission of messages
// Should the connected party fail to respond to these messages, the connection is considered broken
int optval = 1;
int rc;
rc = setsockopt(new_connection_socket.native_handle(), SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval));
if (rc != 0) {
VSOMEIP_WARNING << "tcp_server_endpoint::connect: couldn't enable keep_alive(10)" ;
}
#ifndef __QNX__
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @joeyoravec

Thanks for this Pull Request.

One suggestion to maybe avoid "#ifdef platform" and the hardcoded values, the tcp keep alive options could be added as new configurations in the vsomeip json files.
If no configurations would be present, the default from the platform would be used (this would be preferable for linux based systems, where sysctl is used)
If configurations for the keep alive would be present, those would be used instead, for all platforms.

// Linux has 3 parameters configurable on a both a global and per-socket basis
// TCP_KEEPIDLE / tcp_keepalive_time
// TCP_KEEPCNT / tcp_keepalive_probes
// TCP_KEEPINTVL / tcp_keepalive_intvl
//
// Adjust these on the vsomeip socket to detect breaks within IDLE + (CNT * INTVL) seconds

// The time (in seconds) the connection needs to remain idle before TCP starts sending keepalive probes
optval = 10;
rc = setsockopt(new_connection_socket.native_handle(), IPPROTO_TCP, TCP_KEEPIDLE, &optval, sizeof(optval));
if (rc != 0) {
VSOMEIP_WARNING << "tcp_server_endpoint::connect: couldn't enable keep_alive(TCP_KEEPIDLE)" ;
}

// The maximum count of keepalive probes TCP should send before dropping the connection
optval = 2;
rc = setsockopt(new_connection_socket.native_handle(), IPPROTO_TCP, TCP_KEEPCNT, &optval, sizeof(optval));
if (rc != 0) {
VSOMEIP_WARNING << "tcp_server_endpoint::connect: couldn't enable keep_alive(TCP_KEEPCNT)" ;
}

// The time (in seconds) between individual keepalive probes
optval = 2;
rc = setsockopt(new_connection_socket.native_handle(), IPPROTO_TCP, TCP_KEEPINTVL, &optval, sizeof(optval));
if (rc != 0) {
VSOMEIP_WARNING << "tcp_server_endpoint::connect: couldn't enable keep_alive(TCP_KEEPINTVL)" ;
}
#else
// QNX has 1 parameter configurable on a per-socket basis
// TCP_KEEPALIVE (documented full-seconds)
// and 3 parameters configurable on a global basis as defaults
// sysctl net.inet.tcp.keepidle (half-seconds)
// TCPCTL_KEEPINTVL / sysctl net.inet.tcp.keepintvl (half-seconds)
// TCPCTL_KEEPCNT / sysctl net.inet.tcp.keepcnt
//
// Adjust TCP_KEEPALIVE on the vsomeip socket
// Rely on reasonable global sysctl for CNT and INTVL
// Detect breaks within IDLE + (CNT * INTVL) seconds

// The time (in seconds) the connection needs to remain idle before TCP starts sending keepalive probes
optval = 10;
rc = setsockopt(new_connection_socket.native_handle(), IPPROTO_TCP, TCP_KEEPALIVE, &optval, sizeof(optval));
if (rc != 0) {
VSOMEIP_WARNING << "tcp_server_endpoint::connect: couldn't enable keep_alive(TCP_KEEPALIVE)" ;
}
#endif
}
if (!its_error) {
{
Expand Down