Rename TapPacketReader to PollPacketReader for broader applicability

* Renamed TapPacketReader to PollPacketReader to better reflect its
  functionality beyond TAP interface interaction.
* The class includes general logic for polling and sending packets to
  file descriptors, making it suitable for wider use cases.

Test: TH
Change-Id: Icdf9a9d7ef6f49b589ed9cdbd05159ab95e7e5d9
This commit is contained in:
Yuyang Huang 2024-10-11 13:49:10 +09:00
commit eb3c631b89
20 changed files with 155 additions and 153 deletions

View file

@ -70,7 +70,7 @@ import com.android.net.module.util.Struct;
import com.android.net.module.util.structs.FragmentHeader;
import com.android.net.module.util.structs.Ipv6Header;
import com.android.testutils.HandlerUtils;
import com.android.testutils.TapPacketReader;
import com.android.testutils.PollPacketReader;
import com.android.testutils.TestNetworkTracker;
import org.junit.After;
@ -158,10 +158,10 @@ public abstract class EthernetTetheringTestBase {
protected TetheredInterfaceRequester mTetheredInterfaceRequester;
// Late initialization in initTetheringTester().
private TapPacketReader mUpstreamReader;
private PollPacketReader mUpstreamReader;
private TestNetworkTracker mUpstreamTracker;
private TestNetworkInterface mDownstreamIface;
private TapPacketReader mDownstreamReader;
private PollPacketReader mDownstreamReader;
private MyTetheringEventCallback mTetheringEventCallback;
public Context getContext() {
@ -187,10 +187,10 @@ public abstract class EthernetTetheringTestBase {
return runAsShell(NETWORK_SETTINGS, TETHER_PRIVILEGED, () -> sTm.isTetheringSupported());
}
protected void maybeStopTapPacketReader(final TapPacketReader tapPacketReader)
protected void maybeStopTapPacketReader(final PollPacketReader tapPacketReader)
throws Exception {
if (tapPacketReader != null) {
TapPacketReader reader = tapPacketReader;
PollPacketReader reader = tapPacketReader;
mHandler.post(() -> reader.stop());
}
}
@ -228,7 +228,7 @@ public abstract class EthernetTetheringTestBase {
});
}
if (mUpstreamReader != null) {
TapPacketReader reader = mUpstreamReader;
PollPacketReader reader = mUpstreamReader;
mHandler.post(() -> reader.stop());
mUpstreamReader = null;
}
@ -291,7 +291,7 @@ public abstract class EthernetTetheringTestBase {
});
}
protected static void waitForRouterAdvertisement(TapPacketReader reader, String iface,
protected static void waitForRouterAdvertisement(PollPacketReader reader, String iface,
long timeoutMs) {
final long deadline = SystemClock.uptimeMillis() + timeoutMs;
do {
@ -574,13 +574,13 @@ public abstract class EthernetTetheringTestBase {
return nif.getIndex();
}
protected TapPacketReader makePacketReader(final TestNetworkInterface iface) throws Exception {
protected PollPacketReader makePacketReader(final TestNetworkInterface iface) throws Exception {
FileDescriptor fd = iface.getFileDescriptor().getFileDescriptor();
return makePacketReader(fd, getMTU(iface));
}
protected TapPacketReader makePacketReader(FileDescriptor fd, int mtu) {
final TapPacketReader reader = new TapPacketReader(mHandler, fd, mtu);
protected PollPacketReader makePacketReader(FileDescriptor fd, int mtu) {
final PollPacketReader reader = new PollPacketReader(mHandler, fd, mtu);
mHandler.post(() -> reader.start());
HandlerUtils.waitForIdle(mHandler, TIMEOUT_MS);
return reader;

View file

@ -84,7 +84,7 @@ import com.android.net.module.util.structs.PrefixInformationOption;
import com.android.net.module.util.structs.RaHeader;
import com.android.net.module.util.structs.TcpHeader;
import com.android.net.module.util.structs.UdpHeader;
import com.android.testutils.TapPacketReader;
import com.android.testutils.PollPacketReader;
import java.net.Inet4Address;
import java.net.Inet6Address;
@ -157,14 +157,14 @@ public final class TetheringTester {
public static final String DHCP_HOSTNAME = "testhostname";
private final ArrayMap<MacAddress, TetheredDevice> mTetheredDevices;
private final TapPacketReader mDownstreamReader;
private final TapPacketReader mUpstreamReader;
private final PollPacketReader mDownstreamReader;
private final PollPacketReader mUpstreamReader;
public TetheringTester(TapPacketReader downstream) {
public TetheringTester(PollPacketReader downstream) {
this(downstream, null);
}
public TetheringTester(TapPacketReader downstream, TapPacketReader upstream) {
public TetheringTester(PollPacketReader downstream, PollPacketReader upstream) {
if (downstream == null) fail("Downstream reader could not be NULL");
mDownstreamReader = downstream;

View file

@ -80,7 +80,7 @@ import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
import com.android.testutils.DeviceInfoUtils;
import com.android.testutils.DumpTestUtils;
import com.android.testutils.NetworkStackModuleTest;
import com.android.testutils.TapPacketReader;
import com.android.testutils.PollPacketReader;
import org.junit.After;
import org.junit.Rule;
@ -213,7 +213,7 @@ public class EthernetTetheringTest extends EthernetTetheringTestBase {
TestNetworkInterface downstreamIface = null;
MyTetheringEventCallback tetheringEventCallback = null;
TapPacketReader downstreamReader = null;
PollPacketReader downstreamReader = null;
try {
downstreamIface = createTestInterface();
@ -253,7 +253,7 @@ public class EthernetTetheringTest extends EthernetTetheringTestBase {
TestNetworkInterface downstreamIface = null;
MyTetheringEventCallback tetheringEventCallback = null;
TapPacketReader downstreamReader = null;
PollPacketReader downstreamReader = null;
try {
downstreamIface = createTestInterface();
@ -283,7 +283,7 @@ public class EthernetTetheringTest extends EthernetTetheringTestBase {
TestNetworkInterface downstreamIface = null;
MyTetheringEventCallback tetheringEventCallback = null;
TapPacketReader downstreamReader = null;
PollPacketReader downstreamReader = null;
try {
downstreamIface = createTestInterface();
@ -357,7 +357,7 @@ public class EthernetTetheringTest extends EthernetTetheringTestBase {
TestNetworkInterface downstreamIface = null;
MyTetheringEventCallback tetheringEventCallback = null;
TapPacketReader downstreamReader = null;
PollPacketReader downstreamReader = null;
try {
downstreamIface = createTestInterface();
@ -423,7 +423,7 @@ public class EthernetTetheringTest extends EthernetTetheringTestBase {
// client, which is not possible in this test.
}
private void checkTetheredClientCallbacks(final TapPacketReader packetReader,
private void checkTetheredClientCallbacks(final PollPacketReader packetReader,
final MyTetheringEventCallback tetheringEventCallback) throws Exception {
// Create a fake client.
byte[] clientMacAddr = new byte[6];

View file

@ -43,7 +43,7 @@ import com.android.net.module.util.InterfaceParams;
import com.android.networkstack.tethering.util.TetheringUtils;
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
import com.android.testutils.DevSdkIgnoreRunner;
import com.android.testutils.TapPacketReader;
import com.android.testutils.PollPacketReader;
import com.android.testutils.TapPacketReaderRule;
import org.junit.After;
@ -75,7 +75,7 @@ public class DadProxyTest {
private InterfaceParams mUpstreamParams, mTetheredParams;
private HandlerThread mHandlerThread;
private Handler mHandler;
private TapPacketReader mUpstreamPacketReader, mTetheredPacketReader;
private PollPacketReader mUpstreamPacketReader, mTetheredPacketReader;
private static INetd sNetd;
@ -219,7 +219,7 @@ public class DadProxyTest {
}
// TODO: change to assert.
private boolean waitForPacket(ByteBuffer packet, TapPacketReader reader) {
private boolean waitForPacket(ByteBuffer packet, PollPacketReader reader) {
byte[] p;
while ((p = reader.popPacket(PACKET_TIMEOUT_MS)) != null) {
@ -247,7 +247,7 @@ public class DadProxyTest {
}
private void receivePacketAndMaybeExpectForwarded(boolean expectForwarded,
ByteBuffer in, TapPacketReader inReader, ByteBuffer out, TapPacketReader outReader)
ByteBuffer in, PollPacketReader inReader, ByteBuffer out, PollPacketReader outReader)
throws IOException {
inReader.sendResponse(in);
@ -271,13 +271,13 @@ public class DadProxyTest {
assertEquals(msg, expectForwarded, waitForPacket(out, outReader));
}
private void receivePacketAndExpectForwarded(ByteBuffer in, TapPacketReader inReader,
ByteBuffer out, TapPacketReader outReader) throws IOException {
private void receivePacketAndExpectForwarded(ByteBuffer in, PollPacketReader inReader,
ByteBuffer out, PollPacketReader outReader) throws IOException {
receivePacketAndMaybeExpectForwarded(true, in, inReader, out, outReader);
}
private void receivePacketAndExpectNotForwarded(ByteBuffer in, TapPacketReader inReader,
ByteBuffer out, TapPacketReader outReader) throws IOException {
private void receivePacketAndExpectNotForwarded(ByteBuffer in, PollPacketReader inReader,
ByteBuffer out, PollPacketReader outReader) throws IOException {
receivePacketAndMaybeExpectForwarded(false, in, inReader, out, outReader);
}

View file

@ -64,7 +64,7 @@ import com.android.net.module.util.structs.MtuOption;
import com.android.net.module.util.structs.PrefixInformationOption;
import com.android.net.module.util.structs.RaHeader;
import com.android.net.module.util.structs.RdnssOption;
import com.android.testutils.TapPacketReader;
import com.android.testutils.PollPacketReader;
import com.android.testutils.TapPacketReaderRule;
import org.junit.After;
@ -93,7 +93,7 @@ public final class RouterAdvertisementDaemonTest {
private InterfaceParams mTetheredParams;
private HandlerThread mHandlerThread;
private Handler mHandler;
private TapPacketReader mTetheredPacketReader;
private PollPacketReader mTetheredPacketReader;
private RouterAdvertisementDaemon mRaDaemon;
private static INetd sNetd;

View file

@ -35,12 +35,12 @@ import java.nio.ByteBuffer
private const val NS_TYPE = 135.toShort()
/**
* A class that can be used to reply to Neighbor Solicitation packets on a [TapPacketReader].
* A class that can be used to reply to Neighbor Solicitation packets on a [PollPacketReader].
*/
class NSResponder(
reader: TapPacketReader,
table: Map<Inet6Address, MacAddress>,
name: String = NSResponder::class.java.simpleName
reader: PollPacketReader,
table: Map<Inet6Address, MacAddress>,
name: String = NSResponder::class.java.simpleName
) : PacketResponder(reader, Icmpv6Filter(), name) {
companion object {
private val TAG = NSResponder::class.simpleName
@ -49,7 +49,7 @@ class NSResponder(
// Copy the map if not already immutable (toMap) to make sure it is not modified
private val table = table.toMap()
override fun replyToPacket(packet: ByteArray, reader: TapPacketReader) {
override fun replyToPacket(packet: ByteArray, reader: PollPacketReader) {
if (packet.size < IPV6_HEADER_LENGTH) {
return
}

View file

@ -30,17 +30,17 @@ private val TYPE_ARP = byteArrayOf(0x08, 0x06)
private val ARP_REPLY_IPV4 = byteArrayOf(0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x02)
/**
* A class that can be used to reply to ARP packets on a [TapPacketReader].
* A class that can be used to reply to ARP packets on a [PollPacketReader].
*/
class ArpResponder(
reader: TapPacketReader,
table: Map<Inet4Address, MacAddress>,
name: String = ArpResponder::class.java.simpleName
reader: PollPacketReader,
table: Map<Inet4Address, MacAddress>,
name: String = ArpResponder::class.java.simpleName
) : PacketResponder(reader, ArpRequestFilter(), name) {
// Copy the map if not already immutable (toMap) to make sure it is not modified
private val table = table.toMap()
override fun replyToPacket(packet: ByteArray, reader: TapPacketReader) {
override fun replyToPacket(packet: ByteArray, reader: PollPacketReader) {
val targetIp = InetAddress.getByAddress(
packet.copyFromIndexWithLength(ARP_TARGET_IPADDR_OFFSET, 4))
as Inet4Address

View file

@ -28,8 +28,6 @@ import com.android.net.module.util.NetworkStackConstants.IPV6_DST_ADDR_OFFSET
import com.android.net.module.util.NetworkStackConstants.IPV6_HEADER_LEN
import com.android.net.module.util.NetworkStackConstants.UDP_HEADER_LEN
import com.android.net.module.util.TrackRecord
import com.android.testutils.IPv6UdpFilter
import com.android.testutils.TapPacketReader
import java.net.Inet6Address
import java.net.InetAddress
import kotlin.test.assertEquals
@ -246,7 +244,7 @@ private fun getDstAddr(packet: ByteArray): Inet6Address {
as Inet6Address
}
fun TapPacketReader.pollForMdnsPacket(
fun PollPacketReader.pollForMdnsPacket(
timeoutMs: Long = MDNS_REGISTRATION_TIMEOUT_MS,
predicate: (TestDnsPacket) -> Boolean
): TestDnsPacket? {
@ -264,7 +262,7 @@ fun TapPacketReader.pollForMdnsPacket(
}
}
fun TapPacketReader.pollForProbe(
fun PollPacketReader.pollForProbe(
serviceName: String,
serviceType: String,
timeoutMs: Long = MDNS_REGISTRATION_TIMEOUT_MS
@ -272,7 +270,7 @@ fun TapPacketReader.pollForProbe(
it.isProbeFor("$serviceName.$serviceType.local")
}
fun TapPacketReader.pollForAdvertisement(
fun PollPacketReader.pollForAdvertisement(
serviceName: String,
serviceType: String,
timeoutMs: Long = MDNS_REGISTRATION_TIMEOUT_MS
@ -280,19 +278,19 @@ fun TapPacketReader.pollForAdvertisement(
it.isReplyFor("$serviceName.$serviceType.local")
}
fun TapPacketReader.pollForQuery(
fun PollPacketReader.pollForQuery(
recordName: String,
vararg requiredTypes: Int,
timeoutMs: Long = MDNS_REGISTRATION_TIMEOUT_MS
): TestDnsPacket? = pollForMdnsPacket(timeoutMs) { it.isQueryFor(recordName, *requiredTypes) }
fun TapPacketReader.pollForReply(
fun PollPacketReader.pollForReply(
recordName: String,
type: Int,
timeoutMs: Long = MDNS_REGISTRATION_TIMEOUT_MS
): TestDnsPacket? = pollForMdnsPacket(timeoutMs) { it.isReplyFor(recordName, type) }
fun TapPacketReader.pollForReply(
fun PollPacketReader.pollForReply(
serviceName: String,
serviceType: String,
timeoutMs: Long = MDNS_REGISTRATION_TIMEOUT_MS

View file

@ -21,24 +21,24 @@ import java.util.function.Predicate
private const val POLL_FREQUENCY_MS = 1000L
/**
* A class that can be used to reply to packets from a [TapPacketReader].
* A class that can be used to reply to packets from a [PollPacketReader].
*
* A reply thread will be created to reply to incoming packets asynchronously.
* The receiver creates a new read head on the [TapPacketReader], to read packets, so it does not
* affect packets obtained through [TapPacketReader.popPacket].
* The receiver creates a new read head on the [PollPacketReader], to read packets, so it does not
* affect packets obtained through [PollPacketReader.popPacket].
*
* @param reader a [TapPacketReader] to obtain incoming packets and reply to them.
* @param reader a [PollPacketReader] to obtain incoming packets and reply to them.
* @param packetFilter A filter to apply to incoming packets.
* @param name Name to use for the internal responder thread.
*/
abstract class PacketResponder(
private val reader: TapPacketReader,
private val packetFilter: Predicate<ByteArray>,
name: String
private val reader: PollPacketReader,
private val packetFilter: Predicate<ByteArray>,
name: String
) {
private val replyThread = ReplyThread(name)
protected abstract fun replyToPacket(packet: ByteArray, reader: TapPacketReader)
protected abstract fun replyToPacket(packet: ByteArray, reader: PollPacketReader)
/**
* Start the [PacketResponder].

View file

@ -0,0 +1,137 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.testutils;
import android.os.Handler;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.net.module.util.ArrayTrackRecord;
import com.android.net.module.util.PacketReader;
import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.function.Predicate;
import kotlin.Lazy;
import kotlin.LazyKt;
/**
* A packet reader that can poll for received packets and send responses on a fd.
*
* It also implements facilities to reply to received packets.
*/
public class PollPacketReader extends PacketReader {
private final FileDescriptor mFd;
private final ArrayTrackRecord<byte[]> mReceivedPackets = new ArrayTrackRecord<>();
private final Lazy<ArrayTrackRecord<byte[]>.ReadHead> mReadHead =
LazyKt.lazy(mReceivedPackets::newReadHead);
public PollPacketReader(Handler h, FileDescriptor fd, int maxPacketSize) {
super(h, maxPacketSize);
mFd = fd;
}
/**
* Attempt to start the FdEventsReader on its handler thread.
*
* As opposed to {@link android.net.util.FdEventsReader#start()}, this method will not report
* failure to start, so it is only appropriate in tests that will fail later if that happens.
*/
public void startAsyncForTest() {
getHandler().post(this::start);
}
@Override
protected FileDescriptor createFd() {
return mFd;
}
@Override
protected void handlePacket(byte[] recvbuf, int length) {
final byte[] newPacket = Arrays.copyOf(recvbuf, length);
if (!mReceivedPackets.add(newPacket)) {
throw new AssertionError("More than " + Integer.MAX_VALUE + " packets outstanding!");
}
}
/**
* @deprecated This method does not actually "pop" (which generally means the last packet).
* Use {@link #poll(long)}, which has the same behavior, instead.
*/
@Nullable
@Deprecated
public byte[] popPacket(long timeoutMs) {
return poll(timeoutMs);
}
/**
* @deprecated This method does not actually "pop" (which generally means the last packet).
* Use {@link #poll(long, Predicate)}, which has the same behavior, instead.
*/
@Nullable
@Deprecated
public byte[] popPacket(long timeoutMs, @NonNull Predicate<byte[]> filter) {
return poll(timeoutMs, filter);
}
/**
* Get the next packet that was received on the interface.
*/
@Nullable
public byte[] poll(long timeoutMs) {
return mReadHead.getValue().poll(timeoutMs, packet -> true);
}
/**
* Get the next packet that was received on the interface and matches the specified filter.
*/
@Nullable
public byte[] poll(long timeoutMs, @NonNull Predicate<byte[]> filter) {
return mReadHead.getValue().poll(timeoutMs, filter::test);
}
/**
* Get the {@link ArrayTrackRecord} that records all packets received by the reader since its
* creation.
*/
public ArrayTrackRecord<byte[]> getReceivedPackets() {
return mReceivedPackets;
}
/*
* Send a response on the fd.
*
* The passed ByteBuffer is flipped after use.
*
* @param packet The packet to send.
* @throws IOException if the interface can't be written to.
*/
public void sendResponse(final ByteBuffer packet) throws IOException {
try (FileOutputStream out = new FileOutputStream(mFd)) {
byte[] packetBytes = new byte[packet.limit()];
packet.get(packetBytes);
packet.flip(); // So we can reuse it in the future.
out.write(packetBytes);
}
}
}

View file

@ -62,18 +62,18 @@ public class RouterAdvertisementResponder extends PacketResponder {
private static final String TAG = "RouterAdvertisementResponder";
private static final Inet6Address DNS_SERVER =
(Inet6Address) InetAddresses.parseNumericAddress("2001:4860:4860::64");
private final TapPacketReader mPacketReader;
private final PollPacketReader mPacketReader;
// Maps IPv6 address to MacAddress and isRouter boolean.
private final Map<Inet6Address, Pair<MacAddress, Boolean>> mNeighborMap = new ArrayMap<>();
private final IpPrefix mPrefix;
public RouterAdvertisementResponder(TapPacketReader packetReader, IpPrefix prefix) {
public RouterAdvertisementResponder(PollPacketReader packetReader, IpPrefix prefix) {
super(packetReader, RouterAdvertisementResponder::isRsOrNs, TAG);
mPacketReader = packetReader;
mPrefix = Objects.requireNonNull(prefix);
}
public RouterAdvertisementResponder(TapPacketReader packetReader) {
public RouterAdvertisementResponder(PollPacketReader packetReader) {
this(packetReader, makeRandomPrefix());
}
@ -148,7 +148,7 @@ public class RouterAdvertisementResponder extends PacketResponder {
buildSllaOption(srcMac));
}
private static void sendResponse(TapPacketReader reader, ByteBuffer buffer) {
private static void sendResponse(PollPacketReader reader, ByteBuffer buffer) {
try {
reader.sendResponse(buffer);
} catch (IOException e) {
@ -158,7 +158,7 @@ public class RouterAdvertisementResponder extends PacketResponder {
}
}
private void replyToRouterSolicitation(TapPacketReader reader, MacAddress dstMac) {
private void replyToRouterSolicitation(PollPacketReader reader, MacAddress dstMac) {
for (Map.Entry<Inet6Address, Pair<MacAddress, Boolean>> it : mNeighborMap.entrySet()) {
final boolean isRouter = it.getValue().second;
if (!isRouter) {
@ -169,7 +169,7 @@ public class RouterAdvertisementResponder extends PacketResponder {
}
}
private void replyToNeighborSolicitation(TapPacketReader reader, MacAddress dstMac,
private void replyToNeighborSolicitation(PollPacketReader reader, MacAddress dstMac,
Inet6Address dstIp, Inet6Address targetIp) {
final Pair<MacAddress, Boolean> neighbor = mNeighborMap.get(targetIp);
if (neighbor == null) {
@ -190,7 +190,7 @@ public class RouterAdvertisementResponder extends PacketResponder {
}
@Override
protected void replyToPacket(byte[] packet, TapPacketReader reader) {
protected void replyToPacket(byte[] packet, PollPacketReader reader) {
final ByteBuffer buf = ByteBuffer.wrap(packet);
// Messages are filtered by parent class, so it is safe to assume that packet is either an
// RS or NS.

View file

@ -31,9 +31,9 @@ import kotlin.test.fail
private const val HANDLER_TIMEOUT_MS = 10_000L
/**
* A [TestRule] that sets up a [TapPacketReader] on a [TestNetworkInterface] for use in the test.
* A [TestRule] that sets up a [PollPacketReader] on a [TestNetworkInterface] for use in the test.
*
* @param maxPacketSize Maximum size of packets read in the [TapPacketReader] buffer.
* @param maxPacketSize Maximum size of packets read in the [PollPacketReader] buffer.
* @param autoStart Whether to initialize the interface and start the reader automatically for every
* test. If false, each test must either call start() and stop(), or be annotated
* with TapPacketReaderTest before using the reader or interface.
@ -50,21 +50,21 @@ class TapPacketReaderRule @JvmOverloads constructor(
// referenced before they could be initialized (typically if autoStart is false and the test
// does not call start or use @TapPacketReaderTest).
lateinit var iface: TestNetworkInterface
lateinit var reader: TapPacketReader
lateinit var reader: PollPacketReader
@Volatile
private var readerRunning = false
/**
* Indicates that the [TapPacketReaderRule] should initialize its [TestNetworkInterface] and
* start the [TapPacketReader] before the test, and tear them down afterwards.
* start the [PollPacketReader] before the test, and tear them down afterwards.
*
* For use when [TapPacketReaderRule] is created with autoStart = false.
*/
annotation class TapPacketReaderTest
/**
* Initialize the tap interface and start the [TapPacketReader].
* Initialize the tap interface and start the [PollPacketReader].
*
* Tests using this method must also call [stop] before exiting.
* @param handler Handler to run the reader on. Callers are responsible for safely terminating
@ -85,13 +85,13 @@ class TapPacketReaderRule @JvmOverloads constructor(
}
val usedHandler = handler ?: HandlerThread(
TapPacketReaderRule::class.java.simpleName).apply { start() }.threadHandler
reader = TapPacketReader(usedHandler, iface.fileDescriptor.fileDescriptor, maxPacketSize)
reader = PollPacketReader(usedHandler, iface.fileDescriptor.fileDescriptor, maxPacketSize)
reader.startAsyncForTest()
readerRunning = true
}
/**
* Stop the [TapPacketReader].
* Stop the [PollPacketReader].
*
* Tests calling [start] must call this method before exiting. If a handler was specified in
* [start], all messages on that handler must also be processed after calling this method and

View file

@ -71,7 +71,7 @@ import com.android.testutils.ConnectivityModuleTest
import com.android.testutils.DevSdkIgnoreRule
import com.android.testutils.RouterAdvertisementResponder
import com.android.testutils.SC_V2
import com.android.testutils.TapPacketReader
import com.android.testutils.PollPacketReader
import com.android.testutils.TestableNetworkAgent
import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnDscpPolicyStatusUpdated
import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnNetworkCreated
@ -135,7 +135,7 @@ class DscpPolicyTest {
private lateinit var srcAddressV6: Inet6Address
private lateinit var iface: TestNetworkInterface
private lateinit var tunNetworkCallback: TestNetworkCallback
private lateinit var reader: TapPacketReader
private lateinit var reader: PollPacketReader
private lateinit var arpResponder: ArpResponder
private lateinit var raResponder: RouterAdvertisementResponder
@ -169,7 +169,7 @@ class DscpPolicyTest {
}
handlerThread.start()
reader = TapPacketReader(
reader = PollPacketReader(
handlerThread.threadHandler,
iface.fileDescriptor.fileDescriptor,
MAX_PACKET_LENGTH)

View file

@ -72,7 +72,7 @@ import com.android.testutils.RecorderCallback.CallbackEntry.CapabilitiesChanged
import com.android.testutils.RecorderCallback.CallbackEntry.LinkPropertiesChanged
import com.android.testutils.RecorderCallback.CallbackEntry.Lost
import com.android.testutils.RouterAdvertisementResponder
import com.android.testutils.TapPacketReader
import com.android.testutils.PollPacketReader
import com.android.testutils.TestableNetworkCallback
import com.android.testutils.assertThrows
import com.android.testutils.runAsShell
@ -151,7 +151,7 @@ class EthernetManagerTest {
hasCarrier: Boolean
) {
private val tapInterface: TestNetworkInterface
private val packetReader: TapPacketReader
private val packetReader: PollPacketReader
private val raResponder: RouterAdvertisementResponder
private val tnm: TestNetworkManager
val name get() = tapInterface.interfaceName
@ -169,7 +169,11 @@ class EthernetManagerTest {
tnm.createTapInterface(hasCarrier, false /* bringUp */)
}
val mtu = tapInterface.mtu
packetReader = TapPacketReader(handler, tapInterface.fileDescriptor.fileDescriptor, mtu)
packetReader = PollPacketReader(
handler,
tapInterface.fileDescriptor.fileDescriptor,
mtu
)
raResponder = RouterAdvertisementResponder(packetReader)
val iidString = "fe80::${Integer.toHexString(Random().nextInt(65536))}"
val linklocal = InetAddresses.parseNumericAddress(iidString) as Inet6Address
@ -336,7 +340,7 @@ class EthernetManagerTest {
}
}
private fun isEthernetSupported() : Boolean {
private fun isEthernetSupported(): Boolean {
return context.getSystemService(EthernetManager::class.java) != null
}

View file

@ -46,7 +46,7 @@ import com.android.testutils.AutoCloseTestInterfaceRule
import com.android.testutils.DhcpClientPacketFilter
import com.android.testutils.DhcpOptionFilter
import com.android.testutils.RecorderCallback.CallbackEntry
import com.android.testutils.TapPacketReader
import com.android.testutils.PollPacketReader
import com.android.testutils.TestHttpServer
import com.android.testutils.TestableNetworkCallback
import com.android.testutils.runAsShell
@ -93,7 +93,7 @@ class NetworkValidationTest {
private val ethRequestCb = TestableNetworkCallback()
private lateinit var iface: TestNetworkInterface
private lateinit var reader: TapPacketReader
private lateinit var reader: PollPacketReader
private lateinit var capportUrl: Uri
private var testSkipped = false
@ -118,7 +118,7 @@ class NetworkValidationTest {
iface = testInterfaceRule.createTapInterface()
handlerThread.start()
reader = TapPacketReader(
reader = PollPacketReader(
handlerThread.threadHandler,
iface.fileDescriptor.fileDescriptor,
MAX_PACKET_LENGTH)
@ -218,7 +218,7 @@ class NetworkValidationTest {
TEST_MTU, false /* rapidCommit */, capportUrl.toString())
}
private fun <T : DhcpPacket> TapPacketReader.assertDhcpPacketReceived(
private fun <T : DhcpPacket> PollPacketReader.assertDhcpPacketReceived(
packetType: Class<T>,
timeoutMs: Long,
type: Byte

View file

@ -100,7 +100,7 @@ import com.android.testutils.NsdServiceInfoCallbackRecord.ServiceInfoCallbackEve
import com.android.testutils.NsdServiceInfoCallbackRecord.ServiceInfoCallbackEvent.UnregisterCallbackSucceeded
import com.android.testutils.RecorderCallback.CallbackEntry.CapabilitiesChanged
import com.android.testutils.RecorderCallback.CallbackEntry.LinkPropertiesChanged
import com.android.testutils.TapPacketReader
import com.android.testutils.PollPacketReader
import com.android.testutils.TestDnsPacket
import com.android.testutils.TestableNetworkAgent
import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnNetworkCreated
@ -1299,10 +1299,10 @@ class NsdManagerTest {
val si = makeTestServiceInfo(testNetwork1.network)
val packetReader = TapPacketReader(
Handler(handlerThread.looper),
val packetReader = PollPacketReader(
Handler(handlerThread.looper),
testNetwork1.iface.fileDescriptor.fileDescriptor,
1500 /* maxPacketSize */
1500 /* maxPacketSize */
)
packetReader.startAsyncForTest()
handlerThread.waitForIdle(TIMEOUT_MS)
@ -1345,10 +1345,10 @@ class NsdManagerTest {
parseNumericAddress("2001:db8::3"))
}
val packetReader = TapPacketReader(
Handler(handlerThread.looper),
val packetReader = PollPacketReader(
Handler(handlerThread.looper),
testNetwork1.iface.fileDescriptor.fileDescriptor,
1500 /* maxPacketSize */
1500 /* maxPacketSize */
)
packetReader.startAsyncForTest()
handlerThread.waitForIdle(TIMEOUT_MS)
@ -1391,10 +1391,10 @@ class NsdManagerTest {
hostname = customHostname
}
val packetReader = TapPacketReader(
Handler(handlerThread.looper),
val packetReader = PollPacketReader(
Handler(handlerThread.looper),
testNetwork1.iface.fileDescriptor.fileDescriptor,
1500 /* maxPacketSize */
1500 /* maxPacketSize */
)
packetReader.startAsyncForTest()
handlerThread.waitForIdle(TIMEOUT_MS)
@ -1438,10 +1438,10 @@ class NsdManagerTest {
val registrationRecord = NsdRegistrationRecord()
val discoveryRecord = NsdDiscoveryRecord()
val registeredService = registerService(registrationRecord, si)
val packetReader = TapPacketReader(
Handler(handlerThread.looper),
val packetReader = PollPacketReader(
Handler(handlerThread.looper),
testNetwork1.iface.fileDescriptor.fileDescriptor,
1500 /* maxPacketSize */
1500 /* maxPacketSize */
)
packetReader.startAsyncForTest()
handlerThread.waitForIdle(TIMEOUT_MS)
@ -1518,10 +1518,10 @@ class NsdManagerTest {
val registrationRecord = NsdRegistrationRecord()
val discoveryRecord = NsdDiscoveryRecord()
val registeredService = registerService(registrationRecord, si)
val packetReader = TapPacketReader(
val packetReader = PollPacketReader(
Handler(handlerThread.looper),
testNetwork1.iface.fileDescriptor.fileDescriptor,
1500 /* maxPacketSize */
1500 /* maxPacketSize */
)
packetReader.startAsyncForTest()
handlerThread.waitForIdle(TIMEOUT_MS)
@ -1587,10 +1587,10 @@ class NsdManagerTest {
val registrationRecord = NsdRegistrationRecord()
val discoveryRecord = NsdDiscoveryRecord()
val registeredService = registerService(registrationRecord, si)
val packetReader = TapPacketReader(
Handler(handlerThread.looper),
val packetReader = PollPacketReader(
Handler(handlerThread.looper),
testNetwork1.iface.fileDescriptor.fileDescriptor,
1500 /* maxPacketSize */
1500 /* maxPacketSize */
)
packetReader.startAsyncForTest()
handlerThread.waitForIdle(TIMEOUT_MS)
@ -1630,10 +1630,10 @@ class NsdManagerTest {
fun testDiscoveryWithPtrOnlyResponse_ServiceIsFound() {
// Register service on testNetwork1
val discoveryRecord = NsdDiscoveryRecord()
val packetReader = TapPacketReader(
Handler(handlerThread.looper),
val packetReader = PollPacketReader(
Handler(handlerThread.looper),
testNetwork1.iface.fileDescriptor.fileDescriptor,
1500 /* maxPacketSize */
1500 /* maxPacketSize */
)
packetReader.startAsyncForTest()
handlerThread.waitForIdle(TIMEOUT_MS)
@ -1688,10 +1688,10 @@ class NsdManagerTest {
fun testResolveWhenServerSendsNoAdditionalRecord() {
// Resolve service on testNetwork1
val resolveRecord = NsdResolveRecord()
val packetReader = TapPacketReader(
Handler(handlerThread.looper),
val packetReader = PollPacketReader(
Handler(handlerThread.looper),
testNetwork1.iface.fileDescriptor.fileDescriptor,
1500 /* maxPacketSize */
1500 /* maxPacketSize */
)
packetReader.startAsyncForTest()
handlerThread.waitForIdle(TIMEOUT_MS)
@ -1776,8 +1776,8 @@ class NsdManagerTest {
var nsResponder: NSResponder? = null
tryTest {
registerService(registrationRecord, si)
val packetReader = TapPacketReader(Handler(handlerThread.looper),
testNetwork1.iface.fileDescriptor.fileDescriptor, 1500 /* maxPacketSize */)
val packetReader = PollPacketReader(Handler(handlerThread.looper),
testNetwork1.iface.fileDescriptor.fileDescriptor, 1500 /* maxPacketSize */)
packetReader.startAsyncForTest()
handlerThread.waitForIdle(TIMEOUT_MS)
@ -1826,7 +1826,7 @@ class NsdManagerTest {
var nsResponder: NSResponder? = null
tryTest {
registerService(registrationRecord, si)
val packetReader = TapPacketReader(Handler(handlerThread.looper),
val packetReader = PollPacketReader(Handler(handlerThread.looper),
testNetwork1.iface.fileDescriptor.fileDescriptor, 1500 /* maxPacketSize */)
packetReader.startAsyncForTest()
@ -1916,7 +1916,7 @@ class NsdManagerTest {
var nsResponder: NSResponder? = null
tryTest {
registerService(registrationRecord, si)
val packetReader = TapPacketReader(Handler(handlerThread.looper),
val packetReader = PollPacketReader(Handler(handlerThread.looper),
testNetwork1.iface.fileDescriptor.fileDescriptor, 1500 /* maxPacketSize */)
packetReader.startAsyncForTest()
@ -1991,10 +1991,10 @@ class NsdManagerTest {
// Register service on testNetwork1
val discoveryRecord = NsdDiscoveryRecord()
val packetReader = TapPacketReader(
Handler(handlerThread.looper),
val packetReader = PollPacketReader(
Handler(handlerThread.looper),
testNetwork1.iface.fileDescriptor.fileDescriptor,
1500 /* maxPacketSize */
1500 /* maxPacketSize */
)
packetReader.startAsyncForTest()
handlerThread.waitForIdle(TIMEOUT_MS)
@ -2355,10 +2355,10 @@ class NsdManagerTest {
it.port = TEST_PORT
it.publicKey = publicKey
}
val packetReader = TapPacketReader(
Handler(handlerThread.looper),
val packetReader = PollPacketReader(
Handler(handlerThread.looper),
testNetwork1.iface.fileDescriptor.fileDescriptor,
1500 /* maxPacketSize */
1500 /* maxPacketSize */
)
packetReader.startAsyncForTest()
handlerThread.waitForIdle(TIMEOUT_MS)
@ -2410,10 +2410,10 @@ class NsdManagerTest {
parseNumericAddress("2001:db8::2"))
it.publicKey = publicKey
}
val packetReader = TapPacketReader(
Handler(handlerThread.looper),
val packetReader = PollPacketReader(
Handler(handlerThread.looper),
testNetwork1.iface.fileDescriptor.fileDescriptor,
1500 /* maxPacketSize */
1500 /* maxPacketSize */
)
packetReader.startAsyncForTest()
handlerThread.waitForIdle(TIMEOUT_MS)
@ -2467,10 +2467,10 @@ class NsdManagerTest {
it.hostAddresses = listOf()
it.publicKey = publicKey
}
val packetReader = TapPacketReader(
Handler(handlerThread.looper),
testNetwork1.iface.fileDescriptor.fileDescriptor,
1500 /* maxPacketSize */
val packetReader = PollPacketReader(
Handler(handlerThread.looper),
testNetwork1.iface.fileDescriptor.fileDescriptor,
1500 /* maxPacketSize */
)
packetReader.startAsyncForTest()
handlerThread.waitForIdle(TIMEOUT_MS)
@ -2582,10 +2582,10 @@ class NsdManagerTest {
"test_nsd_avoid_advertising_empty_txt_records",
"1"
)
val packetReader = TapPacketReader(
Handler(handlerThread.looper),
testNetwork1.iface.fileDescriptor.fileDescriptor,
1500 /* maxPacketSize */
val packetReader = PollPacketReader(
Handler(handlerThread.looper),
testNetwork1.iface.fileDescriptor.fileDescriptor,
1500 /* maxPacketSize */
)
packetReader.startAsyncForTest()
handlerThread.waitForIdle(TIMEOUT_MS)

View file

@ -28,7 +28,7 @@ import android.net.cts.util.EthernetTestInterface.EthernetStateListener.Callback
import android.os.Handler
import android.util.Log
import com.android.net.module.util.ArrayTrackRecord
import com.android.testutils.TapPacketReader
import com.android.testutils.PollPacketReader
import com.android.testutils.runAsShell
import com.android.testutils.waitForIdle
import java.net.NetworkInterface
@ -85,7 +85,7 @@ class EthernetTestInterface(
assertNotNull(nif)
return nif.mtu
}
val packetReader = TapPacketReader(handler, testIface.fileDescriptor.fileDescriptor, mtu)
val packetReader = PollPacketReader(handler, testIface.fileDescriptor.fileDescriptor, mtu)
private val listener = EthernetStateListener(name)
private val em = context.getSystemService(EthernetManager::class.java)!!
@Volatile private var cleanedUp = false

View file

@ -68,7 +68,7 @@ import androidx.test.core.app.ApplicationProvider;
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.testutils.TapPacketReader;
import com.android.testutils.PollPacketReader;
import com.android.testutils.TestNetworkTracker;
import org.junit.After;
@ -118,7 +118,7 @@ public class BorderRoutingTest {
private Handler mHandler;
private TestNetworkTracker mInfraNetworkTracker;
private List<FullThreadDevice> mFtds;
private TapPacketReader mInfraNetworkReader;
private PollPacketReader mInfraNetworkReader;
private InfraNetworkDevice mInfraDevice;
@Before

View file

@ -28,7 +28,7 @@ import android.net.MacAddress;
import com.android.net.module.util.Ipv6Utils;
import com.android.net.module.util.structs.LlaOption;
import com.android.net.module.util.structs.PrefixInformationOption;
import com.android.testutils.TapPacketReader;
import com.android.testutils.PollPacketReader;
import java.io.IOException;
import java.net.Inet6Address;
@ -49,18 +49,18 @@ public final class InfraNetworkDevice {
// The MAC address of this device.
public final MacAddress macAddr;
// The packet reader of the TUN interface of the test network.
public final TapPacketReader packetReader;
public final PollPacketReader packetReader;
// The IPv6 address generated by SLAAC for the device.
public Inet6Address ipv6Addr;
/**
* Constructs an InfraNetworkDevice with the given {@link MAC address} and {@link
* TapPacketReader}.
* PollPacketReader}.
*
* @param macAddr the MAC address of the device
* @param packetReader the packet reader of the TUN interface of the test network.
*/
public InfraNetworkDevice(MacAddress macAddr, TapPacketReader packetReader) {
public InfraNetworkDevice(MacAddress macAddr, PollPacketReader packetReader) {
this.macAddr = macAddr;
this.packetReader = packetReader;
}

View file

@ -47,7 +47,7 @@ import com.android.net.module.util.structs.Ipv4Header
import com.android.net.module.util.structs.Ipv6Header
import com.android.net.module.util.structs.PrefixInformationOption
import com.android.net.module.util.structs.RaHeader
import com.android.testutils.TapPacketReader
import com.android.testutils.PollPacketReader
import com.android.testutils.TestNetworkTracker
import com.android.testutils.initTestNetwork
import com.android.testutils.runAsShell
@ -136,18 +136,18 @@ object IntegrationTestUtils {
}
/**
* Creates a [TapPacketReader] given the [TestNetworkInterface] and [Handler].
* Creates a [PollPacketReader] given the [TestNetworkInterface] and [Handler].
*
* @param testNetworkInterface the TUN interface of the test network
* @param handler the handler to process the packets
* @return the [TapPacketReader]
* @return the [PollPacketReader]
*/
@JvmStatic
fun newPacketReader(
testNetworkInterface: TestNetworkInterface, handler: Handler
): TapPacketReader {
): PollPacketReader {
val fd = testNetworkInterface.fileDescriptor.fileDescriptor
val reader = TapPacketReader(handler, fd, testNetworkInterface.mtu)
val reader = PollPacketReader(handler, fd, testNetworkInterface.mtu)
handler.post { reader.start() }
handler.waitForIdle(timeoutMs = 5000)
return reader
@ -191,7 +191,7 @@ object IntegrationTestUtils {
}
/**
* Polls for a packet from a given [TapPacketReader] that satisfies the `filter`.
* Polls for a packet from a given [PollPacketReader] that satisfies the `filter`.
*
* @param packetReader a TUN packet reader
* @param filter the filter to be applied on the packet
@ -199,7 +199,7 @@ object IntegrationTestUtils {
* than 3000ms to read the next packet, the method will return null
*/
@JvmStatic
fun pollForPacket(packetReader: TapPacketReader, filter: Predicate<ByteArray>): ByteArray? {
fun pollForPacket(packetReader: PollPacketReader, filter: Predicate<ByteArray>): ByteArray? {
var packet: ByteArray?
while ((packetReader.poll(3000 /* timeoutMs */, filter).also { packet = it }) != null) {
return packet
@ -570,10 +570,10 @@ object IntegrationTestUtils {
@JvmStatic
@JvmOverloads
fun startInfraDeviceAndWaitForOnLinkAddr(
tapPacketReader: TapPacketReader,
macAddress: MacAddress = MacAddress.fromString("1:2:3:4:5:6")
pollPacketReader: PollPacketReader,
macAddress: MacAddress = MacAddress.fromString("1:2:3:4:5:6")
): InfraNetworkDevice {
val infraDevice = InfraNetworkDevice(macAddress, tapPacketReader)
val infraDevice = InfraNetworkDevice(macAddress, pollPacketReader)
infraDevice.runSlaac(Duration.ofSeconds(60))
requireNotNull(infraDevice.ipv6Addr)
return infraDevice