Snap for 11052082 from d023c314fa5f6a2b14c75c9c3e741449cda83470 to mainline-media-release Change-Id: I2cbb6f78e74d283438cde136185a1ed431c524de
diff --git a/src/com/android/networkstack/netlink/TcpSocketTracker.java b/src/com/android/networkstack/netlink/TcpSocketTracker.java index d28f4b5..fea858f 100644 --- a/src/com/android/networkstack/netlink/TcpSocketTracker.java +++ b/src/com/android/networkstack/netlink/TcpSocketTracker.java
@@ -68,9 +68,9 @@ import com.android.net.module.util.DeviceConfigUtils; import com.android.net.module.util.SocketUtils; import com.android.net.module.util.netlink.InetDiagMessage; -import com.android.net.module.util.netlink.NetlinkConstants; import com.android.net.module.util.netlink.NetlinkUtils; import com.android.net.module.util.netlink.StructInetDiagMsg; +import com.android.net.module.util.netlink.StructNlAttr; import com.android.net.module.util.netlink.StructNlMsgHdr; import com.android.networkstack.apishim.NetworkShimImpl; import com.android.networkstack.apishim.common.UnsupportedApiLevelException; @@ -401,18 +401,13 @@ int mark = NetlinkUtils.INIT_MARK_VALUE; // Get a tcp_info. while (bytes.position() < remainingDataSize) { - final RoutingAttribute rtattr = - new RoutingAttribute(bytes.getShort(), bytes.getShort()); - final short dataLen = rtattr.getDataLength(); - if (rtattr.rtaType == NetlinkUtils.INET_DIAG_INFO) { - tcpInfo = TcpInfo.parse(bytes, dataLen); - } else if (rtattr.rtaType == NetlinkUtils.INET_DIAG_MARK) { - mark = bytes.getInt(); - } else { - // Data provided by kernel will include both valid data and padding data. The data - // len provided from kernel indicates the valid data size. Readers must deduce the - // alignment by themselves. - skipRemainingAttributesBytesAligned(bytes, dataLen); + final StructNlAttr nlattr = StructNlAttr.parse(bytes); + if (nlattr == null) break; + + if (nlattr.nla_type == NetlinkUtils.INET_DIAG_MARK) { + mark = nlattr.getValueAsInteger(); + } else if (nlattr.nla_type == NetlinkUtils.INET_DIAG_INFO) { + tcpInfo = TcpInfo.parse(nlattr.getValueAsByteBuffer(), nlattr.getAlignedLength()); } } final SocketInfo info = new SocketInfo(tcpInfo, family, mark, time, uid, cookie, dstPort); @@ -503,31 +498,6 @@ return mTcpPacketsFailRateThreshold; } - /** - * Method to skip the remaining attributes bytes. - * Corresponds to NLMSG_NEXT in bionic/libc/kernel/uapi/linux/netlink.h. - * - * @param buffer the target ByteBuffer - * @param len the remaining length to skip. - */ - private static void skipRemainingAttributesBytesAligned(@NonNull final ByteBuffer buffer, - final short len) { - // Data in {@Code RoutingAttribute} is followed after header with size {@Code NLA_ALIGNTO} - // bytes long for each block. Next attribute will start after the padding bytes if any. - // If all remaining bytes after header are valid in a data block, next attr will just start - // after valid bytes. - // - // E.g. With NLA_ALIGNTO(4), an attr struct with length 5 means 1 byte valid data remains - // after header and 3(4-1) padding bytes. Next attr with length 8 will start after the - // padding bytes and contain 4(8-4) valid bytes of data. The next attr start after the - // valid bytes, like: - // - // [HEADER(L=5)][ 4-Bytes DATA ][ HEADER(L=8) ][4 bytes DATA][Next attr] - // [ 5 valid bytes ][3 padding bytes ][ 8 valid bytes ] ... - final int cur = buffer.position(); - buffer.position(cur + NetlinkConstants.alignedLengthOf(len)); - } - private static void log(final String str) { if (DBG) Log.d(TAG, str); } @@ -539,30 +509,6 @@ } /** - * Corresponds to {@code struct rtattr} from bionic/libc/kernel/uapi/linux/rtnetlink.h - * - * struct rtattr { - * unsigned short rta_len; // Length of option - * unsigned short rta_type; // Type of option - * // Data follows - * }; - */ - static class RoutingAttribute { - public static final int HEADER_LENGTH = 4; - - public final short rtaLen; // The whole valid size of the struct. - public final short rtaType; - - RoutingAttribute(final short len, final short type) { - rtaLen = len; - rtaType = type; - } - public short getDataLength() { - return (short) (rtaLen - HEADER_LENGTH); - } - } - - /** * Data class for keeping the socket info. */ @VisibleForTesting
diff --git a/tests/unit/src/com/android/networkstack/netlink/TcpSocketTrackerTest.java b/tests/unit/src/com/android/networkstack/netlink/TcpSocketTrackerTest.java index a697d8d..165deab 100644 --- a/tests/unit/src/com/android/networkstack/netlink/TcpSocketTrackerTest.java +++ b/tests/unit/src/com/android/networkstack/netlink/TcpSocketTrackerTest.java
@@ -474,82 +474,82 @@ private static String composeSockDiagTcpHex(int retrans, int sent, short dstPort, long cookie) { return // struct nlmsghdr. - "14010000" + // length = 276 - "1400" + // type = SOCK_DIAG_BY_FAMILY - "0301" + // flags = NLM_F_REQUEST | NLM_F_DUMP - "00000000" + // seqno - "00000000" + // pid (0 == kernel) + "14010000" // length = 276 + + "1400" // type = SOCK_DIAG_BY_FAMILY + + "0301" // flags = NLM_F_REQUEST | NLM_F_DUMP + + "00000000" // seqno + + "00000000" // pid (0 == kernel) // struct inet_diag_req_v2 - "02" + // family = AF_INET - "06" + // state - "00" + // timer - "00" + // retrans + + "02" // family = AF_INET + + "06" // state + + "00" // timer + + "00" // retrans // inet_diag_sockid: ports and addresses are always in big endian, // see StructInetDiagSockId. - "DEA5" + // idiag_sport = 56997 - getHexStringFromShort(dstPort, ByteOrder.BIG_ENDIAN) + // idiag_dport - "0a006402000000000000000000000000" + // idiag_src = 10.0.100.2 - "08080808000000000000000000000000" + // idiag_dst = 8.8.8.8 - "00000000" + // idiag_if - getHexStringFromLong(cookie) + // idiag_cookie - "00000000" + // idiag_expires - "00000000" + // idiag_rqueue - "00000000" + // idiag_wqueue - getHexStringFromInt(TEST_UID1) + // idiag_uid - "00000000" + // idiag_inode + + "DEA5" // idiag_sport = 56997 + + getHexStringFromShort(dstPort, ByteOrder.BIG_ENDIAN) // idiag_dport + + "0a006402000000000000000000000000" // idiag_src = 10.0.100.2 + + "08080808000000000000000000000000" // idiag_dst = 8.8.8.8 + + "00000000" // idiag_if + + getHexStringFromLong(cookie) // idiag_cookie + + "00000000" // idiag_expires + + "00000000" // idiag_rqueue + + "00000000" // idiag_wqueue + + getHexStringFromInt(TEST_UID1) // idiag_uid + + "00000000" // idiag_inode // rtattr - "0500" + // len = 5 - "0800" + // type = 8 - "00000000" + // data - "0800" + // len = 8 - "0F00" + // type = 15(INET_DIAG_MARK) - "850A0C00" + // data, socket mark=789125 - "AC00" + // len = 172 - "0200" + // type = 2(INET_DIAG_INFO) + + "0500" // len = 5 + + "0800" // type = 8 + + "00000000" // data + + "0800" // len = 8 + + "0F00" // type = 15(INET_DIAG_MARK) + + "850A0C00" // data, socket mark=789125 + + "AC00" // len = 172 + + "0200" // type = 2(INET_DIAG_INFO) // tcp_info - "01" + // state = TCP_ESTABLISHED - "00" + // ca_state = TCP_CA_OPEN - "05" + // retransmits = 5 - "00" + // probes = 0 - "00" + // backoff = 0 - "07" + // option = TCPI_OPT_WSCALE|TCPI_OPT_SACK|TCPI_OPT_TIMESTAMPS - "88" + // wscale = 8 - "00" + // delivery_rate_app_limited = 0 - "4A911B00" + // rto = 1806666 - "00000000" + // ato = 0 - "2E050000" + // sndMss = 1326 - "18020000" + // rcvMss = 536 - "00000000" + // unsacked = 0 - "00000000" + // acked = 0 - "00000000" + // lost - "00000000" + // retrans = 0 - "00000000" + // fackets = 0 - "BB000000" + // lastDataSent = 187 - "00000000" + // lastAckSent = 0 - "BB000000" + // lastDataRecv = 187 - "BB000000" + // lastDataAckRecv = 187 - "DC050000" + // pmtu = 1500 - "30560100" + // rcvSsthresh = 87600 - "3E2C0900" + // rttt = 601150 - "1F960400" + // rttvar = 300575 - "78050000" + // sndSsthresh = 1400 - "0A000000" + // sndCwnd = 10 - "A8050000" + // advmss = 1448 - "03000000" + // reordering = 3 - "00000000" + // rcvrtt = 0 - "30560100" + // rcvspace = 87600 - getHexStringFromInt(retrans) + // totalRetrans - "53AC000000000000" + // pacingRate = 44115 - "FFFFFFFFFFFFFFFF" + // maxPacingRate = 18446744073709551615 - "0100000000000000" + // bytesAcked = 1 - "0000000000000000" + // bytesReceived = 0 - getHexStringFromInt(sent) + // SegsOut - "00000000" + // SegsIn = 0 - "00000000" + // NotSentBytes = 0 - "3E2C0900" + // minRtt = 601150 - "00000000" + // DataSegsIn = 0 - "00000000" + // DataSegsOut = 0 - "0000000000000000"; // deliverRate = 0 + + "01" // state = TCP_ESTABLISHED + + "00" // ca_state = TCP_CA_OPEN + + "05" // retransmits = 5 + + "00" // probes = 0 + + "00" // backoff = 0 + + "07" // option = TCPI_OPT_WSCALE|TCPI_OPT_SACK|TCPI_OPT_TIMESTAMPS + + "88" // wscale = 8 + + "00" // delivery_rate_app_limited = 0 + + "4A911B00" // rto = 1806666 + + "00000000" // ato = 0 + + "2E050000" // sndMss = 1326 + + "18020000" // rcvMss = 536 + + "00000000" // unsacked = 0 + + "00000000" // acked = 0 + + "00000000" // lost + + "00000000" // retrans = 0 + + "00000000" // fackets = 0 + + "BB000000" // lastDataSent = 187 + + "00000000" // lastAckSent = 0 + + "BB000000" // lastDataRecv = 187 + + "BB000000" // lastDataAckRecv = 187 + + "DC050000" // pmtu = 1500 + + "30560100" // rcvSsthresh = 87600 + + "3E2C0900" // rttt = 601150 + + "1F960400" // rttvar = 300575 + + "78050000" // sndSsthresh = 1400 + + "0A000000" // sndCwnd = 10 + + "A8050000" // advmss = 1448 + + "03000000" // reordering = 3 + + "00000000" // rcvrtt = 0 + + "30560100" // rcvspace = 87600 + + getHexStringFromInt(retrans) // totalRetrans + + "53AC000000000000" // pacingRate = 44115 + + "FFFFFFFFFFFFFFFF" // maxPacingRate = 18446744073709551615 + + "0100000000000000" // bytesAcked = 1 + + "0000000000000000" // bytesReceived = 0 + + getHexStringFromInt(sent) // SegsOut + + "00000000" // SegsIn = 0 + + "00000000" // NotSentBytes = 0 + + "3E2C0900" // minRtt = 601150 + + "00000000" // DataSegsIn = 0 + + "00000000" // DataSegsOut = 0 + + "0000000000000000"; // deliverRate = 0 } @Test @@ -643,28 +643,28 @@ private static final String BAD_DIAG_MSG_HEX = // struct nlmsghdr. - "00000058" + // length = 1476395008 - "1400" + // type = SOCK_DIAG_BY_FAMILY - "0301" + // flags = NLM_F_REQUEST | NLM_F_DUMP - "00000000" + // seqno - "00000000" + // pid (0 == kernel) + "00000058" // length = 1476395008 + + "1400" // type = SOCK_DIAG_BY_FAMILY + + "0301" // flags = NLM_F_REQUEST | NLM_F_DUMP + + "00000000" // seqno + + "00000000" // pid (0 == kernel) // struct inet_diag_req_v2 - "02" + // family = AF_INET - "06" + // state - "00" + // timer - "00" + // retrans + + "02" // family = AF_INET + + "06" // state + + "00" // timer + + "00" // retrans // inet_diag_sockid - "DEA5" + // idiag_sport = 42462 - "71B9" + // idiag_dport = 47473 - "0a006402000000000000000000000000" + // idiag_src = 10.0.100.2 - "08080808000000000000000000000000" + // idiag_dst = 8.8.8.8 - "00000000" + // idiag_if - "34ED000076270000" + // idiag_cookie = 43387759684916 - "00000000" + // idiag_expires - "00000000" + // idiag_rqueue - "00000000" + // idiag_wqueue - "00000000" + // idiag_uid - "00000000"; // idiag_inode + + "DEA5" // idiag_sport = 42462 + + "71B9" // idiag_dport = 47473 + + "0a006402000000000000000000000000" // idiag_src = 10.0.100.2 + + "08080808000000000000000000000000" // idiag_dst = 8.8.8.8 + + "00000000" // idiag_if + + "34ED000076270000" // idiag_cookie = 43387759684916 + + "00000000" // idiag_expires + + "00000000" // idiag_rqueue + + "00000000" // idiag_wqueue + + "00000000" // idiag_uid + + "00000000"; // idiag_inode private static final byte[] BAD_SOCK_DIAG_MSG_BYTES = HexEncoding.decode(BAD_DIAG_MSG_HEX.toCharArray(), false);