2012-02-22 17:03:10 +01:00
|
|
|
/****************************************************************************
|
2017-08-29 16:40:13 +02:00
|
|
|
* net/tcp/tcp_monitor.c
|
2012-02-22 17:03:10 +01:00
|
|
|
*
|
2024-09-11 14:39:39 +02:00
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
|
*
|
2021-02-19 12:45:37 +01:00
|
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
|
|
* contributor license agreements. See the NOTICE file distributed with
|
|
|
|
* this work for additional information regarding copyright ownership. The
|
|
|
|
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
|
|
* "License"); you may not use this file except in compliance with the
|
|
|
|
* License. You may obtain a copy of the License at
|
2012-02-22 17:03:10 +01:00
|
|
|
*
|
2021-02-19 12:45:37 +01:00
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
2012-02-22 17:03:10 +01:00
|
|
|
*
|
2021-02-19 12:45:37 +01:00
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
|
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
|
|
* License for the specific language governing permissions and limitations
|
|
|
|
* under the License.
|
2012-02-22 17:03:10 +01:00
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Included Files
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#include <nuttx/config.h>
|
|
|
|
|
|
|
|
#include <stdint.h>
|
2012-04-23 22:33:25 +02:00
|
|
|
#include <assert.h>
|
2012-02-22 17:03:10 +01:00
|
|
|
#include <debug.h>
|
|
|
|
|
2014-06-26 17:32:39 +02:00
|
|
|
#include <nuttx/net/tcp.h>
|
|
|
|
|
2014-06-29 02:07:02 +02:00
|
|
|
#include "devif/devif.h"
|
2014-07-06 20:34:27 +02:00
|
|
|
#include "socket/socket.h"
|
2017-08-29 16:40:13 +02:00
|
|
|
#include "tcp/tcp.h"
|
2012-02-22 17:03:10 +01:00
|
|
|
|
2017-03-31 16:58:14 +02:00
|
|
|
#ifdef NET_TCP_HAVE_STACK
|
|
|
|
|
2012-02-22 17:03:10 +01:00
|
|
|
/****************************************************************************
|
|
|
|
* Private Function Prototypes
|
|
|
|
****************************************************************************/
|
|
|
|
|
2022-02-08 17:08:15 +01:00
|
|
|
static void tcp_close_connection(FAR struct tcp_conn_s *conn,
|
|
|
|
uint16_t flags);
|
2021-08-10 14:42:35 +02:00
|
|
|
static uint16_t tcp_monitor_event(FAR struct net_driver_s *dev,
|
2022-08-25 15:17:57 +02:00
|
|
|
FAR void *pvpriv, uint16_t flags);
|
2012-02-22 17:03:10 +01:00
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Private Functions
|
|
|
|
****************************************************************************/
|
2016-02-26 14:35:55 +01:00
|
|
|
|
2015-05-30 19:49:55 +02:00
|
|
|
/****************************************************************************
|
2017-08-29 18:38:01 +02:00
|
|
|
* Name: tcp_close_connection
|
2015-05-30 19:49:55 +02:00
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Called when a loss-of-connection event has occurred.
|
|
|
|
*
|
2018-03-13 16:52:27 +01:00
|
|
|
* Input Parameters:
|
2022-02-08 17:08:15 +01:00
|
|
|
* conn The TCP connection structure
|
2015-05-30 19:49:55 +02:00
|
|
|
* flags Set of connection events events
|
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
* None
|
|
|
|
*
|
|
|
|
* Assumptions:
|
|
|
|
* The caller holds the network lock.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
2022-02-08 17:08:15 +01:00
|
|
|
static void tcp_close_connection(FAR struct tcp_conn_s *conn, uint16_t flags)
|
2015-05-30 19:49:55 +02:00
|
|
|
{
|
|
|
|
/* These loss-of-connection events may be reported:
|
|
|
|
*
|
|
|
|
* TCP_CLOSE: The remote host has closed the connection
|
|
|
|
* TCP_ABORT: The remote host has aborted the connection
|
|
|
|
* TCP_TIMEDOUT: Connection aborted due to too many retransmissions.
|
|
|
|
* NETDEV_DOWN: The network device went down
|
|
|
|
*
|
|
|
|
* And we need to set these two socket status bits appropriately:
|
|
|
|
*
|
|
|
|
* _SF_CONNECTED==1 && _SF_CLOSED==0 - the socket is connected
|
2019-03-11 19:48:17 +01:00
|
|
|
* _SF_CONNECTED==0 && _SF_CLOSED==1 - the socket was gracefully
|
|
|
|
* disconnected
|
2015-05-30 19:49:55 +02:00
|
|
|
* _SF_CONNECTED==0 && _SF_CLOSED==0 - the socket was rudely disconnected
|
|
|
|
*/
|
|
|
|
|
|
|
|
if ((flags & TCP_CLOSE) != 0)
|
|
|
|
{
|
|
|
|
/* The peer gracefully closed the connection. Marking the
|
|
|
|
* connection as disconnected will suppress some subsequent
|
|
|
|
* ENOTCONN errors from receive. A graceful disconnection is
|
|
|
|
* not handle as an error but as an "end-of-file"
|
|
|
|
*/
|
|
|
|
|
2022-02-08 17:08:15 +01:00
|
|
|
conn->sconn.s_flags &= ~_SF_CONNECTED;
|
|
|
|
conn->sconn.s_flags |= _SF_CLOSED;
|
2015-05-30 19:49:55 +02:00
|
|
|
}
|
|
|
|
else if ((flags & (TCP_ABORT | TCP_TIMEDOUT | NETDEV_DOWN)) != 0)
|
|
|
|
{
|
2019-03-11 19:48:17 +01:00
|
|
|
/* The loss of connection was less than graceful. This will
|
|
|
|
* (eventually) be reported as an ENOTCONN error.
|
2015-05-30 19:49:55 +02:00
|
|
|
*/
|
|
|
|
|
2022-02-08 17:08:15 +01:00
|
|
|
conn->sconn.s_flags &= ~(_SF_CONNECTED | _SF_CLOSED);
|
2015-05-30 19:49:55 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-22 17:03:10 +01:00
|
|
|
/****************************************************************************
|
2021-08-10 14:42:35 +02:00
|
|
|
* Name: tcp_monitor_event
|
2012-02-22 17:03:10 +01:00
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Some connection related event has occurred
|
|
|
|
*
|
2018-03-13 16:52:27 +01:00
|
|
|
* Input Parameters:
|
2015-05-30 19:29:47 +02:00
|
|
|
* dev The device which as active when the event was detected.
|
2022-08-25 15:17:57 +02:00
|
|
|
* pvpriv An instance of struct tcp_conn_s cast to void*
|
2012-02-22 17:03:10 +01:00
|
|
|
* flags Set of events describing why the callback was invoked
|
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
* None
|
|
|
|
*
|
|
|
|
* Assumptions:
|
2015-05-30 19:29:47 +02:00
|
|
|
* The network is locked.
|
2012-02-22 17:03:10 +01:00
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
2021-08-10 14:42:35 +02:00
|
|
|
static uint16_t tcp_monitor_event(FAR struct net_driver_s *dev,
|
2022-08-25 15:17:57 +02:00
|
|
|
FAR void *pvpriv, uint16_t flags)
|
2012-02-22 17:03:10 +01:00
|
|
|
{
|
2022-02-08 17:08:15 +01:00
|
|
|
FAR struct tcp_conn_s *conn = pvpriv;
|
2012-02-22 17:03:10 +01:00
|
|
|
|
2022-02-08 17:08:15 +01:00
|
|
|
if (conn != NULL)
|
2012-02-22 17:03:10 +01:00
|
|
|
{
|
2022-02-08 17:08:15 +01:00
|
|
|
ninfo("flags: %04x s_flags: %02x\n", flags, conn->sconn.s_flags);
|
2012-02-22 17:03:10 +01:00
|
|
|
|
2015-05-30 17:12:27 +02:00
|
|
|
/* TCP_DISCONN_EVENTS: TCP_CLOSE, TCP_ABORT, TCP_TIMEDOUT, or
|
|
|
|
* NETDEV_DOWN. All loss-of-connection events.
|
|
|
|
*/
|
2012-02-22 17:03:10 +01:00
|
|
|
|
2015-05-30 17:12:27 +02:00
|
|
|
if ((flags & TCP_DISCONN_EVENTS) != 0)
|
2012-02-22 17:03:10 +01:00
|
|
|
{
|
2022-02-08 17:08:15 +01:00
|
|
|
tcp_close_connection(conn, flags);
|
2012-02-22 17:03:10 +01:00
|
|
|
}
|
|
|
|
|
2014-07-07 01:22:02 +02:00
|
|
|
/* TCP_CONNECTED: The socket is successfully connected */
|
2012-02-22 17:03:10 +01:00
|
|
|
|
2014-07-07 01:22:02 +02:00
|
|
|
else if ((flags & TCP_CONNECTED) != 0)
|
2012-02-22 17:03:10 +01:00
|
|
|
{
|
2015-08-27 18:38:43 +02:00
|
|
|
#if 0 /* REVISIT: Assertion fires. Why? */
|
2023-05-08 16:11:04 +02:00
|
|
|
FAR struct tcp_conn_s *conn = psock->s_conn;
|
2015-08-27 18:38:43 +02:00
|
|
|
|
|
|
|
/* Make sure that this is the device bound to the connection */
|
|
|
|
|
|
|
|
DEBUGASSERT(conn->dev == NULL || conn->dev == dev);
|
|
|
|
conn->dev = dev;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* If there is no local address assigned to the socket (perhaps
|
|
|
|
* because it was INADDR_ANY), then assign it the address of the
|
|
|
|
* connecting device.
|
|
|
|
*
|
|
|
|
* TODO: Implement this.
|
|
|
|
*/
|
|
|
|
|
2021-08-10 14:42:35 +02:00
|
|
|
/* Clear the socket error */
|
|
|
|
|
2022-11-24 12:15:10 +01:00
|
|
|
_SO_CONN_SETERRNO(conn, OK);
|
2021-08-10 14:42:35 +02:00
|
|
|
|
2012-02-22 17:03:10 +01:00
|
|
|
/* Indicate that the socket is now connected */
|
|
|
|
|
2022-02-08 17:08:15 +01:00
|
|
|
conn->sconn.s_flags |= (_SF_BOUND | _SF_CONNECTED);
|
|
|
|
conn->sconn.s_flags &= ~_SF_CLOSED;
|
2012-02-22 17:03:10 +01:00
|
|
|
}
|
|
|
|
}
|
2015-05-30 19:29:47 +02:00
|
|
|
|
|
|
|
return flags;
|
2012-02-22 17:03:10 +01:00
|
|
|
}
|
|
|
|
|
2017-08-29 18:38:01 +02:00
|
|
|
/****************************************************************************
|
|
|
|
* Name: tcp_shutdown_monitor
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Stop monitoring TCP connection changes for a given socket.
|
|
|
|
*
|
|
|
|
* Input Parameters:
|
|
|
|
* conn - The TCP connection of interest
|
|
|
|
* flags - Indicates the type of shutdown. TCP_CLOSE or TCP_ABORT
|
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
* None
|
|
|
|
*
|
|
|
|
* Assumptions:
|
|
|
|
* The caller holds the network lock (if not, it will be locked momentarily
|
|
|
|
* by this function).
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
2018-03-12 17:59:46 +01:00
|
|
|
static void tcp_shutdown_monitor(FAR struct tcp_conn_s *conn, uint16_t flags)
|
2017-08-29 18:38:01 +02:00
|
|
|
{
|
|
|
|
/* Perform callbacks to assure that all sockets, including dup'ed copies,
|
|
|
|
* are informed of the loss of connection event.
|
|
|
|
*/
|
|
|
|
|
|
|
|
net_lock();
|
|
|
|
|
2018-10-30 01:00:30 +01:00
|
|
|
/* Free all allocated connection event callback structures */
|
2017-08-29 18:38:01 +02:00
|
|
|
|
|
|
|
while (conn->connevents != NULL)
|
|
|
|
{
|
|
|
|
devif_conn_callback_free(conn->dev, conn->connevents,
|
net/devif/devif_callback.c: corrected the connection event list to work as FIFO instead of LIFO.
In case of enabled packet forwarding mode, packets were forwarded in a reverse order
because of LIFO behavior of the connection event list.
The issue exposed only during high network traffic. Thus the event list started to grow
that resulted in changing the order of packets inside of groups of several packets
like the following: 3, 2, 1, 6, 5, 4, 8, 7 etc.
Remarks concerning the connection event list implementation:
* Now the queue (list) is FIFO as it should be.
* The list is singly linked.
* The list has a head pointer (inside of outer net_driver_s structure),
and a tail pointer is added into outer net_driver_s structure.
* The list item is devif_callback_s structure.
It still has two pointers to two different list chains (*nxtconn and *nxtdev).
* As before the first argument (*dev) of the list functions can be NULL,
while the other argument (*list) is effective (not NULL).
* An extra (*tail) argument is added to devif_callback_alloc()
and devif_conn_callback_free() functions.
* devif_callback_alloc() time complexity is O(1) (i.e. O(n) to fill the whole list).
* devif_callback_free() time complexity is O(n) (i.e. O(n^2) to empty the whole list).
* devif_conn_event() time complexity is O(n).
2021-08-29 22:57:26 +02:00
|
|
|
&conn->connevents,
|
|
|
|
&conn->connevents_tail);
|
2017-08-29 18:38:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
net_unlock();
|
|
|
|
}
|
|
|
|
|
2012-02-22 17:03:10 +01:00
|
|
|
/****************************************************************************
|
|
|
|
* Public Functions
|
|
|
|
****************************************************************************/
|
2017-08-29 18:38:01 +02:00
|
|
|
|
2012-02-22 17:03:10 +01:00
|
|
|
/****************************************************************************
|
2017-08-29 16:40:13 +02:00
|
|
|
* Name: tcp_start_monitor
|
2012-02-22 17:03:10 +01:00
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Set up to receive TCP connection state changes for a given socket
|
|
|
|
*
|
|
|
|
* Input Parameters:
|
|
|
|
* psock - The socket of interest
|
|
|
|
*
|
|
|
|
* Returned Value:
|
2017-08-29 16:40:13 +02:00
|
|
|
* On success, tcp_start_monitor returns OK; On any failure,
|
|
|
|
* tcp_start_monitor will return a negated errno value. The only failure
|
2015-05-28 16:23:51 +02:00
|
|
|
* that can occur is if the socket has already been closed and, in this
|
|
|
|
* case, -ENOTCONN is returned.
|
|
|
|
*
|
|
|
|
* Assumptions:
|
2015-05-30 19:29:47 +02:00
|
|
|
* The caller holds the network lock (if not, it will be locked momentarily
|
|
|
|
* by this function).
|
2012-02-22 17:03:10 +01:00
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
2017-08-29 16:40:13 +02:00
|
|
|
int tcp_start_monitor(FAR struct socket *psock)
|
2012-02-22 17:03:10 +01:00
|
|
|
{
|
2015-05-30 19:29:47 +02:00
|
|
|
FAR struct devif_callback_s *cb;
|
2021-08-10 14:42:35 +02:00
|
|
|
FAR struct tcp_conn_s *conn;
|
|
|
|
bool nonblock_conn;
|
2012-02-22 17:03:10 +01:00
|
|
|
|
2023-05-08 16:11:04 +02:00
|
|
|
conn = psock->s_conn;
|
2012-02-22 17:03:10 +01:00
|
|
|
|
2021-08-10 14:42:35 +02:00
|
|
|
net_lock();
|
|
|
|
|
|
|
|
/* Non-blocking connection ? */
|
|
|
|
|
|
|
|
nonblock_conn = (conn->tcpstateflags == TCP_SYN_SENT &&
|
2022-02-08 06:18:01 +01:00
|
|
|
_SS_ISNONBLOCK(conn->sconn.s_flags));
|
2021-08-10 14:42:35 +02:00
|
|
|
|
2015-05-28 16:23:51 +02:00
|
|
|
/* Check if the connection has already been closed before any callbacks
|
|
|
|
* have been registered. (Maybe the connection is lost before accept has
|
|
|
|
* registered the monitoring callback.)
|
2013-09-06 16:25:03 +02:00
|
|
|
*/
|
|
|
|
|
2014-07-07 00:10:26 +02:00
|
|
|
if (!(conn->tcpstateflags == TCP_ESTABLISHED ||
|
2021-08-10 14:42:35 +02:00
|
|
|
conn->tcpstateflags == TCP_SYN_RCVD || nonblock_conn))
|
2013-09-06 16:25:03 +02:00
|
|
|
{
|
2015-05-28 16:23:51 +02:00
|
|
|
/* Invoke the TCP_CLOSE connection event now */
|
|
|
|
|
2017-08-29 18:38:01 +02:00
|
|
|
tcp_shutdown_monitor(conn, TCP_CLOSE);
|
2015-05-28 16:23:51 +02:00
|
|
|
|
2023-04-17 16:01:32 +02:00
|
|
|
/* If the peer close the connection before we call accept,
|
|
|
|
* in order to allow user to read the readahead data,
|
|
|
|
* return OK.
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (conn->tcpstateflags == TCP_CLOSED ||
|
|
|
|
conn->tcpstateflags == TCP_LAST_ACK)
|
|
|
|
{
|
|
|
|
net_unlock();
|
|
|
|
return OK;
|
|
|
|
}
|
|
|
|
|
2017-05-11 21:35:56 +02:00
|
|
|
/* And return -ENOTCONN to indicate the monitor was not started
|
2015-05-28 16:23:51 +02:00
|
|
|
* because the socket was already disconnected.
|
|
|
|
*/
|
|
|
|
|
2016-12-03 23:28:19 +01:00
|
|
|
net_unlock();
|
2015-05-28 16:23:51 +02:00
|
|
|
return -ENOTCONN;
|
2013-09-06 16:25:03 +02:00
|
|
|
}
|
|
|
|
|
2015-05-30 19:29:47 +02:00
|
|
|
/* Allocate a callback structure that we will use to get callbacks if
|
|
|
|
* the network goes down.
|
|
|
|
*/
|
|
|
|
|
net/devif/devif_callback.c: corrected the connection event list to work as FIFO instead of LIFO.
In case of enabled packet forwarding mode, packets were forwarded in a reverse order
because of LIFO behavior of the connection event list.
The issue exposed only during high network traffic. Thus the event list started to grow
that resulted in changing the order of packets inside of groups of several packets
like the following: 3, 2, 1, 6, 5, 4, 8, 7 etc.
Remarks concerning the connection event list implementation:
* Now the queue (list) is FIFO as it should be.
* The list is singly linked.
* The list has a head pointer (inside of outer net_driver_s structure),
and a tail pointer is added into outer net_driver_s structure.
* The list item is devif_callback_s structure.
It still has two pointers to two different list chains (*nxtconn and *nxtdev).
* As before the first argument (*dev) of the list functions can be NULL,
while the other argument (*list) is effective (not NULL).
* An extra (*tail) argument is added to devif_callback_alloc()
and devif_conn_callback_free() functions.
* devif_callback_alloc() time complexity is O(1) (i.e. O(n) to fill the whole list).
* devif_callback_free() time complexity is O(n) (i.e. O(n^2) to empty the whole list).
* devif_conn_event() time complexity is O(n).
2021-08-29 22:57:26 +02:00
|
|
|
cb = devif_callback_alloc(conn->dev,
|
|
|
|
&conn->connevents,
|
|
|
|
&conn->connevents_tail);
|
2015-05-30 19:29:47 +02:00
|
|
|
if (cb != NULL)
|
|
|
|
{
|
2021-08-10 14:42:35 +02:00
|
|
|
cb->event = tcp_monitor_event;
|
2022-02-08 17:08:15 +01:00
|
|
|
cb->priv = (FAR void *)conn;
|
2017-08-29 18:38:01 +02:00
|
|
|
cb->flags = TCP_DISCONN_EVENTS;
|
2021-08-10 14:42:35 +02:00
|
|
|
|
|
|
|
/* Monitor the connected event */
|
|
|
|
|
|
|
|
if (nonblock_conn)
|
|
|
|
{
|
|
|
|
cb->flags |= TCP_CONNECTED;
|
|
|
|
}
|
2015-05-30 19:29:47 +02:00
|
|
|
}
|
|
|
|
|
2016-12-03 23:28:19 +01:00
|
|
|
net_unlock();
|
2012-02-22 17:03:10 +01:00
|
|
|
return OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************
|
2017-08-29 16:40:13 +02:00
|
|
|
* Name: tcp_stop_monitor
|
2012-02-22 17:03:10 +01:00
|
|
|
*
|
|
|
|
* Description:
|
2017-08-29 20:27:58 +02:00
|
|
|
* Stop monitoring TCP connection changes for a sockets associated with
|
2020-02-22 19:31:14 +01:00
|
|
|
* a given TCP connection structure.
|
2012-02-22 17:03:10 +01:00
|
|
|
*
|
|
|
|
* Input Parameters:
|
|
|
|
* conn - The TCP connection of interest
|
2017-08-29 20:27:58 +02:00
|
|
|
* flags Set of disconnection events
|
2012-02-22 17:03:10 +01:00
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
* None
|
|
|
|
*
|
2015-05-30 19:29:47 +02:00
|
|
|
* Assumptions:
|
|
|
|
* The caller holds the network lock (if not, it will be locked momentarily
|
|
|
|
* by this function).
|
|
|
|
*
|
2012-02-22 17:03:10 +01:00
|
|
|
****************************************************************************/
|
|
|
|
|
2017-08-29 20:27:58 +02:00
|
|
|
void tcp_stop_monitor(FAR struct tcp_conn_s *conn, uint16_t flags)
|
2012-02-22 17:03:10 +01:00
|
|
|
{
|
2017-08-29 18:38:01 +02:00
|
|
|
DEBUGASSERT(conn != NULL);
|
2015-05-30 19:29:47 +02:00
|
|
|
|
2017-08-29 18:38:01 +02:00
|
|
|
/* Stop the network monitor */
|
2015-05-30 19:29:47 +02:00
|
|
|
|
2017-08-29 20:27:58 +02:00
|
|
|
tcp_shutdown_monitor(conn, flags);
|
2012-02-22 17:03:10 +01:00
|
|
|
}
|
|
|
|
|
2013-01-20 18:21:42 +01:00
|
|
|
/****************************************************************************
|
2017-08-29 16:40:13 +02:00
|
|
|
* Name: tcp_lost_connection
|
2013-01-20 18:21:42 +01:00
|
|
|
*
|
|
|
|
* Description:
|
2017-08-29 20:27:58 +02:00
|
|
|
* Called when a loss-of-connection event has been detected by network
|
2017-08-29 22:08:04 +02:00
|
|
|
* event handling logic. Perform operations like tcp_stop_monitor but (1)
|
|
|
|
* explicitly mark this socket and (2) disable further callbacks the to the
|
|
|
|
* event handler.
|
2013-01-20 18:21:42 +01:00
|
|
|
*
|
2018-03-13 16:52:27 +01:00
|
|
|
* Input Parameters:
|
2022-02-08 17:08:15 +01:00
|
|
|
* conn - The TCP connection of interest
|
2017-08-29 20:27:58 +02:00
|
|
|
* cb - devif callback structure
|
2017-08-29 18:38:01 +02:00
|
|
|
* flags - Set of connection events events
|
2013-01-20 18:21:42 +01:00
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
* None
|
|
|
|
*
|
|
|
|
* Assumptions:
|
2015-05-30 19:49:55 +02:00
|
|
|
* The caller holds the network lock (if not, it will be locked momentarily
|
|
|
|
* by this function).
|
2013-01-20 18:21:42 +01:00
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
2022-02-08 17:08:15 +01:00
|
|
|
void tcp_lost_connection(FAR struct tcp_conn_s *conn,
|
2017-08-29 20:27:58 +02:00
|
|
|
FAR struct devif_callback_s *cb, uint16_t flags)
|
2013-01-20 18:21:42 +01:00
|
|
|
{
|
2022-02-08 17:08:15 +01:00
|
|
|
DEBUGASSERT(conn != NULL);
|
2013-01-20 18:21:42 +01:00
|
|
|
|
2017-08-29 20:27:58 +02:00
|
|
|
/* Nullify the callback structure so that recursive callbacks are not
|
2017-08-29 22:08:04 +02:00
|
|
|
* received by the event handler due to disconnection processing.
|
2017-10-13 14:47:09 +02:00
|
|
|
*
|
|
|
|
* NOTE: In a configuration with CONFIG_NET_TCP_WRITE_BUFFERS=y,
|
|
|
|
* the "semi-permanent" callback structure may have already been
|
|
|
|
* nullified.
|
2017-08-29 20:27:58 +02:00
|
|
|
*/
|
|
|
|
|
2017-10-13 14:47:09 +02:00
|
|
|
if (cb != NULL)
|
|
|
|
{
|
|
|
|
cb->flags = 0;
|
|
|
|
cb->priv = NULL;
|
|
|
|
cb->event = NULL;
|
|
|
|
}
|
2017-08-29 20:27:58 +02:00
|
|
|
|
2017-08-29 21:24:49 +02:00
|
|
|
/* Make sure that this socket is explicitly marked. It may not get a
|
2017-08-29 20:27:58 +02:00
|
|
|
* callback due to the above nullification.
|
|
|
|
*/
|
|
|
|
|
2022-02-08 17:08:15 +01:00
|
|
|
tcp_close_connection(conn, flags);
|
2017-08-29 20:27:58 +02:00
|
|
|
|
2017-08-29 21:24:49 +02:00
|
|
|
/* Then stop the network monitor for all sockets. */
|
2015-05-30 19:49:55 +02:00
|
|
|
|
2022-02-08 17:08:15 +01:00
|
|
|
tcp_shutdown_monitor(conn, flags);
|
2013-01-20 18:21:42 +01:00
|
|
|
}
|
|
|
|
|
2017-03-31 16:58:14 +02:00
|
|
|
#endif /* NET_TCP_HAVE_STACK */
|