Merge "Add option to skip map/prog based on build type"
diff --git a/staticlibs/Android.bp b/staticlibs/Android.bp
index 63c8b4e..d8a397d 100644
--- a/staticlibs/Android.bp
+++ b/staticlibs/Android.bp
@@ -40,6 +40,7 @@
"device/com/android/net/module/util/NetworkMonitorUtils.java",
"device/com/android/net/module/util/PacketReader.java",
"device/com/android/net/module/util/SharedLog.java",
+ "device/com/android/net/module/util/SocketUtils.java",
// This library is used by system modules, for which the system health impact of Kotlin
// has not yet been evaluated. Annotations may need jarjar'ing.
// "src_devicecommon/**/*.kt",
diff --git a/staticlibs/device/com/android/net/module/util/SocketUtils.java b/staticlibs/device/com/android/net/module/util/SocketUtils.java
new file mode 100644
index 0000000..9878ea5
--- /dev/null
+++ b/staticlibs/device/com/android/net/module/util/SocketUtils.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2022 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.net.module.util;
+
+import static android.net.util.SocketUtils.closeSocket;
+
+import android.annotation.NonNull;
+import android.system.NetlinkSocketAddress;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.net.SocketAddress;
+
+/**
+ * Collection of utilities to interact with raw sockets.
+ *
+ * This class also provides utilities to interact with {@link android.net.util.SocketUtils}
+ * because it is in the API surface could not be simply move the frameworks/libs/net/
+ * to share with module.
+ *
+ * TODO: deprecate android.net.util.SocketUtils and replace with this class.
+ */
+public class SocketUtils {
+
+ /**
+ * Make a socket address to communicate with netlink.
+ */
+ @NonNull
+ public static SocketAddress makeNetlinkSocketAddress(int portId, int groupsMask) {
+ return new NetlinkSocketAddress(portId, groupsMask);
+ }
+
+ /**
+ * Close a socket, ignoring any exception while closing.
+ */
+ public static void closeSocketQuietly(FileDescriptor fd) {
+ try {
+ closeSocket(fd);
+ } catch (IOException ignored) {
+ }
+ }
+
+ private SocketUtils() {}
+}
diff --git a/staticlibs/device/com/android/net/module/util/ip/IpNeighborMonitor.java b/staticlibs/device/com/android/net/module/util/ip/IpNeighborMonitor.java
index 4a61794..e88e7f0 100644
--- a/staticlibs/device/com/android/net/module/util/ip/IpNeighborMonitor.java
+++ b/staticlibs/device/com/android/net/module/util/ip/IpNeighborMonitor.java
@@ -31,7 +31,7 @@
import com.android.net.module.util.SharedLog;
import com.android.net.module.util.netlink.NetlinkMessage;
-import com.android.net.module.util.netlink.NetlinkSocket;
+import com.android.net.module.util.netlink.NetlinkUtils;
import com.android.net.module.util.netlink.RtNetlinkNeighborMessage;
import com.android.net.module.util.netlink.StructNdMsg;
@@ -68,7 +68,7 @@
1, ip, StructNdMsg.NUD_PROBE, ifIndex, null);
try {
- NetlinkSocket.sendOneShotKernelMessage(NETLINK_ROUTE, msg);
+ NetlinkUtils.sendOneShotKernelMessage(NETLINK_ROUTE, msg);
} catch (ErrnoException e) {
Log.e(TAG, "Error " + msgSnippet + ": " + e);
return -e.errno;
diff --git a/staticlibs/device/com/android/net/module/util/ip/NetlinkMonitor.java b/staticlibs/device/com/android/net/module/util/ip/NetlinkMonitor.java
index 942aaf1..f882483 100644
--- a/staticlibs/device/com/android/net/module/util/ip/NetlinkMonitor.java
+++ b/staticlibs/device/com/android/net/module/util/ip/NetlinkMonitor.java
@@ -16,7 +16,6 @@
package com.android.net.module.util.ip;
-import static android.net.util.SocketUtils.makeNetlinkSocketAddress;
import static android.system.OsConstants.AF_NETLINK;
import static android.system.OsConstants.ENOBUFS;
import static android.system.OsConstants.SOCK_DGRAM;
@@ -24,10 +23,11 @@
import static android.system.OsConstants.SOL_SOCKET;
import static android.system.OsConstants.SO_RCVBUF;
+import static com.android.net.module.util.SocketUtils.closeSocketQuietly;
+import static com.android.net.module.util.SocketUtils.makeNetlinkSocketAddress;
import static com.android.net.module.util.netlink.NetlinkConstants.hexify;
import android.annotation.NonNull;
-import android.net.util.SocketUtils;
import android.os.Handler;
import android.os.SystemClock;
import android.system.ErrnoException;
@@ -38,10 +38,9 @@
import com.android.net.module.util.SharedLog;
import com.android.net.module.util.netlink.NetlinkErrorMessage;
import com.android.net.module.util.netlink.NetlinkMessage;
-import com.android.net.module.util.netlink.NetlinkSocket;
+import com.android.net.module.util.netlink.NetlinkUtils;
import java.io.FileDescriptor;
-import java.io.IOException;
import java.net.SocketAddress;
import java.net.SocketException;
import java.nio.ByteBuffer;
@@ -83,7 +82,7 @@
*/
public NetlinkMonitor(@NonNull Handler h, @NonNull SharedLog log, @NonNull String tag,
int family, int bindGroups, int sockRcvbufSize) {
- super(h, NetlinkSocket.DEFAULT_RECV_BUFSIZE);
+ super(h, NetlinkUtils.DEFAULT_RECV_BUFSIZE);
mLog = log.forSubComponent(tag);
mTag = tag;
mFamily = family;
@@ -110,7 +109,7 @@
}
}
Os.bind(fd, makeNetlinkSocketAddress(0, mBindGroups));
- NetlinkSocket.connectToKernel(fd);
+ NetlinkUtils.connectSocketToNetlink(fd);
if (DBG) {
final SocketAddress nlAddr = Os.getsockname(fd);
@@ -179,14 +178,6 @@
return true;
}
- // TODO: move NetworkStackUtils to frameworks/libs/net for NetworkStackUtils#closeSocketQuietly.
- private void closeSocketQuietly(FileDescriptor fd) {
- try {
- SocketUtils.closeSocket(fd);
- } catch (IOException ignored) {
- }
- }
-
/**
* Processes one netlink message. Must be overridden by subclasses.
* @param nlMsg the message to process.
diff --git a/staticlibs/device/com/android/net/module/util/netlink/InetDiagMessage.java b/staticlibs/device/com/android/net/module/util/netlink/InetDiagMessage.java
index eff1f25..5a180e7 100644
--- a/staticlibs/device/com/android/net/module/util/netlink/InetDiagMessage.java
+++ b/staticlibs/device/com/android/net/module/util/netlink/InetDiagMessage.java
@@ -19,11 +19,12 @@
import static android.os.Process.INVALID_UID;
import static android.system.OsConstants.AF_INET;
import static android.system.OsConstants.AF_INET6;
+import static android.system.OsConstants.IPPROTO_TCP;
import static android.system.OsConstants.IPPROTO_UDP;
import static android.system.OsConstants.NETLINK_INET_DIAG;
import static com.android.net.module.util.netlink.NetlinkConstants.SOCK_DIAG_BY_FAMILY;
-import static com.android.net.module.util.netlink.NetlinkSocket.DEFAULT_RECV_BUFSIZE;
+import static com.android.net.module.util.netlink.NetlinkUtils.DEFAULT_RECV_BUFSIZE;
import static com.android.net.module.util.netlink.StructNlMsgHdr.NLM_F_DUMP;
import static com.android.net.module.util.netlink.StructNlMsgHdr.NLM_F_REQUEST;
@@ -132,8 +133,8 @@
FileDescriptor fd)
throws ErrnoException, InterruptedIOException {
byte[] msg = inetDiagReqV2(protocol, local, remote, family, flags);
- NetlinkSocket.sendMessage(fd, msg, 0, msg.length, TIMEOUT_MS);
- ByteBuffer response = NetlinkSocket.recvMessage(fd, DEFAULT_RECV_BUFSIZE, TIMEOUT_MS);
+ NetlinkUtils.sendMessage(fd, msg, 0, msg.length, TIMEOUT_MS);
+ ByteBuffer response = NetlinkUtils.recvMessage(fd, DEFAULT_RECV_BUFSIZE, TIMEOUT_MS);
final NetlinkMessage nlMsg = NetlinkMessage.parse(response, NETLINK_INET_DIAG);
if (nlMsg == null) {
@@ -210,8 +211,8 @@
int uid = INVALID_UID;
FileDescriptor fd = null;
try {
- fd = NetlinkSocket.forProto(NETLINK_INET_DIAG);
- NetlinkSocket.connectToKernel(fd);
+ fd = NetlinkUtils.netlinkSocketForProto(NETLINK_INET_DIAG);
+ NetlinkUtils.connectSocketToNetlink(fd);
uid = lookupUid(protocol, local, remote, fd);
} catch (ErrnoException | SocketException | IllegalArgumentException
| InterruptedIOException e) {
@@ -228,6 +229,20 @@
return uid;
}
+ /**
+ * Construct an inet_diag_req_v2 message for querying alive TCP sockets from kernel.
+ */
+ public static byte[] buildInetDiagReqForAliveTcpSockets(int family) {
+ return inetDiagReqV2(IPPROTO_TCP,
+ null /* local addr */,
+ null /* remote addr */,
+ family,
+ (short) (StructNlMsgHdr.NLM_F_REQUEST | StructNlMsgHdr.NLM_F_DUMP) /* flag */,
+ 0 /* pad */,
+ 1 << NetlinkConstants.INET_DIAG_MEMINFO /* idiagExt */,
+ NetlinkUtils.TCP_MONITOR_STATE_FILTER);
+ }
+
@Override
public String toString() {
return "InetDiagMessage{ "
diff --git a/staticlibs/device/com/android/net/module/util/netlink/NetlinkSocket.java b/staticlibs/device/com/android/net/module/util/netlink/NetlinkSocket.java
deleted file mode 100644
index ec326dd..0000000
--- a/staticlibs/device/com/android/net/module/util/netlink/NetlinkSocket.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (C) 2015 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.net.module.util.netlink;
-
-import static android.net.util.SocketUtils.makeNetlinkSocketAddress;
-import static android.system.OsConstants.AF_NETLINK;
-import static android.system.OsConstants.EIO;
-import static android.system.OsConstants.EPROTO;
-import static android.system.OsConstants.ETIMEDOUT;
-import static android.system.OsConstants.SOCK_DGRAM;
-import static android.system.OsConstants.SOL_SOCKET;
-import static android.system.OsConstants.SO_RCVBUF;
-import static android.system.OsConstants.SO_RCVTIMEO;
-import static android.system.OsConstants.SO_SNDTIMEO;
-
-import android.net.util.SocketUtils;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.system.StructTimeval;
-import android.util.Log;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.io.InterruptedIOException;
-import java.net.SocketException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-
-/**
- * NetlinkSocket
- *
- * A small static class to assist with AF_NETLINK socket operations.
- *
- * @hide
- */
-public class NetlinkSocket {
- private static final String TAG = "NetlinkSocket";
- private static final long IO_TIMEOUT_MS = 300L;
-
- public static final int DEFAULT_RECV_BUFSIZE = 8 * 1024;
- public static final int SOCKET_RECV_BUFSIZE = 64 * 1024;
-
- /**
- * Send one netlink message to kernel via netlink socket.
- *
- * @param nlProto netlink protocol type.
- * @param msg the raw bytes of netlink message to be sent.
- */
- public static void sendOneShotKernelMessage(int nlProto, byte[] msg) throws ErrnoException {
- final String errPrefix = "Error in NetlinkSocket.sendOneShotKernelMessage";
- final FileDescriptor fd = forProto(nlProto);
-
- try {
- connectToKernel(fd);
- sendMessage(fd, msg, 0, msg.length, IO_TIMEOUT_MS);
- final ByteBuffer bytes = recvMessage(fd, DEFAULT_RECV_BUFSIZE, IO_TIMEOUT_MS);
- // recvMessage() guaranteed to not return null if it did not throw.
- final NetlinkMessage response = NetlinkMessage.parse(bytes, nlProto);
- if (response != null && response instanceof NetlinkErrorMessage
- && (((NetlinkErrorMessage) response).getNlMsgError() != null)) {
- final int errno = ((NetlinkErrorMessage) response).getNlMsgError().error;
- if (errno != 0) {
- // TODO: consider ignoring EINVAL (-22), which appears to be
- // normal when probing a neighbor for which the kernel does
- // not already have / no longer has a link layer address.
- Log.e(TAG, errPrefix + ", errmsg=" + response.toString());
- // Note: convert kernel errnos (negative) into userspace errnos (positive).
- throw new ErrnoException(response.toString(), Math.abs(errno));
- }
- } else {
- final String errmsg;
- if (response == null) {
- bytes.position(0);
- errmsg = "raw bytes: " + NetlinkConstants.hexify(bytes);
- } else {
- errmsg = response.toString();
- }
- Log.e(TAG, errPrefix + ", errmsg=" + errmsg);
- throw new ErrnoException(errmsg, EPROTO);
- }
- } catch (InterruptedIOException e) {
- Log.e(TAG, errPrefix, e);
- throw new ErrnoException(errPrefix, ETIMEDOUT, e);
- } catch (SocketException e) {
- Log.e(TAG, errPrefix, e);
- throw new ErrnoException(errPrefix, EIO, e);
- } finally {
- try {
- SocketUtils.closeSocket(fd);
- } catch (IOException e) {
- // Nothing we can do here
- }
- }
- }
-
- /**
- * Create netlink socket with the given netlink protocol type.
- *
- * @return fd the fileDescriptor of the socket.
- * Throw ErrnoException if the exception is thrown.
- */
- public static FileDescriptor forProto(int nlProto) throws ErrnoException {
- final FileDescriptor fd = Os.socket(AF_NETLINK, SOCK_DGRAM, nlProto);
- Os.setsockoptInt(fd, SOL_SOCKET, SO_RCVBUF, SOCKET_RECV_BUFSIZE);
- return fd;
- }
-
- /**
- * Connect to kernel via netlink socket.
- *
- * Throw ErrnoException, SocketException if the exception is thrown.
- */
- public static void connectToKernel(FileDescriptor fd) throws ErrnoException, SocketException {
- Os.connect(fd, makeNetlinkSocketAddress(0, 0));
- }
-
- private static void checkTimeout(long timeoutMs) {
- if (timeoutMs < 0) {
- throw new IllegalArgumentException("Negative timeouts not permitted");
- }
- }
-
- /**
- * Wait up to |timeoutMs| (or until underlying socket error) for a
- * netlink message of at most |bufsize| size.
- *
- * Multi-threaded calls with different timeouts will cause unexpected results.
- */
- public static ByteBuffer recvMessage(FileDescriptor fd, int bufsize, long timeoutMs)
- throws ErrnoException, IllegalArgumentException, InterruptedIOException {
- checkTimeout(timeoutMs);
-
- Os.setsockoptTimeval(fd, SOL_SOCKET, SO_RCVTIMEO, StructTimeval.fromMillis(timeoutMs));
-
- ByteBuffer byteBuffer = ByteBuffer.allocate(bufsize);
- int length = Os.read(fd, byteBuffer);
- if (length == bufsize) {
- Log.w(TAG, "maximum read");
- }
- byteBuffer.position(0);
- byteBuffer.limit(length);
- byteBuffer.order(ByteOrder.nativeOrder());
- return byteBuffer;
- }
-
- /**
- * Send a message to a peer to which this socket has previously connected,
- * waiting at most |timeoutMs| milliseconds for the send to complete.
- *
- * Multi-threaded calls with different timeouts will cause unexpected results.
- */
- public static int sendMessage(
- FileDescriptor fd, byte[] bytes, int offset, int count, long timeoutMs)
- throws ErrnoException, IllegalArgumentException, InterruptedIOException {
- checkTimeout(timeoutMs);
- Os.setsockoptTimeval(fd, SOL_SOCKET, SO_SNDTIMEO, StructTimeval.fromMillis(timeoutMs));
- return Os.write(fd, bytes, offset, count);
- }
-}
diff --git a/staticlibs/device/com/android/net/module/util/netlink/NetlinkUtils.java b/staticlibs/device/com/android/net/module/util/netlink/NetlinkUtils.java
index 34c468a..ae16cf8 100644
--- a/staticlibs/device/com/android/net/module/util/netlink/NetlinkUtils.java
+++ b/staticlibs/device/com/android/net/module/util/netlink/NetlinkUtils.java
@@ -16,13 +16,40 @@
package com.android.net.module.util.netlink;
-import static android.system.OsConstants.IPPROTO_TCP;
+import static android.net.util.SocketUtils.makeNetlinkSocketAddress;
+import static android.system.OsConstants.AF_NETLINK;
+import static android.system.OsConstants.EIO;
+import static android.system.OsConstants.EPROTO;
+import static android.system.OsConstants.ETIMEDOUT;
+import static android.system.OsConstants.NETLINK_INET_DIAG;
+import static android.system.OsConstants.SOCK_CLOEXEC;
+import static android.system.OsConstants.SOCK_DGRAM;
+import static android.system.OsConstants.SOL_SOCKET;
+import static android.system.OsConstants.SO_RCVBUF;
+import static android.system.OsConstants.SO_RCVTIMEO;
+import static android.system.OsConstants.SO_SNDTIMEO;
+
+import android.net.util.SocketUtils;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.StructTimeval;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.net.SocketException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
/**
- * Utilities for netlink related class.
+ * Utilities for netlink related class that may not be able to fit into a specific class.
* @hide
*/
public class NetlinkUtils {
+ private static final String TAG = "NetlinkUtils";
/** Corresponds to enum from bionic/libc/include/netinet/tcp.h. */
private static final int TCP_ESTABLISHED = 1;
private static final int TCP_SYN_SENT = 2;
@@ -31,17 +58,155 @@
public static final int TCP_MONITOR_STATE_FILTER =
(1 << TCP_ESTABLISHED) | (1 << TCP_SYN_SENT) | (1 << TCP_SYN_RECV);
+ public static final int UNKNOWN_MARK = 0xffffffff;
+ public static final int NULL_MASK = 0;
+
+ // Initial mark value corresponds to the initValue in system/netd/include/Fwmark.h.
+ public static final int INIT_MARK_VALUE = 0;
+ // Corresponds to enum definition in bionic/libc/kernel/uapi/linux/inet_diag.h
+ public static final int INET_DIAG_INFO = 2;
+ public static final int INET_DIAG_MARK = 15;
+
+ public static final long IO_TIMEOUT_MS = 300L;
+
+ public static final int DEFAULT_RECV_BUFSIZE = 8 * 1024;
+ public static final int SOCKET_RECV_BUFSIZE = 64 * 1024;
+
/**
- * Construct an inet_diag_req_v2 message for querying alive TCP sockets from kernel.
+ * Return whether the input ByteBuffer contains enough remaining bytes for
+ * {@code StructNlMsgHdr}.
*/
- public static byte[] buildInetDiagReqForAliveTcpSockets(int family) {
- return InetDiagMessage.inetDiagReqV2(IPPROTO_TCP,
- null /* local addr */,
- null /* remote addr */,
- family,
- (short) (StructNlMsgHdr.NLM_F_REQUEST | StructNlMsgHdr.NLM_F_DUMP) /* flag */,
- 0 /* pad */,
- 1 << NetlinkConstants.INET_DIAG_MEMINFO /* idiagExt */,
- TCP_MONITOR_STATE_FILTER);
+ public static boolean enoughBytesRemainForValidNlMsg(@NonNull final ByteBuffer bytes) {
+ return bytes.remaining() >= StructNlMsgHdr.STRUCT_SIZE;
}
+
+ /**
+ * Send one netlink message to kernel via netlink socket.
+ *
+ * @param nlProto netlink protocol type.
+ * @param msg the raw bytes of netlink message to be sent.
+ */
+ public static void sendOneShotKernelMessage(int nlProto, byte[] msg) throws ErrnoException {
+ final String errPrefix = "Error in NetlinkSocket.sendOneShotKernelMessage";
+ final FileDescriptor fd = netlinkSocketForProto(nlProto);
+
+ try {
+ connectSocketToNetlink(fd);
+ sendMessage(fd, msg, 0, msg.length, IO_TIMEOUT_MS);
+ final ByteBuffer bytes = recvMessage(fd, DEFAULT_RECV_BUFSIZE, IO_TIMEOUT_MS);
+ // recvMessage() guaranteed to not return null if it did not throw.
+ final NetlinkMessage response = NetlinkMessage.parse(bytes, nlProto);
+ if (response != null && response instanceof NetlinkErrorMessage
+ && (((NetlinkErrorMessage) response).getNlMsgError() != null)) {
+ final int errno = ((NetlinkErrorMessage) response).getNlMsgError().error;
+ if (errno != 0) {
+ // TODO: consider ignoring EINVAL (-22), which appears to be
+ // normal when probing a neighbor for which the kernel does
+ // not already have / no longer has a link layer address.
+ Log.e(TAG, errPrefix + ", errmsg=" + response.toString());
+ // Note: convert kernel errnos (negative) into userspace errnos (positive).
+ throw new ErrnoException(response.toString(), Math.abs(errno));
+ }
+ } else {
+ final String errmsg;
+ if (response == null) {
+ bytes.position(0);
+ errmsg = "raw bytes: " + NetlinkConstants.hexify(bytes);
+ } else {
+ errmsg = response.toString();
+ }
+ Log.e(TAG, errPrefix + ", errmsg=" + errmsg);
+ throw new ErrnoException(errmsg, EPROTO);
+ }
+ } catch (InterruptedIOException e) {
+ Log.e(TAG, errPrefix, e);
+ throw new ErrnoException(errPrefix, ETIMEDOUT, e);
+ } catch (SocketException e) {
+ Log.e(TAG, errPrefix, e);
+ throw new ErrnoException(errPrefix, EIO, e);
+ } finally {
+ try {
+ SocketUtils.closeSocket(fd);
+ } catch (IOException e) {
+ // Nothing we can do here
+ }
+ }
+ }
+
+ /**
+ * Create netlink socket with the given netlink protocol type.
+ *
+ * @return fd the fileDescriptor of the socket.
+ * @throws ErrnoException if the FileDescriptor not connect to be created successfully
+ */
+ public static FileDescriptor netlinkSocketForProto(int nlProto) throws ErrnoException {
+ final FileDescriptor fd = Os.socket(AF_NETLINK, SOCK_DGRAM, nlProto);
+ Os.setsockoptInt(fd, SOL_SOCKET, SO_RCVBUF, SOCKET_RECV_BUFSIZE);
+ return fd;
+ }
+
+ /**
+ * Construct a netlink inet_diag socket.
+ */
+ public static FileDescriptor createNetLinkInetDiagSocket() throws ErrnoException {
+ return Os.socket(AF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_INET_DIAG);
+ }
+
+ /**
+ * Connect the given file descriptor to the Netlink interface to the kernel.
+ *
+ * The fd must be a SOCK_DGRAM socket : create it with {@link #netlinkSocketForProto}
+ *
+ * @throws ErrnoException if the {@code fd} could not connect to kernel successfully
+ * @throws SocketException if there is an error accessing a socket.
+ */
+ public static void connectSocketToNetlink(FileDescriptor fd)
+ throws ErrnoException, SocketException {
+ Os.connect(fd, makeNetlinkSocketAddress(0, 0));
+ }
+
+ private static void checkTimeout(long timeoutMs) {
+ if (timeoutMs < 0) {
+ throw new IllegalArgumentException("Negative timeouts not permitted");
+ }
+ }
+
+ /**
+ * Wait up to |timeoutMs| (or until underlying socket error) for a
+ * netlink message of at most |bufsize| size.
+ *
+ * Multi-threaded calls with different timeouts will cause unexpected results.
+ */
+ public static ByteBuffer recvMessage(FileDescriptor fd, int bufsize, long timeoutMs)
+ throws ErrnoException, IllegalArgumentException, InterruptedIOException {
+ checkTimeout(timeoutMs);
+
+ Os.setsockoptTimeval(fd, SOL_SOCKET, SO_RCVTIMEO, StructTimeval.fromMillis(timeoutMs));
+
+ final ByteBuffer byteBuffer = ByteBuffer.allocate(bufsize);
+ final int length = Os.read(fd, byteBuffer);
+ if (length == bufsize) {
+ Log.w(TAG, "maximum read");
+ }
+ byteBuffer.position(0);
+ byteBuffer.limit(length);
+ byteBuffer.order(ByteOrder.nativeOrder());
+ return byteBuffer;
+ }
+
+ /**
+ * Send a message to a peer to which this socket has previously connected.
+ *
+ * This waits at most |timeoutMs| milliseconds for the send to complete, will get the exception
+ * if it times out.
+ */
+ public static int sendMessage(
+ FileDescriptor fd, byte[] bytes, int offset, int count, long timeoutMs)
+ throws ErrnoException, IllegalArgumentException, InterruptedIOException {
+ checkTimeout(timeoutMs);
+ Os.setsockoptTimeval(fd, SOL_SOCKET, SO_SNDTIMEO, StructTimeval.fromMillis(timeoutMs));
+ return Os.write(fd, bytes, offset, count);
+ }
+
+ private NetlinkUtils() {}
}
diff --git a/staticlibs/framework/com/android/net/module/util/NetworkStackConstants.java b/staticlibs/framework/com/android/net/module/util/NetworkStackConstants.java
index 287473e..7b3943c 100644
--- a/staticlibs/framework/com/android/net/module/util/NetworkStackConstants.java
+++ b/staticlibs/framework/com/android/net/module/util/NetworkStackConstants.java
@@ -210,6 +210,17 @@
public static final int DHCP4_CLIENT_PORT = 68;
/**
+ * DHCPv6 constants.
+ *
+ * See also:
+ * - https://datatracker.ietf.org/doc/html/rfc8415
+ */
+ public static final int DHCP6_CLIENT_PORT = 546;
+ public static final int DHCP6_SERVER_PORT = 547;
+ public static final Inet6Address ALL_DHCP_RELAY_AGENTS_AND_SERVERS =
+ (Inet6Address) InetAddresses.parseNumericAddress("ff02::1:2");
+
+ /**
* IEEE802.11 standard constants.
*
* See also:
diff --git a/staticlibs/native/bpf_headers/include/bpf/BpfUtils.h b/staticlibs/native/bpf_headers/include/bpf/BpfUtils.h
index 157f210..dc4fb17 100644
--- a/staticlibs/native/bpf_headers/include/bpf/BpfUtils.h
+++ b/staticlibs/native/bpf_headers/include/bpf/BpfUtils.h
@@ -115,22 +115,5 @@
return kernelVersion() >= KVER(major, minor, sub);
}
-#define SKIP_IF_BPF_NOT_SUPPORTED \
- do { \
- if (!android::bpf::isAtLeastKernelVersion(4, 9, 0)) \
- GTEST_SKIP() << "Skip: bpf is not supported."; \
- } while (0)
-
-// Only used by tm-mainline-prod's system/netd/tests/bpf_base_test.cpp
-// but platform and platform tests aren't expected to build/work in tm-mainline-prod
-// so we can just trivialize this
-#define SKIP_IF_EXTENDED_BPF_NOT_SUPPORTED
-
-#define SKIP_IF_XDP_NOT_SUPPORTED \
- do { \
- if (!android::bpf::isAtLeastKernelVersion(5, 9, 0)) \
- GTEST_SKIP() << "Skip: xdp not supported."; \
- } while (0)
-
} // namespace bpf
} // namespace android
diff --git a/staticlibs/native/bpf_syscall_wrappers/include/BpfSyscallWrappers.h b/staticlibs/native/bpf_syscall_wrappers/include/BpfSyscallWrappers.h
index d5b7670..f7d6a38 100644
--- a/staticlibs/native/bpf_syscall_wrappers/include/BpfSyscallWrappers.h
+++ b/staticlibs/native/bpf_syscall_wrappers/include/BpfSyscallWrappers.h
@@ -38,7 +38,7 @@
* all unused portions are zero. It will fail with E2BIG if we don't fully zero bpf_attr.
*/
-inline int bpf(int cmd, const bpf_attr& attr) {
+inline int bpf(enum bpf_cmd cmd, const bpf_attr& attr) {
return syscall(__NR_bpf, cmd, &attr, sizeof(attr));
}
diff --git a/staticlibs/netd/Android.bp b/staticlibs/netd/Android.bp
index 79bde9b..6cc445b 100644
--- a/staticlibs/netd/Android.bp
+++ b/staticlibs/netd/Android.bp
@@ -21,7 +21,7 @@
sdk_version: "system_current",
min_sdk_version: "29",
static_libs: [
- "netd_aidl_interface-V10-java",
+ "netd_aidl_interface-V11-java",
],
apex_available: [
"//apex_available:platform", // used from services.net
@@ -44,7 +44,7 @@
cc_library_static {
name: "netd_aidl_interface-lateststable-ndk",
whole_static_libs: [
- "netd_aidl_interface-V10-ndk",
+ "netd_aidl_interface-V11-ndk",
],
apex_available: [
"com.android.resolv",
@@ -55,12 +55,12 @@
cc_defaults {
name: "netd_aidl_interface_lateststable_cpp_static",
- static_libs: ["netd_aidl_interface-V10-cpp"],
+ static_libs: ["netd_aidl_interface-V11-cpp"],
}
cc_defaults {
name: "netd_aidl_interface_lateststable_cpp_shared",
- shared_libs: ["netd_aidl_interface-V10-cpp"],
+ shared_libs: ["netd_aidl_interface-V11-cpp"],
}
aidl_interface {
@@ -149,6 +149,10 @@
version: "10",
imports: [],
},
+ {
+ version: "11",
+ imports: [],
+ },
],
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/11/.hash b/staticlibs/netd/aidl_api/netd_aidl_interface/11/.hash
new file mode 100644
index 0000000..d22cb04
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/11/.hash
@@ -0,0 +1 @@
+d384a1d9f2f6dc0301a43d2b9d6d3a49e3898ae7
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/11/android/net/INetd.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/11/android/net/INetd.aidl
new file mode 100644
index 0000000..e671fdb
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/11/android/net/INetd.aidl
@@ -0,0 +1,222 @@
+/**
+ * Copyright (c) 2016, 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+interface INetd {
+ boolean isAlive();
+ boolean firewallReplaceUidChain(in @utf8InCpp String chainName, boolean isAllowlist, in int[] uids);
+ boolean bandwidthEnableDataSaver(boolean enable);
+ /**
+ * @deprecated use networkCreate() instead.
+ */
+ void networkCreatePhysical(int netId, int permission);
+ /**
+ * @deprecated use networkCreate() instead.
+ */
+ void networkCreateVpn(int netId, boolean secure);
+ void networkDestroy(int netId);
+ void networkAddInterface(int netId, in @utf8InCpp String iface);
+ void networkRemoveInterface(int netId, in @utf8InCpp String iface);
+ void networkAddUidRanges(int netId, in android.net.UidRangeParcel[] uidRanges);
+ void networkRemoveUidRanges(int netId, in android.net.UidRangeParcel[] uidRanges);
+ void networkRejectNonSecureVpn(boolean add, in android.net.UidRangeParcel[] uidRanges);
+ void socketDestroy(in android.net.UidRangeParcel[] uidRanges, in int[] exemptUids);
+ boolean tetherApplyDnsInterfaces();
+ android.net.TetherStatsParcel[] tetherGetStats();
+ void interfaceAddAddress(in @utf8InCpp String ifName, in @utf8InCpp String addrString, int prefixLength);
+ void interfaceDelAddress(in @utf8InCpp String ifName, in @utf8InCpp String addrString, int prefixLength);
+ @utf8InCpp String getProcSysNet(int ipversion, int which, in @utf8InCpp String ifname, in @utf8InCpp String parameter);
+ void setProcSysNet(int ipversion, int which, in @utf8InCpp String ifname, in @utf8InCpp String parameter, in @utf8InCpp String value);
+ void ipSecSetEncapSocketOwner(in ParcelFileDescriptor socket, int newUid);
+ int ipSecAllocateSpi(int transformId, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int spi);
+ void ipSecAddSecurityAssociation(int transformId, int mode, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int underlyingNetId, int spi, int markValue, int markMask, in @utf8InCpp String authAlgo, in byte[] authKey, in int authTruncBits, in @utf8InCpp String cryptAlgo, in byte[] cryptKey, in int cryptTruncBits, in @utf8InCpp String aeadAlgo, in byte[] aeadKey, in int aeadIcvBits, int encapType, int encapLocalPort, int encapRemotePort, int interfaceId);
+ void ipSecDeleteSecurityAssociation(int transformId, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int spi, int markValue, int markMask, int interfaceId);
+ void ipSecApplyTransportModeTransform(in ParcelFileDescriptor socket, int transformId, int direction, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int spi);
+ void ipSecRemoveTransportModeTransform(in ParcelFileDescriptor socket);
+ void ipSecAddSecurityPolicy(int transformId, int selAddrFamily, int direction, in @utf8InCpp String tmplSrcAddress, in @utf8InCpp String tmplDstAddress, int spi, int markValue, int markMask, int interfaceId);
+ void ipSecUpdateSecurityPolicy(int transformId, int selAddrFamily, int direction, in @utf8InCpp String tmplSrcAddress, in @utf8InCpp String tmplDstAddress, int spi, int markValue, int markMask, int interfaceId);
+ void ipSecDeleteSecurityPolicy(int transformId, int selAddrFamily, int direction, int markValue, int markMask, int interfaceId);
+ void ipSecAddTunnelInterface(in @utf8InCpp String deviceName, in @utf8InCpp String localAddress, in @utf8InCpp String remoteAddress, int iKey, int oKey, int interfaceId);
+ void ipSecUpdateTunnelInterface(in @utf8InCpp String deviceName, in @utf8InCpp String localAddress, in @utf8InCpp String remoteAddress, int iKey, int oKey, int interfaceId);
+ void ipSecRemoveTunnelInterface(in @utf8InCpp String deviceName);
+ void wakeupAddInterface(in @utf8InCpp String ifName, in @utf8InCpp String prefix, int mark, int mask);
+ void wakeupDelInterface(in @utf8InCpp String ifName, in @utf8InCpp String prefix, int mark, int mask);
+ void setIPv6AddrGenMode(in @utf8InCpp String ifName, int mode);
+ void idletimerAddInterface(in @utf8InCpp String ifName, int timeout, in @utf8InCpp String classLabel);
+ void idletimerRemoveInterface(in @utf8InCpp String ifName, int timeout, in @utf8InCpp String classLabel);
+ void strictUidCleartextPenalty(int uid, int policyPenalty);
+ /**
+ * @deprecated This method has no effect and throws UnsupportedOperationException. The clatd control plane moved to the mainline module starting in T. See ClatCoordinator.
+ */
+ @utf8InCpp String clatdStart(in @utf8InCpp String ifName, in @utf8InCpp String nat64Prefix);
+ /**
+ * @deprecated This method has no effect and throws UnsupportedOperationException. The clatd control plane moved to the mainline module starting in T. See ClatCoordinator.
+ */
+ void clatdStop(in @utf8InCpp String ifName);
+ boolean ipfwdEnabled();
+ @utf8InCpp String[] ipfwdGetRequesterList();
+ void ipfwdEnableForwarding(in @utf8InCpp String requester);
+ void ipfwdDisableForwarding(in @utf8InCpp String requester);
+ void ipfwdAddInterfaceForward(in @utf8InCpp String fromIface, in @utf8InCpp String toIface);
+ void ipfwdRemoveInterfaceForward(in @utf8InCpp String fromIface, in @utf8InCpp String toIface);
+ void bandwidthSetInterfaceQuota(in @utf8InCpp String ifName, long bytes);
+ void bandwidthRemoveInterfaceQuota(in @utf8InCpp String ifName);
+ void bandwidthSetInterfaceAlert(in @utf8InCpp String ifName, long bytes);
+ void bandwidthRemoveInterfaceAlert(in @utf8InCpp String ifName);
+ void bandwidthSetGlobalAlert(long bytes);
+ void bandwidthAddNaughtyApp(int uid);
+ void bandwidthRemoveNaughtyApp(int uid);
+ void bandwidthAddNiceApp(int uid);
+ void bandwidthRemoveNiceApp(int uid);
+ void tetherStart(in @utf8InCpp String[] dhcpRanges);
+ void tetherStop();
+ boolean tetherIsEnabled();
+ void tetherInterfaceAdd(in @utf8InCpp String ifName);
+ void tetherInterfaceRemove(in @utf8InCpp String ifName);
+ @utf8InCpp String[] tetherInterfaceList();
+ void tetherDnsSet(int netId, in @utf8InCpp String[] dnsAddrs);
+ @utf8InCpp String[] tetherDnsList();
+ void networkAddRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop);
+ void networkRemoveRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop);
+ void networkAddLegacyRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop, int uid);
+ void networkRemoveLegacyRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop, int uid);
+ int networkGetDefault();
+ void networkSetDefault(int netId);
+ void networkClearDefault();
+ void networkSetPermissionForNetwork(int netId, int permission);
+ void networkSetPermissionForUser(int permission, in int[] uids);
+ void networkClearPermissionForUser(in int[] uids);
+ void trafficSetNetPermForUids(int permission, in int[] uids);
+ void networkSetProtectAllow(int uid);
+ void networkSetProtectDeny(int uid);
+ boolean networkCanProtect(int uid);
+ void firewallSetFirewallType(int firewalltype);
+ void firewallSetInterfaceRule(in @utf8InCpp String ifName, int firewallRule);
+ void firewallSetUidRule(int childChain, int uid, int firewallRule);
+ void firewallEnableChildChain(int childChain, boolean enable);
+ @utf8InCpp String[] interfaceGetList();
+ android.net.InterfaceConfigurationParcel interfaceGetCfg(in @utf8InCpp String ifName);
+ void interfaceSetCfg(in android.net.InterfaceConfigurationParcel cfg);
+ void interfaceSetIPv6PrivacyExtensions(in @utf8InCpp String ifName, boolean enable);
+ void interfaceClearAddrs(in @utf8InCpp String ifName);
+ void interfaceSetEnableIPv6(in @utf8InCpp String ifName, boolean enable);
+ void interfaceSetMtu(in @utf8InCpp String ifName, int mtu);
+ void tetherAddForward(in @utf8InCpp String intIface, in @utf8InCpp String extIface);
+ void tetherRemoveForward(in @utf8InCpp String intIface, in @utf8InCpp String extIface);
+ void setTcpRWmemorySize(in @utf8InCpp String rmemValues, in @utf8InCpp String wmemValues);
+ void registerUnsolicitedEventListener(android.net.INetdUnsolicitedEventListener listener);
+ void firewallAddUidInterfaceRules(in @utf8InCpp String ifName, in int[] uids);
+ void firewallRemoveUidInterfaceRules(in int[] uids);
+ void trafficSwapActiveStatsMap();
+ IBinder getOemNetd();
+ void tetherStartWithConfiguration(in android.net.TetherConfigParcel config);
+ android.net.MarkMaskParcel getFwmarkForNetwork(int netId);
+ void networkAddRouteParcel(int netId, in android.net.RouteInfoParcel routeInfo);
+ void networkUpdateRouteParcel(int netId, in android.net.RouteInfoParcel routeInfo);
+ void networkRemoveRouteParcel(int netId, in android.net.RouteInfoParcel routeInfo);
+ /**
+ * @deprecated This method has no effect and throws UnsupportedOperationException. The mainline module accesses the BPF map directly starting in S. See BpfCoordinator.
+ */
+ void tetherOffloadRuleAdd(in android.net.TetherOffloadRuleParcel rule);
+ /**
+ * @deprecated This method has no effect and throws UnsupportedOperationException. The mainline module accesses the BPF map directly starting in S. See BpfCoordinator.
+ */
+ void tetherOffloadRuleRemove(in android.net.TetherOffloadRuleParcel rule);
+ /**
+ * @deprecated This method has no effect and throws UnsupportedOperationException. The mainline module accesses the BPF map directly starting in S. See BpfCoordinator.
+ */
+ android.net.TetherStatsParcel[] tetherOffloadGetStats();
+ /**
+ * @deprecated This method has no effect and throws UnsupportedOperationException. The mainline module accesses the BPF map directly starting in S. See BpfCoordinator.
+ */
+ void tetherOffloadSetInterfaceQuota(int ifIndex, long quotaBytes);
+ /**
+ * @deprecated This method has no effect and throws UnsupportedOperationException. The mainline module accesses the BPF map directly starting in S. See BpfCoordinator.
+ */
+ android.net.TetherStatsParcel tetherOffloadGetAndClearStats(int ifIndex);
+ void networkCreate(in android.net.NativeNetworkConfig config);
+ void networkAddUidRangesParcel(in android.net.netd.aidl.NativeUidRangeConfig uidRangesConfig);
+ void networkRemoveUidRangesParcel(in android.net.netd.aidl.NativeUidRangeConfig uidRangesConfig);
+ const int IPV4 = 4;
+ const int IPV6 = 6;
+ const int CONF = 1;
+ const int NEIGH = 2;
+ const String IPSEC_INTERFACE_PREFIX = "ipsec";
+ const int IPV6_ADDR_GEN_MODE_EUI64 = 0;
+ const int IPV6_ADDR_GEN_MODE_NONE = 1;
+ const int IPV6_ADDR_GEN_MODE_STABLE_PRIVACY = 2;
+ const int IPV6_ADDR_GEN_MODE_RANDOM = 3;
+ const int IPV6_ADDR_GEN_MODE_DEFAULT = 0;
+ const int PENALTY_POLICY_ACCEPT = 1;
+ const int PENALTY_POLICY_LOG = 2;
+ const int PENALTY_POLICY_REJECT = 3;
+ const int CLAT_MARK = -559038041;
+ const int LOCAL_NET_ID = 99;
+ const int DUMMY_NET_ID = 51;
+ const int UNREACHABLE_NET_ID = 52;
+ const String NEXTHOP_NONE = "";
+ const String NEXTHOP_UNREACHABLE = "unreachable";
+ const String NEXTHOP_THROW = "throw";
+ const int PERMISSION_NONE = 0;
+ const int PERMISSION_NETWORK = 1;
+ const int PERMISSION_SYSTEM = 2;
+ const int NO_PERMISSIONS = 0;
+ const int PERMISSION_INTERNET = 4;
+ const int PERMISSION_UPDATE_DEVICE_STATS = 8;
+ const int PERMISSION_UNINSTALLED = -1;
+ /**
+ * @deprecated use FIREWALL_ALLOWLIST.
+ */
+ const int FIREWALL_WHITELIST = 0;
+ const int FIREWALL_ALLOWLIST = 0;
+ /**
+ * @deprecated use FIREWALL_DENYLIST.
+ */
+ const int FIREWALL_BLACKLIST = 1;
+ const int FIREWALL_DENYLIST = 1;
+ const int FIREWALL_RULE_ALLOW = 1;
+ const int FIREWALL_RULE_DENY = 2;
+ const int FIREWALL_CHAIN_NONE = 0;
+ const int FIREWALL_CHAIN_DOZABLE = 1;
+ const int FIREWALL_CHAIN_STANDBY = 2;
+ const int FIREWALL_CHAIN_POWERSAVE = 3;
+ const int FIREWALL_CHAIN_RESTRICTED = 4;
+ const String IF_STATE_UP = "up";
+ const String IF_STATE_DOWN = "down";
+ const String IF_FLAG_BROADCAST = "broadcast";
+ const String IF_FLAG_LOOPBACK = "loopback";
+ const String IF_FLAG_POINTOPOINT = "point-to-point";
+ const String IF_FLAG_RUNNING = "running";
+ const String IF_FLAG_MULTICAST = "multicast";
+}
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/11/android/net/INetdUnsolicitedEventListener.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/11/android/net/INetdUnsolicitedEventListener.aidl
new file mode 100644
index 0000000..31775df
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/11/android/net/INetdUnsolicitedEventListener.aidl
@@ -0,0 +1,48 @@
+/**
+ * Copyright (c) 2018, 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+interface INetdUnsolicitedEventListener {
+ oneway void onInterfaceClassActivityChanged(boolean isActive, int timerLabel, long timestampNs, int uid);
+ oneway void onQuotaLimitReached(@utf8InCpp String alertName, @utf8InCpp String ifName);
+ oneway void onInterfaceDnsServerInfo(@utf8InCpp String ifName, long lifetimeS, in @utf8InCpp String[] servers);
+ oneway void onInterfaceAddressUpdated(@utf8InCpp String addr, @utf8InCpp String ifName, int flags, int scope);
+ oneway void onInterfaceAddressRemoved(@utf8InCpp String addr, @utf8InCpp String ifName, int flags, int scope);
+ oneway void onInterfaceAdded(@utf8InCpp String ifName);
+ oneway void onInterfaceRemoved(@utf8InCpp String ifName);
+ oneway void onInterfaceChanged(@utf8InCpp String ifName, boolean up);
+ oneway void onInterfaceLinkStateChanged(@utf8InCpp String ifName, boolean up);
+ oneway void onRouteChanged(boolean updated, @utf8InCpp String route, @utf8InCpp String gateway, @utf8InCpp String ifName);
+ oneway void onStrictCleartextDetected(int uid, @utf8InCpp String hex);
+}
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/11/android/net/InterfaceConfigurationParcel.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/11/android/net/InterfaceConfigurationParcel.aidl
new file mode 100644
index 0000000..1869d8d
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/11/android/net/InterfaceConfigurationParcel.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+parcelable InterfaceConfigurationParcel {
+ @utf8InCpp String ifName;
+ @utf8InCpp String hwAddr;
+ @utf8InCpp String ipv4Addr;
+ int prefixLength;
+ @utf8InCpp String[] flags;
+}
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/11/android/net/MarkMaskParcel.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/11/android/net/MarkMaskParcel.aidl
new file mode 100644
index 0000000..8ea20d1
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/11/android/net/MarkMaskParcel.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+parcelable MarkMaskParcel {
+ int mark;
+ int mask;
+}
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/11/android/net/NativeNetworkConfig.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/11/android/net/NativeNetworkConfig.aidl
new file mode 100644
index 0000000..77d814b
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/11/android/net/NativeNetworkConfig.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @JavaOnlyImmutable
+parcelable NativeNetworkConfig {
+ int netId;
+ android.net.NativeNetworkType networkType = android.net.NativeNetworkType.PHYSICAL;
+ int permission;
+ boolean secure;
+ android.net.NativeVpnType vpnType = android.net.NativeVpnType.PLATFORM;
+ boolean excludeLocalRoutes = false;
+}
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/11/android/net/NativeNetworkType.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/11/android/net/NativeNetworkType.aidl
new file mode 100644
index 0000000..e77a143
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/11/android/net/NativeNetworkType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+@Backing(type="int")
+enum NativeNetworkType {
+ PHYSICAL = 0,
+ VIRTUAL = 1,
+ PHYSICAL_LOCAL = 2,
+}
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/11/android/net/NativeVpnType.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/11/android/net/NativeVpnType.aidl
new file mode 100644
index 0000000..8a8be83
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/11/android/net/NativeVpnType.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+@Backing(type="int")
+enum NativeVpnType {
+ SERVICE = 1,
+ PLATFORM = 2,
+ LEGACY = 3,
+ OEM = 4,
+}
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/11/android/net/RouteInfoParcel.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/11/android/net/RouteInfoParcel.aidl
new file mode 100644
index 0000000..5ef95e6
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/11/android/net/RouteInfoParcel.aidl
@@ -0,0 +1,40 @@
+/**
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+parcelable RouteInfoParcel {
+ @utf8InCpp String destination;
+ @utf8InCpp String ifName;
+ @utf8InCpp String nextHop;
+ int mtu;
+}
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/11/android/net/TetherConfigParcel.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/11/android/net/TetherConfigParcel.aidl
new file mode 100644
index 0000000..7b39c22
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/11/android/net/TetherConfigParcel.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+parcelable TetherConfigParcel {
+ boolean usingLegacyDnsProxy;
+ @utf8InCpp String[] dhcpRanges;
+}
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/11/android/net/TetherOffloadRuleParcel.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/11/android/net/TetherOffloadRuleParcel.aidl
new file mode 100644
index 0000000..983e986
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/11/android/net/TetherOffloadRuleParcel.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+parcelable TetherOffloadRuleParcel {
+ int inputInterfaceIndex;
+ int outputInterfaceIndex;
+ byte[] destination;
+ int prefixLength;
+ byte[] srcL2Address;
+ byte[] dstL2Address;
+ int pmtu = 1500;
+}
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/11/android/net/TetherStatsParcel.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/11/android/net/TetherStatsParcel.aidl
new file mode 100644
index 0000000..5f1b722
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/11/android/net/TetherStatsParcel.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+parcelable TetherStatsParcel {
+ @utf8InCpp String iface;
+ long rxBytes;
+ long rxPackets;
+ long txBytes;
+ long txPackets;
+ int ifIndex = 0;
+}
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/11/android/net/UidRangeParcel.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/11/android/net/UidRangeParcel.aidl
new file mode 100644
index 0000000..72e987a
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/11/android/net/UidRangeParcel.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @JavaOnlyImmutable
+parcelable UidRangeParcel {
+ int start;
+ int stop;
+}
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/11/android/net/netd/aidl/NativeUidRangeConfig.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/11/android/net/netd/aidl/NativeUidRangeConfig.aidl
new file mode 100644
index 0000000..9bb679f
--- /dev/null
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/11/android/net/netd/aidl/NativeUidRangeConfig.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.netd.aidl;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @JavaOnlyImmutable
+parcelable NativeUidRangeConfig {
+ int netId;
+ android.net.UidRangeParcel[] uidRanges;
+ int subPriority;
+}
diff --git a/staticlibs/netd/aidl_api/netd_aidl_interface/current/android/net/NativeNetworkType.aidl b/staticlibs/netd/aidl_api/netd_aidl_interface/current/android/net/NativeNetworkType.aidl
index 06c8979..e77a143 100644
--- a/staticlibs/netd/aidl_api/netd_aidl_interface/current/android/net/NativeNetworkType.aidl
+++ b/staticlibs/netd/aidl_api/netd_aidl_interface/current/android/net/NativeNetworkType.aidl
@@ -36,4 +36,5 @@
enum NativeNetworkType {
PHYSICAL = 0,
VIRTUAL = 1,
+ PHYSICAL_LOCAL = 2,
}
diff --git a/staticlibs/netd/binder/android/net/NativeNetworkConfig.aidl b/staticlibs/netd/binder/android/net/NativeNetworkConfig.aidl
index e654a1f..96eccc7 100644
--- a/staticlibs/netd/binder/android/net/NativeNetworkConfig.aidl
+++ b/staticlibs/netd/binder/android/net/NativeNetworkConfig.aidl
@@ -31,13 +31,13 @@
int netId;
/**
- * The type of network, e.g. physical network or virtual network.
+ * The type of network : virtual, physical or physical local network.
*/
NativeNetworkType networkType = NativeNetworkType.PHYSICAL;
/**
- * For physical networks. The permission necessary to use the network. Must be one of
- * PERMISSION_NONE/PERMISSION_NETWORK/PERMISSION_SYSTEM. Ignored for all other network types.
+ * The permission necessary to use the network. Must be PERMISSION_NONE, PERMISSION_NETWORK
+ * or PERMISSION_SYSTEM. Ignored for virtual network types.
*/
int permission;
diff --git a/staticlibs/netd/binder/android/net/NativeNetworkType.aidl b/staticlibs/netd/binder/android/net/NativeNetworkType.aidl
index d667029..7005535 100644
--- a/staticlibs/netd/binder/android/net/NativeNetworkType.aidl
+++ b/staticlibs/netd/binder/android/net/NativeNetworkType.aidl
@@ -27,4 +27,9 @@
* Virtual private network type.
*/
VIRTUAL = 1,
-}
\ No newline at end of file
+
+ /**
+ * Physical local network, such as a tethering downstream.
+ */
+ PHYSICAL_LOCAL = 2,
+}
diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/ip/ConntrackMonitorTest.java b/staticlibs/tests/unit/src/com/android/net/module/util/ip/ConntrackMonitorTest.java
index 99d8f07..7ee376c 100644
--- a/staticlibs/tests/unit/src/com/android/net/module/util/ip/ConntrackMonitorTest.java
+++ b/staticlibs/tests/unit/src/com/android/net/module/util/ip/ConntrackMonitorTest.java
@@ -47,7 +47,7 @@
import com.android.net.module.util.SharedLog;
import com.android.net.module.util.ip.ConntrackMonitor.ConntrackEvent;
import com.android.net.module.util.netlink.NetlinkConstants;
-import com.android.net.module.util.netlink.NetlinkSocket;
+import com.android.net.module.util.netlink.NetlinkUtils;
import libcore.util.HexEncoding;
@@ -104,7 +104,7 @@
private void sendMessage(byte[] msg) {
mHandler.post(() -> {
try {
- NetlinkSocket.sendMessage(mWriteFd, msg, 0 /* offset */, msg.length,
+ NetlinkUtils.sendMessage(mWriteFd, msg, 0 /* offset */, msg.length,
TIMEOUT_MS);
} catch (ErrnoException | InterruptedIOException e) {
fail("Unable to send netfilter message: " + e);
diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/netlink/NetlinkSocketTest.java b/staticlibs/tests/unit/src/com/android/net/module/util/netlink/NetlinkUtilsTest.java
similarity index 89%
rename from staticlibs/tests/unit/src/com/android/net/module/util/netlink/NetlinkSocketTest.java
rename to staticlibs/tests/unit/src/com/android/net/module/util/netlink/NetlinkUtilsTest.java
index f4073b6..7a1639a 100644
--- a/staticlibs/tests/unit/src/com/android/net/module/util/netlink/NetlinkSocketTest.java
+++ b/staticlibs/tests/unit/src/com/android/net/module/util/netlink/NetlinkUtilsTest.java
@@ -22,7 +22,7 @@
import static android.system.OsConstants.EACCES;
import static android.system.OsConstants.NETLINK_ROUTE;
-import static com.android.net.module.util.netlink.NetlinkSocket.DEFAULT_RECV_BUFSIZE;
+import static com.android.net.module.util.netlink.NetlinkUtils.DEFAULT_RECV_BUFSIZE;
import static com.android.net.module.util.netlink.StructNlMsgHdr.NLM_F_DUMP;
import static com.android.net.module.util.netlink.StructNlMsgHdr.NLM_F_REQUEST;
@@ -42,8 +42,6 @@
import com.android.modules.utils.build.SdkLevel;
import com.android.net.module.util.Struct;
-import com.android.net.module.util.Struct.Field;
-import com.android.net.module.util.Struct.Type;
import libcore.io.IoUtils;
@@ -56,17 +54,17 @@
@RunWith(AndroidJUnit4.class)
@SmallTest
-public class NetlinkSocketTest {
- private static final String TAG = "NetlinkSocketTest";
+public class NetlinkUtilsTest {
+ private static final String TAG = "NetlinkUitlsTest";
private static final int TEST_SEQNO = 5;
private static final int TEST_TIMEOUT_MS = 500;
@Test
public void testGetNeighborsQuery() throws Exception {
- final FileDescriptor fd = NetlinkSocket.forProto(NETLINK_ROUTE);
+ final FileDescriptor fd = NetlinkUtils.netlinkSocketForProto(NETLINK_ROUTE);
assertNotNull(fd);
- NetlinkSocket.connectToKernel(fd);
+ NetlinkUtils.connectSocketToNetlink(fd);
final NetlinkSocketAddress localAddr = (NetlinkSocketAddress) Os.getsockname(fd);
assertNotNull(localAddr);
@@ -85,7 +83,7 @@
// Apps targeting an SDK version > S are not allowed to send RTM_GETNEIGH{TBL} messages
if (SdkLevel.isAtLeastT() && targetSdk > 31) {
try {
- NetlinkSocket.sendMessage(fd, req, 0, req.length, TEST_TIMEOUT_MS);
+ NetlinkUtils.sendMessage(fd, req, 0, req.length, TEST_TIMEOUT_MS);
fail("RTM_GETNEIGH is not allowed for apps targeting SDK > 31 on T+ platforms,"
+ " target SDK version: " + targetSdk);
} catch (ErrnoException e) {
@@ -97,14 +95,14 @@
// Check that apps targeting lower API levels / running on older platforms succeed
assertEquals(req.length,
- NetlinkSocket.sendMessage(fd, req, 0, req.length, TEST_TIMEOUT_MS));
+ NetlinkUtils.sendMessage(fd, req, 0, req.length, TEST_TIMEOUT_MS));
int neighMessageCount = 0;
int doneMessageCount = 0;
while (doneMessageCount == 0) {
ByteBuffer response =
- NetlinkSocket.recvMessage(fd, DEFAULT_RECV_BUFSIZE, TEST_TIMEOUT_MS);
+ NetlinkUtils.recvMessage(fd, DEFAULT_RECV_BUFSIZE, TEST_TIMEOUT_MS);
assertNotNull(response);
assertTrue(StructNlMsgHdr.STRUCT_SIZE <= response.limit());
assertEquals(0, response.position());
@@ -141,10 +139,10 @@
@Test
public void testBasicWorkingGetAddrQuery() throws Exception {
- final FileDescriptor fd = NetlinkSocket.forProto(NETLINK_ROUTE);
+ final FileDescriptor fd = NetlinkUtils.netlinkSocketForProto(NETLINK_ROUTE);
assertNotNull(fd);
- NetlinkSocket.connectToKernel(fd);
+ NetlinkUtils.connectSocketToNetlink(fd);
final NetlinkSocketAddress localAddr = (NetlinkSocketAddress) Os.getsockname(fd);
assertNotNull(localAddr);
@@ -156,12 +154,12 @@
assertNotNull(req);
final long timeout = 500;
- assertEquals(req.length, NetlinkSocket.sendMessage(fd, req, 0, req.length, timeout));
+ assertEquals(req.length, NetlinkUtils.sendMessage(fd, req, 0, req.length, timeout));
int addrMessageCount = 0;
while (true) {
- ByteBuffer response = NetlinkSocket.recvMessage(fd, DEFAULT_RECV_BUFSIZE, timeout);
+ ByteBuffer response = NetlinkUtils.recvMessage(fd, DEFAULT_RECV_BUFSIZE, timeout);
assertNotNull(response);
assertTrue(StructNlMsgHdr.STRUCT_SIZE <= response.limit());
assertEquals(0, response.position());
diff --git a/staticlibs/tests/unit/src/com/android/testutils/TestDnsServerTest.kt b/staticlibs/tests/unit/src/com/android/testutils/TestDnsServerTest.kt
new file mode 100644
index 0000000..6f4587b
--- /dev/null
+++ b/staticlibs/tests/unit/src/com/android/testutils/TestDnsServerTest.kt
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2022 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.net.DnsResolver.CLASS_IN
+import android.net.DnsResolver.TYPE_AAAA
+import android.net.Network
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.net.module.util.DnsPacket
+import com.android.net.module.util.DnsPacket.DnsRecord
+import libcore.net.InetAddressUtils
+import org.junit.After
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito
+import java.net.DatagramPacket
+import java.net.DatagramSocket
+import java.net.InetAddress
+import java.net.InetSocketAddress
+import kotlin.test.assertEquals
+import kotlin.test.assertFailsWith
+import kotlin.test.assertFalse
+import kotlin.test.assertTrue
+
+val TEST_V6_ADDR = InetAddressUtils.parseNumericAddress("2001:db8::3")
+const val TEST_DOMAIN = "hello.example.com"
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class TestDnsServerTest {
+ private val network = Mockito.mock(Network::class.java)
+ private val localAddr = InetSocketAddress(InetAddress.getLocalHost(), 0 /* port */)
+ private val testServer: TestDnsServer = TestDnsServer(network, localAddr)
+
+ @After
+ fun tearDown() {
+ if (testServer.isAlive) testServer.stop()
+ }
+
+ @Test
+ fun testStartStop() {
+ repeat(100) {
+ val server = TestDnsServer(network, localAddr)
+ server.start()
+ assertTrue(server.isAlive)
+ server.stop()
+ assertFalse(server.isAlive)
+ }
+
+ // Test illegal start/stop.
+ assertFailsWith<IllegalStateException> { testServer.stop() }
+ testServer.start()
+ assertTrue(testServer.isAlive)
+ assertFailsWith<IllegalStateException> { testServer.start() }
+ testServer.stop()
+ assertFalse(testServer.isAlive)
+ assertFailsWith<IllegalStateException> { testServer.stop() }
+ // TestDnsServer rejects start after stop.
+ assertFailsWith<IllegalStateException> { testServer.start() }
+ }
+
+ @Test
+ fun testHandleDnsQuery() {
+ testServer.setAnswer(TEST_DOMAIN, listOf(TEST_V6_ADDR))
+ testServer.start()
+
+ // Mock query and send it to the test server.
+ val queryHeader = DnsPacket.DnsHeader(0xbeef /* id */,
+ 0x0 /* flag */, 1 /* qcount */, 0 /* ancount */)
+ val qlist = listOf(DnsRecord.makeQuestion(TEST_DOMAIN, TYPE_AAAA, CLASS_IN))
+ val queryPacket = TestDnsServer.DnsQueryPacket(queryHeader, qlist, emptyList())
+ val response = resolve(queryPacket, testServer.port)
+
+ // Verify expected answer packet. Set QR bit of flag to 1 for response packet
+ // according to RFC 1035 section 4.1.1.
+ val answerHeader = DnsPacket.DnsHeader(0xbeef,
+ 1 shl 15 /* flag */, 1 /* qcount */, 1 /* ancount */)
+ val alist = listOf(DnsRecord.makeAOrAAAARecord(DnsPacket.ANSECTION, TEST_DOMAIN,
+ CLASS_IN, DEFAULT_TTL_S, TEST_V6_ADDR))
+ val expectedAnswerPacket = TestDnsServer.DnsAnswerPacket(answerHeader, qlist, alist)
+ assertEquals(expectedAnswerPacket, response)
+
+ // Clean up the server in tearDown.
+ }
+
+ private fun resolve(queryDnsPacket: DnsPacket, serverPort: Int): TestDnsServer.DnsAnswerPacket {
+ val bytes = queryDnsPacket.bytes
+ // Create a new client socket, the socket will be bound to a
+ // random port other than the server port.
+ val socket = DatagramSocket(localAddr).also { it.soTimeout = 100 }
+ val queryPacket = DatagramPacket(bytes, bytes.size, localAddr.address, serverPort)
+
+ // Send query and wait for the reply.
+ socket.send(queryPacket)
+ val buffer = ByteArray(MAX_BUF_SIZE)
+ val reply = DatagramPacket(buffer, buffer.size)
+ socket.receive(reply)
+ return TestDnsServer.DnsAnswerPacket(reply.data)
+ }
+
+ // TODO: Add more tests, which includes:
+ // * Empty question RR packet (or more unexpected states)
+ // * No answer found (setAnswer empty list at L.78)
+ // * Test one or multi A record(s)
+ // * Test multi AAAA records
+ // * Test CNAME records
+}
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/DnsAnswerProvider.kt b/staticlibs/testutils/devicetests/com/android/testutils/DnsAnswerProvider.kt
new file mode 100644
index 0000000..6a804bf
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/DnsAnswerProvider.kt
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2022 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.net.DnsResolver.CLASS_IN
+import com.android.net.module.util.DnsPacket
+import com.android.net.module.util.DnsPacket.ANSECTION
+import java.net.InetAddress
+import java.util.concurrent.ConcurrentHashMap
+
+const val DEFAULT_TTL_S = 5L
+
+/**
+ * Helper class to store the mapping of DNS queries.
+ *
+ * DnsAnswerProvider is built atop a ConcurrentHashMap and as such it provides the same
+ * guarantees as ConcurrentHashMap between writing and reading elements. Specifically :
+ * - Setting an answer happens-before reading the same answer.
+ * - Callers can read and write concurrently from DnsAnswerProvider and expect no
+ * ConcurrentModificationException.
+ * Freshness of the answers depends on ordering of the threads ; if callers need a
+ * freshness guarantee, they need to provide the happens-before relationship from a
+ * write that they want to observe to the read that they need to be observed.
+ */
+class DnsAnswerProvider {
+ private val mDnsKeyToRecords = ConcurrentHashMap<String, List<DnsPacket.DnsRecord>>()
+
+ /**
+ * Get answer for the specified hostname.
+ *
+ * @param query the target hostname.
+ * @param type type of record, could be A or AAAA.
+ *
+ * @return list of [DnsPacket.DnsRecord] associated to the query. Empty if no record matches.
+ */
+ fun getAnswer(query: String, type: Int) = mDnsKeyToRecords[query]
+ .orEmpty().filter { it.nsType == type }
+
+ /** Set answer for the specified {@code query}.
+ *
+ * @param query the target hostname
+ * @param addresses [List<InetAddress>] which could be used to generate multiple A or AAAA
+ * RRs with the corresponding addresses.
+ */
+ fun setAnswer(query: String, hosts: List<InetAddress>) = mDnsKeyToRecords.put(query, hosts.map {
+ DnsPacket.DnsRecord.makeAOrAAAARecord(ANSECTION, query, CLASS_IN, DEFAULT_TTL_S, it)
+ })
+
+ fun clearAnswer(query: String) = mDnsKeyToRecords.remove(query)
+ fun clearAll() = mDnsKeyToRecords.clear()
+}
\ No newline at end of file
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/TestDnsServer.kt b/staticlibs/testutils/devicetests/com/android/testutils/TestDnsServer.kt
new file mode 100644
index 0000000..e1b771b
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/TestDnsServer.kt
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2022 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.net.Network
+import android.util.Log
+import com.android.internal.annotations.GuardedBy
+import com.android.internal.annotations.VisibleForTesting
+import com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE
+import com.android.net.module.util.DnsPacket
+import java.net.DatagramPacket
+import java.net.DatagramSocket
+import java.net.InetAddress
+import java.net.InetSocketAddress
+import java.net.SocketAddress
+import java.net.SocketException
+import java.util.ArrayList
+
+private const val TAG = "TestDnsServer"
+private const val VDBG = true
+@VisibleForTesting(visibility = PRIVATE)
+const val MAX_BUF_SIZE = 8192
+
+/**
+ * A simple implementation of Dns Server that can be bound on specific address and Network.
+ *
+ * The caller should use start() to make the server start a new thread to receive DNS queries
+ * on the bound address, [isAlive] to check status, and stop() for stopping.
+ * The server allows user to manipulate the records to be answered through
+ * [setAnswer] at runtime.
+ *
+ * This server runs on its own thread. Please make sure writing the query to the socket
+ * happens-after using [setAnswer] to guarantee the correct answer is returned. If possible,
+ * use [setAnswer] before calling [start] for simplicity.
+ */
+class TestDnsServer(network: Network, addr: InetSocketAddress) {
+ enum class Status {
+ NOT_STARTED, STARTED, STOPPED
+ }
+ @GuardedBy("thread")
+ private var status: Status = Status.NOT_STARTED
+ private val thread = ReceivingThread()
+ private val socket = DatagramSocket(addr).also { network.bindSocket(it) }
+ private val ansProvider = DnsAnswerProvider()
+
+ // The buffer to store the received packet. They are being reused for
+ // efficiency and it's fine because they are only ever accessed
+ // on the server thread in a sequential manner.
+ private val buffer = ByteArray(MAX_BUF_SIZE)
+ private val packet = DatagramPacket(buffer, buffer.size)
+
+ fun setAnswer(hostname: String, answer: List<InetAddress>) =
+ ansProvider.setAnswer(hostname, answer)
+
+ private fun processPacket() {
+ // Blocking read and try construct a DnsQueryPacket object.
+ socket.receive(packet)
+ val q = DnsQueryPacket(packet.data)
+ handleDnsQuery(q, packet.socketAddress)
+ }
+
+ // TODO: Add support to reply some error with a DNS reply packet with failure RCODE.
+ private fun handleDnsQuery(q: DnsQueryPacket, src: SocketAddress) {
+ val queryRecords = q.queryRecords
+ if (queryRecords.size != 1) {
+ throw IllegalArgumentException(
+ "Expected one dns query record but got ${queryRecords.size}"
+ )
+ }
+ val answerRecords = queryRecords[0].let { ansProvider.getAnswer(it.dName, it.nsType) }
+
+ if (VDBG) {
+ Log.v(TAG, "handleDnsPacket: " +
+ queryRecords.map { "${it.dName},${it.nsType}" }.joinToString() +
+ " ansCount=${answerRecords.size} socketAddress=$src")
+ }
+
+ val bytes = q.getAnswerPacket(answerRecords).bytes
+ val reply = DatagramPacket(bytes, bytes.size, src)
+ socket.send(reply)
+ }
+
+ fun start() {
+ synchronized(thread) {
+ if (status != Status.NOT_STARTED) {
+ throw IllegalStateException("unexpected status: $status")
+ }
+ thread.start()
+ status = Status.STARTED
+ }
+ }
+ fun stop() {
+ synchronized(thread) {
+ if (status != Status.STARTED) {
+ throw IllegalStateException("unexpected status: $status")
+ }
+ // The thread needs to be interrupted before closing the socket to prevent a data
+ // race where the thread tries to read from the socket while it's being closed.
+ // DatagramSocket is not thread-safe and running both concurrently can end up in
+ // getPort() returning -1 after it's been checked not to, resulting in a crash by
+ // IllegalArgumentException inside the DatagramSocket implementation.
+ thread.interrupt()
+ socket.close()
+ thread.join()
+ status = Status.STOPPED
+ }
+ }
+ val isAlive get() = thread.isAlive
+ val port get() = socket.localPort
+
+ inner class ReceivingThread : Thread() {
+ override fun run() {
+ while (!interrupted() && !socket.isClosed) {
+ try {
+ processPacket()
+ } catch (e: InterruptedException) {
+ // The caller terminated the server, exit.
+ break
+ } catch (e: SocketException) {
+ // The caller terminated the server, exit.
+ break
+ }
+ }
+ Log.i(TAG, "exiting socket={$socket}")
+ }
+ }
+
+ @VisibleForTesting(visibility = PRIVATE)
+ class DnsQueryPacket : DnsPacket {
+ constructor(data: ByteArray) : super(data)
+ constructor(header: DnsHeader, qd: List<DnsRecord>, an: List<DnsRecord>) :
+ super(header, qd, an)
+
+ init {
+ if (mHeader.isResponse) {
+ throw ParseException("Not a query packet")
+ }
+ }
+
+ val queryRecords: List<DnsRecord>
+ get() = mRecords[QDSECTION]
+
+ fun getAnswerPacket(ar: List<DnsRecord>): DnsAnswerPacket {
+ // Set QR bit of flag to 1 for response packet according to RFC 1035 section 4.1.1.
+ val flags = 1 shl 15
+ val qr = ArrayList(mRecords[QDSECTION])
+ // Copy the query packet header id to the answer packet as RFC 1035 section 4.1.1.
+ val header = DnsHeader(mHeader.id, flags, qr.size, ar.size)
+ return DnsAnswerPacket(header, qr, ar)
+ }
+ }
+
+ class DnsAnswerPacket : DnsPacket {
+ constructor(header: DnsHeader, qr: List<DnsRecord>, ar: List<DnsRecord>) :
+ super(header, qr, ar)
+ @VisibleForTesting(visibility = PRIVATE)
+ constructor(bytes: ByteArray) : super(bytes)
+ }
+}