Merge changes I33e945f8,I9b5c9618
* changes: CTS: Verify rekey-based tunnel migration with encapType change Verify Kernel MOBIKE with V6 UDP encapsulation
This commit is contained in:
@@ -364,10 +364,20 @@ public class IpSecManagerTest extends IpSecBaseTest {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assumeExperimentalIpv6UdpEncapSupported() throws Exception {
|
private static boolean isIpv6UdpEncapSupportedByKernel() {
|
||||||
|
return isKernelVersionAtLeast("5.15.31")
|
||||||
|
|| (isKernelVersionAtLeast("5.10.108") && !isKernelVersionAtLeast("5.15.0"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Packet private for use in IpSecManagerTunnelTest
|
||||||
|
static boolean isIpv6UdpEncapSupported() {
|
||||||
|
return SdkLevel.isAtLeastU() && isIpv6UdpEncapSupportedByKernel();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Packet private for use in IpSecManagerTunnelTest
|
||||||
|
static void assumeExperimentalIpv6UdpEncapSupported() throws Exception {
|
||||||
assumeTrue("Not supported before U", SdkLevel.isAtLeastU());
|
assumeTrue("Not supported before U", SdkLevel.isAtLeastU());
|
||||||
assumeTrue("Not supported by kernel", isKernelVersionAtLeast("5.15.31")
|
assumeTrue("Not supported by kernel", isIpv6UdpEncapSupportedByKernel());
|
||||||
|| (isKernelVersionAtLeast("5.10.108") && !isKernelVersionAtLeast("5.15.0")));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ package android.net.cts;
|
|||||||
|
|
||||||
import static android.app.AppOpsManager.OP_MANAGE_IPSEC_TUNNELS;
|
import static android.app.AppOpsManager.OP_MANAGE_IPSEC_TUNNELS;
|
||||||
import static android.net.IpSecManager.UdpEncapsulationSocket;
|
import static android.net.IpSecManager.UdpEncapsulationSocket;
|
||||||
|
import static android.net.cts.IpSecManagerTest.assumeExperimentalIpv6UdpEncapSupported;
|
||||||
|
import static android.net.cts.IpSecManagerTest.isIpv6UdpEncapSupported;
|
||||||
import static android.net.cts.PacketUtils.AES_CBC_BLK_SIZE;
|
import static android.net.cts.PacketUtils.AES_CBC_BLK_SIZE;
|
||||||
import static android.net.cts.PacketUtils.AES_CBC_IV_LEN;
|
import static android.net.cts.PacketUtils.AES_CBC_IV_LEN;
|
||||||
import static android.net.cts.PacketUtils.BytePayload;
|
import static android.net.cts.PacketUtils.BytePayload;
|
||||||
@@ -111,6 +113,7 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
|
|
||||||
private static final int IP4_PREFIX_LEN = 32;
|
private static final int IP4_PREFIX_LEN = 32;
|
||||||
private static final int IP6_PREFIX_LEN = 128;
|
private static final int IP6_PREFIX_LEN = 128;
|
||||||
|
private static final int IP6_UDP_ENCAP_SOCKET_PORT_ANY = 65536;
|
||||||
|
|
||||||
private static final int TIMEOUT_MS = 500;
|
private static final int TIMEOUT_MS = 500;
|
||||||
|
|
||||||
@@ -310,6 +313,18 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
return expectedPacketSize;
|
return expectedPacketSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private UdpEncapsulationSocket openUdpEncapsulationSocket(int ipVersion) throws Exception {
|
||||||
|
if (ipVersion == AF_INET) {
|
||||||
|
return mISM.openUdpEncapsulationSocket();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isIpv6UdpEncapSupported()) {
|
||||||
|
throw new UnsupportedOperationException("IPv6 UDP encapsulation unsupported");
|
||||||
|
}
|
||||||
|
|
||||||
|
return mISM.openUdpEncapsulationSocket(IP6_UDP_ENCAP_SOCKET_PORT_ANY);
|
||||||
|
}
|
||||||
|
|
||||||
private interface IpSecTunnelTestRunnableFactory {
|
private interface IpSecTunnelTestRunnableFactory {
|
||||||
/**
|
/**
|
||||||
* Build a IpSecTunnelTestRunnable.
|
* Build a IpSecTunnelTestRunnable.
|
||||||
@@ -321,7 +336,7 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
* @param remoteInner The remote address of the inner IP packet
|
* @param remoteInner The remote address of the inner IP packet
|
||||||
* @param inTransportTransform The inbound transport mode transform
|
* @param inTransportTransform The inbound transport mode transform
|
||||||
* @param outTransportTransform The outbound transport mode transform
|
* @param outTransportTransform The outbound transport mode transform
|
||||||
* @param encapPort The port of the UDP encapsulation socket
|
* @param encapSocket The UDP encapsulation socket or null
|
||||||
* @param innerSocketPort The inner socket port
|
* @param innerSocketPort The inner socket port
|
||||||
*/
|
*/
|
||||||
IpSecTunnelTestRunnable getIpSecTunnelTestRunnable(
|
IpSecTunnelTestRunnable getIpSecTunnelTestRunnable(
|
||||||
@@ -331,7 +346,7 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
InetAddress remoteInner,
|
InetAddress remoteInner,
|
||||||
IpSecTransform inTransportTransform,
|
IpSecTransform inTransportTransform,
|
||||||
IpSecTransform outTransportTransform,
|
IpSecTransform outTransportTransform,
|
||||||
int encapPort,
|
UdpEncapsulationSocket encapSocket,
|
||||||
int innerSocketPort)
|
int innerSocketPort)
|
||||||
throws Exception;
|
throws Exception;
|
||||||
}
|
}
|
||||||
@@ -344,7 +359,7 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
InetAddress remoteInner,
|
InetAddress remoteInner,
|
||||||
IpSecTransform inTransportTransform,
|
IpSecTransform inTransportTransform,
|
||||||
IpSecTransform outTransportTransform,
|
IpSecTransform outTransportTransform,
|
||||||
int encapPort,
|
UdpEncapsulationSocket encapSocket,
|
||||||
int unusedInnerSocketPort) {
|
int unusedInnerSocketPort) {
|
||||||
return new IpSecTunnelTestRunnable() {
|
return new IpSecTunnelTestRunnable() {
|
||||||
@Override
|
@Override
|
||||||
@@ -378,7 +393,7 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
// inner IP header (flow label, flags, etc)
|
// inner IP header (flow label, flags, etc)
|
||||||
int innerFamily = localInner instanceof Inet4Address ? AF_INET : AF_INET6;
|
int innerFamily = localInner instanceof Inet4Address ? AF_INET : AF_INET6;
|
||||||
int outerFamily = localOuter instanceof Inet4Address ? AF_INET : AF_INET6;
|
int outerFamily = localOuter instanceof Inet4Address ? AF_INET : AF_INET6;
|
||||||
boolean useEncap = encapPort != 0;
|
boolean useEncap = encapSocket != null;
|
||||||
int expectedPacketSize =
|
int expectedPacketSize =
|
||||||
getPacketSize(
|
getPacketSize(
|
||||||
innerFamily, outerFamily, useEncap, transportInTunnelMode);
|
innerFamily, outerFamily, useEncap, transportInTunnelMode);
|
||||||
@@ -401,7 +416,7 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
InetAddress remoteInner,
|
InetAddress remoteInner,
|
||||||
IpSecTransform inTransportTransform,
|
IpSecTransform inTransportTransform,
|
||||||
IpSecTransform outTransportTransform,
|
IpSecTransform outTransportTransform,
|
||||||
int encapPort,
|
UdpEncapsulationSocket encapSocket,
|
||||||
int innerSocketPort)
|
int innerSocketPort)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
return new IpSecTunnelTestRunnable() {
|
return new IpSecTunnelTestRunnable() {
|
||||||
@@ -450,7 +465,7 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
InetAddress remoteInner,
|
InetAddress remoteInner,
|
||||||
IpSecTransform inTransportTransform,
|
IpSecTransform inTransportTransform,
|
||||||
IpSecTransform outTransportTransform,
|
IpSecTransform outTransportTransform,
|
||||||
int encapPort,
|
UdpEncapsulationSocket encapSocket,
|
||||||
int innerSocketPort)
|
int innerSocketPort)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
return new IpSecTunnelTestRunnable() {
|
return new IpSecTunnelTestRunnable() {
|
||||||
@@ -488,7 +503,7 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
remoteOuter,
|
remoteOuter,
|
||||||
localOuter,
|
localOuter,
|
||||||
socket.getPort(),
|
socket.getPort(),
|
||||||
encapPort,
|
encapSocket != null ? encapSocket.getPort() : 0,
|
||||||
seqNum);
|
seqNum);
|
||||||
} else {
|
} else {
|
||||||
pkt =
|
pkt =
|
||||||
@@ -499,7 +514,7 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
remoteOuter,
|
remoteOuter,
|
||||||
localOuter,
|
localOuter,
|
||||||
socket.getPort(),
|
socket.getPort(),
|
||||||
encapPort,
|
encapSocket != null ? encapSocket.getPort() : 0,
|
||||||
seqNum);
|
seqNum);
|
||||||
}
|
}
|
||||||
tunUtils.injectPacket(pkt);
|
tunUtils.injectPacket(pkt);
|
||||||
@@ -517,13 +532,16 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
|
|
||||||
private class MigrateIpSecTunnelTestRunnableFactory implements IpSecTunnelTestRunnableFactory {
|
private class MigrateIpSecTunnelTestRunnableFactory implements IpSecTunnelTestRunnableFactory {
|
||||||
private final IpSecTunnelTestRunnableFactory mTestRunnableFactory;
|
private final IpSecTunnelTestRunnableFactory mTestRunnableFactory;
|
||||||
|
private final boolean mTestEncapTypeChange;
|
||||||
|
|
||||||
MigrateIpSecTunnelTestRunnableFactory(boolean isOutputTest) {
|
MigrateIpSecTunnelTestRunnableFactory(boolean isOutputTest, boolean testEncapTypeChange) {
|
||||||
if (isOutputTest) {
|
if (isOutputTest) {
|
||||||
mTestRunnableFactory = new OutputIpSecTunnelTestRunnableFactory();
|
mTestRunnableFactory = new OutputIpSecTunnelTestRunnableFactory();
|
||||||
} else {
|
} else {
|
||||||
mTestRunnableFactory = new InputPacketGeneratorIpSecTunnelTestRunnableFactory();
|
mTestRunnableFactory = new InputPacketGeneratorIpSecTunnelTestRunnableFactory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mTestEncapTypeChange = testEncapTypeChange;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -534,7 +552,7 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
InetAddress remoteInner,
|
InetAddress remoteInner,
|
||||||
IpSecTransform inTransportTransform,
|
IpSecTransform inTransportTransform,
|
||||||
IpSecTransform outTransportTransform,
|
IpSecTransform outTransportTransform,
|
||||||
int encapPort,
|
UdpEncapsulationSocket encapSocket,
|
||||||
int unusedInnerSocketPort) {
|
int unusedInnerSocketPort) {
|
||||||
return new IpSecTunnelTestRunnable() {
|
return new IpSecTunnelTestRunnable() {
|
||||||
@Override
|
@Override
|
||||||
@@ -556,7 +574,7 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
remoteInner,
|
remoteInner,
|
||||||
inTransportTransform,
|
inTransportTransform,
|
||||||
outTransportTransform,
|
outTransportTransform,
|
||||||
encapPort,
|
encapSocket,
|
||||||
unusedInnerSocketPort)
|
unusedInnerSocketPort)
|
||||||
.run(
|
.run(
|
||||||
ipsecNetwork,
|
ipsecNetwork,
|
||||||
@@ -569,6 +587,10 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
seqNum);
|
seqNum);
|
||||||
tunnelIface.setUnderlyingNetwork(sTunWrapperNew.network);
|
tunnelIface.setUnderlyingNetwork(sTunWrapperNew.network);
|
||||||
|
|
||||||
|
final boolean useEncapBeforeMigrate = encapSocket != null;
|
||||||
|
final boolean useEncapAfterMigrate =
|
||||||
|
mTestEncapTypeChange ? !useEncapBeforeMigrate : useEncapBeforeMigrate;
|
||||||
|
|
||||||
// Verify migrating to IPv4 and IPv6 addresses. It ensures that not only
|
// Verify migrating to IPv4 and IPv6 addresses. It ensures that not only
|
||||||
// can IPsec tunnel migrate across interfaces, IPsec tunnel can also migrate to
|
// can IPsec tunnel migrate across interfaces, IPsec tunnel can also migrate to
|
||||||
// a different address on the same interface.
|
// a different address on the same interface.
|
||||||
@@ -577,22 +599,25 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
remoteInner,
|
remoteInner,
|
||||||
LOCAL_OUTER_4_NEW,
|
LOCAL_OUTER_4_NEW,
|
||||||
REMOTE_OUTER_4_NEW,
|
REMOTE_OUTER_4_NEW,
|
||||||
encapPort != 0,
|
useEncapAfterMigrate,
|
||||||
transportInTunnelMode,
|
|
||||||
sTunWrapperNew.utils,
|
|
||||||
tunnelIface,
|
|
||||||
ipsecNetwork);
|
|
||||||
checkMigratedTunnel(
|
|
||||||
localInner,
|
|
||||||
remoteInner,
|
|
||||||
LOCAL_OUTER_6_NEW,
|
|
||||||
REMOTE_OUTER_6_NEW,
|
|
||||||
false, // IPv6 does not support UDP encapsulation
|
|
||||||
transportInTunnelMode,
|
transportInTunnelMode,
|
||||||
sTunWrapperNew.utils,
|
sTunWrapperNew.utils,
|
||||||
tunnelIface,
|
tunnelIface,
|
||||||
ipsecNetwork);
|
ipsecNetwork);
|
||||||
|
|
||||||
|
if (!useEncapAfterMigrate || isIpv6UdpEncapSupported()) {
|
||||||
|
checkMigratedTunnel(
|
||||||
|
localInner,
|
||||||
|
remoteInner,
|
||||||
|
LOCAL_OUTER_6_NEW,
|
||||||
|
REMOTE_OUTER_6_NEW,
|
||||||
|
useEncapAfterMigrate,
|
||||||
|
transportInTunnelMode,
|
||||||
|
sTunWrapperNew.utils,
|
||||||
|
tunnelIface,
|
||||||
|
ipsecNetwork);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -631,7 +656,8 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
buildIpSecTransform(sContext, inTransportSpi, null, remoteInner);
|
buildIpSecTransform(sContext, inTransportSpi, null, remoteInner);
|
||||||
IpSecTransform outTransportTransform =
|
IpSecTransform outTransportTransform =
|
||||||
buildIpSecTransform(sContext, outTransportSpi, null, localInner);
|
buildIpSecTransform(sContext, outTransportSpi, null, localInner);
|
||||||
UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket()) {
|
UdpEncapsulationSocket encapSocket =
|
||||||
|
useEncap ? openUdpEncapsulationSocket(outerFamily) : null) {
|
||||||
|
|
||||||
// Configure tunnel mode Transform parameters
|
// Configure tunnel mode Transform parameters
|
||||||
IpSecTransform.Builder transformBuilder = new IpSecTransform.Builder(sContext);
|
IpSecTransform.Builder transformBuilder = new IpSecTransform.Builder(sContext);
|
||||||
@@ -641,7 +667,7 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
new IpSecAlgorithm(
|
new IpSecAlgorithm(
|
||||||
IpSecAlgorithm.AUTH_HMAC_SHA256, AUTH_KEY, AUTH_KEY.length * 4));
|
IpSecAlgorithm.AUTH_HMAC_SHA256, AUTH_KEY, AUTH_KEY.length * 4));
|
||||||
|
|
||||||
if (useEncap) {
|
if (encapSocket != null) {
|
||||||
transformBuilder.setIpv4Encapsulation(encapSocket, encapSocket.getPort());
|
transformBuilder.setIpv4Encapsulation(encapSocket, encapSocket.getPort());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -667,7 +693,7 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
remoteInner,
|
remoteInner,
|
||||||
inTransportTransform,
|
inTransportTransform,
|
||||||
outTransportTransform,
|
outTransportTransform,
|
||||||
useEncap ? encapSocket.getPort() : 0,
|
encapSocket,
|
||||||
0)
|
0)
|
||||||
.run(
|
.run(
|
||||||
ipsecNetwork,
|
ipsecNetwork,
|
||||||
@@ -703,7 +729,7 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
InetAddress remoteInner,
|
InetAddress remoteInner,
|
||||||
IpSecTransform inTransportTransform,
|
IpSecTransform inTransportTransform,
|
||||||
IpSecTransform outTransportTransform,
|
IpSecTransform outTransportTransform,
|
||||||
int encapPort,
|
UdpEncapsulationSocket encapSocket,
|
||||||
int unusedInnerSocketPort) {
|
int unusedInnerSocketPort) {
|
||||||
return new IpSecTunnelTestRunnable() {
|
return new IpSecTunnelTestRunnable() {
|
||||||
@Override
|
@Override
|
||||||
@@ -725,7 +751,7 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
remoteInner,
|
remoteInner,
|
||||||
inTransportTransform,
|
inTransportTransform,
|
||||||
outTransportTransform,
|
outTransportTransform,
|
||||||
encapPort,
|
encapSocket,
|
||||||
unusedInnerSocketPort);
|
unusedInnerSocketPort);
|
||||||
testRunnable.run(
|
testRunnable.run(
|
||||||
ipsecNetwork,
|
ipsecNetwork,
|
||||||
@@ -738,19 +764,28 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
seqNum++);
|
seqNum++);
|
||||||
|
|
||||||
tunnelIface.setUnderlyingNetwork(sTunWrapperNew.network);
|
tunnelIface.setUnderlyingNetwork(sTunWrapperNew.network);
|
||||||
checkMigrateTunnelModeTransform(
|
|
||||||
testRunnable,
|
|
||||||
inTunnelTransform,
|
|
||||||
outTunnelTransform,
|
|
||||||
tunnelIface,
|
|
||||||
ipsecNetwork,
|
|
||||||
sTunWrapperNew.utils,
|
|
||||||
LOCAL_OUTER_4_NEW,
|
|
||||||
REMOTE_OUTER_4_NEW,
|
|
||||||
seqNum++);
|
|
||||||
|
|
||||||
// Only test migration to IPv6 in non-UDP Encapsulation case
|
final boolean useEncap = encapSocket != null;
|
||||||
if (encapPort == 0) {
|
if (useEncap) {
|
||||||
|
sTunWrapperNew.network.bindSocket(encapSocket.getFileDescriptor());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Updating UDP encapsulation socket is not supported. Thus this runnable will
|
||||||
|
// only cover 1) migration from non-encap to non-encap and 2) migration from
|
||||||
|
// encap to encap with the same family
|
||||||
|
if (!useEncap || localOuter instanceof Inet4Address) {
|
||||||
|
checkMigrateTunnelModeTransform(
|
||||||
|
testRunnable,
|
||||||
|
inTunnelTransform,
|
||||||
|
outTunnelTransform,
|
||||||
|
tunnelIface,
|
||||||
|
ipsecNetwork,
|
||||||
|
sTunWrapperNew.utils,
|
||||||
|
LOCAL_OUTER_4_NEW,
|
||||||
|
REMOTE_OUTER_4_NEW,
|
||||||
|
seqNum++);
|
||||||
|
}
|
||||||
|
if (!useEncap || localOuter instanceof Inet6Address) {
|
||||||
checkMigrateTunnelModeTransform(
|
checkMigrateTunnelModeTransform(
|
||||||
testRunnable,
|
testRunnable,
|
||||||
inTunnelTransform,
|
inTunnelTransform,
|
||||||
@@ -825,25 +860,33 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void checkMigrateTunnelOutput(
|
private void checkMigrateTunnelOutput(
|
||||||
int innerFamily, int outerFamily, boolean useEncap, boolean transportInTunnelMode)
|
int innerFamily,
|
||||||
|
int outerFamily,
|
||||||
|
boolean useEncap,
|
||||||
|
boolean transportInTunnelMode,
|
||||||
|
boolean isEncapTypeChanged)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
checkTunnel(
|
checkTunnel(
|
||||||
innerFamily,
|
innerFamily,
|
||||||
outerFamily,
|
outerFamily,
|
||||||
useEncap,
|
useEncap,
|
||||||
transportInTunnelMode,
|
transportInTunnelMode,
|
||||||
new MigrateIpSecTunnelTestRunnableFactory(true));
|
new MigrateIpSecTunnelTestRunnableFactory(true, isEncapTypeChanged));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkMigrateTunnelInput(
|
private void checkMigrateTunnelInput(
|
||||||
int innerFamily, int outerFamily, boolean useEncap, boolean transportInTunnelMode)
|
int innerFamily,
|
||||||
|
int outerFamily,
|
||||||
|
boolean useEncap,
|
||||||
|
boolean transportInTunnelMode,
|
||||||
|
boolean isEncapTypeChanged)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
checkTunnel(
|
checkTunnel(
|
||||||
innerFamily,
|
innerFamily,
|
||||||
outerFamily,
|
outerFamily,
|
||||||
useEncap,
|
useEncap,
|
||||||
transportInTunnelMode,
|
transportInTunnelMode,
|
||||||
new MigrateIpSecTunnelTestRunnableFactory(false));
|
new MigrateIpSecTunnelTestRunnableFactory(false, isEncapTypeChanged));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkMigrateTunnelModeTransformOutput(
|
private void checkMigrateTunnelModeTransformOutput(
|
||||||
@@ -897,7 +940,8 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
buildIpSecTransform(sContext, inTransportSpi, null, remoteInner);
|
buildIpSecTransform(sContext, inTransportSpi, null, remoteInner);
|
||||||
IpSecTransform outTransportTransform =
|
IpSecTransform outTransportTransform =
|
||||||
buildIpSecTransform(sContext, outTransportSpi, null, localInner);
|
buildIpSecTransform(sContext, outTransportSpi, null, localInner);
|
||||||
UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket()) {
|
UdpEncapsulationSocket encapSocket =
|
||||||
|
useEncap ? openUdpEncapsulationSocket(outerFamily) : null) {
|
||||||
|
|
||||||
// Run output direction tests
|
// Run output direction tests
|
||||||
IpSecTunnelTestRunnable outputIpSecTunnelTestRunnable =
|
IpSecTunnelTestRunnable outputIpSecTunnelTestRunnable =
|
||||||
@@ -909,7 +953,7 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
remoteInner,
|
remoteInner,
|
||||||
inTransportTransform,
|
inTransportTransform,
|
||||||
outTransportTransform,
|
outTransportTransform,
|
||||||
useEncap ? encapSocket.getPort() : 0,
|
encapSocket,
|
||||||
0);
|
0);
|
||||||
int innerSocketPort =
|
int innerSocketPort =
|
||||||
buildTunnelNetworkAndRunTests(
|
buildTunnelNetworkAndRunTests(
|
||||||
@@ -918,7 +962,7 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
localOuter,
|
localOuter,
|
||||||
remoteOuter,
|
remoteOuter,
|
||||||
spi,
|
spi,
|
||||||
useEncap ? encapSocket : null,
|
encapSocket,
|
||||||
outputIpSecTunnelTestRunnable);
|
outputIpSecTunnelTestRunnable);
|
||||||
|
|
||||||
// Input direction tests, with matching inner socket ports.
|
// Input direction tests, with matching inner socket ports.
|
||||||
@@ -931,7 +975,7 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
localInner,
|
localInner,
|
||||||
inTransportTransform,
|
inTransportTransform,
|
||||||
outTransportTransform,
|
outTransportTransform,
|
||||||
useEncap ? encapSocket.getPort() : 0,
|
encapSocket,
|
||||||
innerSocketPort);
|
innerSocketPort);
|
||||||
buildTunnelNetworkAndRunTests(
|
buildTunnelNetworkAndRunTests(
|
||||||
remoteInner,
|
remoteInner,
|
||||||
@@ -939,7 +983,7 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
localOuter,
|
localOuter,
|
||||||
remoteOuter,
|
remoteOuter,
|
||||||
spi,
|
spi,
|
||||||
useEncap ? encapSocket : null,
|
encapSocket,
|
||||||
inputIpSecTunnelTestRunnable);
|
inputIpSecTunnelTestRunnable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -973,7 +1017,8 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
buildIpSecTransform(sContext, inTransportSpi, null, remoteInner);
|
buildIpSecTransform(sContext, inTransportSpi, null, remoteInner);
|
||||||
IpSecTransform outTransportTransform =
|
IpSecTransform outTransportTransform =
|
||||||
buildIpSecTransform(sContext, outTransportSpi, null, localInner);
|
buildIpSecTransform(sContext, outTransportSpi, null, localInner);
|
||||||
UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket()) {
|
UdpEncapsulationSocket encapSocket =
|
||||||
|
useEncap ? openUdpEncapsulationSocket(outerFamily) : null) {
|
||||||
|
|
||||||
buildTunnelNetworkAndRunTests(
|
buildTunnelNetworkAndRunTests(
|
||||||
localInner,
|
localInner,
|
||||||
@@ -981,7 +1026,7 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
localOuter,
|
localOuter,
|
||||||
remoteOuter,
|
remoteOuter,
|
||||||
spi,
|
spi,
|
||||||
useEncap ? encapSocket : null,
|
encapSocket,
|
||||||
factory.getIpSecTunnelTestRunnable(
|
factory.getIpSecTunnelTestRunnable(
|
||||||
transportInTunnelMode,
|
transportInTunnelMode,
|
||||||
spi,
|
spi,
|
||||||
@@ -989,7 +1034,7 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
remoteInner,
|
remoteInner,
|
||||||
inTransportTransform,
|
inTransportTransform,
|
||||||
outTransportTransform,
|
outTransportTransform,
|
||||||
useEncap ? encapSocket.getPort() : 0,
|
encapSocket,
|
||||||
0));
|
0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1038,6 +1083,7 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
|
|
||||||
if (encapSocket != null) {
|
if (encapSocket != null) {
|
||||||
transformBuilder.setIpv4Encapsulation(encapSocket, encapSocket.getPort());
|
transformBuilder.setIpv4Encapsulation(encapSocket, encapSocket.getPort());
|
||||||
|
sTunWrapper.network.bindSocket(encapSocket.getFileDescriptor());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply transform and check that traffic is properly encrypted
|
// Apply transform and check that traffic is properly encrypted
|
||||||
@@ -1189,11 +1235,39 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void doTestMigrateTunnel(
|
private void doTestMigrateTunnel(
|
||||||
int innerFamily, int outerFamily, boolean useEncap, boolean transportInTunnelMode)
|
int innerFamily,
|
||||||
|
int outerFamily,
|
||||||
|
boolean useEncap,
|
||||||
|
boolean transportInTunnelMode,
|
||||||
|
boolean testEncapTypeChange)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
|
assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
|
||||||
checkMigrateTunnelOutput(innerFamily, outerFamily, useEncap, transportInTunnelMode);
|
checkMigrateTunnelOutput(
|
||||||
checkMigrateTunnelInput(innerFamily, outerFamily, useEncap, transportInTunnelMode);
|
innerFamily, outerFamily, useEncap, transportInTunnelMode, testEncapTypeChange);
|
||||||
|
checkMigrateTunnelInput(
|
||||||
|
innerFamily, outerFamily, useEncap, transportInTunnelMode, testEncapTypeChange);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doTestMigrateTunnel(
|
||||||
|
int innerFamily, int outerFamily, boolean useEncap, boolean transportInTunnelMode)
|
||||||
|
throws Exception {
|
||||||
|
doTestMigrateTunnel(
|
||||||
|
innerFamily,
|
||||||
|
outerFamily,
|
||||||
|
useEncap,
|
||||||
|
transportInTunnelMode,
|
||||||
|
false /* testEncapTypeChange */);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doTestMigrateTunnelWithEncapTypeChange(
|
||||||
|
int innerFamily, int outerFamily, boolean useEncap, boolean transportInTunnelMode)
|
||||||
|
throws Exception {
|
||||||
|
doTestMigrateTunnel(
|
||||||
|
innerFamily,
|
||||||
|
outerFamily,
|
||||||
|
useEncap,
|
||||||
|
transportInTunnelMode,
|
||||||
|
true /* testEncapTypeChange */);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doTestMigrateTunnelModeTransform(
|
private void doTestMigrateTunnelModeTransform(
|
||||||
@@ -1230,6 +1304,12 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
doTestMigrateTunnel(AF_INET, AF_INET, false, true);
|
doTestMigrateTunnel(AF_INET, AF_INET, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@IgnoreUpTo(Build.VERSION_CODES.R)
|
||||||
|
@Test
|
||||||
|
public void testMigrateTransportInTunnelModeV4InV4_EncapTypeChange() throws Exception {
|
||||||
|
doTestMigrateTunnelWithEncapTypeChange(AF_INET, AF_INET, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTransportInTunnelModeV4InV4Reflected() throws Exception {
|
public void testTransportInTunnelModeV4InV4Reflected() throws Exception {
|
||||||
assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
|
assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
|
||||||
@@ -1249,6 +1329,12 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
doTestMigrateTunnel(AF_INET, AF_INET, true, true);
|
doTestMigrateTunnel(AF_INET, AF_INET, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@IgnoreUpTo(Build.VERSION_CODES.R)
|
||||||
|
@Test
|
||||||
|
public void testMigrateTransportInTunnelModeV4InV4UdpEncap_EncapTypeChange() throws Exception {
|
||||||
|
doTestMigrateTunnelWithEncapTypeChange(AF_INET, AF_INET, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTransportInTunnelModeV4InV4UdpEncapReflected() throws Exception {
|
public void testTransportInTunnelModeV4InV4UdpEncapReflected() throws Exception {
|
||||||
assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
|
assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
|
||||||
@@ -1268,6 +1354,12 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
doTestMigrateTunnel(AF_INET, AF_INET6, false, true);
|
doTestMigrateTunnel(AF_INET, AF_INET6, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@IgnoreUpTo(Build.VERSION_CODES.R)
|
||||||
|
@Test
|
||||||
|
public void testMigrateTransportInTunnelModeV4InV6_EncapTypeChange() throws Exception {
|
||||||
|
doTestMigrateTunnelWithEncapTypeChange(AF_INET, AF_INET6, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTransportInTunnelModeV4InV6Reflected() throws Exception {
|
public void testTransportInTunnelModeV4InV6Reflected() throws Exception {
|
||||||
assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
|
assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
|
||||||
@@ -1287,6 +1379,12 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
doTestMigrateTunnel(AF_INET6, AF_INET, false, true);
|
doTestMigrateTunnel(AF_INET6, AF_INET, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@IgnoreUpTo(Build.VERSION_CODES.R)
|
||||||
|
@Test
|
||||||
|
public void testMigrateTransportInTunnelModeV6InV4_EncapTypeChange() throws Exception {
|
||||||
|
doTestMigrateTunnelWithEncapTypeChange(AF_INET6, AF_INET, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTransportInTunnelModeV6InV4Reflected() throws Exception {
|
public void testTransportInTunnelModeV6InV4Reflected() throws Exception {
|
||||||
assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
|
assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
|
||||||
@@ -1306,6 +1404,12 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
doTestMigrateTunnel(AF_INET6, AF_INET, true, true);
|
doTestMigrateTunnel(AF_INET6, AF_INET, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@IgnoreUpTo(Build.VERSION_CODES.R)
|
||||||
|
@Test
|
||||||
|
public void testMigrateTransportInTunnelModeV6InV4UdpEncap_EncapTypeChange() throws Exception {
|
||||||
|
doTestMigrateTunnelWithEncapTypeChange(AF_INET6, AF_INET, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTransportInTunnelModeV6InV4UdpEncapReflected() throws Exception {
|
public void testTransportInTunnelModeV6InV4UdpEncapReflected() throws Exception {
|
||||||
assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
|
assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
|
||||||
@@ -1325,6 +1429,12 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
doTestMigrateTunnel(AF_INET, AF_INET6, false, true);
|
doTestMigrateTunnel(AF_INET, AF_INET6, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@IgnoreUpTo(Build.VERSION_CODES.R)
|
||||||
|
@Test
|
||||||
|
public void testMigrateTransportInTunnelModeV6InV6_EncapTypeChange() throws Exception {
|
||||||
|
doTestMigrateTunnelWithEncapTypeChange(AF_INET, AF_INET6, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTransportInTunnelModeV6InV6Reflected() throws Exception {
|
public void testTransportInTunnelModeV6InV6Reflected() throws Exception {
|
||||||
assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
|
assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
|
||||||
@@ -1345,6 +1455,12 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
doTestMigrateTunnel(AF_INET, AF_INET, false, false);
|
doTestMigrateTunnel(AF_INET, AF_INET, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@IgnoreUpTo(Build.VERSION_CODES.R)
|
||||||
|
@Test
|
||||||
|
public void testMigrateTunnelV4InV4_EncapTypeChange() throws Exception {
|
||||||
|
doTestMigrateTunnelWithEncapTypeChange(AF_INET, AF_INET, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTunnelV4InV4Reflected() throws Exception {
|
public void testTunnelV4InV4Reflected() throws Exception {
|
||||||
assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
|
assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
|
||||||
@@ -1364,6 +1480,12 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
doTestMigrateTunnel(AF_INET, AF_INET, true, false);
|
doTestMigrateTunnel(AF_INET, AF_INET, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@IgnoreUpTo(Build.VERSION_CODES.R)
|
||||||
|
@Test
|
||||||
|
public void testMigrateTunnelV4InV4UdpEncap_EncapTypeChange() throws Exception {
|
||||||
|
doTestMigrateTunnelWithEncapTypeChange(AF_INET, AF_INET, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTunnelV4InV4UdpEncapReflected() throws Exception {
|
public void testTunnelV4InV4UdpEncapReflected() throws Exception {
|
||||||
assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
|
assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
|
||||||
@@ -1383,6 +1505,12 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
doTestMigrateTunnel(AF_INET, AF_INET6, false, false);
|
doTestMigrateTunnel(AF_INET, AF_INET6, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@IgnoreUpTo(Build.VERSION_CODES.R)
|
||||||
|
@Test
|
||||||
|
public void testMigrateTunnelV4InV6_EncapTypeChange() throws Exception {
|
||||||
|
doTestMigrateTunnelWithEncapTypeChange(AF_INET, AF_INET6, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTunnelV4InV6Reflected() throws Exception {
|
public void testTunnelV4InV6Reflected() throws Exception {
|
||||||
assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
|
assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
|
||||||
@@ -1402,6 +1530,12 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
doTestMigrateTunnel(AF_INET6, AF_INET, false, false);
|
doTestMigrateTunnel(AF_INET6, AF_INET, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@IgnoreUpTo(Build.VERSION_CODES.R)
|
||||||
|
@Test
|
||||||
|
public void testMigrateTunnelV6InV4_EncapTypeChange() throws Exception {
|
||||||
|
doTestMigrateTunnelWithEncapTypeChange(AF_INET6, AF_INET, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTunnelV6InV4Reflected() throws Exception {
|
public void testTunnelV6InV4Reflected() throws Exception {
|
||||||
assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
|
assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
|
||||||
@@ -1421,6 +1555,12 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
doTestMigrateTunnel(AF_INET6, AF_INET, true, false);
|
doTestMigrateTunnel(AF_INET6, AF_INET, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@IgnoreUpTo(Build.VERSION_CODES.R)
|
||||||
|
@Test
|
||||||
|
public void testMigrateTunnelV6InV4UdpEncap_EncapTypeChange() throws Exception {
|
||||||
|
doTestMigrateTunnelWithEncapTypeChange(AF_INET6, AF_INET, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTunnelV6InV4UdpEncapReflected() throws Exception {
|
public void testTunnelV6InV4UdpEncapReflected() throws Exception {
|
||||||
assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
|
assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
|
||||||
@@ -1440,6 +1580,12 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
doTestMigrateTunnel(AF_INET6, AF_INET6, false, false);
|
doTestMigrateTunnel(AF_INET6, AF_INET6, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@IgnoreUpTo(Build.VERSION_CODES.R)
|
||||||
|
@Test
|
||||||
|
public void testMigrateTunnelV6InV6_EncapTypeChange() throws Exception {
|
||||||
|
doTestMigrateTunnelWithEncapTypeChange(AF_INET6, AF_INET6, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTunnelV6InV6Reflected() throws Exception {
|
public void testTunnelV6InV6Reflected() throws Exception {
|
||||||
assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
|
assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
|
||||||
@@ -1482,6 +1628,20 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
doTestMigrateTunnelModeTransform(AF_INET6, AF_INET, true, true);
|
doTestMigrateTunnelModeTransform(AF_INET6, AF_INET, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@IgnoreUpTo(Build.VERSION_CODES.TIRAMISU)
|
||||||
|
@Test
|
||||||
|
public void testMigrateTransformTransportInTunnelModeV4InV6UdpEncap() throws Exception {
|
||||||
|
assumeExperimentalIpv6UdpEncapSupported();
|
||||||
|
doTestMigrateTunnelModeTransform(AF_INET, AF_INET6, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreUpTo(Build.VERSION_CODES.TIRAMISU)
|
||||||
|
@Test
|
||||||
|
public void testMigrateTransformTransportInTunnelModeV6InV6UdpEncap() throws Exception {
|
||||||
|
assumeExperimentalIpv6UdpEncapSupported();
|
||||||
|
doTestMigrateTunnelModeTransform(AF_INET6, AF_INET6, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
@IgnoreUpTo(Build.VERSION_CODES.TIRAMISU)
|
@IgnoreUpTo(Build.VERSION_CODES.TIRAMISU)
|
||||||
@Test
|
@Test
|
||||||
public void testMigrateTransformTunnelV4InV4() throws Exception {
|
public void testMigrateTransformTunnelV4InV4() throws Exception {
|
||||||
@@ -1517,4 +1677,18 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest {
|
|||||||
public void testMigrateTransformTunnelV6InV4UdpEncap() throws Exception {
|
public void testMigrateTransformTunnelV6InV4UdpEncap() throws Exception {
|
||||||
doTestMigrateTunnelModeTransform(AF_INET6, AF_INET, true, false);
|
doTestMigrateTunnelModeTransform(AF_INET6, AF_INET, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@IgnoreUpTo(Build.VERSION_CODES.TIRAMISU)
|
||||||
|
@Test
|
||||||
|
public void testMigrateTransformTunnelV4InV6UdpEncap() throws Exception {
|
||||||
|
assumeExperimentalIpv6UdpEncapSupported();
|
||||||
|
doTestMigrateTunnelModeTransform(AF_INET, AF_INET6, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreUpTo(Build.VERSION_CODES.TIRAMISU)
|
||||||
|
@Test
|
||||||
|
public void testMigrateTransformTunnelV6InV6UdpEncap() throws Exception {
|
||||||
|
assumeExperimentalIpv6UdpEncapSupported();
|
||||||
|
doTestMigrateTunnelModeTransform(AF_INET6, AF_INET6, true, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user