diff --git a/app/src/main/java/eu/faircode/email/MailService.java b/app/src/main/java/eu/faircode/email/MailService.java index d5904780a9..87bccfcd67 100644 --- a/app/src/main/java/eu/faircode/email/MailService.java +++ b/app/src/main/java/eu/faircode/email/MailService.java @@ -7,13 +7,19 @@ import com.bugsnag.android.Bugsnag; import com.sun.mail.imap.IMAPStore; import com.sun.mail.smtp.SMTPTransport; import com.sun.mail.util.MailConnectException; +import com.sun.mail.util.SocketConnectException; import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; +import java.net.InterfaceAddress; +import java.net.NetworkInterface; import java.net.UnknownHostException; +import java.util.Collections; +import java.util.Enumeration; import java.util.HashMap; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import java.util.Properties; @@ -30,8 +36,6 @@ public class MailService implements AutoCloseable { private Session isession; private Service iservice; - private static final String any4 = "0.0.0.0"; - private MailService() { } @@ -76,22 +80,50 @@ public class MailService implements AutoCloseable { public void connect(String host, int port, String user, String password) throws MessagingException { try { + if (BuildConfig.DEBUG) + throw new MailConnectException(new SocketConnectException("Debug", new Exception(), host, port, 0)); _connect(context, host, port, user, password); } catch (MailConnectException ex) { - if (!hasIPv6(host)) - throw ex; - try { - Log.i("Binding to " + any4); - properties.put("mail.imap.localaddress", any4); - properties.put("mail.imaps.localaddress", any4); - properties.put("mail.smtp.localaddress", any4); - properties.put("mail.smtps.localaddress", any4); - _connect(context, host, port, user, password); + // Addresses + InetAddress[] iaddrs = InetAddress.getAllByName(host); + if (iaddrs.length == 1 && !BuildConfig.DEBUG) + throw ex; + + // Interfaces + Enumeration _nis = NetworkInterface.getNetworkInterfaces(); + if (_nis == null) + throw ex; + List nis = Collections.list(_nis); + + // Match address/interfaces + for (InetAddress iaddr : iaddrs) { + Log.i("Evaluating " + iaddr); + for (NetworkInterface ni : nis) + if (ni.isUp() && !ni.isLoopback()) { + Log.i("Evaluating " + ni); + List ias = ni.getInterfaceAddresses(); + if (ias != null) + for (InterfaceAddress ia : ias) { + InetAddress a = ia.getAddress(); + if (a != null && a.getClass().equals(iaddr.getClass())) { + Log.i("Binding to " + ia + " for " + iaddr); + properties.put("mail." + this.protocol + ".localaddress", a.getHostAddress()); + try { + _connect(context, host, port, user, password); + return; + } catch (MessagingException ex1) { + Log.w(ex1); + } + } + } + } + } } catch (Throwable ex1) { Log.w(ex1); - throw ex; } + + throw ex; } } @@ -130,19 +162,6 @@ public class MailService implements AutoCloseable { throw new NoSuchProviderException(protocol); } - private static boolean hasIPv6(String host) { - boolean has = false; - try { - for (InetAddress iaddr : InetAddress.getAllByName(host)) { - Log.i(host + " resolves to " + iaddr); - if (iaddr instanceof Inet6Address) - has = true; - } - } catch (UnknownHostException ignored) { - } - return has; - } - IMAPStore getStore() { return (IMAPStore) this.iservice; }