Add support for setsockoptBytes
Test: atest FrameworksNetTests:android.net.connectivity.android.net.NetworkUtilsTest Change-Id: I3d94172fa8a42e2ab8ba4caf80d5caaa11fac703
This commit is contained in:
@@ -26,6 +26,7 @@
|
||||
#include <bpf/BpfClassic.h>
|
||||
#include <DnsProxydProtocol.h> // NETID_USE_LOCAL_NAMESERVERS
|
||||
#include <nativehelper/JNIPlatformHelp.h>
|
||||
#include <nativehelper/ScopedPrimitiveArray.h>
|
||||
#include <utils/Log.h>
|
||||
|
||||
#include "jni.h"
|
||||
@@ -240,6 +241,15 @@ static jobject android_net_utils_getTcpRepairWindow(JNIEnv *env, jclass clazz, j
|
||||
trw.rcv_wnd, trw.rcv_wup, tcpinfo.tcpi_rcv_wscale);
|
||||
}
|
||||
|
||||
static void android_net_utils_setsockoptBytes(JNIEnv *env, jclass clazz, jobject javaFd,
|
||||
jint level, jint option, jbyteArray javaBytes) {
|
||||
int sock = AFileDescriptor_getFd(env, javaFd);
|
||||
ScopedByteArrayRO value(env, javaBytes);
|
||||
if (setsockopt(sock, level, option, value.get(), value.size()) != 0) {
|
||||
jniThrowErrnoException(env, "setsockoptBytes", errno);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
@@ -260,6 +270,8 @@ static const JNINativeMethod gNetworkUtilMethods[] = {
|
||||
{ "resNetworkResult", "(Ljava/io/FileDescriptor;)Landroid/net/DnsResolver$DnsResponse;", (void*) android_net_utils_resNetworkResult },
|
||||
{ "resNetworkCancel", "(Ljava/io/FileDescriptor;)V", (void*) android_net_utils_resNetworkCancel },
|
||||
{ "getDnsNetwork", "()Landroid/net/Network;", (void*) android_net_utils_getDnsNetwork },
|
||||
{ "setsockoptBytes", "(Ljava/io/FileDescriptor;II[B)V",
|
||||
(void*) android_net_utils_setsockoptBytes},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
|
||||
@@ -426,4 +426,16 @@ public class NetworkUtils {
|
||||
return routedIPCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a socket option with byte array
|
||||
*
|
||||
* @param fd The socket file descriptor
|
||||
* @param level The level at which the option is defined
|
||||
* @param option The socket option for which the value is to be set
|
||||
* @param value The option value to be set in byte array
|
||||
* @throws ErrnoException if setsockopt fails
|
||||
*/
|
||||
public static native void setsockoptBytes(FileDescriptor fd, int level, int option,
|
||||
byte[] value) throws ErrnoException;
|
||||
|
||||
}
|
||||
|
||||
@@ -16,19 +16,32 @@
|
||||
|
||||
package android.net;
|
||||
|
||||
import static android.system.OsConstants.AF_INET6;
|
||||
import static android.system.OsConstants.IPPROTO_ICMPV6;
|
||||
import static android.system.OsConstants.SOCK_DGRAM;
|
||||
import static android.system.OsConstants.SOL_SOCKET;
|
||||
import static android.system.OsConstants.SO_RCVTIMEO;
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
|
||||
import android.os.Build;
|
||||
import android.system.ErrnoException;
|
||||
import android.system.Os;
|
||||
import android.system.StructTimeval;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.net.module.util.SocketUtils;
|
||||
import com.android.testutils.DevSdkIgnoreRule;
|
||||
import com.android.testutils.DevSdkIgnoreRunner;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.TreeSet;
|
||||
|
||||
@RunWith(DevSdkIgnoreRunner.class)
|
||||
@@ -131,4 +144,27 @@ public class NetworkUtilsTest {
|
||||
assertEquals(BigInteger.valueOf(7l - 4 + 4 + 16 + 65536),
|
||||
NetworkUtils.routedIPv6AddressCount(set));
|
||||
}
|
||||
|
||||
private byte[] getTimevalBytes(StructTimeval tv) {
|
||||
byte[] timeval = new byte[16];
|
||||
ByteBuffer buf = ByteBuffer.wrap(timeval);
|
||||
buf.order(ByteOrder.nativeOrder());
|
||||
buf.putLong(tv.tv_sec);
|
||||
buf.putLong(tv.tv_usec);
|
||||
return timeval;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetSockOptBytes() throws ErrnoException {
|
||||
final FileDescriptor sock = Os.socket(AF_INET6, SOCK_DGRAM, IPPROTO_ICMPV6);
|
||||
final StructTimeval writeTimeval = StructTimeval.fromMillis(1200);
|
||||
byte[] timeval = getTimevalBytes(writeTimeval);
|
||||
final StructTimeval readTimeval;
|
||||
|
||||
NetworkUtils.setsockoptBytes(sock, SOL_SOCKET, SO_RCVTIMEO, timeval);
|
||||
readTimeval = Os.getsockoptTimeval(sock, SOL_SOCKET, SO_RCVTIMEO);
|
||||
|
||||
assertEquals(writeTimeval, readTimeval);
|
||||
SocketUtils.closeSocketQuietly(sock);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user