FreeRTOS TCP/IP Stack possible memory leak?

I haven’t tried your implementation of a telnet server, but I tested my own server, just to see if there is a memory leak in the library.

If you like, here is a simple implementation of telnet: telnet.c/telnet.h.

This solution does not create any task, it wants to be called by the application.

Here is an example of how to use the telnet module:

#include "telnet.h"

#if ( ipconfigSOCKET_HAS_USER_SEMAPHORE == 0 )
    #error Please define ipconfigSOCKET_HAS_USER_SEMAPHORE as '1'
#endif

static Telnet_t xTelnet;
static SemaphoreHandle_t xServerSemaphore;

void my_application( void *pvParameter )
{
    char pcBuffer[ 128 ];

    xServerSemaphore = xSemaphoreCreateBinary();
    configASSERT( xServerSemaphore != NULL );

    xTelnetCreate( &xTelnet, TELNET_PORT_NUMBER );

    if( xTelnet.xParentSocket != 0 )
    {
        FreeRTOS_setsockopt( xTelnet.xParentSocket,
                             0,
                             FREERTOS_SO_SET_SEMAPHORE,
                             ( void * ) &xServerSemaphore,
                             sizeof( xServerSemaphore ) );
    }

    for( ;; )
    {
        /* Go asleep for at most 200 msec, the Telnet socket might give
		 * to the semaphore and wake-up this task.
         */
        xSemaphoreTake( xServerSemaphore, pdMS_TO_TICKS( 200U ) );

        if( xTelnet.xParentSocket != NULL )
        {
            struct freertos_sockaddr fromAddr;
			BaseType_t xCount;

            xCount = xTelnetRecv( &xTelnet,
                                  &fromAddr,
                                  pcBuffer,
                                  sizeof( pcBuffer ) - 1 );

            if( xCount > 0 )
            {
                pcBuffer[ xCount ] = 0;
                /* Just bounce back the string. */
                xTelnetSend( &xTelnet, &fromAddr, pcBuffer, xCount );
            }
        }
    }
}

Some general remarks, after reading your sample code:

Make sure that after calling closesocket(), the socket is not referred to any more. It is a good habit to clear the pointer:

    FreeRTOS_closesocket( pCtrl->socketClient );
    pCtrl->socketClient = NULL;

This might avoid an ugly crash.

Quite recently I wrote about the use of shutdown, when to use it and how. See my long post in this forum.

Normally, a TCP server will not shut down a connection. It is the client who initiates a graceful shutdown. The client is e.g. a telnet client or a browser.

Shutdown is applied to a connected socket, and after calling shutdown(), the socket must continue to exist because shutting down a connection takes time. On a LAN it will take a few milliseconds, but on the Internet it make take up to a few seconds.

Normally, the listening socket is created at boot time, and it continues to exist until the device goes down.
The client sockets obtained with accept() have a temporary life. use them until recv() or send() returns an error.