From 822935397c573c27ee22d95596b555915073439e Mon Sep 17 00:00:00 2001 From: markchien Date: Wed, 20 Feb 2019 22:47:08 +0800 Subject: [PATCH] Return not supported if no necessary socket option In order to support tcp keepalive offload, some socket options are necessary. If one of them isn't supported in kernel, just return ERROR_HARDWARE_UNSUPPORTED to the caller. e.g. TCP_REPAIR starts from kernel 3.5 TCP_REPAIR_QUEUE starts from kernel 3.5 TCP_QUEUE_SEQ starts from kernel 3.5 TCP_REPAIR_WINDOW starts from kernel version 4.8 Bug: 124453402 Test: -boot, flash, atest FrameworksNetTests -start tcp keepalive offload in kernel 4.4 and 4.9 device. Change-Id: I6f87e5be2f2ca7aae1293820c164d0bc7b664eb6 --- .../server/connectivity/TcpKeepaliveController.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/services/core/java/com/android/server/connectivity/TcpKeepaliveController.java b/services/core/java/com/android/server/connectivity/TcpKeepaliveController.java index 8a9ac23cf0..65de83b204 100644 --- a/services/core/java/com/android/server/connectivity/TcpKeepaliveController.java +++ b/services/core/java/com/android/server/connectivity/TcpKeepaliveController.java @@ -16,10 +16,12 @@ package com.android.server.connectivity; import static android.net.SocketKeepalive.DATA_RECEIVED; +import static android.net.SocketKeepalive.ERROR_HARDWARE_UNSUPPORTED; import static android.net.SocketKeepalive.ERROR_INVALID_SOCKET; import static android.net.SocketKeepalive.ERROR_SOCKET_NOT_IDLE; import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_ERROR; import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_INPUT; +import static android.system.OsConstants.ENOPROTOOPT; import static android.system.OsConstants.FIONREAD; import static android.system.OsConstants.IPPROTO_TCP; import static android.system.OsConstants.TIOCOUTQ; @@ -179,12 +181,13 @@ public class TcpKeepaliveController { trw = NetworkUtils.getTcpRepairWindow(fd); } catch (ErrnoException e) { Log.e(TAG, "Exception reading TCP state from socket", e); - try { - Os.setsockoptInt(fd, IPPROTO_TCP, TCP_REPAIR, TCP_REPAIR_OFF); - } catch (ErrnoException ex) { - Log.e(TAG, "Exception while turning off repair mode due to exception", ex); + if (e.errno == ENOPROTOOPT) { + // ENOPROTOOPT may happen in kernel version lower than 4.8. + // Treat it as ERROR_HARDWARE_UNSUPPORTED. + throw new InvalidSocketException(ERROR_HARDWARE_UNSUPPORTED, e); + } else { + throw new InvalidSocketException(ERROR_INVALID_SOCKET, e); } - throw new InvalidSocketException(ERROR_INVALID_SOCKET, e); } finally { dropAllIncomingPackets(fd, false); }