Skip to content

Commit

Permalink
DNS local lookups using mDNS repaired (#1118)
Browse files Browse the repository at this point in the history
* DNS local lookups using mDNS or LLMNR

* Fix unit tests

* Add decriptions to new tests

* Fix formatting

* API changes

* Add UTs for new API

* Fix doxygen

* Fix doxygen

* Fix formatting

---------

Co-authored-by: Tony Josi <tonyjosi@amazon.com>
  • Loading branch information
htibosch and tony-josi-aws authored Jun 7, 2024
1 parent ba6ba81 commit 3287009
Show file tree
Hide file tree
Showing 6 changed files with 244 additions and 24 deletions.
47 changes: 36 additions & 11 deletions source/FreeRTOS_DNS.c
Original file line number Diff line number Diff line change
Expand Up @@ -1249,17 +1249,6 @@
/* Make sure all fields of the 'sockaddr' are cleared. */
( void ) memset( ( void * ) &xAddress, 0, sizeof( xAddress ) );

#if ( ipconfigUSE_IPv6 != 0 )
if( xFamily == ( BaseType_t ) FREERTOS_AF_INET6 )
{
xDNS_IP_Preference = xPreferenceIPv6;
}
else
{
xDNS_IP_Preference = xPreferenceIPv4;
}
#endif /* ( ipconfigUSE_IPv6 != 0 ) */

pxEndPoint = prvFillSockAddress( &xAddress, pcHostName );

if( pxEndPoint != NULL )
Expand Down Expand Up @@ -1648,6 +1637,42 @@

/*-----------------------------------------------------------*/

/**
* @brief Sets the DNS IP preference while doing DNS lookup to indicate the preference
* for a DNS server: either IPv4 or IPv6. Defaults to xPreferenceIPv4
* @param[in] eIPPreference IP preference, can be either xPreferenceIPv4 or
* xPreferenceIPv6
* @return pdPASS on success and pdFAIL on failure.
*/
BaseType_t FreeRTOS_SetDNSIPPreference( IPPreference_t eIPPreference )
{
BaseType_t xReturn = pdPASS;

switch( eIPPreference )
{
#if ( ipconfigUSE_IPv4 != 0 )
case xPreferenceIPv4:
xDNS_IP_Preference = xPreferenceIPv4;
break;
#endif

#if ( ipconfigUSE_IPv6 != 0 )
case xPreferenceIPv6:
xDNS_IP_Preference = xPreferenceIPv6;
break;
#endif

default:
xReturn = pdFAIL;
FreeRTOS_printf( ( "Invalid DNS IPPreference_t\n" ) );
break;
}

return xReturn;
}

/*-----------------------------------------------------------*/

#endif /* ipconfigUSE_DNS != 0 */

/*-----------------------------------------------------------*/
Expand Down
53 changes: 40 additions & 13 deletions source/FreeRTOS_DNS_Parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -295,21 +295,52 @@
{
size_t uxBytesRead = 0U;
size_t uxResult;
BaseType_t xIsResponse = pdFALSE;

/* Start at the first byte after the header. */
xSet.pucUDPPayloadBuffer = pucUDPPayloadBuffer;
/* Skip 12-byte header. */
xSet.pucByte = &( pucUDPPayloadBuffer[ sizeof( DNSMessage_t ) ] );
xSet.uxSourceBytesRemaining -= sizeof( DNSMessage_t );

/* Skip any question records. */
/* The number of questions supplied. */
xSet.usQuestions = FreeRTOS_ntohs( xSet.pxDNSMessageHeader->usQuestions );
/* The number of answer records. */
xSet.usAnswers = FreeRTOS_ntohs( xSet.pxDNSMessageHeader->usAnswers );

if( xSet.usQuestions == 0U )
if( ( xSet.pxDNSMessageHeader->usFlags & dnsRX_FLAGS_MASK ) == dnsEXPECTED_RX_FLAGS )
{
/* The IP-stack will only accept DNS replies that have a copy
* of the questions. */
xReturn = pdFALSE;
break;
xIsResponse = pdTRUE;

if( xSet.usAnswers == 0U )
{
/* This is a response that does not include answers. */
xReturn = pdFALSE;
break;
}

if( xSet.usQuestions == 0U )
{
#if ( ( ipconfigUSE_LLMNR == 1 ) || ( ipconfigUSE_MDNS == 1 ) )
{
xSet.pcRequestedName = ( char * ) xSet.pucByte;
}
#endif

#if ( ipconfigUSE_DNS_CACHE == 1 ) || ( ipconfigDNS_USE_CALLBACKS == 1 )
uxResult = DNS_ReadNameField( &xSet,
sizeof( xSet.pcName ) );
#endif
}
}
else
{
if( xSet.usQuestions == 0U )
{
/* This is a query that does not include any question. */
xReturn = pdFALSE;
break;
}
}

for( x = 0U; x < xSet.usQuestions; x++ )
Expand Down Expand Up @@ -376,13 +407,9 @@
break;
}

/* Search through the answer records. */
xSet.pxDNSMessageHeader->usAnswers =
FreeRTOS_ntohs( xSet.pxDNSMessageHeader->usAnswers );

if( ( xSet.pxDNSMessageHeader->usFlags & dnsRX_FLAGS_MASK )
== dnsEXPECTED_RX_FLAGS )
if( xIsResponse == pdTRUE )
{
/* Search through the answer records. */
ulIPAddress = parseDNSAnswer( &( xSet ), ppxAddressInfo, &uxBytesRead );
}

Expand Down Expand Up @@ -608,7 +635,7 @@

struct freertos_addrinfo * pxNewAddress = NULL;

for( x = 0U; x < pxSet->pxDNSMessageHeader->usAnswers; x++ )
for( x = 0U; x < pxSet->usAnswers; x++ )
{
BaseType_t xDoAccept = pdFALSE;

Expand Down
4 changes: 4 additions & 0 deletions source/include/FreeRTOS_DNS.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,10 @@ BaseType_t FreeRTOS_getaddrinfo( const char * pcName, /* Th
*/
void FreeRTOS_freeaddrinfo( struct freertos_addrinfo * pxInfo );

/* Sets the DNS IP preference while doing DNS lookup to indicate the preference
* for a DNS server: either IPv4 or IPv6. Defaults to xPreferenceIPv4 */
BaseType_t FreeRTOS_SetDNSIPPreference( IPPreference_t eIPPreference );

#if ( ipconfigDNS_USE_CALLBACKS == 1 )

/*
Expand Down
1 change: 1 addition & 0 deletions source/include/FreeRTOS_DNS_Globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@
{
DNSMessage_t * pxDNSMessageHeader; /**< A pointer to the UDP payload buffer where the DNS message is stored. */
uint16_t usQuestions; /**< The number of DNS questions that were asked. */
uint16_t usAnswers; /**< The number of DNS answers that were given. */
uint8_t * pucUDPPayloadBuffer; /**< A pointer to the original UDP load buffer. */
uint8_t * pucByte; /**< A pointer that is used while parsing. */
size_t uxBufferLength; /**< The total number of bytes received in the UDP payload. */
Expand Down
55 changes: 55 additions & 0 deletions test/unit-test/FreeRTOS_DNS/FreeRTOS_DNS_utest.c
Original file line number Diff line number Diff line change
Expand Up @@ -1040,6 +1040,8 @@ void test_FreeRTOS_getaddrinfo_a_IPv6Random_BindFailWithDot( void )
struct xSOCKET xDNSSocket;
NetworkEndPoint_t xEndPoint[ 5 ];

xDNS_IP_Preference = xPreferenceIPv6;

memset( &xAddress, 0, sizeof( struct freertos_addrinfo ) );
memset( &xHint, 0, sizeof( struct freertos_addrinfo ) );
memset( &xDNSSocket, 0, sizeof( struct xSOCKET ) );
Expand Down Expand Up @@ -1154,6 +1156,8 @@ void test_FreeRTOS_getaddrinfo_a_IPv6Random_BindFailWODot( void )
struct xSOCKET xDNSSocket;
NetworkEndPoint_t xEndPoint[ 2 ];

xDNS_IP_Preference = xPreferenceIPv6;

memset( &xAddress, 0, sizeof( struct freertos_addrinfo ) );
memset( &xHint, 0, sizeof( struct freertos_addrinfo ) );
memset( &xDNSSocket, 0, sizeof( struct xSOCKET ) );
Expand Down Expand Up @@ -1237,6 +1241,8 @@ void test_FreeRTOS_getaddrinfo_a_IPv6Random_InvalidDNSServerIndex( void )
struct xSOCKET xDNSSocket;
NetworkEndPoint_t xEndPoint;

xDNS_IP_Preference = xPreferenceIPv6;

memset( &xAddress, 0, sizeof( struct freertos_addrinfo ) );
memset( &xHint, 0, sizeof( struct freertos_addrinfo ) );
memset( &xDNSSocket, 0, sizeof( struct xSOCKET ) );
Expand Down Expand Up @@ -1323,6 +1329,8 @@ void test_FreeRTOS_getaddrinfo_a_IPv6Random_DNSReplySuccess( void )
struct xDNSBuffer xReceiveBuffer;
DNSMessage_t * pxDNSMessageHeader = NULL;

xDNS_IP_Preference = xPreferenceIPv6;

memset( &xAddress, 0, sizeof( struct freertos_addrinfo ) );
memset( &xHint, 0, sizeof( struct freertos_addrinfo ) );
memset( &xExpectedAddress, 0, sizeof( struct freertos_addrinfo ) );
Expand Down Expand Up @@ -1407,6 +1415,8 @@ void test_FreeRTOS_getaddrinfo_a_IPv6Random_RetryExhaust( void )
DNSMessage_t * pxDNSMessageHeader = NULL;
int i;

xDNS_IP_Preference = xPreferenceIPv6;

memset( &xAddress, 0, sizeof( struct freertos_addrinfo ) );
memset( &xHint, 0, sizeof( struct freertos_addrinfo ) );
memset( &xExpectedAddress, 0, sizeof( struct freertos_addrinfo ) );
Expand Down Expand Up @@ -1576,6 +1586,8 @@ void test_FreeRTOS_getaddrinfo_a_IPv6Random_LocalDNSSuccess( void )
DNSMessage_t * pxDNSMessageHeader = NULL;
int i;

xDNS_IP_Preference = xPreferenceIPv6;

memset( &xAddress, 0, sizeof( struct freertos_addrinfo ) );
memset( &xHint, 0, sizeof( struct freertos_addrinfo ) );
memset( &xExpectedAddress, 0, sizeof( struct freertos_addrinfo ) );
Expand Down Expand Up @@ -1661,6 +1673,8 @@ void test_FreeRTOS_getaddrinfo_a_IPv4Random_LocalDNSUnknownPreference( void )
DNSMessage_t * pxDNSMessageHeader = NULL;
int i;

xDNS_IP_Preference = xPreferenceIPv6;

memset( &xAddress, 0, sizeof( struct freertos_addrinfo ) );
memset( &xHint, 0, sizeof( struct freertos_addrinfo ) );
memset( &xExpectedAddress, 0, sizeof( struct freertos_addrinfo ) );
Expand Down Expand Up @@ -1732,6 +1746,8 @@ void test_FreeRTOS_getaddrinfo_a_IPv6Random_LLMNRDNSSuccess( void )
DNSMessage_t * pxDNSMessageHeader = NULL;
int i;

xDNS_IP_Preference = xPreferenceIPv6;

memset( &xAddress, 0, sizeof( struct freertos_addrinfo ) );
memset( &xHint, 0, sizeof( struct freertos_addrinfo ) );
memset( &xExpectedAddress, 0, sizeof( struct freertos_addrinfo ) );
Expand Down Expand Up @@ -2025,6 +2041,8 @@ void test_FreeRTOS_getaddrinfo_a_IPv6Random_LLMNRFail( void )
DNSMessage_t * pxDNSMessageHeader = NULL;
int i;

xDNS_IP_Preference = xPreferenceIPv6;

memset( &xAddress, 0, sizeof( struct freertos_addrinfo ) );
memset( &xHint, 0, sizeof( struct freertos_addrinfo ) );
memset( &xExpectedAddress, 0, sizeof( struct freertos_addrinfo ) );
Expand Down Expand Up @@ -2125,6 +2143,8 @@ void test_FreeRTOS_getaddrinfo_a_IPv4Random_PortSpecified( void )
DNSMessage_t * pxDNSMessageHeader = NULL;
uint16_t usExpectPort = 0x1234;

xDNS_IP_Preference = xPreferenceIPv6;

memset( &xAddress, 0, sizeof( struct freertos_addrinfo ) );
memset( &xHint, 0, sizeof( struct freertos_addrinfo ) );
memset( &xExpectedAddress, 0, sizeof( struct freertos_addrinfo ) );
Expand Down Expand Up @@ -2224,3 +2244,38 @@ void test_FreeRTOS_freeaddrinfo_NullInput( void )
{
FreeRTOS_freeaddrinfo( NULL );
}

/**
* @brief Preference is IPv6
*/
void test_FreeRTOS_SetDNSIPPreference_IPv4( void )
{
BaseType_t xReturn;

xReturn = FreeRTOS_SetDNSIPPreference( xPreferenceIPv4 );
TEST_ASSERT_EQUAL( pdPASS, xReturn );
TEST_ASSERT_EQUAL( xPreferenceIPv4, xDNS_IP_Preference );
}

/**
* @brief Preference is IPv6
*/
void test_FreeRTOS_SetDNSIPPreference_IPv6( void )
{
BaseType_t xReturn;

xReturn = FreeRTOS_SetDNSIPPreference( xPreferenceIPv6 );
TEST_ASSERT_EQUAL( pdPASS, xReturn );
TEST_ASSERT_EQUAL( xPreferenceIPv6, xDNS_IP_Preference );
}

/**
* @brief Preference is None
*/
void test_FreeRTOS_SetDNSIPPreference_None( void )
{
BaseType_t xReturn;

xReturn = FreeRTOS_SetDNSIPPreference( xPreferenceNone );
TEST_ASSERT_EQUAL( pdFAIL, xReturn );
}
Loading

0 comments on commit 3287009

Please sign in to comment.