This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Difference in behaviour between getifaddrs() and ioctl(SIOCGIFCONF)


On 02/12/2010 18:59, Corinna Vinschen wrote:
On Dec 2 14:23, Jason Curl wrote:
One of my use cases is to test a particular interface if it has an IP address
or not (due to DHCP, AutoIP, etc.). Then on definition of an address, I can
trigger a process. This assumes that the interface names remains constant. So a
dynamically changing interface name is something I'd like to NOT see.

Huh? My proposal does exactly that. It would always return unique interface names.

Maybe I don't understand your proposal. You want to assign an index name based on the IPv4 address. The "UUID:Index" is the complete interface name. It's unique for that IPv4 address, but as soon as its IP changes, so does the interface name.


Then I think ioctl(SIOCGIFCONF) would also need to follow this behaviour. ioctl(SIOCGIFxxx) would also need to accept the interface names given. Then there will be maximum compatibility in my source with how other OSes work. getifaddrs() returns a name, this same name can be used with ioctl(). (note 1)

I have an embedded device that I connect to my PC via Ethernet. When I physically connect it, I want to start a process. That process should be started, when a specified interface receives an IPv4 address, is IFF_UP and has a IFF_LINK. So I need to poll this interface.

With Linux, QNX, FBSD, Solaris, I don't even need to use getifaddrs() or ioctl(SIOCGIFCONF), I can poll it directly with ioctl(SIOCGIFADDR) as normally the interfaces don't have an alias. With Cygwin 1.7.7 I can obtain a complete list once, use SIOCGIFFRNDLYNAM to find the interface name and then poll (only with SIOCGIFCONF, not with getifaddrs(), my original problem). Cygwin 1.5.x was problematic, except if I had precisely only one interface, but generally the names were static, so in practice it worked.

Now with the proposal, I need to obtain a complete list of all interfaces every time I poll, perform a check against SIOCGIFFRNDLYNAM, because the name of the interfaces themselves change.

(note 1) I would not like to make assumptions about the format of the Cygwin interface name to get the ioctl() value from getifaddrs(). This places an unnecessary burden on Cygwin developers that this format remains the same always. Cygwin 1.9 might have a better idea yet, breaking my code. Thus my suggestion that ioctl() from Cygwin support this ":index" format, which it currently doesn't, also in 1.7.7.


The solution that I do prefer, is one similar to QNX. QNX behaves differently
to Linux, but could be the simplest implementation for Cygwin. If an interface
has aliases, it simply has multiple records in getifaddrs(). The ioctl()
interface returns the main/preferred address. Cygwin could return the first
AF_INET record in this case.

Here's the problem. Windows does not mark an IPv4 address as preferred address, nor does it always return the addresses in the order you'd expect. Actually, it appears as if the addresses of an interface are always returned in ascending order (on W7, at least).

So, following your proposal, if you add an address which is numerically
lower than the other addresses, the next call to ioctl(SIOCGIFADDR) would
return the new address.  If you remove the address again it would return
the old address again.  From my POV this is as much surprising as the
current behaviour.  Hence my proposal.


That's why it is now a good time to move to getifaddrs() as recommended in general for systems that support it. The programmer can remove this issue because they get a complete list. Even on Linux, QNX, FreeBSD, Solaris, ioctl() can't guarantee atomicity. With ioctl() interface may change sometime between queries. getifaddrs() offers the potential for atomicity. And they all provide getifaddrs().


This issue will also only be apparent if the user has multiple IPv4 addresses assigned to a single interface.

I'm also assuming, that IP address orders will only change if there is a change in the system configuration. So such a surprise won't occur too often. But importantly, interface names are known in advance with ioctl() without having to use SIOCGIFCONF.

And it provides for the minimalistic amount of change to Cygwin, remains compatible with other OSes and mappings continue to work with names returned by getifaddrs() and ioctl() - always.

Jason.


-- Problem reports: http://cygwin.com/problems.html FAQ: http://cygwin.com/faq/ Documentation: http://cygwin.com/docs.html Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]