Merge "Add API for VCN configuration of UDP port 4500 NAT Timeouts"

This commit is contained in:
Benedict Wong
2023-02-16 08:25:34 +00:00
committed by Gerrit Code Review
8 changed files with 163 additions and 16 deletions

View File

@@ -27345,6 +27345,7 @@ package android.net.vcn {
method @NonNull public int[] getExposedCapabilities(); method @NonNull public int[] getExposedCapabilities();
method @NonNull public String getGatewayConnectionName(); method @NonNull public String getGatewayConnectionName();
method @IntRange(from=0x500) public int getMaxMtu(); method @IntRange(from=0x500) public int getMaxMtu();
method public int getMinUdpPort4500NatTimeoutSeconds();
method @NonNull public long[] getRetryIntervalsMillis(); method @NonNull public long[] getRetryIntervalsMillis();
method @NonNull public java.util.List<android.net.vcn.VcnUnderlyingNetworkTemplate> getVcnUnderlyingNetworkPriorities(); method @NonNull public java.util.List<android.net.vcn.VcnUnderlyingNetworkTemplate> getVcnUnderlyingNetworkPriorities();
method public boolean hasGatewayOption(int); method public boolean hasGatewayOption(int);
@@ -27359,6 +27360,7 @@ package android.net.vcn {
method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder removeExposedCapability(int); method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder removeExposedCapability(int);
method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder removeGatewayOption(int); method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder removeGatewayOption(int);
method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setMaxMtu(@IntRange(from=0x500) int); method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setMaxMtu(@IntRange(from=0x500) int);
method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setMinUdpPort4500NatTimeoutSeconds(@IntRange(from=0x78) int);
method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setRetryIntervalsMillis(@NonNull long[]); method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setRetryIntervalsMillis(@NonNull long[]);
method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setVcnUnderlyingNetworkPriorities(@NonNull java.util.List<android.net.vcn.VcnUnderlyingNetworkTemplate>); method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setVcnUnderlyingNetworkPriorities(@NonNull java.util.List<android.net.vcn.VcnUnderlyingNetworkTemplate>);
} }

View File

@@ -81,6 +81,12 @@ import java.util.concurrent.TimeUnit;
* </ul> * </ul>
*/ */
public final class VcnGatewayConnectionConfig { public final class VcnGatewayConnectionConfig {
/** @hide */
public static final int MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET = -1;
/** @hide */
public static final int MIN_UDP_PORT_4500_NAT_TIMEOUT_SECONDS = 120;
// TODO: Use MIN_MTU_V6 once it is public, @hide // TODO: Use MIN_MTU_V6 once it is public, @hide
@VisibleForTesting(visibility = Visibility.PRIVATE) @VisibleForTesting(visibility = Visibility.PRIVATE)
static final int MIN_MTU_V6 = 1280; static final int MIN_MTU_V6 = 1280;
@@ -225,6 +231,10 @@ public final class VcnGatewayConnectionConfig {
private static final String RETRY_INTERVAL_MS_KEY = "mRetryIntervalsMs"; private static final String RETRY_INTERVAL_MS_KEY = "mRetryIntervalsMs";
@NonNull private final long[] mRetryIntervalsMs; @NonNull private final long[] mRetryIntervalsMs;
private static final String MIN_UDP_PORT_4500_NAT_TIMEOUT_SECONDS_KEY =
"mMinUdpPort4500NatTimeoutSeconds";
private final int mMinUdpPort4500NatTimeoutSeconds;
private static final String GATEWAY_OPTIONS_KEY = "mGatewayOptions"; private static final String GATEWAY_OPTIONS_KEY = "mGatewayOptions";
@NonNull private final Set<Integer> mGatewayOptions; @NonNull private final Set<Integer> mGatewayOptions;
@@ -236,12 +246,14 @@ public final class VcnGatewayConnectionConfig {
@NonNull List<VcnUnderlyingNetworkTemplate> underlyingNetworkTemplates, @NonNull List<VcnUnderlyingNetworkTemplate> underlyingNetworkTemplates,
@NonNull long[] retryIntervalsMs, @NonNull long[] retryIntervalsMs,
@IntRange(from = MIN_MTU_V6) int maxMtu, @IntRange(from = MIN_MTU_V6) int maxMtu,
@NonNull int minUdpPort4500NatTimeoutSeconds,
@NonNull Set<Integer> gatewayOptions) { @NonNull Set<Integer> gatewayOptions) {
mGatewayConnectionName = gatewayConnectionName; mGatewayConnectionName = gatewayConnectionName;
mTunnelConnectionParams = tunnelConnectionParams; mTunnelConnectionParams = tunnelConnectionParams;
mExposedCapabilities = new TreeSet(exposedCapabilities); mExposedCapabilities = new TreeSet(exposedCapabilities);
mRetryIntervalsMs = retryIntervalsMs; mRetryIntervalsMs = retryIntervalsMs;
mMaxMtu = maxMtu; mMaxMtu = maxMtu;
mMinUdpPort4500NatTimeoutSeconds = minUdpPort4500NatTimeoutSeconds;
mGatewayOptions = Collections.unmodifiableSet(new ArraySet(gatewayOptions)); mGatewayOptions = Collections.unmodifiableSet(new ArraySet(gatewayOptions));
mUnderlyingNetworkTemplates = new ArrayList<>(underlyingNetworkTemplates); mUnderlyingNetworkTemplates = new ArrayList<>(underlyingNetworkTemplates);
@@ -301,6 +313,10 @@ public final class VcnGatewayConnectionConfig {
mRetryIntervalsMs = in.getLongArray(RETRY_INTERVAL_MS_KEY); mRetryIntervalsMs = in.getLongArray(RETRY_INTERVAL_MS_KEY);
mMaxMtu = in.getInt(MAX_MTU_KEY); mMaxMtu = in.getInt(MAX_MTU_KEY);
mMinUdpPort4500NatTimeoutSeconds =
in.getInt(
MIN_UDP_PORT_4500_NAT_TIMEOUT_SECONDS_KEY,
MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET);
validate(); validate();
} }
@@ -323,6 +339,12 @@ public final class VcnGatewayConnectionConfig {
Preconditions.checkArgument( Preconditions.checkArgument(
mMaxMtu >= MIN_MTU_V6, "maxMtu must be at least IPv6 min MTU (1280)"); mMaxMtu >= MIN_MTU_V6, "maxMtu must be at least IPv6 min MTU (1280)");
Preconditions.checkArgument(
mMinUdpPort4500NatTimeoutSeconds == MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET
|| mMinUdpPort4500NatTimeoutSeconds
>= MIN_UDP_PORT_4500_NAT_TIMEOUT_SECONDS,
"minUdpPort4500NatTimeoutSeconds must be at least 120s");
for (int option : mGatewayOptions) { for (int option : mGatewayOptions) {
validateGatewayOption(option); validateGatewayOption(option);
} }
@@ -451,6 +473,15 @@ public final class VcnGatewayConnectionConfig {
return mMaxMtu; return mMaxMtu;
} }
/**
* Retrieves the maximum supported IKEv2/IPsec NATT keepalive timeout.
*
* @see Builder#setMinUdpPort4500NatTimeoutSeconds(int)
*/
public int getMinUdpPort4500NatTimeoutSeconds() {
return mMinUdpPort4500NatTimeoutSeconds;
}
/** /**
* Checks if the given VCN gateway option is enabled. * Checks if the given VCN gateway option is enabled.
* *
@@ -496,6 +527,7 @@ public final class VcnGatewayConnectionConfig {
result.putPersistableBundle(GATEWAY_OPTIONS_KEY, gatewayOptionsBundle); result.putPersistableBundle(GATEWAY_OPTIONS_KEY, gatewayOptionsBundle);
result.putLongArray(RETRY_INTERVAL_MS_KEY, mRetryIntervalsMs); result.putLongArray(RETRY_INTERVAL_MS_KEY, mRetryIntervalsMs);
result.putInt(MAX_MTU_KEY, mMaxMtu); result.putInt(MAX_MTU_KEY, mMaxMtu);
result.putInt(MIN_UDP_PORT_4500_NAT_TIMEOUT_SECONDS_KEY, mMinUdpPort4500NatTimeoutSeconds);
return result; return result;
} }
@@ -509,6 +541,7 @@ public final class VcnGatewayConnectionConfig {
mUnderlyingNetworkTemplates, mUnderlyingNetworkTemplates,
Arrays.hashCode(mRetryIntervalsMs), Arrays.hashCode(mRetryIntervalsMs),
mMaxMtu, mMaxMtu,
mMinUdpPort4500NatTimeoutSeconds,
mGatewayOptions); mGatewayOptions);
} }
@@ -525,6 +558,7 @@ public final class VcnGatewayConnectionConfig {
&& mUnderlyingNetworkTemplates.equals(rhs.mUnderlyingNetworkTemplates) && mUnderlyingNetworkTemplates.equals(rhs.mUnderlyingNetworkTemplates)
&& Arrays.equals(mRetryIntervalsMs, rhs.mRetryIntervalsMs) && Arrays.equals(mRetryIntervalsMs, rhs.mRetryIntervalsMs)
&& mMaxMtu == rhs.mMaxMtu && mMaxMtu == rhs.mMaxMtu
&& mMinUdpPort4500NatTimeoutSeconds == rhs.mMinUdpPort4500NatTimeoutSeconds
&& mGatewayOptions.equals(rhs.mGatewayOptions); && mGatewayOptions.equals(rhs.mGatewayOptions);
} }
@@ -542,6 +576,7 @@ public final class VcnGatewayConnectionConfig {
@NonNull private long[] mRetryIntervalsMs = DEFAULT_RETRY_INTERVALS_MS; @NonNull private long[] mRetryIntervalsMs = DEFAULT_RETRY_INTERVALS_MS;
private int mMaxMtu = DEFAULT_MAX_MTU; private int mMaxMtu = DEFAULT_MAX_MTU;
private int mMinUdpPort4500NatTimeoutSeconds = MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET;
@NonNull private final Set<Integer> mGatewayOptions = new ArraySet<>(); @NonNull private final Set<Integer> mGatewayOptions = new ArraySet<>();
@@ -702,6 +737,29 @@ public final class VcnGatewayConnectionConfig {
return this; return this;
} }
/**
* Sets the maximum supported IKEv2/IPsec NATT keepalive timeout.
*
* <p>This is used as a power-optimization hint for other IKEv2/IPsec use cases (e.g. VPNs,
* or IWLAN) to reduce the necessary keepalive frequency, thus conserving power and data.
*
* @param minUdpPort4500NatTimeoutSeconds the maximum keepalive timeout supported by the VCN
* Gateway Connection, generally the minimum duration a NAT mapping is cached on the VCN
* Gateway.
* @return this {@link Builder} instance, for chaining
*/
@NonNull
public Builder setMinUdpPort4500NatTimeoutSeconds(
@IntRange(from = MIN_UDP_PORT_4500_NAT_TIMEOUT_SECONDS)
int minUdpPort4500NatTimeoutSeconds) {
Preconditions.checkArgument(
minUdpPort4500NatTimeoutSeconds >= MIN_UDP_PORT_4500_NAT_TIMEOUT_SECONDS,
"Timeout must be at least 120s");
mMinUdpPort4500NatTimeoutSeconds = minUdpPort4500NatTimeoutSeconds;
return this;
}
/** /**
* Enables the specified VCN gateway option. * Enables the specified VCN gateway option.
* *
@@ -744,6 +802,7 @@ public final class VcnGatewayConnectionConfig {
mUnderlyingNetworkTemplates, mUnderlyingNetworkTemplates,
mRetryIntervalsMs, mRetryIntervalsMs,
mMaxMtu, mMaxMtu,
mMinUdpPort4500NatTimeoutSeconds,
mGatewayOptions); mGatewayOptions);
} }
} }

View File

@@ -17,6 +17,7 @@
package android.net.vcn; package android.net.vcn;
import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS; import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS;
import static android.net.vcn.VcnGatewayConnectionConfig.MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET;
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
import android.annotation.NonNull; import android.annotation.NonNull;
@@ -49,18 +50,29 @@ import java.util.Objects;
public class VcnTransportInfo implements TransportInfo, Parcelable { public class VcnTransportInfo implements TransportInfo, Parcelable {
@Nullable private final WifiInfo mWifiInfo; @Nullable private final WifiInfo mWifiInfo;
private final int mSubId; private final int mSubId;
private final int mMinUdpPort4500NatTimeoutSeconds;
public VcnTransportInfo(@NonNull WifiInfo wifiInfo) { public VcnTransportInfo(@NonNull WifiInfo wifiInfo) {
this(wifiInfo, INVALID_SUBSCRIPTION_ID); this(wifiInfo, INVALID_SUBSCRIPTION_ID, MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET);
}
public VcnTransportInfo(@NonNull WifiInfo wifiInfo, int minUdpPort4500NatTimeoutSeconds) {
this(wifiInfo, INVALID_SUBSCRIPTION_ID, minUdpPort4500NatTimeoutSeconds);
} }
public VcnTransportInfo(int subId) { public VcnTransportInfo(int subId) {
this(null /* wifiInfo */, subId); this(null /* wifiInfo */, subId, MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET);
} }
private VcnTransportInfo(@Nullable WifiInfo wifiInfo, int subId) { public VcnTransportInfo(int subId, int minUdpPort4500NatTimeoutSeconds) {
this(null /* wifiInfo */, subId, minUdpPort4500NatTimeoutSeconds);
}
private VcnTransportInfo(
@Nullable WifiInfo wifiInfo, int subId, int minUdpPort4500NatTimeoutSeconds) {
mWifiInfo = wifiInfo; mWifiInfo = wifiInfo;
mSubId = subId; mSubId = subId;
mMinUdpPort4500NatTimeoutSeconds = minUdpPort4500NatTimeoutSeconds;
} }
/** /**
@@ -88,16 +100,28 @@ public class VcnTransportInfo implements TransportInfo, Parcelable {
return mSubId; return mSubId;
} }
/**
* Get the VCN provided UDP port 4500 NAT timeout
*
* @return the UDP 4500 NAT timeout, or
* VcnGatewayConnectionConfig.MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET if not set.
*/
public int getMinUdpPort4500NatTimeoutSeconds() {
return mMinUdpPort4500NatTimeoutSeconds;
}
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(mWifiInfo, mSubId); return Objects.hash(mWifiInfo, mSubId, mMinUdpPort4500NatTimeoutSeconds);
} }
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (!(o instanceof VcnTransportInfo)) return false; if (!(o instanceof VcnTransportInfo)) return false;
final VcnTransportInfo that = (VcnTransportInfo) o; final VcnTransportInfo that = (VcnTransportInfo) o;
return Objects.equals(mWifiInfo, that.mWifiInfo) && mSubId == that.mSubId; return Objects.equals(mWifiInfo, that.mWifiInfo)
&& mSubId == that.mSubId
&& mMinUdpPort4500NatTimeoutSeconds == that.mMinUdpPort4500NatTimeoutSeconds;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
@@ -110,11 +134,14 @@ public class VcnTransportInfo implements TransportInfo, Parcelable {
@NonNull @NonNull
public TransportInfo makeCopy(long redactions) { public TransportInfo makeCopy(long redactions) {
if ((redactions & NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS) != 0) { if ((redactions & NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS) != 0) {
return new VcnTransportInfo(null, INVALID_SUBSCRIPTION_ID); return new VcnTransportInfo(
null, INVALID_SUBSCRIPTION_ID, MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET);
} }
return new VcnTransportInfo( return new VcnTransportInfo(
(mWifiInfo == null) ? null : mWifiInfo.makeCopy(redactions), mSubId); (mWifiInfo == null) ? null : mWifiInfo.makeCopy(redactions),
mSubId,
mMinUdpPort4500NatTimeoutSeconds);
} }
@Override @Override
@@ -134,6 +161,7 @@ public class VcnTransportInfo implements TransportInfo, Parcelable {
public void writeToParcel(@NonNull Parcel dest, int flags) { public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeInt(mSubId); dest.writeInt(mSubId);
dest.writeParcelable(mWifiInfo, flags); dest.writeParcelable(mWifiInfo, flags);
dest.writeInt(mMinUdpPort4500NatTimeoutSeconds);
} }
@Override @Override
@@ -146,16 +174,21 @@ public class VcnTransportInfo implements TransportInfo, Parcelable {
new Creator<VcnTransportInfo>() { new Creator<VcnTransportInfo>() {
public VcnTransportInfo createFromParcel(Parcel in) { public VcnTransportInfo createFromParcel(Parcel in) {
final int subId = in.readInt(); final int subId = in.readInt();
final WifiInfo wifiInfo = in.readParcelable(null, android.net.wifi.WifiInfo.class); final WifiInfo wifiInfo =
in.readParcelable(null, android.net.wifi.WifiInfo.class);
final int minUdpPort4500NatTimeoutSeconds = in.readInt();
// If all fields are their null values, return null TransportInfo to avoid // If all fields are their null values, return null TransportInfo to avoid
// leaking information about this being a VCN Network (instead of macro // leaking information about this being a VCN Network (instead of macro
// cellular, etc) // cellular, etc)
if (wifiInfo == null && subId == INVALID_SUBSCRIPTION_ID) { if (wifiInfo == null
&& subId == INVALID_SUBSCRIPTION_ID
&& minUdpPort4500NatTimeoutSeconds
== MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET) {
return null; return null;
} }
return new VcnTransportInfo(wifiInfo, subId); return new VcnTransportInfo(wifiInfo, subId, minUdpPort4500NatTimeoutSeconds);
} }
public VcnTransportInfo[] newArray(int size) { public VcnTransportInfo[] newArray(int size) {

View File

@@ -2255,12 +2255,18 @@ public class VcnGatewayConnection extends StateMachine {
if (underlyingCaps.hasTransport(TRANSPORT_WIFI) if (underlyingCaps.hasTransport(TRANSPORT_WIFI)
&& underlyingCaps.getTransportInfo() instanceof WifiInfo) { && underlyingCaps.getTransportInfo() instanceof WifiInfo) {
final WifiInfo wifiInfo = (WifiInfo) underlyingCaps.getTransportInfo(); final WifiInfo wifiInfo = (WifiInfo) underlyingCaps.getTransportInfo();
builder.setTransportInfo(new VcnTransportInfo(wifiInfo)); builder.setTransportInfo(
new VcnTransportInfo(
wifiInfo,
gatewayConnectionConfig.getMinUdpPort4500NatTimeoutSeconds()));
} else if (underlyingCaps.hasTransport(TRANSPORT_CELLULAR) } else if (underlyingCaps.hasTransport(TRANSPORT_CELLULAR)
&& underlyingCaps.getNetworkSpecifier() instanceof TelephonyNetworkSpecifier) { && underlyingCaps.getNetworkSpecifier() instanceof TelephonyNetworkSpecifier) {
final TelephonyNetworkSpecifier telNetSpecifier = final TelephonyNetworkSpecifier telNetSpecifier =
(TelephonyNetworkSpecifier) underlyingCaps.getNetworkSpecifier(); (TelephonyNetworkSpecifier) underlyingCaps.getNetworkSpecifier();
builder.setTransportInfo(new VcnTransportInfo(telNetSpecifier.getSubscriptionId())); builder.setTransportInfo(
new VcnTransportInfo(
telNetSpecifier.getSubscriptionId(),
gatewayConnectionConfig.getMinUdpPort4500NatTimeoutSeconds()));
} else { } else {
Slog.wtf( Slog.wtf(
TAG, TAG,

View File

@@ -82,6 +82,7 @@ public class VcnGatewayConnectionConfigTest {
TimeUnit.MINUTES.toMillis(30) TimeUnit.MINUTES.toMillis(30)
}; };
public static final int MAX_MTU = 1360; public static final int MAX_MTU = 1360;
public static final int MIN_UDP_PORT_4500_NAT_TIMEOUT = 120;
private static final Set<Integer> GATEWAY_OPTIONS = private static final Set<Integer> GATEWAY_OPTIONS =
Collections.singleton(VCN_GATEWAY_OPTION_ENABLE_DATA_STALL_RECOVERY_WITH_MOBILITY); Collections.singleton(VCN_GATEWAY_OPTION_ENABLE_DATA_STALL_RECOVERY_WITH_MOBILITY);
@@ -104,7 +105,9 @@ public class VcnGatewayConnectionConfigTest {
public static VcnGatewayConnectionConfig buildTestConfig( public static VcnGatewayConnectionConfig buildTestConfig(
List<VcnUnderlyingNetworkTemplate> nwTemplates) { List<VcnUnderlyingNetworkTemplate> nwTemplates) {
final VcnGatewayConnectionConfig.Builder builder = final VcnGatewayConnectionConfig.Builder builder =
newBuilder().setVcnUnderlyingNetworkPriorities(nwTemplates); newBuilder()
.setVcnUnderlyingNetworkPriorities(nwTemplates)
.setMinUdpPort4500NatTimeoutSeconds(MIN_UDP_PORT_4500_NAT_TIMEOUT);
return buildTestConfigWithExposedCaps(builder, EXPOSED_CAPS); return buildTestConfigWithExposedCaps(builder, EXPOSED_CAPS);
} }

View File

@@ -19,6 +19,7 @@ package android.net.vcn;
import static android.net.NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION; import static android.net.NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION;
import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS; import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS;
import static android.net.NetworkCapabilities.REDACT_NONE; import static android.net.NetworkCapabilities.REDACT_NONE;
import static android.net.vcn.VcnGatewayConnectionConfig.MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET;
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
@@ -37,11 +38,14 @@ import java.util.Arrays;
public class VcnTransportInfoTest { public class VcnTransportInfoTest {
private static final int SUB_ID = 1; private static final int SUB_ID = 1;
private static final int NETWORK_ID = 5; private static final int NETWORK_ID = 5;
private static final int MIN_UDP_PORT_4500_NAT_TIMEOUT = 120;
private static final WifiInfo WIFI_INFO = private static final WifiInfo WIFI_INFO =
new WifiInfo.Builder().setNetworkId(NETWORK_ID).build(); new WifiInfo.Builder().setNetworkId(NETWORK_ID).build();
private static final VcnTransportInfo CELL_UNDERLYING_INFO = new VcnTransportInfo(SUB_ID); private static final VcnTransportInfo CELL_UNDERLYING_INFO =
private static final VcnTransportInfo WIFI_UNDERLYING_INFO = new VcnTransportInfo(WIFI_INFO); new VcnTransportInfo(SUB_ID, MIN_UDP_PORT_4500_NAT_TIMEOUT);
private static final VcnTransportInfo WIFI_UNDERLYING_INFO =
new VcnTransportInfo(WIFI_INFO, MIN_UDP_PORT_4500_NAT_TIMEOUT);
@Test @Test
public void testGetWifiInfo() { public void testGetWifiInfo() {
@@ -57,6 +61,16 @@ public class VcnTransportInfoTest {
assertEquals(INVALID_SUBSCRIPTION_ID, WIFI_UNDERLYING_INFO.getSubId()); assertEquals(INVALID_SUBSCRIPTION_ID, WIFI_UNDERLYING_INFO.getSubId());
} }
@Test
public void testGetMinUdpPort4500NatTimeoutSeconds() {
assertEquals(
MIN_UDP_PORT_4500_NAT_TIMEOUT,
CELL_UNDERLYING_INFO.getMinUdpPort4500NatTimeoutSeconds());
assertEquals(
MIN_UDP_PORT_4500_NAT_TIMEOUT,
WIFI_UNDERLYING_INFO.getMinUdpPort4500NatTimeoutSeconds());
}
@Test @Test
public void testMakeCopyRedactForNetworkSettings() { public void testMakeCopyRedactForNetworkSettings() {
for (VcnTransportInfo info : Arrays.asList(CELL_UNDERLYING_INFO, WIFI_UNDERLYING_INFO)) { for (VcnTransportInfo info : Arrays.asList(CELL_UNDERLYING_INFO, WIFI_UNDERLYING_INFO)) {
@@ -67,6 +81,10 @@ public class VcnTransportInfoTest {
assertNull( assertNull(
((VcnTransportInfo) info.makeCopy(REDACT_FOR_NETWORK_SETTINGS)) ((VcnTransportInfo) info.makeCopy(REDACT_FOR_NETWORK_SETTINGS))
.getWifiInfo()); .getWifiInfo());
assertEquals(
MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET,
((VcnTransportInfo) info.makeCopy(REDACT_FOR_NETWORK_SETTINGS))
.getMinUdpPort4500NatTimeoutSeconds());
} }
} }
@@ -76,10 +94,18 @@ public class VcnTransportInfoTest {
SUB_ID, SUB_ID,
((VcnTransportInfo) CELL_UNDERLYING_INFO.makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION)) ((VcnTransportInfo) CELL_UNDERLYING_INFO.makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION))
.getSubId()); .getSubId());
assertEquals(
MIN_UDP_PORT_4500_NAT_TIMEOUT,
((VcnTransportInfo) CELL_UNDERLYING_INFO.makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION))
.getMinUdpPort4500NatTimeoutSeconds());
assertEquals( assertEquals(
WifiConfiguration.INVALID_NETWORK_ID, WifiConfiguration.INVALID_NETWORK_ID,
((VcnTransportInfo) WIFI_UNDERLYING_INFO.makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION)) ((VcnTransportInfo) WIFI_UNDERLYING_INFO.makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION))
.getWifiInfo().getNetworkId()); .getWifiInfo().getNetworkId());
assertEquals(
MIN_UDP_PORT_4500_NAT_TIMEOUT,
((VcnTransportInfo) WIFI_UNDERLYING_INFO.makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION))
.getMinUdpPort4500NatTimeoutSeconds());
} }
@Test @Test
@@ -110,8 +136,12 @@ public class VcnTransportInfoTest {
public void testParcelNotRedactedForSysUi() { public void testParcelNotRedactedForSysUi() {
VcnTransportInfo cellRedacted = parcelForSysUi(CELL_UNDERLYING_INFO); VcnTransportInfo cellRedacted = parcelForSysUi(CELL_UNDERLYING_INFO);
assertEquals(SUB_ID, cellRedacted.getSubId()); assertEquals(SUB_ID, cellRedacted.getSubId());
assertEquals(
MIN_UDP_PORT_4500_NAT_TIMEOUT, cellRedacted.getMinUdpPort4500NatTimeoutSeconds());
VcnTransportInfo wifiRedacted = parcelForSysUi(WIFI_UNDERLYING_INFO); VcnTransportInfo wifiRedacted = parcelForSysUi(WIFI_UNDERLYING_INFO);
assertEquals(NETWORK_ID, wifiRedacted.getWifiInfo().getNetworkId()); assertEquals(NETWORK_ID, wifiRedacted.getWifiInfo().getNetworkId());
assertEquals(
MIN_UDP_PORT_4500_NAT_TIMEOUT, wifiRedacted.getMinUdpPort4500NatTimeoutSeconds());
} }
private VcnTransportInfo parcelForSysUi(VcnTransportInfo vcnTransportInfo) { private VcnTransportInfo parcelForSysUi(VcnTransportInfo vcnTransportInfo) {

View File

@@ -25,6 +25,7 @@ import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI; import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_AUTHENTICATION_FAILED; import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_AUTHENTICATION_FAILED;
import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_TEMPORARY_FAILURE; import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_TEMPORARY_FAILURE;
import static android.net.vcn.VcnGatewayConnectionConfigTest.MIN_UDP_PORT_4500_NAT_TIMEOUT;
import static android.net.vcn.VcnManager.VCN_ERROR_CODE_CONFIG_ERROR; import static android.net.vcn.VcnManager.VCN_ERROR_CODE_CONFIG_ERROR;
import static android.net.vcn.VcnManager.VCN_ERROR_CODE_INTERNAL_ERROR; import static android.net.vcn.VcnManager.VCN_ERROR_CODE_INTERNAL_ERROR;
import static android.net.vcn.VcnManager.VCN_ERROR_CODE_NETWORK_ERROR; import static android.net.vcn.VcnManager.VCN_ERROR_CODE_NETWORK_ERROR;
@@ -66,6 +67,7 @@ import android.net.ipsec.ike.exceptions.IkeProtocolException;
import android.net.vcn.VcnGatewayConnectionConfig; import android.net.vcn.VcnGatewayConnectionConfig;
import android.net.vcn.VcnGatewayConnectionConfigTest; import android.net.vcn.VcnGatewayConnectionConfigTest;
import android.net.vcn.VcnManager.VcnErrorCode; import android.net.vcn.VcnManager.VcnErrorCode;
import android.net.vcn.VcnTransportInfo;
import android.os.PersistableBundle; import android.os.PersistableBundle;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
@@ -425,6 +427,12 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection
assertTrue(nc.hasCapability(cap)); assertTrue(nc.hasCapability(cap));
} }
assertTrue(nc.getTransportInfo() instanceof VcnTransportInfo);
final VcnTransportInfo vcnTransportInfo = (VcnTransportInfo) nc.getTransportInfo();
assertEquals(
MIN_UDP_PORT_4500_NAT_TIMEOUT,
vcnTransportInfo.getMinUdpPort4500NatTimeoutSeconds());
// Now that Vcn Network is up, notify it as validated and verify the SafeMode alarm is // Now that Vcn Network is up, notify it as validated and verify the SafeMode alarm is
// canceled // canceled
triggerValidation(NetworkAgent.VALIDATION_STATUS_VALID); triggerValidation(NetworkAgent.VALIDATION_STATUS_VALID);

View File

@@ -16,6 +16,8 @@
package com.android.server.vcn; package com.android.server.vcn;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static com.android.server.vcn.VcnGatewayConnection.VcnIkeSession; import static com.android.server.vcn.VcnGatewayConnection.VcnIkeSession;
import static com.android.server.vcn.VcnGatewayConnection.VcnNetworkAgent; import static com.android.server.vcn.VcnGatewayConnection.VcnNetworkAgent;
import static com.android.server.vcn.VcnTestUtils.setupIpSecManager; import static com.android.server.vcn.VcnTestUtils.setupIpSecManager;
@@ -46,6 +48,7 @@ import android.net.LinkAddress;
import android.net.LinkProperties; import android.net.LinkProperties;
import android.net.Network; import android.net.Network;
import android.net.NetworkCapabilities; import android.net.NetworkCapabilities;
import android.net.TelephonyNetworkSpecifier;
import android.net.ipsec.ike.ChildSessionCallback; import android.net.ipsec.ike.ChildSessionCallback;
import android.net.ipsec.ike.IkeSessionCallback; import android.net.ipsec.ike.IkeSessionCallback;
import android.net.ipsec.ike.IkeSessionConfiguration; import android.net.ipsec.ike.IkeSessionConfiguration;
@@ -127,7 +130,10 @@ public class VcnGatewayConnectionTestBase {
protected static final UnderlyingNetworkRecord TEST_UNDERLYING_NETWORK_RECORD_1 = protected static final UnderlyingNetworkRecord TEST_UNDERLYING_NETWORK_RECORD_1 =
getTestNetworkRecord( getTestNetworkRecord(
mock(Network.class, CALLS_REAL_METHODS), mock(Network.class, CALLS_REAL_METHODS),
new NetworkCapabilities(), new NetworkCapabilities.Builder()
.addTransportType(TRANSPORT_CELLULAR)
.setNetworkSpecifier(new TelephonyNetworkSpecifier(TEST_SUB_ID))
.build(),
new LinkProperties(), new LinkProperties(),
false /* blocked */); false /* blocked */);