Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multicast Support - Work In Progress #1019

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions source/FreeRTOS_DNS_Networking.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@
* going to be '0' i.e. success. Thus, return value is discarded */
( void ) FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_SNDTIMEO, &( uxWriteTimeOut_ticks ), sizeof( TickType_t ) );
( void ) FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_RCVTIMEO, &( uxReadTimeOut_ticks ), sizeof( TickType_t ) );
#if ( ipconfigIS_ENABLED( ipconfigSUPPORT_IP_MULTICAST ) )
/* Since this socket may be used for LLMNR or mDNS, set the multicast TTL to 1. */
uint8_t ucMulticastTTL = 1;
( void ) FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_IP_MULTICAST_TTL, &( ucMulticastTTL ), sizeof( ucMulticastTTL ) );
#endif /* ipconfigIS_ENABLED( ipconfigSUPPORT_IP_MULTICAST ) */
}

return xSocket;
Expand Down
30 changes: 30 additions & 0 deletions source/FreeRTOS_DNS_Parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -949,6 +949,26 @@
}

xUDPPacket_IPv6->xUDPHeader.usLength = FreeRTOS_htons( ( uint16_t ) lNetLength + ipSIZE_OF_UDP_HEADER );

if( xUDPPacket_IPv6->xUDPHeader.usDestinationPort == FreeRTOS_ntohs( ipMDNS_PORT ) )
{
/* RFC6762, section 11 */
xUDPPacket_IPv6->xIPHeader.ucHopLimit = 255U;
}
else if( xUDPPacket_IPv6->xUDPHeader.usDestinationPort == FreeRTOS_ntohs( ipLLMNR_PORT ) )
{
/* LLMNR: RFC4795 section 2.5 recommends UDP requests and responses use TTL of 255 */

/* Theoretically, LLMNR replies can go "off-link" and create a DDoS scenario. That should be preventable
* by settings our rely's TTL/HopLimit to 1. Please note that in certain situations ( I think unicast
* responses), Wireshark flags some LLMNR packets that have TTL of 1 as too low. */
xUDPPacket_IPv6->xIPHeader.ucHopLimit = 1U;
}
else
{
xUDPPacket_IPv6->xIPHeader.ucHopLimit = ipconfigUDP_TIME_TO_LIVE;
}

vFlip_16( pxUDPHeader->usSourcePort, pxUDPHeader->usDestinationPort );
uxDataLength = ( size_t ) lNetLength + ipSIZE_OF_IPv6_HEADER + ipSIZE_OF_UDP_HEADER + ipSIZE_OF_ETH_HEADER;
}
Expand All @@ -964,8 +984,18 @@
/* HT:endian: should not be translated, copying from packet to packet */
if( pxIPHeader->ulDestinationIPAddress == ipMDNS_IP_ADDRESS )
{
/* RFC6762, section 11 */
pxIPHeader->ucTimeToLive = ipMDNS_TIME_TO_LIVE;
}
else if( pxUDPHeader->usDestinationPort == FreeRTOS_ntohs( ipLLMNR_PORT ) )
{
/* LLMNR: RFC4795 section 2.5 recommends UDP requests and responses use TTL of 255 */

/* Theoretically, LLMNR replies can go "off-link" and create a DDoS scenario. That should be preventable
* by settings our rely's TTL/HopLimit to 1. Please note that in certain situations ( I think unicast
* responses), Wireshark flags some LLMNR packets that have TTL of 1 as too low. */
pxIPHeader->ucTimeToLive = 1;
}
else
{
pxIPHeader->ulDestinationIPAddress = pxIPHeader->ulSourceIPAddress;
Expand Down
40 changes: 40 additions & 0 deletions source/FreeRTOS_IP.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@
#include "NetworkBufferManagement.h"
#include "FreeRTOS_DNS.h"
#include "FreeRTOS_Routing.h"
#if ( ipconfigIS_ENABLED( ipconfigSUPPORT_IP_MULTICAST ) )
#include "FreeRTOS_IGMP.h"
#endif /* ipconfigIS_ENABLED( ipconfigSUPPORT_IP_MULTICAST ) */

/** @brief Time delay between repeated attempts to initialise the network hardware. */
#ifndef ipINITIALISATION_RETRY_DELAY
Expand Down Expand Up @@ -477,6 +480,20 @@ static void prvProcessIPEventsAndTimers( void )
/* xQueueReceive() returned because of a normal time-out. */
break;

#if ( ipconfigIS_ENABLED( ipconfigSUPPORT_IP_MULTICAST ) )
case eSocketOptAddMembership:
case eSocketOptDropMembership:
{
MulticastAction_t * pxMCA = ( MulticastAction_t * ) xReceivedEvent.pvData;
vModifyMulticastMembership( pxMCA, xReceivedEvent.eEventType );
break;
}

case eMulticastTimerEvent:
vIPMulticast_HandleTimerEvent();
break;
#endif /* ipconfigIS_ENABLED( ipconfigSUPPORT_IP_MULTICAST ) */

default:
/* Should not get here. */
break;
Expand Down Expand Up @@ -543,6 +560,11 @@ static void prvIPTask_Initialise( void )
}
#endif /* ( ( ipconfigUSE_DNS_CACHE != 0 ) && ( ipconfigUSE_DNS != 0 ) ) */

#if ( ipconfigIS_ENABLED( ipconfigSUPPORT_IP_MULTICAST ) )
/* Init the list that will hold scheduled IGMP reports. */
( void ) vIPMulticast_Init();
#endif /* ipconfigIS_ENABLED( ipconfigSUPPORT_IP_MULTICAST ) */

/* Initialisation is complete and events can now be processed. */
xIPTaskInitialised = pdTRUE;
}
Expand Down Expand Up @@ -656,6 +678,16 @@ void vIPNetworkUpCalls( struct xNetworkEndPoint * pxEndPoint )
#endif
}

#if ( ipconfigIS_ENABLED( ipconfigSUPPORT_IP_MULTICAST ) )

/* Reschedule all multicast reports associated with this end-point.
* Note: countdown is in increments of ipIGMP_TIMER_PERIOD_MS. It's a good idea to spread out all reports a little.
* 200 to 500ms ( xMaxCountdown of 2 - 5 ) should be a good happy medium. If the network we just connected to has a IGMP/MLD querier,
* they will soon ask us for reports anyways, so sending these unsolicited reports is not required. It simply enhances the user
* experience by shortening the time it takes before we begin receiving the multicasts that we care for. */
vRescheduleAllMulticastReports( pxEndPoint->pxNetworkInterface, 5 );
#endif /* ipconfigIS_ENABLED( ipconfigSUPPORT_IP_MULTICAST ) */

pxEndPoint->bits.bEndPointUp = pdTRUE_UNSIGNED;

#if ( ipconfigUSE_NETWORK_EVENT_HOOK == 1 )
Expand Down Expand Up @@ -1347,6 +1379,7 @@ void FreeRTOS_ReleaseUDPPayloadBuffer( void const * pvBuffer )
pxNetworkBuffer->pucEthernetBuffer[ ipSOCKET_OPTIONS_OFFSET ] = FREERTOS_SO_UDPCKSUM_OUT;
pxNetworkBuffer->xIPAddress.ulIP_IPv4 = ulIPAddress;
pxNetworkBuffer->usPort = ipPACKET_CONTAINS_ICMP_DATA;
pxNetworkBuffer->ucMaximumHops = ipconfigICMP_TIME_TO_LIVE;
/* xDataLength is the size of the total packet, including the Ethernet header. */
pxNetworkBuffer->xDataLength = uxTotalLength;

Expand Down Expand Up @@ -2147,6 +2180,13 @@ static eFrameProcessingResult_t prvProcessIPPacket( const IPPacket_t * pxIPPacke
break;
#endif /* ( ipconfigUSE_IPv6 != 0 ) */

#if ( ipconfigIS_ENABLED( ipconfigSUPPORT_IP_MULTICAST ) && ipconfigIS_ENABLED( ipconfigUSE_IPv4 ) )
case ipPROTOCOL_IGMP:
/* The IP packet contained an IGMP frame. */
eReturn = eProcessIGMPPacket( pxNetworkBuffer );
break;
#endif /* ( ipconfigIS_ENABLED( ipconfigSUPPORT_IP_MULTICAST ) && ipconfigIS_ENABLED( ipconfigUSE_IPv4 ) ) */

case ipPROTOCOL_UDP:
/* The IP packet contained a UDP frame. */

Expand Down
Loading