I was hunting for a bug today that would occur consistently on one box and never on the other. In the end, I believe Data.Streaming.Network.getSocketFamilyGen is to blame.
This function gets a host, a port and an address-family and calls Network.Socket.getAddrInfo to resolve the host address. The problem lies in that getAddrInfo may return more than one address and, in that case, getSocketFamilyGen will try to connect to the first one and if that one fails, won't try with the rest.
Now, why would this be a problem? Our application was using (indirectly, via a dependency) runTCPClient with the default settings (i.e. clientSettingsTCP), which, in particular, set the address family to AF_UNSPEC. Moreover, it was trying to connect to a port on localhost and in Debian /etc/hosts/ includes the following definitions:
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
Because we use AF_UNSPEC, getAddrInfo would return addresses for IPv4 and IPv6, and because Debian defines localhost also for IPv6, the call would return a two-element list for localhost. Finally, because the first address in the returned list happened to be ::1, the connection would unexpectedly fail. Note that the other box was running Ubuntu, which reserves localhost for 127.0.0.1 on /etc/hosts, so it would succeed there.
This and other kind of nasty surprises are solved by going through the list of addresses returned by getaddrinfo until a connection succeeds. As far as I understand, this is the recommended way of using this function anyway (I also can't think of a common scenario where trying the first one and then immediately failing could be the desired behaviour).
I was hunting for a bug today that would occur consistently on one box and never on the other. In the end, I believe
Data.Streaming.Network.getSocketFamilyGenis to blame.This function gets a host, a port and an address-family and calls
Network.Socket.getAddrInfoto resolve the host address. The problem lies in thatgetAddrInfomay return more than one address and, in that case,getSocketFamilyGenwill try to connect to the first one and if that one fails, won't try with the rest.Now, why would this be a problem? Our application was using (indirectly, via a dependency)
runTCPClientwith the default settings (i.e.clientSettingsTCP), which, in particular, set the address family toAF_UNSPEC. Moreover, it was trying to connect to a port onlocalhostand in Debian/etc/hosts/includes the following definitions:Because we use
AF_UNSPEC,getAddrInfowould return addresses for IPv4 and IPv6, and because Debian defineslocalhostalso for IPv6, the call would return a two-element list forlocalhost. Finally, because the first address in the returned list happened to be::1, the connection would unexpectedly fail. Note that the other box was running Ubuntu, which reserveslocalhostfor127.0.0.1on/etc/hosts, so it would succeed there.This and other kind of nasty surprises are solved by going through the list of addresses returned by
getaddrinfountil a connection succeeds. As far as I understand, this is the recommended way of using this function anyway (I also can't think of a common scenario where trying the first one and then immediately failing could be the desired behaviour).