Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Failure to bind socket when custom ip is set for ethernet adapter

The problem

On our system running RTEMS 4.9.2 we are experiencing a very odd issue with socket communications. We are setting up a socket and using the following command to bind:

// Bind the socket to set the local port
sockaddr_in localSocketAddress = {0};
localSocketAddress.sin_family = AF_INET;
localSocketAddress.sin_port = (u_short)localPort;
localSocketAddress.sin_addr.s_addr = localAddress;

if (bind( mSocket, (sockaddr *)&localSocketAddress, sizeof(sockaddr_in)) == SOCKET_ERROR)
{
    int errorOut = errno;
    ...

And this works for UDP communications except in a strange specific scenario which is explained below. The problem that we experience is a failure of this bind call even though the setup is correct. We get the error 125 which for RTEMS is EADDRNOTAVAIL:

A nonexistent interface was requested or the requested address was not local.

The Apparent Cause

At boot of the device we can set up our network in 1 of 2 ways:

  1. The Network IP and SUBNET is autoconfigured based on what is in the default bootloader (UBOOT), and is set up through the RTEMS OS.

  2. The RTEMS function rtems_bsdnet_ifconfig is called to change the ip address of the sole ethernet interface after boot time.

For clarification, option 2 is called like this:

rtems_bsdnet_ifconfig(eth_interface, SIOCSIFADDR, &ipaddr);

If the network is set up as indicated by option 1, everything works as expected, but if option 2 is used (even in the case where the setup matches the network options defined by option 1) then the socket bind fails.

Is there a known reason or bug for RTEMS that indicates that this bind would fail if you reconfigure your IP?

Additional Information

  • We are setting up a new IP address (option 2) using a method that essentially uses ioctl("eht1", SIOCSIFADDR, ...).

  • If we bind our socket without specifying a local ADDRESS (ie use INADDR_ANY) then it works in any case.

  • The rtems_bsdnet_ifconfig is a simple interface for the ioctl function. It is from rtems_glue.c and has the function signiture int rtems_bsdnet_ifconfig(const char *ifname, uint32_t cmd, void *param)

  • All normal network functions seem to work except for this bind.

  • After looking at this i thought maybe I needed to do more in resetting my IP address. But this doesn't work , using the first answer or even doing anything with SIOCSIFFLAGS causes all network functionality to cease.

like image 501
Fantastic Mr Fox Avatar asked Jun 08 '16 16:06

Fantastic Mr Fox


People also ask

Why does socket bind fail?

If you're seeing a "TCP/UDP: Socket bind failed on local address" error message in the OpenVPN log, it means your VPN connection is configured to bind to a fixed local address and/or port number, and that this address/port number is unavailable.

What does it mean to bind a socket to an address?

When a socket has both an IP address and a port number it is said to be 'bound to a port', or 'bound to an address'. A bound socket can receive data because it has a complete address. The process of allocating a port number to a socket is called 'binding'.

Why do we bind socket to port?

By binding the socket to a specific port number, you avoid having an ephemeral port number assigned to the socket. Servers find it inconvenient to have an ephemeral port number assigned, because clients have to connect to a different port number for every instance of the server.


1 Answers

You didn't mention the architecture you are running on, but you are setting the port and address in local byte order, which may not be the same as network byte order. The very first thing I would try is:

localSocketAddress.sin_port = htons (localPort); localSocketAddress.sin_addr.s_addr = htonl (localAddress);

This will also make your code more portable, in case that is NOT your problem (i.e. you are running on a big-endian host) and you one day try to compile on a different system that is little endian.

like image 136
Kean Avatar answered Oct 14 '22 09:10

Kean