Open seriyps opened 4 years ago
TIL: there is a recommended way of doing this: https://en.m.wikipedia.org/wiki/Happy_Eyeballs
UPD: even more concrete RFC specifically for dual-stack SMTP servers and clients: https://datatracker.ietf.org/doc/html/rfc3974
Why?
Well, shortage of ipv4 addresses. More flexibility. But at the same time, not all mail receivers support ipv6, so, you can't just be ipv6-only
Problem
gen_smtp_client
usesgen_tcp:connect/3
and this one always uses ipv4:It's possible to tell gen_tcp which protocol to use by providing
inet
orinet6
options, but if you'll provide both, only 1st one will be used:Also,
smtp_util:mxlookup
explicitly resolvesA
dns if noMX
is found and ignoresAAAA
ones.https://github.com/gen-smtp/gen_smtp/blob/62f585bf8d630908c9f958c978140f1012be0343/src/smtp_util.erl#L52
Proposed solutions
So it seems like OTP does not provide an easy way to do this. What we can do instead is to: A: manually resolve MX - A/AAAA records and try them one-by-one. B: call
gen_tcp:connect("example.com", 25, [inet6])
and if that failsgen_tcp:connect("example.com", 25, [inet])
. Both are quite intrusive changes I would say (can increase latency), so, probably should be turned on by some option? Say{ip_versions, [inet:address_family()]}
- this way one can define both priority (elements in a list are tried one-by-one) and can enable/disable ip families by not including to a list. Also, smth should be done withsmtp_util:mxlookup
. Either we always return all IPs from MX and A or we just return unresolved domain from mxlookup fallback.