Hi!
Every first DNS request after system start does not send . The situation is 100% repeated at the first request after launching the application
I attach log and screenshot from wireshark
This is part of the log of the first failed request:
[12:51:41:077] > dnscheck google.com
[12:51:41:083] <
[12:51:41:083] < FreeRTOS_FindEndPointOnNetMask[4]: No match for 5fae6002ip
[12:51:41:083] < ARP 5fae6002ip miss using c0a85801ip
[12:51:41:083] < FreeRTOS_FindEndPointOnNetMask[11]: No match for 5fae6002ip
[12:51:46:094] < DNS_ReadReply returns -11
[12:51:46:094] < prvIncreaseDNS4Index: from 0 to 1
[12:51:46:094] < FreeRTOS_FindEndPointOnNetMask[4]: No match for 8080808ip
[12:51:46:094] < ARP 8080808ip miss using c0a85801ip
[12:51:50:877] < Network buffers: 56 lowest 54
[12:51:50:877] < pxEasyFit: ARP c0a8586dip -> c0a85801ip
[12:51:50:877] < ipARP_REPLY from c0a85801ip to c0a8586dip end-point c0a8586dip
[12:51:51:093] < DNS_ReadReply returns -11
[12:51:51:093] < prvIncreaseDNS4Index: from 1 to 0
[12:51:51:093] < REsolved addr:0.0.0.0
FreeRTOS TCP version 4.1.0 and custom port for Cortex M4 with zerocopy driver based on STM32F4 port. If you need more debug information (breakpoints, data etc…) dont hesitate to ask-)
It looks like it took some time for the ARP resolution for the default gateway 192.168.88.1? From the logs below, once the ARP resolution for default gateway succeeds, the DNS resolves, which is expected.
[12:51:41:083] < FreeRTOS_FindEndPointOnNetMask[4]: No match for 5fae6002ip
[12:51:41:083] < ARP 5fae6002ip miss using c0a85801ip
[12:51:41:083] < FreeRTOS_FindEndPointOnNetMask[11]: No match for 5fae6002ip
[12:51:46:094] < DNS_ReadReply returns -11
[12:51:46:094] < prvIncreaseDNS4Index: from 0 to 1
[12:51:46:094] < FreeRTOS_FindEndPointOnNetMask[4]: No match for 8080808ip
[12:51:46:094] < ARP 8080808ip miss using c0a85801ip
[12:51:50:877] < Network buffers: 56 lowest 54
[12:51:50:877] < pxEasyFit: ARP c0a8586dip -> c0a85801ip
[12:51:50:877] < ipARP_REPLY from c0a85801ip to c0a8586dip end-point c0a8586dip
[12:51:51:093] < DNS_ReadReply returns -11
[12:51:51:093] < prvIncreaseDNS4Index: from 1 to 0
[12:51:51:093] < REsolved addr:0.0.0.0
[12:52:08:073] > dnscheck amazon.com
[12:52:08:088] <
[12:52:08:088] < FreeRTOS_FindEndPointOnNetMask[4]: No match for 5fae6002ip
[12:52:08:088] < ARP 5fae6002ip hit using c0a85801ip
[12:52:08:104] < FreeRTOS_ProcessDNSCache: add: amazon.com @ 205.251.242.103 (TTL 723)
[12:52:08:104] < DNS[0xEAE1]: The answer to amazon.com (205.251.242.103) will be stored
[12:52:08:104] < REsolved addr:205.251.242.103
Can you share the wireshark capture for ARP as well along with DNS? Overall the behavior looks as expected, but might be interesting to see why it took so long for ARP to resolve. @ActoryOu@moninom1
When FreeRTOS sends a packet to an unresolved IP-address, it will change the UDP packet into an ARP request. This was created in a time that RAM was very expensive
The UDP packet will not be sent, that is why you must do it a second time.
You can force an ARP lookup of the gateway with this function:
/* xARPWaitResolution checks if an IPv4 address is already known. If not
* it may send an ARP request and wait for a reply. This function will
* only be called from an application. */
BaseType_t xARPWaitResolution( uint32_t ulIPAddress,
TickType_t uxTicksToWait );
You can call it like this, as soon as the network is up:
BaseType_t doARPLookup = pdFALSE;
void vApplicationIPNetworkEventHook_Multi( eIPCallbackEvent_t eNetworkEvent,
NetworkEndPoint_t *pxEndPoint )
{
/* If the network has just come up...*/
if( eNetworkEvent == eNetworkUp )
{
doARPLookup = pdTRUE;
}
}
void main_loop()
{
if( doARPLookup == pdTRUE )
{
doARPLookup = pdFALSE;
xARPWaitResolution( pxEndPoint->ipv4_settings.ulGatewayAddress,
pdMS_TO_TICKS( 500U ) );
}
Note that vApplicationIPNetworkEventHook_Multi() is called by the IP-task, and therefore it is not allowed to call xARPWaitResolution() immediately.
and this code from you post in vApplicationIPNetworkEventHook_Multi:
I will add a similar code to the tasks who uses dns (mqtt agent) or can create a high-priority task that will be created in vApplicationIPNetworkEventHook_Multi and executed once and then deleted? What is your opinion?
You need to do gateway resolution once only, so the second option seems better. Have you also thought about adding retries in case of error? This way you won’t have to add extra code for triggering ARP resolution and the normal error handling code would take care of sending the DNS query. Adding retries would also have the benefit of making your application robust in case of unpredictable network errors.
Hi @newbie,
I’d like to clarify that what you’re experiencing is not actually a bug, but rather an expected behavior in certain network configurations.
The message you’re seeing indicates that FreeRTOS-Plus-TCP is unable to locate the corresponding endpoint for the specific IP address. This situation typically occurs when the remote IP address is not within the same subnet as your device.
I would like to not show “FreeRTOS_FindEndPointOnNetMask[4]: No match for”, but when I check code, it seems I can not.
I hope in next version, this FreeRTOS_debug_printf will be configurated by user that we can show log or not.
Yes, we support configuration to disable FreeRTOS_debug_printf. Please refer to FreeRTOS-Plus-TCP Configuration - FreeRTOS™ for more detail. Hopefully this is good enough for you.
@ActoryOu . Thanks. I will try later.
This FreeRTOS-Plus-TCP version is different from previous on showing the log. May I know the purpose of the adding FreeRTOS_InterfaceEndPointOnNetMask?
FreeRTOS_InterfaceEndPointOnNetMask was introduced as part of our efforts to enhance FreeRTOS-Plus-TCP’s capabilities. When we updated to version 4.0.0, we not only implemented IPv6 support but also added functionality for managing multiple network interfaces. The FreeRTOS_InterfaceEndPointOnNetMask is one of the key function in supporting these multiple interfaces.