+tcp dns documentation

The documentation for Freertos gethostbyname is incorrect.

  1. uint32_t ulIPAddress Is the wrong signature now
  2. For the non blocking version, what is this about freeing the address? If so, the example should be updated.

I am not sure about your first point. This function does return IPv4 address using that data type. For IPv6 address, this API should be used: FreeRTOS_getaddrinfo()

For the second point, I think you are right. That should be sorted out in the doc.

My first point is that the example in the link is not compilable.

You probably want something like the following, right?

/* FreeRTOS-Plus-TCP DNS include. */  
#include "FreeRTOS_DNS.h"

BastType_t xHasIPv4Address = pdFALSE;

static void vDNS_callback( const char * pcName,
                           void * pvSearchID,
                           struct freertos_addrinfo * pxAddressInfo )
{
    if( pxAddressInfo && pxAddressInfo->ai_family == FREERTOS_AF_INET4 )
    {
        char pcBuf[ 16 ];
        uint32_t ulIPAddress;

        /* The DNS lookup has a result, or it has reached the time-out. */
        ulIPAddress = pxAddressInfo->ai_addr->sin_address.ulIP_IPv4;
        FreeRTOS_inet_ntoa( ulIPAddress, pcBuf );
        FreeRTOS_printf( ( "vDNS_callback: IP address of %s found: %s\n", pcName, pcBuf ) );

        xHasIPv4Address = pdTRUE;
        FreeRTOS_freeaddrinfo( pxAddressInfo );
    }
}

void aFunction( void )  
{
    xHasIPv4Address = pdFALSE;
    FreeRTOS_gethostbyname_a( "www.freertos.org", /* The target DNS name. */
                              vDNS_callback, /* The DNS callback function. */
                              NULL, /* Search ID for the callback function. */
                              1000 ); /* Timeout in ms. */
}

That looks good. What about the comment about freeing the address info, its really unclear what its referring to.

Are you referring to the following line:

The pxAddressInfo should be freed by the application once the callback has been called by the FreeRTOS_freeaddrinfo().

If yes, may be we can update it to the following:

The application must free pxAddressInfo by calling FreeRTOS_freeaddrinfo in the callback.

Let me know if you are referring to something else.

Are you sure about this freeing? This is not how the rest of the library is written to expect this type of handling in a callback.

Based on my reading of the code, I think that is correct. @htibosch Would you please confirm?

Thank you @aggarg for your explanation.

I have one amendment:

 static void vDNS_callback( const char * pcName,
                            void * pvSearchID,
                            struct freertos_addrinfo * pxAddressInfo )
 {
     if( pxAddressInfo && pxAddressInfo->ai_family == FREERTOS_AF_INET4 )
     {
         char pcBuf[ 16 ];
         uint32_t ulIPAddress;
 
         /* The DNS lookup has a result, or it has reached the time-out. */
         ulIPAddress = pxAddressInfo->ai_addr->sin_address.ulIP_IPv4;
         FreeRTOS_inet_ntoa( ulIPAddress, pcBuf );
         FreeRTOS_printf( ( "vDNS_callback: IP address of %s found: %s\n", pcName, pcBuf ) );
 
         xHasIPv4Address = pdTRUE;
-        FreeRTOS_freeaddrinfo( pxAddressInfo );
     }
+    FreeRTOS_freeaddrinfo( pxAddressInfo );
 }

to make sure that pxAddressInfo is always freed, also if the result is IPv6.

This is not how the rest of the library is written to expect this type of handling in a callback.

In this callback, the library is handing over information from the IP-task to the application. There may be multiple results, follow the field “ai_next”. These links will be freed recursively.

Thank you for correcting. @xuelix Would you please get the website documentation updated?

This isn’t quite right, it free’s NULL if pxAddressInfo == NULL

If this is all true, why am I getting an assert when FreeRTOS_freeaddrinfo( pxAddressInfo ); fires in ulDNSHandlePacket?

This cannot happen - FreeRTOS-Plus-TCP/source/FreeRTOS_DNS.c at 22c095e9c3bff7773085dd9b061a0013200eadda · FreeRTOS/FreeRTOS-Plus-TCP · GitHub.

Can you share callstack?

I’m away now, will get it later. But I do know it’s not null, I think it’s trying to free what I freed in the callback as above.

Hi @friesen @aggarg @xuelix , I was mistaken about who shall call FreeRTOS_freeaddrinfo().

When your application gets called (application hook), it doesn’t have to worry about freeing the memory.

When your application calls a DNS API, it gets ownership of the freertos_addrinfo pointer.

Two examples:

static void vDNS_callback( const char * pcName,
                           void * pvSearchID,
                           struct freertos_addrinfo * pxAddressInfo )
{
    if( pxAddressInfo && pxAddressInfo->ai_family == FREERTOS_AF_INET4 )
    {
        /* Read from 'pxAddressInfo' and do not free it. */
    }
}

void aFunction( void )  
{
    struct freertos_addrinfo xHints;
	struct freertos_addrinfo * pxResult;
    memset( xHints, 0, sizeof xHints );
    xHints.ai_family = xPreferredHostType;
	BaseType_t rc =
		FreeRTOS_getaddrinfo( "freertos.org", NULL, &xHints, &pxResult );
	if( rc == pdPASS )
	{
		FreeRTOS_freeaddrinfo( pxResult );
	}
}

@htibosch Thank you for clarifying. This means that we need to update the following documentation on this page:

The callback function which will be called upon DNS response. It will be called with 
pcHostName, pvSearchID  and pxAddressInfo which points to address info. The pxAddressInfo should be freed by the application once the callback has been called by the FreeRTOS_freeaddrinfo(). In case of timeouts pxAddressInfo can be NULL.

Thank you for getting back to me on this.