diff --git a/TODO b/TODO index 67587d1ab78..34b3a156710 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,4 @@ -NuttX TODO List (Last updated April 29, 2019) +NuttX TODO List (Last updated July 1, 2019) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This file summarizes known NuttX bugs, limitations, inconsistencies with @@ -19,7 +19,7 @@ nuttx/: (9) Kernel/Protected Build (3) C++ Support (5) Binary loaders (binfmt/) - (18) Network (net/, drivers/net) + (17) Network (net/, drivers/net) (4) USB (drivers/usbdev, drivers/usbhost) (2) Other drivers (drivers/) (9) Libraries (libs/libc/, libs/libm/) @@ -1653,23 +1653,6 @@ o Network (net/, drivers/net) before, so I suspect it might not be so prevalent as one might expect. - Title: TCP SOCKETS CLOSED TOO QUICKLY - Description: When a socket is closed, the resources are torn down - immediately (unless the SO_LINGER option is selected). As a - result, the socket does not send the FIN and this looks like - an unexpected, abnormal loss of connection to the remote peer. - - Actually, it is worse than this: The is NO logic to send - FIN in when the file is close. This is pretty easy to do, - however: - - - Wait for a TCP poll, then - - Call tcp_append with TCP_CLOSE in the flags. There is - already logic in tcp_appsend to send the FIN in this case, - it is just not being use. - Status: Open - Priority: Medium-Low. - Title: LOCAL DATAGRAM RECVFROM RETURNS WRONG SENDER ADDRESS Description: The recvfrom logic for local datagram sockets returns the incorrect sender "from" address. Instead, it returns the diff --git a/net/inet/inet_close.c b/net/inet/inet_close.c index cdfd8f6836b..5e587417e25 100644 --- a/net/inet/inet_close.c +++ b/net/inet/inet_close.c @@ -213,7 +213,6 @@ static uint16_t tcp_close_eventhandler(FAR struct net_driver_s *dev, pstate->cl_result = -ETIMEDOUT; goto end_wait; } - #endif /* CONFIG_NET_SOLINGER */ #ifdef CONFIG_NET_TCP_WRITE_BUFFERS @@ -327,6 +326,7 @@ static inline int tcp_close_disconnect(FAR struct socket *psock) FAR struct tcp_conn_s *conn; #ifdef CONFIG_NET_SOLINGER struct timespec abstime; + bool linger; #endif int ret = OK; @@ -400,21 +400,31 @@ static inline int tcp_close_disconnect(FAR struct socket *psock) /* Wait for the disconnect event */ #ifdef CONFIG_NET_SOLINGER - DEBUGVERIFY(clock_gettime(CLOCK_REALTIME, &abstime)); + /* A non-NULL value of the priv field means that lingering is + * enabled. + */ - /* NOTE: s_linger's unit is deciseconds, - * so we don't need to update abstime.tv_nsec here. - */ - - abstime.tv_sec += psock->s_linger / DSEC_PER_SEC; - - if (-ETIMEDOUT == net_timedwait(&state.cl_sem, &abstime)) + linger = _SO_GETOPT(psock->s_options, SO_LINGER); + if (linger) { - state.cl_result = -ETIMEDOUT; + DEBUGVERIFY(clock_gettime(CLOCK_REALTIME, &abstime)); + + /* NOTE: s_linger's unit is deciseconds, + * so we don't need to update abstime.tv_nsec here. + */ + + abstime.tv_sec += psock->s_linger / DSEC_PER_SEC; + + if (-ETIMEDOUT == net_timedwait(&state.cl_sem, &abstime)) + { + state.cl_result = -ETIMEDOUT; + } } + else #else - (void)net_timedwait(&state.cl_sem, NULL); -#endif + { + (void)net_timedwait(&state.cl_sem, NULL); + } /* We are now disconnected */