mirror of
https://github.com/apache/nuttx.git
synced 2025-01-13 13:18:50 +08:00
net/tcp/tcp_send*: reliably obtain the TCP connection pointer in TCP event handlers
Do not use pvconn argument to get the TCP connection pointer because pvconn is normally NULL for some events like NETDEV_DOWN. Instead, the TCP connection pointer can be reliably obtained from the corresponding TCP socket.
This commit is contained in:
parent
04b27b6877
commit
5b13797cce
5 changed files with 97 additions and 41 deletions
|
@ -390,7 +390,7 @@ void devif_dev_callback_free(FAR struct net_driver_s *dev,
|
|||
* dev - The network device state structure associated with the network
|
||||
* device that initiated the callback event.
|
||||
* pvconn - Holds a reference to the TCP connection structure or the UDP
|
||||
* port structure. May be NULL if the even is not related to a TCP
|
||||
* port structure. It can be NULL if the event is not related to a TCP
|
||||
* connection or UDP port.
|
||||
* flags - The bit set of events to be notified.
|
||||
* list - The list to traverse in performing the notifications
|
||||
|
@ -416,7 +416,7 @@ uint16_t devif_conn_event(FAR struct net_driver_s *dev, FAR void *pvconn,
|
|||
* dev - The network device state structure associated with the network
|
||||
* device that initiated the callback event.
|
||||
* pvconn - Holds a reference to the TCP connection structure or the UDP
|
||||
* port structure. May be NULL if the even is not related to a TCP
|
||||
* port structure. It can be NULL if the event is not related to a TCP
|
||||
* connection or UDP port.
|
||||
* flags - The bit set of events to be notified.
|
||||
*
|
||||
|
|
|
@ -466,7 +466,7 @@ void devif_dev_callback_free(FAR struct net_driver_s *dev,
|
|||
* dev - The network device state structure associated with the network
|
||||
* device that initiated the callback event.
|
||||
* pvconn - Holds a reference to the TCP connection structure or the UDP
|
||||
* port structure. May be NULL if the even is not related to a TCP
|
||||
* port structure. It can be NULL if the event is not related to a TCP
|
||||
* connection or UDP port.
|
||||
* flags - The bit set of events to be notified.
|
||||
* list - The list to traverse in performing the notifications
|
||||
|
@ -529,7 +529,7 @@ uint16_t devif_conn_event(FAR struct net_driver_s *dev, void *pvconn,
|
|||
* dev - The network device state structure associated with the network
|
||||
* device that initiated the callback event.
|
||||
* pvconn - Holds a reference to the TCP connection structure or the UDP
|
||||
* port structure. May be NULL if the even is not related to a TCP
|
||||
* port structure. It can be NULL if the event is not related to a TCP
|
||||
* connection or UDP port.
|
||||
* flags - The bit set of events to be notified.
|
||||
*
|
||||
|
|
|
@ -355,10 +355,39 @@ static uint16_t psock_send_eventhandler(FAR struct net_driver_s *dev,
|
|||
FAR void *pvconn, FAR void *pvpriv,
|
||||
uint16_t flags)
|
||||
{
|
||||
FAR struct tcp_conn_s *conn = (FAR struct tcp_conn_s *)pvconn;
|
||||
/* FAR struct tcp_conn_s *conn = (FAR struct tcp_conn_s *)pvconn;
|
||||
*
|
||||
* Do not use pvconn argument to get the TCP connection pointer (the above
|
||||
* commented line) because pvconn is normally NULL for some events like
|
||||
* NETDEV_DOWN. Instead, the TCP connection pointer can be reliably
|
||||
* obtained from the corresponding TCP socket.
|
||||
*/
|
||||
|
||||
FAR struct socket *psock = (FAR struct socket *)pvpriv;
|
||||
FAR struct tcp_conn_s *conn;
|
||||
bool rexmit = false;
|
||||
|
||||
DEBUGASSERT(psock != NULL);
|
||||
|
||||
/* Get the TCP connection pointer reliably from
|
||||
* the corresponding TCP socket.
|
||||
*/
|
||||
|
||||
conn = psock->s_conn;
|
||||
DEBUGASSERT(conn != NULL);
|
||||
|
||||
/* The TCP socket is connected and, hence, should be bound to a device.
|
||||
* Make sure that the polling device is the one that we are bound to.
|
||||
*/
|
||||
|
||||
DEBUGASSERT(conn->dev != NULL);
|
||||
if (dev != conn->dev)
|
||||
{
|
||||
return flags;
|
||||
}
|
||||
|
||||
ninfo("flags: %04x\n", flags);
|
||||
|
||||
/* Check for a loss of connection */
|
||||
|
||||
if ((flags & TCP_DISCONN_EVENTS) != 0)
|
||||
|
@ -383,23 +412,11 @@ static uint16_t psock_send_eventhandler(FAR struct net_driver_s *dev,
|
|||
return flags;
|
||||
}
|
||||
|
||||
/* The TCP socket is connected and, hence, should be bound to a device.
|
||||
* Make sure that the polling device is the one that we are bound to.
|
||||
*/
|
||||
|
||||
DEBUGASSERT(conn->dev != NULL);
|
||||
if (dev != conn->dev)
|
||||
{
|
||||
return flags;
|
||||
}
|
||||
|
||||
ninfo("flags: %04x\n", flags);
|
||||
|
||||
/* If this packet contains an acknowledgment, then update the count of
|
||||
* acknowledged bytes.
|
||||
*/
|
||||
|
||||
if ((flags & TCP_ACKDATA) != 0)
|
||||
else if ((flags & TCP_ACKDATA) != 0)
|
||||
{
|
||||
FAR struct tcp_wrbuffer_s *wrb;
|
||||
FAR struct tcp_hdr_s *tcp;
|
||||
|
|
|
@ -170,8 +170,29 @@ static uint16_t tcpsend_eventhandler(FAR struct net_driver_s *dev,
|
|||
FAR void *pvconn,
|
||||
FAR void *pvpriv, uint16_t flags)
|
||||
{
|
||||
FAR struct tcp_conn_s *conn = (FAR struct tcp_conn_s *)pvconn;
|
||||
/* FAR struct tcp_conn_s *conn = (FAR struct tcp_conn_s *)pvconn;
|
||||
*
|
||||
* Do not use pvconn argument to get the TCP connection pointer (the above
|
||||
* commented line) because pvconn is normally NULL for some events like
|
||||
* NETDEV_DOWN. Instead, the TCP connection pointer can be reliably
|
||||
* obtained from the corresponding TCP socket.
|
||||
*/
|
||||
|
||||
FAR struct send_s *pstate = (FAR struct send_s *)pvpriv;
|
||||
FAR struct socket *psock;
|
||||
FAR struct tcp_conn_s *conn;
|
||||
|
||||
DEBUGASSERT(pstate != NULL);
|
||||
|
||||
psock = pstate->snd_sock;
|
||||
DEBUGASSERT(psock != NULL);
|
||||
|
||||
/* Get the TCP connection pointer reliably from
|
||||
* the corresponding TCP socket.
|
||||
*/
|
||||
|
||||
conn = psock->s_conn;
|
||||
DEBUGASSERT(conn != NULL);
|
||||
|
||||
/* The TCP socket is connected and, hence, should be bound to a device.
|
||||
* Make sure that the polling device is the one that we are bound to.
|
||||
|
@ -315,8 +336,6 @@ static uint16_t tcpsend_eventhandler(FAR struct net_driver_s *dev,
|
|||
|
||||
else if ((flags & TCP_DISCONN_EVENTS) != 0)
|
||||
{
|
||||
FAR struct socket *psock = pstate->snd_sock;
|
||||
|
||||
ninfo("Lost connection\n");
|
||||
|
||||
/* We could get here recursively through the callback actions of
|
||||
|
@ -324,7 +343,6 @@ static uint16_t tcpsend_eventhandler(FAR struct net_driver_s *dev,
|
|||
* already been disconnected.
|
||||
*/
|
||||
|
||||
DEBUGASSERT(psock != NULL);
|
||||
if (_SS_ISCONNECTED(psock->s_flags))
|
||||
{
|
||||
/* Report not connected */
|
||||
|
@ -403,6 +421,8 @@ end_wait:
|
|||
|
||||
/* Do not allow any further callbacks */
|
||||
|
||||
DEBUGASSERT(pstate->snd_cb != NULL);
|
||||
|
||||
pstate->snd_cb->flags = 0;
|
||||
pstate->snd_cb->priv = NULL;
|
||||
pstate->snd_cb->event = NULL;
|
||||
|
@ -509,7 +529,6 @@ ssize_t psock_tcp_send(FAR struct socket *psock,
|
|||
/* Make sure that we have the IP address mapping */
|
||||
|
||||
conn = (FAR struct tcp_conn_s *)psock->s_conn;
|
||||
DEBUGASSERT(conn);
|
||||
|
||||
#if defined(CONFIG_NET_ARP_SEND) || defined(CONFIG_NET_ICMPv6_NEIGHBOR)
|
||||
#ifdef CONFIG_NET_ARP_SEND
|
||||
|
|
|
@ -161,11 +161,44 @@ static uint16_t sendfile_eventhandler(FAR struct net_driver_s *dev,
|
|||
FAR void *pvconn, FAR void *pvpriv,
|
||||
uint16_t flags)
|
||||
{
|
||||
FAR struct tcp_conn_s *conn = (FAR struct tcp_conn_s *)pvconn;
|
||||
/* FAR struct tcp_conn_s *conn = (FAR struct tcp_conn_s *)pvconn;
|
||||
*
|
||||
* Do not use pvconn argument to get the TCP connection pointer (the above
|
||||
* commented line) because pvconn is normally NULL for some events like
|
||||
* NETDEV_DOWN. Instead, the TCP connection pointer can be reliably
|
||||
* obtained from the corresponding TCP socket.
|
||||
*/
|
||||
|
||||
FAR struct sendfile_s *pstate = (FAR struct sendfile_s *)pvpriv;
|
||||
FAR struct socket *psock = pstate->snd_sock;
|
||||
FAR struct socket *psock;
|
||||
FAR struct tcp_conn_s *conn;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(pstate != NULL);
|
||||
|
||||
psock = pstate->snd_sock;
|
||||
DEBUGASSERT(psock != NULL);
|
||||
|
||||
/* Get the TCP connection pointer reliably from
|
||||
* the corresponding TCP socket.
|
||||
*/
|
||||
|
||||
conn = psock->s_conn;
|
||||
DEBUGASSERT(conn != NULL);
|
||||
|
||||
/* The TCP socket is connected and, hence, should be bound to a device.
|
||||
* Make sure that the polling device is the own that we are bound to.
|
||||
*/
|
||||
|
||||
DEBUGASSERT(conn->dev != NULL);
|
||||
if (dev != conn->dev)
|
||||
{
|
||||
return flags;
|
||||
}
|
||||
|
||||
ninfo("flags: %04x acked: %" PRId32 " sent: %zd\n",
|
||||
flags, pstate->snd_acked, pstate->snd_sent);
|
||||
|
||||
/* Check for a loss of connection */
|
||||
|
||||
if ((flags & TCP_DISCONN_EVENTS) != 0)
|
||||
|
@ -177,7 +210,6 @@ static uint16_t sendfile_eventhandler(FAR struct net_driver_s *dev,
|
|||
* already been disconnected.
|
||||
*/
|
||||
|
||||
DEBUGASSERT(psock != NULL);
|
||||
if (_SS_ISCONNECTED(psock->s_flags))
|
||||
{
|
||||
/* Report not connected */
|
||||
|
@ -191,25 +223,11 @@ static uint16_t sendfile_eventhandler(FAR struct net_driver_s *dev,
|
|||
goto end_wait;
|
||||
}
|
||||
|
||||
/* The TCP socket is connected and, hence, should be bound to a device.
|
||||
* Make sure that the polling device is the own that we are bound to.
|
||||
*/
|
||||
|
||||
DEBUGASSERT(conn);
|
||||
DEBUGASSERT(conn->dev != NULL);
|
||||
if (dev != conn->dev)
|
||||
{
|
||||
return flags;
|
||||
}
|
||||
|
||||
ninfo("flags: %04x acked: %" PRId32 " sent: %zd\n",
|
||||
flags, pstate->snd_acked, pstate->snd_sent);
|
||||
|
||||
/* If this packet contains an acknowledgement, then update the count of
|
||||
* acknowledged bytes.
|
||||
*/
|
||||
|
||||
if ((flags & TCP_ACKDATA) != 0)
|
||||
else if ((flags & TCP_ACKDATA) != 0)
|
||||
{
|
||||
FAR struct tcp_hdr_s *tcp;
|
||||
|
||||
|
@ -363,6 +381,8 @@ end_wait:
|
|||
|
||||
/* Do not allow any further callbacks */
|
||||
|
||||
DEBUGASSERT(pstate->snd_cb != NULL);
|
||||
|
||||
pstate->snd_cb->flags = 0;
|
||||
pstate->snd_cb->priv = NULL;
|
||||
pstate->snd_cb->event = NULL;
|
||||
|
|
Loading…
Reference in a new issue