thunderbird-android icon indicating copy to clipboard operation
thunderbird-android copied to clipboard

Fall back to IPv4 if IPv6 connection fails

Open Grey-1 opened this issue 8 years ago • 16 comments

Expected behaviour

POP mail should download on timed intervals or on demand

Actual behaviour

POP mail does not download - fails immediately. Mail can still be sent and other Internet applications work.

Steps to reproduce

Problem started only after I switched ISP. Wireless router unchanged. Everything works perfectly until I am out of range of my home WiFi network. F-9 continues to work perfectly using the phone network.

When I return to my home WiFi network, the WiFi network re-connects and it is used preferentially over the phone network, but K-9 no longer fetches mail. K-9 can still send (it uses a different server than for fetching which may or may be relevant) and all other Internet applications are fine.

Neither a Force Stop of K-9 nor an Android reboot fixes the problem. Only solution I have found is to temporarily reconnect my old modem/ISP (which is still working for a few days) and reconnect to the POP server. This resets the problem and it now works when I revert to the new ISP (until I go out of WiFi range again).

Debug logs implies that there is a 30000 MS timeout connecting to port 995, but the error happens almost instantaneously. See log for two consecutive tries 2 seconds apart.

Debug Logs (3 instances - on cursory inspection, they seem to all be the same) attached DebugLog-20160514.txt

Environment

K-9 Mail version: 5.010 Android version: 5.1.1 Account type (IMAP, POP3, WebDAV/Exchange): POP3

Grey-1 avatar May 15 '16 00:05 Grey-1

Forgot to add, at the time K-9 will not fetch mail, my desktop mail application going through the same router and modem has no problem.

Grey-1 avatar May 15 '16 04:05 Grey-1

This seems to be an ipv6 problem. My guess would be your new modem does ipv6 but not correctly, android tries to use ipv6 but it doesn't work so it times out. Your desktop mail application probably just uses ipv4.

Try disabling ipv6 in your modem and see if that fixes it to test this theory, please.

Valodim avatar May 24 '16 07:05 Valodim

For IMAP and SMTP we already cycle through all available addresses we can get for the target host when trying to connect. This needs to be ported to Pop3Store as well.

I want to do this together with SOCKS proxy support in #1181.

cketti avatar May 28 '16 19:05 cketti

Thanks for this.

Based on the presence of athe IPv6 address in the log, I have done further investigation. My old ISP did not support IPv6 at all, and the new one uses 6rd tunneling.

6rd is a stateless mechanism and SHOULD be transparent.

I am working through my mail provider to see if it is possible to access the server logs at the time of the failure.

Grey-1 avatar May 28 '16 20:05 Grey-1

an option to disable ipv6 support would be great.

hgourvest avatar Jun 24 '16 11:06 hgourvest

Wanted to post new issue, but found this one, which is related to mine. Sometimes k9mail fails to sync via IMAP and send mails via SMTP for me. The problem seems that it resolves IPv6 address of mail host although the network does not support IPv6, thus it fails to connect. However it does not try to connect via IPv4, contrary to what @cketti mentioned. Am I missing something here? Also, adding an option to disable IPv6 altogether as @hgourvest suggests would be great.

PF4Public avatar Aug 17 '16 18:08 PF4Public

This happens to me over SMTP, even though the domain name has no quad-A records.

jorissteyn avatar Oct 04 '16 15:10 jorissteyn

I see the issue for both POP3 and SMTP as well (my mail server has IPv4 and IPv6 support) - at hotel wlan or similar low-cost setups over which I have no controll IPv6 might be available but not work, or routing is temporarily broken. I have to turn off wlan and use LTE to get messages out.

K9-Mail version: 5.206

com.fsck.k9.mail.MessagingException: Unable to open connection to SMTP server. at com.fsck.k9.mail.transport.SmtpTransport.open(SmtpTransport.java:405) at com.fsck.k9.mail.transport.SmtpTransport.sendMessageTo(SmtpTransport.java:504) at com.fsck.k9.mail.transport.SmtpTransport.sendMessage(SmtpTransport.java:496) at com.fsck.k9.controller.MessagingController.sendPendingMessagesSynchronous(MessagingController.java:3014) at com.fsck.k9.controller.MessagingController.access$1700(MessagingController.java:115) at com.fsck.k9.controller.MessagingController$21.run(MessagingController.java:2895) at com.fsck.k9.controller.MessagingController.runInBackground(MessagingController.java:204) at com.fsck.k9.controller.MessagingController.access$000(MessagingController.java:115) at com.fsck.k9.controller.MessagingController$1.run(MessagingController.java:173) at java.lang.Thread.run(Thread.java:818) Caused by: java.net.SocketTimeoutException: failed to connect to mailserver.example.com/an:IPv6::address (port 25) after 10000ms at libcore.io.IoBridge.connectErrno(IoBridge.java:169) at libcore.io.IoBridge.connect(IoBridge.java:122) at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:183) at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:452) at java.net.Socket.connect(Socket.java:884) at com.fsck.k9.mail.transport.SmtpTransport.open(SmtpTransport.java:223)

MartinHusemann avatar Jul 06 '17 08:07 MartinHusemann

This is a BIG problem. I cannot send mail to any provider offering IPV6 on their SMTP server - not even my own. The phone picks a private IPV6 address, the server offers one but none of my routers and none of my internet providers offer an IPV6 path.

07-12 23:25:29.670 E/k9 ( 5752): Caused by: java.net.SocketTimeoutException: failed to connect to mail.stellarhost.eu/2a01:4f8:190:2461::200:1 (port 587) after 10000ms

The same to gmail.

None of any other mail clients has any problem with this and READING mail seems no problem, even if the servers offer IPV6 on IMAP too - which they do.

PLEASE, provide a fallback and please keep the timeout reasonable.

rorso avatar Jul 14 '17 05:07 rorso

Instead of a timeout/fallback, even better would be a "happy eyeballs" aproach (that is: connect to all addresses returned by the DNS query and use the one the succeeds first).

MartinHusemann avatar Jul 14 '17 08:07 MartinHusemann

I have two SMTP servers with one name (two A records for the name). If one of the servers is down and K9mail choose address of the dead server then K9mail fails to send email without a retry. The solution described by @MartinHusemann looks good for me. It may help with IPv6 issues too.

eugene-bright avatar Jul 01 '19 11:07 eugene-bright

Current implementation do not use "happy eyeballs" but tries to find first listening server. https://github.com/k9mail/k-9/blob/5.600/k9mail-library/src/main/java/com/fsck/k9/mail/transport/smtp/SmtpTransport.java#L120 It should be enough to fight the problem.

I will try to get the logs.

eugene-bright avatar Jul 02 '19 23:07 eugene-bright

I think happy-eyeballs should be the way to go.

I've just done it for OfflineIMAP https://github.com/OfflineIMAP/offlineimap/commit/0d5496ba0a21aa6df5d10391af01d5017fb973bf, and am looking at doing it for msmtp (testing in https://github.com/shtrom/happy-eyeballs-c at the moment). K9 would be next on my list (but I really cannot promise anything).

Some context finding, though: Is this SmtpTransport the only bit that initiate a connection, or are there others (e.g., POP or IMAP code)? That's the only one I am seeing timeouts through an incorrectly configured IPv6 network, but I assume the same would happen for the other protocols, too.

shtrom avatar Jul 04 '19 02:07 shtrom

I'm running into the same issue with SMTP, but IMAP works fine:

Incoming and Outgoing servers both are the same in k9 settings: myserver.tld (port 143/587, both with STARTTLS)

Internet connection in my home has IPv6 network access, and android prerefs IPv6 over IPv4. Several days ago I've configured IPv6 for my mail server, but not completely: wile MX points to mail.myserver.tld and works fine, myserver.tld (that's specified in k9 settings) don't accept incoming connections on 143/587 ports via IPv6.

532910 avatar Oct 12 '19 08:10 532910

Same here on both IMAP and SMTP. K-9 should definitely have an option to disable IPv6. Feel free to contact me if you need a test mail account on my host.

hokascha avatar Apr 20 '20 18:04 hokascha

I want to share some code that solved this for me. It's partially lifted from SmtpTransport, minus a bug that prevented the fallback to other addresses to work in practice. What is also does -in a very hacky way- is to try IPv4 addresses first, and then IPv6 addresses.

This goes into the Pop3Connection.open method:

InetAddress[] addresses = InetAddress.getAllByName(settings.getHost());
boolean done = false;
// this loop is used to try IPv4 addresses first, and IPv6 addresses afterwards
for (int protocol = 4; protocol <= 6 && ! done; protocol += 2) {
	for (int i = 0; i < addresses.length && ! done; i++) {
		if (! addresses[i].getClass().getName().contains(String.valueOf(protocol)))
			continue;

		Log.i("K9-Mail", "POP3: trying "+addresses[i]);
		try {
			SocketAddress socketAddress = new InetSocketAddress(addresses[i], settings.getPort());
			if (settings.getConnectionSecurity() == ConnectionSecurity.SSL_TLS_REQUIRED) {
				socket = trustedSocketFactory.createSocket(null, settings.getHost(),
						settings.getPort(), settings.getClientCertificateAlias());
				socket.connect(socketAddress, SOCKET_CONNECT_TIMEOUT);
			} else {
				socket = new Socket();
				socket.connect(socketAddress, SOCKET_CONNECT_TIMEOUT);
			}
		} catch (SocketException | SocketTimeoutException ex) {
			// the original code only caught SocketException, but the timout throws SocketTimeoutException
			Log.e("K9-Mail", "POP3: failed "+addresses[i]);
			if (i < (addresses.length - 1)) {
				// there are still other addresses for that host to try
				continue;
			}
			throw new MessagingException("Cannot connect to host", ex);
		}
		done = true; // connection success
	}
}

I also set the timeout from 30 seconds down to 6 seconds, which seems sufficient, but YMMV.

udittmer avatar Jun 02 '22 09:06 udittmer