[syslinux] tftpd: don't use AI_ADDRCONFIG to resolve addresses to bind(2)

Uwe Kleine-König uwe at kleine-koenig.org
Sat Feb 4 14:28:08 PST 2017


Hello Ron,

On Sat, Feb 04, 2017 at 03:46:46PM +1030, Ron wrote:
> > [...]
> That would seem to be a pretty good summation of how we're failing to
> converge here ...

I mixed too many things that IMHO improve the code but actually only
care about one of those. So I suggest we restart the discussion with
focusing on that one thing only. Let me try that:

Currently tftpd when requested to bind to an address X does in pseudo
code and simplified:

	if X looks like an ipv6 address:
		family = AF_INET6
	elif X looks like an ipv4 address:
		family = AF_INET
	else:
		family = AF_UNSPEC
	addrinfo = getaddrinfo(X, NULL, { .ai_family = family, .ai_flags = AI_CANONNAME | AI_ADDRCONFIG })
	bind(fd, addrinfo)

(where bind() works on both AF_INET and AF_INET6 if getaddrinfo returns
both).

This does the right thing most of the time. There are cases however
where the behaviour is wrong or at least undesirable:

 a) if X = 0.0.0.0 and no interface (but lo) has an ipv4 address,
    getaddrinfo returns an error and tftpd fails to start with

    	cannot resolve local IPv4 bind address: 0.0.0.0, Name or service not known

 b) if X is an hostname that resolves to an ipv4 and an ipv6 address and
    the machine currently has no interface (but lo) with an ipv6
    address, tftpd only binds to the ipv4 address.

In case a) my expectation is that tftpd binds to 0.0.0.0 anyhow. I don't
think it is necessary to show a scenario where this is sensible because
I expect a command to do what was requested unless that's impossible.
Nevertheless there are situations where this might make sense:

 a1) On a mobile machine without network access during boot. tftpd might
     later be used when an interface is up (e.g. it is plugged into a
     network later or a virtual machine is booted once it is needed.)
 a2) On a machine where you want to boot quickly and so drop unneeded
     prerequisites. So you can start tftpd in parallel to bringing the
     network up without the need to serialize these two.

Additionally to the refusal to start binding on 0.0.0.0 the error
message is not understandable to me.

In case b) my expectation is that tftpd fails with something like:

	cannot bind to IPv6 address $ipv6_address

a) can be fixed by just dropping AI_ADDRCONFIG from the call to
getaddrinfo. Also for b) this improves the situation, from

	cannot resolve local IPv6 bind address: $X (...); using IPv4 only

to

	cannot bind to local IPv6 socket,IPv6 disabled: ...

So in this case the error message at least matches the actual problem.

This convinces me it's the right thing to drop AI_ADDRCONFIG for tftpd
as AFAICT there is no down side.

Best regards
Uwe
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://www.zytor.com/pipermail/syslinux/attachments/20170204/7d5c9583/attachment.sig>


More information about the Syslinux mailing list