diff --git a/net/inet/inet_sockif.c b/net/inet/inet_sockif.c index 8858c6603b..061e6a6836 100644 --- a/net/inet/inet_sockif.c +++ b/net/inet/inet_sockif.c @@ -157,6 +157,12 @@ static int inet_tcp_alloc(FAR struct socket *psock) DEBUGASSERT(conn->crefs == 0); conn->crefs = 1; + /* It is expected the socket has not yet been associated with + * any other connection. + */ + + DEBUGASSERT(psock->s_conn == NULL); + /* Save the pre-allocated connection in the socket structure */ psock->s_conn = conn; diff --git a/net/tcp/Make.defs b/net/tcp/Make.defs index 702c35e682..e022836d4e 100644 --- a/net/tcp/Make.defs +++ b/net/tcp/Make.defs @@ -60,7 +60,7 @@ NET_CSRCS += tcp_recvwindow.c tcp_netpoll.c tcp_ioctl.c ifeq ($(CONFIG_NET_TCP_WRITE_BUFFERS),y) NET_CSRCS += tcp_wrbuffer.c ifeq ($(CONFIG_DEBUG_FEATURES),y) -NET_CSRCS += tcp_wrbuffer_dump.c +NET_CSRCS += tcp_dump.c endif endif diff --git a/net/tcp/tcp.h b/net/tcp/tcp.h index 030a52b387..d5ec88cfa0 100644 --- a/net/tcp/tcp.h +++ b/net/tcp/tcp.h @@ -311,6 +311,10 @@ struct tcp_conn_s /* Callback instance for TCP send() */ FAR struct devif_callback_s *sndcb; + +#ifdef CONFIG_DEBUG_ASSERTIONS + int sndcb_alloc_cnt; /* The callback allocation counter */ +#endif #endif /* accept() is called when the TCP logic has created a connection @@ -1642,6 +1646,22 @@ void tcp_wrbuffer_release(FAR struct tcp_wrbuffer_s *wrb); int tcp_wrbuffer_test(void); #endif /* CONFIG_NET_TCP_WRITE_BUFFERS */ +/**************************************************************************** + * Name: tcp_event_handler_dump + * + * Description: + * Dump the TCP event handler related variables + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_FEATURES +void tcp_event_handler_dump(FAR struct net_driver_s *dev, + FAR void *pvconn, + FAR void *pvpriv, + uint16_t flags, + FAR struct tcp_conn_s *conn); +#endif + /**************************************************************************** * Name: tcp_wrbuffer_dump * diff --git a/net/tcp/tcp_wrbuffer_dump.c b/net/tcp/tcp_dump.c similarity index 65% rename from net/tcp/tcp_wrbuffer_dump.c rename to net/tcp/tcp_dump.c index c0980e2e1d..4e5f0823bf 100644 --- a/net/tcp/tcp_wrbuffer_dump.c +++ b/net/tcp/tcp_dump.c @@ -1,5 +1,5 @@ /**************************************************************************** - * net/tcp/tcp_wrbuffer_dump.c + * net/tcp/tcp_dump.c * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -38,6 +38,33 @@ * Public Functions ****************************************************************************/ +/**************************************************************************** + * Name: tcp_event_handler_dump + * + * Description: + * Dump the TCP event handler related variables + * + ****************************************************************************/ + +void tcp_event_handler_dump(FAR struct net_driver_s *dev, + FAR void *pvconn, + FAR void *pvpriv, + uint16_t flags, + FAR struct tcp_conn_s *conn) +{ + nerr("ERROR: conn->dev == NULL or pvconn != conn:" + " dev=%p pvconn=%p pvpriv=%p flags=0x%04x" + " conn->dev=%p conn->flags=0x%04x tcpstateflags=0x%02x crefs=%d" + " isn=%" PRIu32 " sndseq=%" PRIu32 + " tx_unacked=%" PRId32 " sent=%" PRId32 + " conn=%p s_flags=0x%02x\n", + dev, pvconn, pvpriv, flags, + conn->dev, conn->flags, conn->tcpstateflags, conn->crefs, + conn->isn, tcp_getsequence(conn->sndseq), + (uint32_t)conn->tx_unacked, conn->sent, + conn, conn->sconn.s_flags); +} + /**************************************************************************** * Name: tcp_wrbuffer_dump * @@ -46,6 +73,8 @@ * ****************************************************************************/ +#ifdef CONFIG_NET_TCP_WRITE_BUFFERS + void tcp_wrbuffer_dump(FAR const char *msg, FAR struct tcp_wrbuffer_s *wrb, unsigned int len, unsigned int offset) { @@ -54,4 +83,6 @@ void tcp_wrbuffer_dump(FAR const char *msg, FAR struct tcp_wrbuffer_s *wrb, iob_dump("I/O Buffer Chain", TCP_WBIOB(wrb), len, offset); } +#endif + #endif /* CONFIG_DEBUG_FEATURES */ diff --git a/net/tcp/tcp_send_buffered.c b/net/tcp/tcp_send_buffered.c index 82f8b74b1c..cb5c62fb7c 100644 --- a/net/tcp/tcp_send_buffered.c +++ b/net/tcp/tcp_send_buffered.c @@ -371,6 +371,19 @@ static uint16_t psock_send_eventhandler(FAR struct net_driver_s *dev, DEBUGASSERT(conn != NULL); +#ifdef CONFIG_DEBUG_FEATURES + if (conn->dev == NULL || (pvconn != conn && pvconn != NULL)) + { + tcp_event_handler_dump(dev, pvconn, pvpriv, flags, conn); + } +#endif + + /* If pvconn is not NULL, make sure that pvconn refers to the same + * connection as the socket is bound to. + */ + + DEBUGASSERT(pvconn == conn || pvconn == 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. */ @@ -1171,6 +1184,20 @@ ssize_t psock_tcp_send(FAR struct socket *psock, FAR const void *buf, if (conn->sndcb == NULL) { conn->sndcb = tcp_callback_alloc(conn); + +#ifdef CONFIG_DEBUG_ASSERTIONS + if (conn->sndcb != NULL) + { + conn->sndcb_alloc_cnt++; + + /* The callback is allowed to be allocated only once. + * This is to catch a potential re-allocation after + * conn->sndcb was set to NULL. + */ + + DEBUGASSERT(conn->sndcb_alloc_cnt == 1); + } +#endif } /* Test if the callback has been allocated */ diff --git a/net/tcp/tcp_send_unbuffered.c b/net/tcp/tcp_send_unbuffered.c index f7dafa39f0..3c8d478d9f 100644 --- a/net/tcp/tcp_send_unbuffered.c +++ b/net/tcp/tcp_send_unbuffered.c @@ -196,6 +196,19 @@ static uint16_t tcpsend_eventhandler(FAR struct net_driver_s *dev, conn = psock->s_conn; DEBUGASSERT(conn != NULL); +#ifdef CONFIG_DEBUG_NET_ERROR + if (conn->dev == NULL || (pvconn != conn && pvconn != NULL)) + { + tcp_event_handler_dump(dev, pvconn, pvpriv, flags, conn); + } +#endif + + /* If pvconn is not NULL, make sure that pvconn refers to the same + * connection as the socket is bound to. + */ + + DEBUGASSERT(pvconn == conn || pvconn == 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. */ diff --git a/net/tcp/tcp_sendfile.c b/net/tcp/tcp_sendfile.c index 535dbcc0d8..509301fb75 100644 --- a/net/tcp/tcp_sendfile.c +++ b/net/tcp/tcp_sendfile.c @@ -150,6 +150,19 @@ static uint16_t sendfile_eventhandler(FAR struct net_driver_s *dev, conn = psock->s_conn; DEBUGASSERT(conn != NULL); +#ifdef CONFIG_DEBUG_NET_ERROR + if (conn->dev == NULL || (pvconn != conn && pvconn != NULL)) + { + tcp_event_handler_dump(dev, pvconn, pvpriv, flags, conn); + } +#endif + + /* If pvconn is not NULL, make sure that pvconn refers to the same + * connection as the socket is bound to. + */ + + DEBUGASSERT(pvconn == conn || pvconn == 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. */