Thanks for your quick reply. Although, I specifically avoid setting the IP address to all 0.0.0.0 … rather I am binding the socket to a specific IP address.
These are the relevant parts of the code I am using:
ip_config_t ipConfigClient =
{
.ipAdr4 = { 192, 168, 9, 5 }, //Client port: 40000
.ipSubNetMask4 = { 255, 255, 255, 0 },
.ipStdGateway4 = { 192, 168, 9, 10}
};
ip_config_t ipConfigPrivate =
{
.ipAdr4 = { 192, 168, 168, 5 }, //Client port 40001
.ipSubNetMask4 = { 255, 255, 255, 0 },
.ipStdGateway4 = { 192, 168, 168, 10}
};
...
//Add the endpoint for the client address
FreeRTOS_FillEndPoint( &(networkInterface),
&(ipEndpoints[IP_ENDPOINT_CLIENT_ACCESS]),
ipConfigClient.ipAdr4,
ipConfigClient.ipSubNetMask4,
ipConfigClient.ipStdGateway4,
ucDNSServerAddress,
macCfg.macArray );
//Add the endpoint for the default IP address
FreeRTOS_FillEndPoint( &(networkInterface),
&(ipEndpoints[IP_ENDPOINT_PRIVATE_ACCESS]),
ipConfigPrivate.ipAdr4,
ipConfigPrivate.ipSubNetMask4,
ipConfigPrivate.ipStdGateway4,
ucDNSServerAddress,
macCfg.macArray );
/* Initialize the interface descriptor. */
FreeRTOS_IPInit_Multi();
...
//Set the protocol
pCtrl->sockAdrListener.sin_family = FREERTOS_AF_INET4;
//Set the port & IP address of the endpoint: 192.168.9.5:40000
pCtrl->sockAdrListener.sin_port = FreeRTOS_htons( 40000 );
sockAdrListener.sin_address.ulIP_IPv4 = networkEndpoint[0].ipv4_settings.ulIPAddress;
// Bind the socket to the port that the client RTOS task will send to.
retVal = FreeRTOS_bind(socketListener, &sockAdrListener, sizeof(freertos_sockaddr));
...
//Set the protocol
pCtrl->sockAdrListener.sin_family = FREERTOS_AF_INET4;
//Set the port & IP address of the endpoint: 192.168.168.5:40001
pCtrl->sockAdrListener.sin_port = FreeRTOS_htons( 40001 );
sockAdrListener.sin_address.ulIP_IPv4 = networkEndpoint[1].ipv4_settings.ulIPAddress;
retVal = FreeRTOS_bind(socketListener, &sockAdrListener, sizeof(freertos_sockaddr));
Do you have any clues why I still am able to connect to both IP addresses on both ports?
Edit:
I studied the TCP/IP stack’s source code and found the function causing the issue. Packets meant for a socket bound to a specific endpoint (defined by IP and port) are processed by any socket bound to an endpoint with a matching destination IP. This occurs regardless of the port associated to the socket, as long as there exists any socket within the system that was bound to this port number.
Inside the IP task prvIPTask()
that handles IP packets, there is a function that handles TCP packets xProcessReceivedTCPPacket()
. Here, the function pxTCPSocketLookup()
, checks if the TCP packet can be matched with an existing port of a bound socket.
/**
* @brief As multiple sockets may be bound to the same local port number
* looking up a socket is a little more complex: Both a local port,
* and a remote port and IP address are being used to find a match.
* For a socket in listening mode, the remote port and IP address
* are both 0.
*
* @param[in] ulLocalIP Local IP address. Ignored for now.
* @param[in] uxLocalPort Local port number.
* @param[in] xRemoteIP Remote (peer) IP address.
* @param[in] uxRemotePort Remote (peer) port.
*
* @return The socket which was found.
*/
FreeRTOS_Socket_t * pxTCPSocketLookup( uint32_t ulLocalIP,
UBaseType_t uxLocalPort,
IPv46_Address_t xRemoteIP,
UBaseType_t uxRemotePort );
Within this function it gets clear that only the remote port (which is taken from the received packet) is ever compared to the ports of existing bound TCP sockets. The packet’s destination IP address is ignored for that matter.
# Pseudo code of how the validity of the packet is checked within pxTCPSocketLookup()
for socket in xBoundTCPSocketsList:
if socket->usLocalPort == uxLocalPort
return socket # If a matching port is found return the socket
return NULL # else return NULL
So, as long as any bound socket has a matching port, the packet is passed on for processing, regardless of if the port+IP combination matches an endpoint configuration.
I got the following question: Is this a bug or intended behaviour?
The presence of the comment ulLocalIP Local IP address. Ignored for now
makes me suppose that the code is still under construction and at some point in a future update, the check to determine if the received packet really matches an existing endpoint, will be added.
Is my assumption correct and can anybody guess how much time it will take to be implemented?
Thanks for your feedback