diff --git a/app/src/main/java/eu/faircode/email/EmailService.java b/app/src/main/java/eu/faircode/email/EmailService.java index f19fbf7e8a..a3f587c1ca 100644 --- a/app/src/main/java/eu/faircode/email/EmailService.java +++ b/app/src/main/java/eu/faircode/email/EmailService.java @@ -1057,10 +1057,10 @@ public class EmailService implements AutoCloseable { int fd = ParcelFileDescriptor.fromSocket(socket).getFd(); int errno = jni_socket_keep_alive(fd, TCP_KEEP_ALIVE_INTERVAL); - if (errno != 0) - throw new ErrnoException("TCP_KEEPIDLE", errno); - - socket.setKeepAlive(true); + if (errno == 0) + Log.i("Enabled TCP keep alive"); + else + throw new ErrnoException("jni_socket_keep_alive", errno); } } catch (Throwable ex) { Log.e(ex); diff --git a/app/src/main/jni/fairemail.cc b/app/src/main/jni/fairemail.cc index c5868fcda0..886594e0cd 100644 --- a/app/src/main/jni/fairemail.cc +++ b/app/src/main/jni/fairemail.cc @@ -62,14 +62,54 @@ JNIEXPORT jint JNICALL Java_eu_faircode_email_EmailService_jni_1socket_1keep_1alive( JNIEnv *env, jclass clazz, jint fd, jint seconds) { - // https://linux.die.net/man/2/setsockopt - // https://linux.die.net/man/3/setsockopt // https://tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO/#setsockopt - int value = seconds; - int res = setsockopt(fd, SOL_TCP, TCP_KEEPIDLE, (void *) &value, sizeof(value)); + int optval; + socklen_t optlen = sizeof(optval); + + if (getsockopt(fd, SOL_TCP, TCP_KEEPCNT, &optval, &optlen) == 0) + log_android(ANDROID_LOG_INFO, "Default TCP_KEEPCNT=%d", optval); + if (getsockopt(fd, SOL_TCP, TCP_KEEPINTVL, &optval, &optlen) == 0) + log_android(ANDROID_LOG_INFO, "Default TCP_KEEPINTVL=%d", optval); + if (getsockopt(fd, SOL_TCP, TCP_KEEPIDLE, &optval, &optlen) == 0) + log_android(ANDROID_LOG_INFO, "Default TCP_KEEPIDLE=%d", optval); + if (getsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &optval, &optlen) == 0) + log_android(ANDROID_LOG_INFO, "Default SO_KEEPALIVE=%d", optval); + + int res; + int on = 1; + int tcp_keepalive_probes = 9; + int tcp_keepalive_intvl = 75; + int tcp_keepalive_time = seconds; // default 7200 + + log_android(ANDROID_LOG_INFO, "Set TCP_KEEPCNT=%d", tcp_keepalive_probes); + res = setsockopt(fd, SOL_TCP, TCP_KEEPCNT, &tcp_keepalive_probes, sizeof(tcp_keepalive_probes)); + if (res < 0) + return errno; + + log_android(ANDROID_LOG_INFO, "Set TCP_KEEPINTVL=%d", tcp_keepalive_intvl); + res = setsockopt(fd, SOL_TCP, TCP_KEEPINTVL, &tcp_keepalive_intvl, sizeof(tcp_keepalive_intvl)); if (res < 0) - res = errno; + return errno; + + log_android(ANDROID_LOG_INFO, "Set TCP_KEEPIDLE=%d", tcp_keepalive_time); + res = setsockopt(fd, SOL_TCP, TCP_KEEPIDLE, &tcp_keepalive_time, sizeof(tcp_keepalive_time)); + if (res < 0) + return errno; + + log_android(ANDROID_LOG_INFO, "Set SO_KEEPALIVE=%d", on); + res = setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)); + if (res < 0) + return errno; + + if (getsockopt(fd, SOL_TCP, TCP_KEEPCNT, &optval, &optlen) == 0) + log_android(ANDROID_LOG_INFO, "Check TCP_KEEPCNT=%d", optval); + if (getsockopt(fd, SOL_TCP, TCP_KEEPINTVL, &optval, &optlen) == 0) + log_android(ANDROID_LOG_INFO, "Check TCP_KEEPINTVL=%d", optval); + if (getsockopt(fd, SOL_TCP, TCP_KEEPIDLE, &optval, &optlen) == 0) + log_android(ANDROID_LOG_INFO, "Check TCP_KEEPIDLE=%d", optval); + if (getsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &optval, &optlen) == 0) + log_android(ANDROID_LOG_INFO, "Check SO_KEEPALIVE=%d", optval); return res; }