diff --git a/net/tcp/tcp.h b/net/tcp/tcp.h index 3957c25cec7..13fd94cffd7 100644 --- a/net/tcp/tcp.h +++ b/net/tcp/tcp.h @@ -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 */ diff --git a/net/tcp/tcp_conn.c b/net/tcp/tcp_conn.c index 23e43db5d9d..2b1fcc5c6c1 100644 --- a/net/tcp/tcp_conn.c +++ b/net/tcp/tcp_conn.c @@ -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; diff --git a/net/tcp/tcp_getsockopt.c b/net/tcp/tcp_getsockopt.c index b864b19d680..7d815f6a5fa 100644 --- a/net/tcp/tcp_getsockopt.c +++ b/net/tcp/tcp_getsockopt.c @@ -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; } diff --git a/net/tcp/tcp_input.c b/net/tcp/tcp_input.c index 5935ab770bd..ce6bf193959 100644 --- a/net/tcp/tcp_input.c +++ b/net/tcp/tcp_input.c @@ -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 diff --git a/net/tcp/tcp_setsockopt.c b/net/tcp/tcp_setsockopt.c index b4082ba2d99..402b0e3e941 100644 --- a/net/tcp/tcp_setsockopt.c +++ b/net/tcp/tcp_setsockopt.c @@ -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; diff --git a/net/tcp/tcp_timer.c b/net/tcp/tcp_timer.c index cbcc80307e8..3b985d995b1 100644 --- a/net/tcp/tcp_timer.c +++ b/net/tcp/tcp_timer.c @@ -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++; }