net/tcp: Use the relative value for keep alive timer

unify the timer process logic as other tcp state

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
This commit is contained in:
Xiang Xiao 2022-05-18 13:32:56 +08:00 committed by Petro Karashchenko
parent 2d3ee157ce
commit d8b97d7ae8
6 changed files with 45 additions and 52 deletions

View File

@ -284,9 +284,7 @@ struct tcp_conn_s
* system clock tick.
*/
clock_t keeptime; /* Last time that the TCP socket was known to be
* alive (ACK or data received) OR time that the
* last probe was sent. */
uint32_t keeptimer; /* KeepAlive timer (dsec) */
uint32_t keepidle; /* Elapsed idle time before first probe sent (dsec) */
uint32_t keepintvl; /* Interval between probes (dsec) */
bool keepalive; /* True: KeepAlive enabled; false: disabled */

View File

@ -727,7 +727,6 @@ FAR struct tcp_conn_s *tcp_alloc(uint8_t domain)
conn->domain = domain;
#endif
#ifdef CONFIG_NET_TCP_KEEPALIVE
conn->keeptime = clock_systime_ticks();
conn->keepidle = 2 * DSEC_PER_HOUR;
conn->keepintvl = 2 * DSEC_PER_SEC;
conn->keepcnt = 3;

View File

@ -132,7 +132,7 @@ int tcp_getsockopt(FAR struct socket *psock, int option,
else
{
FAR int *keepalive = (FAR int *)value;
*keepalive = (int)conn->keepalive;
*keepalive = conn->keepalive;
*value_len = sizeof(int);
ret = OK;
}
@ -216,7 +216,7 @@ int tcp_getsockopt(FAR struct socket *psock, int option,
else
{
FAR int *keepcnt = (FAR int *)value;
*keepcnt = (int)conn->keepcnt;
*keepcnt = conn->keepcnt;
*value_len = sizeof(int);
ret = OK;
}

View File

@ -1143,13 +1143,9 @@ found:
if (conn->keepalive &&
(dev->d_len > 0 || (tcp->flags & TCP_ACK) != 0))
{
/* Reset the last known "alive" time.
*
* REVISIT: At this level, we don't actually know if keep-
* alive is enabled for this connection.
*/
/* Reset the "alive" timer. */
conn->keeptime = clock_systime_ticks();
conn->keeptimer = conn->keepidle;
conn->keepretries = 0;
}
#endif

View File

@ -78,7 +78,7 @@ int tcp_setsockopt(FAR struct socket *psock, int option,
*/
FAR struct tcp_conn_s *conn;
int ret;
int ret = OK;
DEBUGASSERT(psock != NULL && value != NULL && psock->s_conn != NULL);
conn = (FAR struct tcp_conn_s *)psock->s_conn;
@ -107,8 +107,8 @@ int tcp_setsockopt(FAR struct socket *psock, int option,
* all of the clones that may use the underlying connection.
*/
case SO_KEEPALIVE: /* Verifies TCP connections active by enabling the
* periodic transmission of probes */
case SO_KEEPALIVE: /* Verifies TCP connections active by enabling the
* periodic transmission of probes */
if (value_len != sizeof(int))
{
ret = -EDOM;
@ -125,9 +125,15 @@ int tcp_setsockopt(FAR struct socket *psock, int option,
}
else
{
conn->keepalive = (bool)keepalive;
conn->keeptime = clock_systime_ticks(); /* Reset start time */
ret = OK;
conn->keepalive = keepalive;
/* Reset timer */
if (conn->keepalive)
{
conn->keeptimer = conn->keepidle;
conn->keepretries = 0;
}
}
}
break;
@ -141,11 +147,7 @@ int tcp_setsockopt(FAR struct socket *psock, int option,
{
int nodelay = *(FAR int *)value;
if (nodelay)
{
ret = OK;
}
else
if (!nodelay)
{
nerr("ERROR: TCP_NODELAY not supported\n");
ret = -ENOSYS;
@ -170,7 +172,7 @@ int tcp_setsockopt(FAR struct socket *psock, int option,
* be forced to the next larger, whole decisecond value.
*/
dsecs = (socktimeo_t)net_timeval2dsec(tv, TV2DS_CEIL);
dsecs = net_timeval2dsec(tv, TV2DS_CEIL);
}
else if (value_len == sizeof(int))
{
@ -189,20 +191,24 @@ int tcp_setsockopt(FAR struct socket *psock, int option,
if (option == TCP_KEEPIDLE)
{
conn->keepidle = (uint16_t)dsecs;
conn->keepidle = dsecs;
}
else
{
conn->keepintvl = (uint16_t)dsecs;
conn->keepintvl = dsecs;
}
conn->keeptime = clock_systime_ticks(); /* Reset start time */
/* Reset timer */
ret = OK;
if (conn->keepalive)
{
conn->keeptimer = conn->keepidle;
conn->keepretries = 0;
}
}
break;
case TCP_KEEPCNT: /* Number of keepalives before death */
case TCP_KEEPCNT: /* Number of keepalives before death */
if (value_len != sizeof(int))
{
ret = -EDOM;
@ -218,9 +224,15 @@ int tcp_setsockopt(FAR struct socket *psock, int option,
}
else
{
conn->keepcnt = (uint8_t)keepcnt;
conn->keeptime = clock_systime_ticks(); /* Reset start time */
ret = OK;
conn->keepcnt = keepcnt;
/* Reset time */
if (conn->keepalive)
{
conn->keeptimer = conn->keepidle;
conn->keepretries = 0;
}
}
}
break;

View File

@ -375,31 +375,19 @@ void tcp_timer(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn,
if (conn->keepalive)
{
socktimeo_t timeo;
uint32_t saveseq;
/* If this is the first probe, then the keepstart time is
* the time that the last ACK or data was received from the
* remote.
*
* On subsequent retries, keepstart is the time that the
* last probe was sent.
*/
if (conn->keepretries > 0)
{
timeo = (socktimeo_t)conn->keepintvl;
}
else
{
timeo = (socktimeo_t)conn->keepidle;
}
/* Yes... has the idle period elapsed with no data or ACK
* received from the remote peer?
*/
if (net_timeo(conn->keeptime, timeo))
if (conn->keeptimer > hsec)
{
/* Will not yet decrement to zero */
conn->keeptimer -= hsec;
}
else
{
/* Yes.. Has the retry count expired? */
@ -464,7 +452,7 @@ void tcp_timer(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn,
#endif
/* Update for the next probe */
conn->keeptime = clock_systime_ticks();
conn->keeptimer = conn->keepintvl;
conn->keepretries++;
}