Fix critical bug in default TCP keepalive user timeout
It turns out that our calculation of the TCP_USER_TIMEOUT value was flawed in several ways: * there should have been parenthesis around the + operator (line->keepalive_probe_interval + line->keepalive_idle_timeout) as the keepalive_idle_timeout is in seconds, not milli-seconds. * in the default case, all those values are configured to -1 (E1INP_USE_DEFAULT). This means we're using 1000 * -1 * -1 + -1 = 999 i.e. just below aq second which clearly is not enough for a lossy satellite or wifi back-haul. This fixes a regression introduced in Ia7659c209aea0d26eb37d31e771adc91b17ae668 i.e. present since libosmo-abis 1.4.0 In addition, let's print the actually-used values to the log, helping to spot unintended values. Change-Id: Idca24d3e676a45d860d9eec60dc2097d8d87f3bf Closes: OS#6375 Related: OS#5785, SYS#6801 Fixes: Ia7659c209aea0d26eb37d31e771adc91b17ae668
This commit is contained in:
parent
361488f83f
commit
8bc2e31961
|
@ -588,7 +588,7 @@ struct e1inp_driver ipaccess_driver = {
|
|||
static void update_fd_settings(struct e1inp_line *line, int fd)
|
||||
{
|
||||
int ret;
|
||||
int val;
|
||||
int val, idle_val, interval_val, retry_count_val, user_timeout_val;
|
||||
|
||||
if (line->keepalive_num_probes) {
|
||||
/* Enable TCP keepalive to find out if the connection is gone */
|
||||
|
@ -599,33 +599,33 @@ static void update_fd_settings(struct e1inp_line *line, int fd)
|
|||
else
|
||||
LOGPIL(line, DLINP, LOGL_NOTICE, "TCP Keepalive is enabled\n");
|
||||
|
||||
idle_val = line->keepalive_idle_timeout > 0 ?
|
||||
line->keepalive_idle_timeout :
|
||||
DEFAULT_TCP_KEEPALIVE_IDLE_TIMEOUT;
|
||||
interval_val = line->keepalive_probe_interval > -1 ?
|
||||
line->keepalive_probe_interval :
|
||||
DEFAULT_TCP_KEEPALIVE_INTERVAL;
|
||||
retry_count_val = line->keepalive_num_probes > 0 ?
|
||||
line->keepalive_num_probes :
|
||||
DEFAULT_TCP_KEEPALIVE_RETRY_COUNT;
|
||||
user_timeout_val = 1000 * retry_count_val * (interval_val + idle_val);
|
||||
LOGPIL(line, DLINP, LOGL_NOTICE, "TCP keepalive idle_timeout=%us, interval=%us, retry_count=%u "
|
||||
"uesr_timeout=%ums\n", idle_val, interval_val, retry_count_val, user_timeout_val);
|
||||
/* The following options are not portable! */
|
||||
val = line->keepalive_idle_timeout > 0 ?
|
||||
line->keepalive_idle_timeout :
|
||||
DEFAULT_TCP_KEEPALIVE_IDLE_TIMEOUT;
|
||||
ret = setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &val, sizeof(val));
|
||||
ret = setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &idle_val, sizeof(idle_val));
|
||||
if (ret < 0) {
|
||||
LOGPIL(line, DLINP, LOGL_ERROR, "Failed to set TCP keepalive idle time: %s\n",
|
||||
strerror(errno));
|
||||
}
|
||||
val = line->keepalive_probe_interval > -1 ?
|
||||
line->keepalive_probe_interval :
|
||||
DEFAULT_TCP_KEEPALIVE_INTERVAL;
|
||||
ret = setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &val, sizeof(val));
|
||||
ret = setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &interval_val, sizeof(interval_val));
|
||||
if (ret < 0) {
|
||||
LOGPIL(line, DLINP, LOGL_ERROR, "Failed to set TCP keepalive interval: %s\n",
|
||||
strerror(errno));
|
||||
}
|
||||
val = line->keepalive_num_probes > 0 ?
|
||||
line->keepalive_num_probes :
|
||||
DEFAULT_TCP_KEEPALIVE_RETRY_COUNT;
|
||||
ret = setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &val, sizeof(val));
|
||||
ret = setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &retry_count_val, sizeof(retry_count_val));
|
||||
if (ret < 0)
|
||||
LOGPIL(line, DLINP, LOGL_ERROR, "Failed to set TCP keepalive count: %s\n", strerror(errno));
|
||||
val = 1000 * line->keepalive_num_probes *
|
||||
line->keepalive_probe_interval +
|
||||
line->keepalive_idle_timeout;
|
||||
ret = setsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &val, sizeof(val));
|
||||
ret = setsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &user_timeout_val, sizeof(user_timeout_val));
|
||||
if (ret < 0)
|
||||
LOGPIL(line, DLINP, LOGL_ERROR, "Failed to set TCP user timeout: %s\n", strerror(errno));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue