Networking: Fix a runaway recursion problem introduced the previous fixe for shutting down dup'ed sockets.
This commit is contained in:
parent
d40ee8e79d
commit
0f7a52bc28
@ -508,7 +508,7 @@ int inet_close(FAR struct socket *psock)
|
||||
|
||||
/* Stop the network monitor */
|
||||
|
||||
tcp_stop_monitor(conn);
|
||||
tcp_stop_monitor(conn, TCP_CLOSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -737,15 +737,9 @@ static uint16_t inet_tcp_interrupt(FAR struct net_driver_s *dev,
|
||||
{
|
||||
ninfo("Lost connection\n");
|
||||
|
||||
/* Stop further callbacks */
|
||||
|
||||
pstate->ir_cb->flags = 0;
|
||||
pstate->ir_cb->priv = NULL;
|
||||
pstate->ir_cb->event = NULL;
|
||||
|
||||
/* Handle loss-of-connection event */
|
||||
|
||||
tcp_lost_connection(pstate->ir_sock, flags);
|
||||
tcp_lost_connection(pstate->ir_sock, pstate->ir_cb, flags);
|
||||
|
||||
/* Check if the peer gracefully closed the connection. */
|
||||
|
||||
|
@ -439,11 +439,11 @@ static uint16_t tcp_send_interrupt(FAR struct net_driver_s *dev,
|
||||
|
||||
else if ((flags & TCP_DISCONN_EVENTS) != 0)
|
||||
{
|
||||
/* Report not connected */
|
||||
|
||||
ninfo("Lost connection\n");
|
||||
|
||||
tcp_lost_connection(sinfo->s_sock, flags);
|
||||
/* Report the disconnection event to all socket clones */
|
||||
|
||||
tcp_lost_connection(sinfo->s_sock, sinfo->s_cb, flags);
|
||||
sinfo->s_result = -ENOTCONN;
|
||||
goto end_wait;
|
||||
}
|
||||
|
@ -62,6 +62,15 @@
|
||||
* Description:
|
||||
* Performs the low level, common portion of net_dupsd() and net_dupsd2()
|
||||
*
|
||||
* Input Parameters:
|
||||
* psock1 - The existing socket that is being cloned.
|
||||
* psock2 - A reference to an uninitialized socket structure alloated by
|
||||
* the caller.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned on
|
||||
* any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int net_clone(FAR struct socket *psock1, FAR struct socket *psock2)
|
||||
|
@ -557,10 +557,12 @@ int tcp_start_monitor(FAR struct socket *psock);
|
||||
* Name: tcp_stop_monitor
|
||||
*
|
||||
* Description:
|
||||
* Stop monitoring TCP connection changes for a given socket
|
||||
* Stop monitoring TCP connection changes for a sockets associated with
|
||||
* a given TCP connection stucture.
|
||||
*
|
||||
* Input Parameters:
|
||||
* conn - The TCP connection of interest
|
||||
* flags Set of disconnection events
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
@ -571,27 +573,33 @@ int tcp_start_monitor(FAR struct socket *psock);
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void tcp_stop_monitor(FAR struct tcp_conn_s *conn);
|
||||
void tcp_stop_monitor(FAR struct tcp_conn_s *conn, uint16_t flags);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tcp_lost_connection
|
||||
*
|
||||
* Description:
|
||||
* Called when a loss-of-connection event has occurred.
|
||||
* Called when a loss-of-connection event has been detected by network
|
||||
* "interrupt" handling logic. Perform operations like tcp_stop_monitor
|
||||
* but (1) explicitly amek this socket and (2) disable further callbacks
|
||||
* the "interrupt handler".
|
||||
*
|
||||
* Parameters:
|
||||
* psock The TCP socket structure associated.
|
||||
* flags Set of connection events events
|
||||
* psock - The TCP socket structure associated.
|
||||
* cb - devif callback structure
|
||||
* flags - Set of connection events events
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* The caller holds the network lock.
|
||||
* The caller holds the network lock (if not, it will be locked momentarily
|
||||
* by this function).
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void tcp_lost_connection(FAR struct socket *psock, uint16_t flags);
|
||||
void tcp_lost_connection(FAR struct socket *psock,
|
||||
FAR struct devif_callback_s *cb, uint16_t flags);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tcp_ipv4_select
|
||||
|
@ -152,7 +152,7 @@ static void psock_teardown_callbacks(FAR struct tcp_connect_s *pstate,
|
||||
{
|
||||
/* Failed to connect. Stop the connection event monitor */
|
||||
|
||||
tcp_stop_monitor(conn);
|
||||
tcp_stop_monitor(conn, TCP_CLOSE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -411,7 +411,7 @@ int psock_tcp_connect(FAR struct socket *psock,
|
||||
* happen in this context, but just in case...
|
||||
*/
|
||||
|
||||
tcp_lost_connection(psock, TCP_ABORT);
|
||||
tcp_stop_monitor(psock->s_conn, TCP_ABORT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -302,11 +302,12 @@ int tcp_start_monitor(FAR struct socket *psock)
|
||||
* Name: tcp_stop_monitor
|
||||
*
|
||||
* Description:
|
||||
* Stop monitoring TCP connection changes for a given socket. This is part
|
||||
* of a graceful shutdown.
|
||||
* Stop monitoring TCP connection changes for a sockets associated with
|
||||
* a given TCP connection stucture.
|
||||
*
|
||||
* Input Parameters:
|
||||
* conn - The TCP connection of interest
|
||||
* flags Set of disconnection events
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
@ -317,24 +318,27 @@ int tcp_start_monitor(FAR struct socket *psock)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void tcp_stop_monitor(FAR struct tcp_conn_s *conn)
|
||||
void tcp_stop_monitor(FAR struct tcp_conn_s *conn, uint16_t flags)
|
||||
{
|
||||
DEBUGASSERT(conn != NULL);
|
||||
|
||||
/* Stop the network monitor */
|
||||
|
||||
tcp_shutdown_monitor(conn, TCP_CLOSE);
|
||||
tcp_shutdown_monitor(conn, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tcp_lost_connection
|
||||
*
|
||||
* Description:
|
||||
* Called when a loss-of-connection event has occurred. This is for an
|
||||
* unexpected disconnection of some sort from the host.
|
||||
* Called when a loss-of-connection event has been detected by network
|
||||
* "interrupt" handling logic. Perform operations like tcp_stop_monitor
|
||||
* but (1) explicitly amek this socket and (2) disable further callbacks
|
||||
* the "interrupt handler".
|
||||
*
|
||||
* Parameters:
|
||||
* psock - The TCP socket structure associated.
|
||||
* cb - devif callback structure
|
||||
* flags - Set of connection events events
|
||||
*
|
||||
* Returned Value:
|
||||
@ -346,11 +350,26 @@ void tcp_stop_monitor(FAR struct tcp_conn_s *conn)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void tcp_lost_connection(FAR struct socket *psock, uint16_t flags)
|
||||
void tcp_lost_connection(FAR struct socket *psock,
|
||||
FAR struct devif_callback_s *cb, uint16_t flags)
|
||||
{
|
||||
DEBUGASSERT(psock != NULL && psock->s_conn != NULL);
|
||||
|
||||
/* Stop the network monitor */
|
||||
/* Nullify the callback structure so that recursive callbacks are not
|
||||
* received by the "interrupt handler" due to disconnection processing.
|
||||
*/
|
||||
|
||||
cb->flags = 0;
|
||||
cb->priv = NULL;
|
||||
cb->event = NULL;
|
||||
|
||||
/* Make sure that this socket is explicitly marked. It may not bet a
|
||||
* callback due to the above nullification.
|
||||
*/
|
||||
|
||||
tcp_close_connection(psock, flags);
|
||||
|
||||
/* Then stop the network monitor */
|
||||
|
||||
tcp_shutdown_monitor((FAR struct tcp_conn_s *)psock->s_conn, flags);
|
||||
}
|
||||
|
@ -73,8 +73,8 @@ struct tcp_poll_s
|
||||
* Name: tcp_poll_interrupt
|
||||
*
|
||||
* Description:
|
||||
* This function is called from the interrupt level to perform the actual
|
||||
* TCP receive operation via by the device interface layer.
|
||||
* This function is called to perform the actual TCP receive operation via
|
||||
* the device interface layer.
|
||||
*
|
||||
* Parameters:
|
||||
* dev The structure of the network driver that caused the interrupt
|
||||
@ -124,14 +124,20 @@ static uint16_t tcp_poll_interrupt(FAR struct net_driver_s *dev, FAR void *conn,
|
||||
{
|
||||
/* Mark that the connection has been lost */
|
||||
|
||||
tcp_lost_connection(info->psock, flags);
|
||||
tcp_lost_connection(info->psock, pstate->cb, flags);
|
||||
eventset |= (POLLERR | POLLHUP);
|
||||
}
|
||||
|
||||
/* Awaken the caller of poll() if requested event occurred. */
|
||||
|
||||
if (eventset)
|
||||
if (eventset != 0)
|
||||
{
|
||||
/* Stop further callbacks */
|
||||
|
||||
pstate->cb->flags = 0;
|
||||
pstate->cb->priv = NULL;
|
||||
pstate->cb->event = NULL;
|
||||
|
||||
info->fds->revents |= eventset;
|
||||
sem_post(info->fds->sem);
|
||||
}
|
||||
|
@ -515,7 +515,7 @@ static uint16_t psock_send_interrupt(FAR struct net_driver_s *dev,
|
||||
{
|
||||
/* Report not connected */
|
||||
|
||||
tcp_lost_connection(psock, flags);
|
||||
tcp_lost_connection(psock, psock->s_sndcb, flags);
|
||||
}
|
||||
|
||||
/* Free write buffers and terminate polling */
|
||||
@ -1030,14 +1030,14 @@ ssize_t psock_tcp_send(FAR struct socket *psock, FAR const void *buf,
|
||||
|
||||
/* Allocate resources to receive a callback */
|
||||
|
||||
if (!psock->s_sndcb)
|
||||
if (psock->s_sndcb == NULL)
|
||||
{
|
||||
psock->s_sndcb = tcp_callback_alloc(conn);
|
||||
}
|
||||
|
||||
/* Test if the callback has been allocated */
|
||||
|
||||
if (!psock->s_sndcb)
|
||||
if (psock->s_sndcb == NULL)
|
||||
{
|
||||
/* A buffer allocation error occurred */
|
||||
|
||||
|
@ -396,11 +396,11 @@ static uint16_t tcpsend_interrupt(FAR struct net_driver_s *dev,
|
||||
|
||||
else if ((flags & TCP_DISCONN_EVENTS) != 0)
|
||||
{
|
||||
/* Report not connected */
|
||||
|
||||
ninfo("Lost connection\n");
|
||||
|
||||
tcp_lost_connection(pstate->snd_sock, flags);
|
||||
/* Report not connected */
|
||||
|
||||
tcp_lost_connection(pstate->snd_sock, pstate->snd_cb, flags);
|
||||
pstate->snd_sent = -ENOTCONN;
|
||||
goto end_wait;
|
||||
}
|
||||
|
@ -222,14 +222,20 @@ static uint16_t ack_interrupt(FAR struct net_driver_s *dev, FAR void *pvconn,
|
||||
|
||||
else if ((flags & TCP_DISCONN_EVENTS) != 0)
|
||||
{
|
||||
/* Report not connected */
|
||||
|
||||
nwarn("WARNING: Lost connection\n");
|
||||
|
||||
tcp_lost_connection(pstate->snd_sock, flags);
|
||||
/* Report not connected */
|
||||
|
||||
tcp_lost_connection(pstate->snd_sock, pstate->snd_ackcb, flags);
|
||||
pstate->snd_sent = -ENOTCONN;
|
||||
}
|
||||
|
||||
/* Prohibit further callbacks */
|
||||
|
||||
pstate->snd_ackcb->flags = 0;
|
||||
pstate->snd_ackcb->priv = NULL;
|
||||
pstate->snd_ackcb->event = NULL;
|
||||
|
||||
/* Wake up the waiting thread */
|
||||
|
||||
sem_post(&pstate->snd_sem);
|
||||
@ -344,11 +350,11 @@ static uint16_t sendfile_interrupt(FAR struct net_driver_s *dev, FAR void *pvcon
|
||||
|
||||
if ((flags & TCP_DISCONN_EVENTS) != 0)
|
||||
{
|
||||
/* Report not connected */
|
||||
|
||||
nwarn("WARNING: Lost connection\n");
|
||||
|
||||
tcp_lost_connection(pstate->snd_sock, flags);
|
||||
/* Report not connected */
|
||||
|
||||
tcp_lost_connection(pstate->snd_sock, pstate->snd_datacb, flags);
|
||||
pstate->snd_sent = -ENOTCONN;
|
||||
goto end_wait;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user