From b493dde4cf9b3e88cd7ba491aac20d4972586316 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sun, 31 May 2015 11:35:28 -0600 Subject: [PATCH] TCP networking: In the TCP connection operation, it was trying to setup the network monitor BEFORE the socket was successfully connected. This, of course, has ALWAYS failed because the socket is not yet connected and the TCP state is not yet correct for a connected socket. However, because of other changes net_startmonitor(0 no returns a failure condition that causes worse problems when trying to connect. The fix is to move the logic that starts the network monitor to AFTER the socket has been successfully connected. --- net/netdev/netdev_ioctl.c | 4 ++-- net/socket/connect.c | 36 +++++++++++++++++++++--------------- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/net/netdev/netdev_ioctl.c b/net/netdev/netdev_ioctl.c index 903b261108..dfeba23748 100644 --- a/net/netdev/netdev_ioctl.c +++ b/net/netdev/netdev_ioctl.c @@ -588,7 +588,7 @@ static int netdev_ifrioctl(FAR struct socket *psock, int cmd, dev = netdev_ifrdev(req); if (dev) { - if (req->ifr_flags & IFF_UP) + if ((req->ifr_flags & IFF_UP) != 0) { /* Yes.. bring the interface up */ @@ -597,7 +597,7 @@ static int netdev_ifrioctl(FAR struct socket *psock, int cmd, /* Is this a request to take the interface down? */ - else if (req->ifr_flags & IFF_DOWN) + else if ((req->ifr_flags & IFF_DOWN) != 0) { /* Yes.. take the interface down */ diff --git a/net/socket/connect.c b/net/socket/connect.c index 9d5d9699ef..704c18d322 100644 --- a/net/socket/connect.c +++ b/net/socket/connect.c @@ -121,19 +121,7 @@ static inline int psock_setup_callbacks(FAR struct socket *psock, TCP_TIMEDOUT | TCP_CONNECTED | NETDEV_DOWN); pstate->tc_cb->priv = (void*)pstate; pstate->tc_cb->event = psock_connect_interrupt; - - /* Set up the connection event monitor */ - - ret = net_startmonitor(psock); - if (ret < 0) - { - /* net_startmonitor() can only fail on certain race conditions - * where the connection was lost just before this function was - * called. Undo everything we have done and return a failure. - */ - - psock_teardown_callbacks(pstate, ret); - } + ret = OK; } return ret; @@ -390,11 +378,29 @@ static inline int psock_tcp_connect(FAR struct socket *psock, psock_teardown_callbacks(&state, ret); } - /* Mark the connection bound and connected */ + /* Check if the socket was successffully connected. */ if (ret >= 0) { - psock->s_flags |= (_SF_BOUND|_SF_CONNECTED); + /* Yes.. Mark the connection bound and connected */ + + psock->s_flags |= (_SF_BOUND | _SF_CONNECTED); + + /* Now that we are connected, we need to set up to monitor the + * state of the connection up the connection event monitor. + */ + + ret = net_startmonitor(psock); + if (ret < 0) + { + /* net_startmonitor() can only fail on certain race + * conditions where the connection was lost just before + * this function was called. That is not expected to + * happen in this context, but just in case... + */ + + net_lostconnection(psock, TCP_ABORT); + } } }