eggdrop
eggdrop copied to clipboard
IRC server connections cannot be made to both IPv4 and IPv6
With a single server hostname that has one A and one AAAA resource record, eggdrop 1.8.2rc2 will only ever attempt to connect to one type of address. If this times out (no response to SYN packets) then it does not retry over the other address family.
The DNS resolution code only prefers IPv4 or IPv6. It also looks like it behaves differently depending on the order of the A and AAAA responses.
Thanks so much for reporting this, and the associated PRs! We'll look at this shortly
Is there currently a server with DNS entries for both records where you know that one is timing out on, so I can replicate this error for additional testing? You can stop in on freenode and let us know there if you prefer. Thank you
You can use irctest4.uuid.uk
and irctest6.uuid.uk
. These will connect to a freenode server (that is currently working) and Google DNS (which doesn't respond to TCP port 6667 for me).
prefer-ipv6 0:
[01:37:11] Trying server [irctest4.uuid.uk]:6667
[01:37:11] DNS Resolver: Creating new record
[01:37:11] DNS Resolver: Sent domain lookup request for "irctest4.uuid.uk".
[01:37:11] DNS Resolver: Received nameserver reply. (qd:1 an:1 ns:4 ar:3)
[01:37:11] DNS Resolver: answered domain query: "irctest4.uuid.uk"
[01:37:11] DNS Resolver: TTL: 5s
[01:37:11] DNS Resolver: TYPE: AAAA: IP6 Address
[01:37:11] DNS Resolver: answered domain query: "uuid.uk"
[01:37:11] DNS Resolver: answered domain query: "uuid.uk"
[01:37:11] DNS Resolver: answered domain query: "uuid.uk"
[01:37:11] DNS Resolver: answered domain query: "uuid.uk"
[01:37:11] DNS Resolver: answered domain query: "d.ns.uuid.uk"
[01:37:11] DNS Resolver: answered domain query: "c.ns.uuid.uk"
[01:37:11] DNS Resolver: answered domain query: "p.ns.uuid.uk"
[01:37:11] DNS Resolver: Received nameserver reply. (qd:1 an:1 ns:4 ar:4)
[01:37:11] DNS Resolver: answered domain query: "irctest4.uuid.uk"
[01:37:11] DNS Resolver: TTL: 5s
[01:37:11] DNS Resolver: TYPE: A: host address
[01:37:11] DNS Resolver: Lookup successful: irctest4.uuid.uk
[01:37:11] DNS resolved irctest4.uuid.uk to 130.239.18.119
[01:36:40] Trying server [irctest6.uuid.uk]:6667
[01:36:40] DNS Resolver: Creating new record
[01:36:40] DNS Resolver: Sent domain lookup request for "irctest6.uuid.uk".
[01:36:40] DNS Resolver: Received nameserver reply. (qd:1 an:1 ns:4 ar:3)
[01:36:40] DNS Resolver: answered domain query: "irctest6.uuid.uk"
[01:36:40] DNS Resolver: TTL: 5s
[01:36:40] DNS Resolver: TYPE: A: host address
[01:36:40] DNS Resolver: Lookup successful: irctest6.uuid.uk
[01:36:40] DNS resolved irctest6.uuid.uk to 8.8.8.8
prefer-ipv6 1
[01:38:43] Trying server [irctest4.uuid.uk]:6667
[01:38:43] DNS Resolver: Creating new record
[01:38:43] DNS Resolver: Sent domain lookup request for "irctest4.uuid.uk".
[01:38:43] DNS Resolver: Received nameserver reply. (qd:1 an:1 ns:4 ar:3)
[01:38:43] DNS Resolver: answered domain query: "irctest4.uuid.uk"
[01:38:43] DNS Resolver: TTL: 5s
[01:38:43] DNS Resolver: TYPE: AAAA: IP6 Address
[01:38:43] DNS Resolver: Lookup successful: irctest4.uuid.uk
[01:38:43] DNS resolved irctest4.uuid.uk to 2001:4860:4860::8888
[01:38:15] Trying server [irctest6.uuid.uk]:6667
[01:38:15] DNS Resolver: Creating new record
[01:38:15] DNS Resolver: Sent domain lookup request for "irctest6.uuid.uk".
[01:38:15] DNS Resolver: Received nameserver reply. (qd:1 an:1 ns:4 ar:4)
[01:38:15] DNS Resolver: answered domain query: "irctest6.uuid.uk"
[01:38:15] DNS Resolver: TTL: 5s
[01:38:15] DNS Resolver: TYPE: AAAA: IP6 Address
[01:38:15] DNS Resolver: Lookup successful: irctest6.uuid.uk
[01:38:15] DNS resolved irctest6.uuid.uk to 2001:6b0:e:2a18::118
Thanks for setting up those DNS records to use, very smart approach for testing! You also forced me to figure out how to enable ipv6 in my vmware instances, which I'd been putting off far too long...
So now for the philosophy discussion for @thommey and @Cizzle ... let's say I have a list of IPv6 servers in my server list, some of which have dual A and AAAA records, and I have prefer-ipv6 set to 1. If connecting to the IP returned by a AAAA record fails, is it better to try the A record, or just roll to the next server in the list that has a functional IP? Now, what happens if there are multiple IPs associated with a single AAAA record? Am I supposed to iterate through all of them before moving to the next server? We don't do that now on the IPv4 side of the house, we just hit the next server in the list, which is basically what this functionality is already doing.
I think my current take on this is, the current functionality of Eggdrop is the desired functionality. I'm open to hearing otherwise, and I'm also open to seeing if there some additional setting that could be added (maybe a setting to try one IP from both records if two are returned?)... but I'm just not seeing this use case as sufficient to override current functionality of 'try one, then move on to the next entry'.
In the case of multiple IPv4/IPv6 entries and 'prefer-ipv6' set: I would vote for trying the servers first IPv6 address and then rolling to the next server entry in the server list. Each entry should try the first IPv6 address returned. In the case only IPv4 entries are returned it should fall back to using the IPv4 entry.
In the case of multiple IPv4/IPv6 entries and 'prefer-ipv6' not set: I would vote for trying the servers first IPv4 address and then rolling to the next server entry in the server list.
If there is only IPv4 or IPv6 addresses returned then the choice is already made for you, just try the first address.
I believe this would be in the spirit of multiple entries for doing round-robin DNS entries. Whoever maintains the DNS should probably pay more attention and keep their DNS entries updated.
Just my $0.02
Regardless of the order, it must attempt to use all of the A/AAAA responses for each hostname.
One way to do that would be to retain a cache of most recently attempted IP addresses and prefer ones that have not been attempted recently.
We have an open issue to use round robins properly -> #204 I think that requires a more extensive rewrite of dns.mod (it should really store all responses, not just lookup again and rely on it rotating to something it didn't already try)
"Regardless of the order, it must attempt to use all of the A/AAAA responses for each hostname."
Why "must" it attempt to use all responses for each hostname?
because most ircds have a single irc.network.org round robin containing all server IPs and it makes sense to go through all of them if the bot is k-lined on only a few of them, or exceeds the local connection limit on that server (IRCnet has a ton of servers that simply don't allow countries other than their own, etc.)
I'm not sure how that is a "must" though, it still works without doing that now. And just to play out that user scenario a little further, what happens if it does only try the first record? It rolls to the next entry, which is another server for the same network, or in the case of only one entry, it tries that server again, in which case it should be able to grab a different IP? It seems to me that the bot would still get online. However, I'm not sure I want to conflate the round robin request directly with the multiple ipv4 and IPv6 records associated with this issue, though
It is a "must" but there are a lot of ways to implement that behaviour, including randomly picking one IP from all responses for a hostname (which I think it currently does as long as the responses from the resolver aren't always in the same order). It will eventually try all of them.
The problem with trying both A and AAAA records is that it only applies in situations where both addresses resolve to the same hostname. Most commercial shell account providers for instance have different sets of vhosts for v4 and v6. Users need to be able to bind Eggdrop to either of them and have it show up on IRC with the expected vhost.
Arbitrarily picking IP versions to use based on DNS responses might be a desirable in most situations but for IRC my feeling is that it would confuse people more than it would help.
That just means that you need to have two bind addresses for outgoing connections, one for IPv4 and one for IPv6. If you can't supply both then you can't use both address families.
Consider this scenario; you're on a system with multiple v4 and v6 hosts. All of them unique. You configure Eggdrop with vhost4/vhost6 unset but you enable prefer-ipv6. Eggdrop would pick the first available v6 address and use that. Some time later Eggdrop reconnects to IRC. It can't connect to the v6 address for one of the servers in the server list and falls back to v4. Resulting in Eggdrop joining IRC with a different vhost.
So add a new setting for people who want to use DNS properly by removing the restriction on one address family. I can't imagine anyone using eggdrop who would not want to take advantage of both IPv4 and IPv6 connectivity to IRC networks.
Sounds good to me. If Eggdrop ever moves to try connecting to v6 by default it should probably fall back to v4 automatically by default as well.
There is also a bug described in #773 that looks similar. if dns mod is loaded, it will cache any ip (and its type) resolved from a hostname. asking dns mod to resolve to a different ip type while the hostname (as key) is still in its cache wont result into anything else but the cached ip (and its type). a bug, that could complicate the situation described here.