1 /* 2 * Copyright 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.android.iwlan.epdg; 18 19 import static android.net.ipsec.ike.ike3gpp.Ike3gppData.DATA_TYPE_NOTIFY_BACKOFF_TIMER; 20 import static android.net.ipsec.ike.ike3gpp.Ike3gppData.DATA_TYPE_NOTIFY_N1_MODE_INFORMATION; 21 import static android.net.ipsec.ike.ike3gpp.Ike3gppParams.PDU_SESSION_ID_UNSET; 22 import static android.system.OsConstants.AF_INET; 23 import static android.system.OsConstants.AF_INET6; 24 import static android.telephony.PreciseDataConnectionState.NetworkValidationStatus; 25 26 import android.content.Context; 27 import android.net.ConnectivityManager; 28 import android.net.InetAddresses; 29 import android.net.IpPrefix; 30 import android.net.IpSecManager; 31 import android.net.IpSecTransform; 32 import android.net.LinkAddress; 33 import android.net.LinkProperties; 34 import android.net.Network; 35 import android.net.NetworkCapabilities; 36 import android.net.eap.EapAkaInfo; 37 import android.net.eap.EapInfo; 38 import android.net.eap.EapSessionConfig; 39 import android.net.ipsec.ike.ChildSaProposal; 40 import android.net.ipsec.ike.ChildSessionCallback; 41 import android.net.ipsec.ike.ChildSessionConfiguration; 42 import android.net.ipsec.ike.ChildSessionParams; 43 import android.net.ipsec.ike.IkeFqdnIdentification; 44 import android.net.ipsec.ike.IkeIdentification; 45 import android.net.ipsec.ike.IkeKeyIdIdentification; 46 import android.net.ipsec.ike.IkeRfc822AddrIdentification; 47 import android.net.ipsec.ike.IkeSaProposal; 48 import android.net.ipsec.ike.IkeSession; 49 import android.net.ipsec.ike.IkeSessionCallback; 50 import android.net.ipsec.ike.IkeSessionConfiguration; 51 import android.net.ipsec.ike.IkeSessionConnectionInfo; 52 import android.net.ipsec.ike.IkeSessionParams; 53 import android.net.ipsec.ike.IkeTrafficSelector; 54 import android.net.ipsec.ike.SaProposal; 55 import android.net.ipsec.ike.TunnelModeChildSessionParams; 56 import android.net.ipsec.ike.exceptions.IkeException; 57 import android.net.ipsec.ike.exceptions.IkeIOException; 58 import android.net.ipsec.ike.exceptions.IkeProtocolException; 59 import android.net.ipsec.ike.ike3gpp.Ike3gppBackoffTimer; 60 import android.net.ipsec.ike.ike3gpp.Ike3gppData; 61 import android.net.ipsec.ike.ike3gpp.Ike3gppExtension; 62 import android.net.ipsec.ike.ike3gpp.Ike3gppN1ModeInformation; 63 import android.net.ipsec.ike.ike3gpp.Ike3gppParams; 64 import android.os.Handler; 65 import android.os.HandlerThread; 66 import android.os.Looper; 67 import android.os.Message; 68 import android.support.annotation.IntDef; 69 import android.support.annotation.NonNull; 70 import android.support.annotation.Nullable; 71 import android.telephony.CarrierConfigManager; 72 import android.telephony.PreciseDataConnectionState; 73 import android.telephony.SubscriptionManager; 74 import android.telephony.TelephonyManager; 75 import android.telephony.data.ApnSetting; 76 import android.telephony.data.NetworkSliceInfo; 77 import android.util.Log; 78 79 import com.android.internal.annotations.VisibleForTesting; 80 81 import com.google.android.iwlan.ErrorPolicyManager; 82 import com.google.android.iwlan.IwlanCarrierConfig; 83 import com.google.android.iwlan.IwlanError; 84 import com.google.android.iwlan.IwlanHelper; 85 import com.google.android.iwlan.IwlanTunnelMetricsImpl; 86 import com.google.android.iwlan.TunnelMetricsInterface; 87 import com.google.android.iwlan.TunnelMetricsInterface.OnClosedMetrics; 88 import com.google.android.iwlan.TunnelMetricsInterface.OnOpenedMetrics; 89 import com.google.android.iwlan.exceptions.IwlanSimNotReadyException; 90 import com.google.android.iwlan.flags.FeatureFlags; 91 import com.google.android.iwlan.flags.FeatureFlagsImpl; 92 93 import java.io.IOException; 94 import java.io.PrintWriter; 95 import java.net.Inet4Address; 96 import java.net.Inet6Address; 97 import java.net.InetAddress; 98 import java.nio.charset.StandardCharsets; 99 import java.util.ArrayDeque; 100 import java.util.ArrayList; 101 import java.util.Arrays; 102 import java.util.List; 103 import java.util.Map; 104 import java.util.Objects; 105 import java.util.Queue; 106 import java.util.Set; 107 import java.util.concurrent.ConcurrentHashMap; 108 import java.util.concurrent.Executor; 109 import java.util.concurrent.Executors; 110 import java.util.concurrent.TimeUnit; 111 112 public class EpdgTunnelManager { 113 private final FeatureFlags mFeatureFlags; 114 private final Context mContext; 115 private final int mSlotId; 116 private Handler mHandler; 117 118 private static final int EVENT_TUNNEL_BRINGUP_REQUEST = 0; 119 private static final int EVENT_TUNNEL_BRINGDOWN_REQUEST = 1; 120 private static final int EVENT_CHILD_SESSION_OPENED = 2; 121 private static final int EVENT_CHILD_SESSION_CLOSED = 3; 122 private static final int EVENT_IKE_SESSION_CLOSED = 5; 123 private static final int EVENT_EPDG_ADDRESS_SELECTION_REQUEST_COMPLETE = 6; 124 private static final int EVENT_IPSEC_TRANSFORM_CREATED = 7; 125 private static final int EVENT_IPSEC_TRANSFORM_DELETED = 8; 126 private static final int EVENT_UPDATE_NETWORK = 9; 127 private static final int EVENT_IKE_SESSION_OPENED = 10; 128 private static final int EVENT_IKE_SESSION_CONNECTION_INFO_CHANGED = 11; 129 private static final int EVENT_IKE_3GPP_DATA_RECEIVED = 12; 130 private static final int EVENT_IKE_LIVENESS_STATUS_CHANGED = 13; 131 private static final int EVENT_REQUEST_NETWORK_VALIDATION_CHECK = 14; 132 private static final int IKE_HARD_LIFETIME_SEC_MINIMUM = 300; 133 private static final int IKE_HARD_LIFETIME_SEC_MAXIMUM = 86400; 134 private static final int IKE_SOFT_LIFETIME_SEC_MINIMUM = 120; 135 private static final int CHILD_HARD_LIFETIME_SEC_MINIMUM = 300; 136 private static final int CHILD_HARD_LIFETIME_SEC_MAXIMUM = 14400; 137 private static final int CHILD_SOFT_LIFETIME_SEC_MINIMUM = 120; 138 private static final int LIFETIME_MARGIN_SEC_MINIMUM = (int) TimeUnit.MINUTES.toSeconds(1L); 139 private static final int IKE_RETRANS_TIMEOUT_MS_MIN = 500; 140 141 private static final int IKE_RETRANS_TIMEOUT_MS_MAX = (int) TimeUnit.MINUTES.toMillis(30L); 142 143 private static final int IKE_RETRANS_MAX_ATTEMPTS_MAX = 10; 144 private static final int IKE_DPD_DELAY_SEC_MIN = 20; 145 private static final int IKE_DPD_DELAY_SEC_MAX = 1800; // 30 minutes 146 private static final int NATT_KEEPALIVE_DELAY_SEC_MIN = 10; 147 private static final int NATT_KEEPALIVE_DELAY_SEC_MAX = 120; 148 149 private static final int DEVICE_IMEI_LEN = 15; 150 private static final int DEVICE_IMEISV_SUFFIX_LEN = 2; 151 152 private static final int TRAFFIC_SELECTOR_START_PORT = 0; 153 private static final int TRAFFIC_SELECTOR_END_PORT = 65535; 154 private static final String TRAFFIC_SELECTOR_IPV4_START_ADDR = "0.0.0.0"; 155 private static final String TRAFFIC_SELECTOR_IPV4_END_ADDR = "255.255.255.255"; 156 private static final String TRAFFIC_SELECTOR_IPV6_START_ADDR = "::"; 157 private static final String TRAFFIC_SELECTOR_IPV6_END_ADDR = 158 "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"; 159 160 // "192.0.2.0" is selected from RFC5737, "IPv4 Address Blocks Reserved for Documentation" 161 private static final InetAddress DUMMY_ADDR = InetAddresses.parseNumericAddress("192.0.2.0"); 162 163 private static final Map<Integer, EpdgTunnelManager> mTunnelManagerInstances = 164 new ConcurrentHashMap<>(); 165 166 private final Queue<TunnelRequestWrapper> mPendingBringUpRequests = new ArrayDeque<>(); 167 168 private final EpdgInfo mValidEpdgInfo = new EpdgInfo(); 169 170 // The most recently updated system default network as seen by IwlanDataService. 171 @Nullable private Network mDefaultNetwork; 172 // The latest Network provided to the IKE session. Only for debugging purposes. 173 @Nullable private Network mIkeSessionNetwork; 174 175 private int mTransactionId = 0; 176 private boolean mHasConnectedToEpdg; 177 private final IkeSessionCreator mIkeSessionCreator; 178 private final IpSecManager mIpSecManager; 179 180 private final Map<String, TunnelConfig> mApnNameToTunnelConfig = new ConcurrentHashMap<>(); 181 private final Map<String, Integer> mApnNameToCurrentToken = new ConcurrentHashMap<>(); 182 183 private final String TAG; 184 185 @Nullable private byte[] mNextReauthId = null; 186 private long mEpdgServerSelectionDuration = 0; 187 private long mEpdgServerSelectionStartTime = 0; 188 private long mIkeTunnelEstablishmentStartTime = 0; 189 190 private static final Set<Integer> VALID_DH_GROUPS; 191 private static final Set<Integer> VALID_KEY_LENGTHS; 192 private static final Set<Integer> VALID_PRF_ALGOS; 193 private static final Set<Integer> VALID_INTEGRITY_ALGOS; 194 private static final Set<Integer> VALID_ENCRYPTION_ALGOS; 195 private static final Set<Integer> VALID_AEAD_ALGOS; 196 197 private static final String CONFIG_TYPE_DH_GROUP = "dh group"; 198 private static final String CONFIG_TYPE_KEY_LEN = "algorithm key length"; 199 private static final String CONFIG_TYPE_PRF_ALGO = "prf algorithm"; 200 private static final String CONFIG_TYPE_INTEGRITY_ALGO = "integrity algorithm"; 201 private static final String CONFIG_TYPE_ENCRYPT_ALGO = "encryption algorithm"; 202 203 static { 204 VALID_DH_GROUPS = 205 Set.of( 206 SaProposal.DH_GROUP_1024_BIT_MODP, 207 SaProposal.DH_GROUP_1536_BIT_MODP, 208 SaProposal.DH_GROUP_2048_BIT_MODP, 209 SaProposal.DH_GROUP_3072_BIT_MODP, 210 SaProposal.DH_GROUP_4096_BIT_MODP); 211 VALID_KEY_LENGTHS = 212 Set.of( 213 SaProposal.KEY_LEN_AES_128, 214 SaProposal.KEY_LEN_AES_192, 215 SaProposal.KEY_LEN_AES_256); 216 217 VALID_ENCRYPTION_ALGOS = 218 Set.of( 219 SaProposal.ENCRYPTION_ALGORITHM_AES_CBC, 220 SaProposal.ENCRYPTION_ALGORITHM_AES_CTR); 221 222 VALID_INTEGRITY_ALGOS = 223 Set.of( 224 SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96, 225 SaProposal.INTEGRITY_ALGORITHM_AES_XCBC_96, 226 SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_256_128, 227 SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_384_192, 228 SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_512_256); 229 230 VALID_AEAD_ALGOS = 231 Set.of( 232 SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8, 233 SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12, 234 SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_16); 235 236 VALID_PRF_ALGOS = 237 Set.of( 238 SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1, 239 SaProposal.PSEUDORANDOM_FUNCTION_AES128_XCBC, 240 SaProposal.PSEUDORANDOM_FUNCTION_SHA2_256, 241 SaProposal.PSEUDORANDOM_FUNCTION_SHA2_384, 242 SaProposal.PSEUDORANDOM_FUNCTION_SHA2_512); 243 } 244 245 @VisibleForTesting protected EpdgMonitor mEpdgMonitor = new EpdgMonitor(); 246 247 public static final int BRINGDOWN_REASON_UNKNOWN = 0; 248 public static final int BRINGDOWN_REASON_DISABLE_N1_MODE = 1; 249 public static final int BRINGDOWN_REASON_ENABLE_N1_MODE = 2; 250 public static final int BRINGDOWN_REASON_SERVICE_OUT_OF_SYNC = 3; 251 public static final int BRINGDOWN_REASON_IN_DEACTIVATING_STATE = 4; 252 public static final int BRINGDOWN_REASON_NETWORK_UPDATE_WHEN_TUNNEL_IN_BRINGUP = 5; 253 public static final int BRINGDOWN_REASON_DEACTIVATE_DATA_CALL = 6; 254 255 @IntDef({ 256 BRINGDOWN_REASON_UNKNOWN, 257 BRINGDOWN_REASON_DISABLE_N1_MODE, 258 BRINGDOWN_REASON_ENABLE_N1_MODE, 259 BRINGDOWN_REASON_SERVICE_OUT_OF_SYNC, 260 BRINGDOWN_REASON_IN_DEACTIVATING_STATE, 261 BRINGDOWN_REASON_NETWORK_UPDATE_WHEN_TUNNEL_IN_BRINGUP, 262 BRINGDOWN_REASON_DEACTIVATE_DATA_CALL, 263 }) 264 public @interface TunnelBringDownReason {} 265 bringdownReasonToString(@unnelBringDownReason int reason)266 private static String bringdownReasonToString(@TunnelBringDownReason int reason) { 267 switch (reason) { 268 case BRINGDOWN_REASON_UNKNOWN: 269 return "BRINGDOWN_REASON_UNKNOWN"; 270 case BRINGDOWN_REASON_DISABLE_N1_MODE: 271 return "BRINGDOWN_REASON_DISABLE_N1_MODE"; 272 case BRINGDOWN_REASON_ENABLE_N1_MODE: 273 return "BRINGDOWN_REASON_ENABLE_N1_MODE"; 274 case BRINGDOWN_REASON_SERVICE_OUT_OF_SYNC: 275 return "BRINGDOWN_REASON_SERVICE_OUT_OF_SYNC"; 276 case BRINGDOWN_REASON_IN_DEACTIVATING_STATE: 277 return "BRINGDOWN_REASON_IN_DEACTIVATING_STATE"; 278 case BRINGDOWN_REASON_NETWORK_UPDATE_WHEN_TUNNEL_IN_BRINGUP: 279 return "BRINGDOWN_REASON_NETWORK_UPDATE_WHEN_TUNNEL_IN_BRINGUP"; 280 case BRINGDOWN_REASON_DEACTIVATE_DATA_CALL: 281 return "BRINGDOWN_REASON_DEACTIVATE_DATA_CALL"; 282 default: 283 return "Unknown(" + reason + ")"; 284 } 285 } 286 287 private final EpdgSelector.EpdgSelectorCallback mSelectorCallback = 288 new EpdgSelector.EpdgSelectorCallback() { 289 @Override 290 public void onServerListChanged(int transactionId, List<InetAddress> validIPList) { 291 sendSelectionRequestComplete( 292 validIPList, new IwlanError(IwlanError.NO_ERROR), transactionId); 293 } 294 295 @Override 296 public void onError(int transactionId, IwlanError epdgSelectorError) { 297 sendSelectionRequestComplete(null, epdgSelectorError, transactionId); 298 } 299 }; 300 301 @VisibleForTesting 302 class TunnelConfig { 303 @NonNull final TunnelCallback mTunnelCallback; 304 @NonNull final TunnelMetricsInterface mTunnelMetrics; 305 // TODO: Change this to TunnelLinkProperties after removing autovalue 306 private List<InetAddress> mPcscfAddrList; 307 private List<InetAddress> mDnsAddrList; 308 private List<LinkAddress> mInternalAddrList; 309 310 private final InetAddress mSrcIpv6Address; 311 private final int mSrcIpv6AddressPrefixLen; 312 private NetworkSliceInfo mSliceInfo; 313 private boolean mIsBackoffTimeValid = false; 314 private long mBackoffTime; 315 316 @NonNull final IkeSession mIkeSession; 317 318 IwlanError mError; 319 private final IpSecManager.IpSecTunnelInterface mIface; 320 private IkeSessionState mIkeSessionState; 321 private final boolean mIsEmergency; 322 private final InetAddress mEpdgAddress; 323 TunnelConfig( IkeSession ikeSession, TunnelCallback tunnelCallback, TunnelMetricsInterface tunnelMetrics, IpSecManager.IpSecTunnelInterface iface, InetAddress srcIpv6Addr, int srcIpv6PrefixLength, boolean isEmergency, InetAddress epdgAddress)324 public TunnelConfig( 325 IkeSession ikeSession, 326 TunnelCallback tunnelCallback, 327 TunnelMetricsInterface tunnelMetrics, 328 IpSecManager.IpSecTunnelInterface iface, 329 InetAddress srcIpv6Addr, 330 int srcIpv6PrefixLength, 331 boolean isEmergency, 332 InetAddress epdgAddress) { 333 mTunnelCallback = tunnelCallback; 334 mTunnelMetrics = tunnelMetrics; 335 mIkeSession = ikeSession; 336 mError = new IwlanError(IwlanError.NO_ERROR); 337 mSrcIpv6Address = srcIpv6Addr; 338 mSrcIpv6AddressPrefixLen = srcIpv6PrefixLength; 339 mIface = iface; 340 setIkeSessionState(IkeSessionState.IKE_SESSION_INIT_IN_PROGRESS); 341 mIsEmergency = isEmergency; 342 mEpdgAddress = epdgAddress; 343 } 344 getIkeSessionState()345 public IkeSessionState getIkeSessionState() { 346 return mIkeSessionState; 347 } 348 setIkeSessionState(IkeSessionState ikeSessionState)349 public void setIkeSessionState(IkeSessionState ikeSessionState) { 350 mIkeSessionState = ikeSessionState; 351 } 352 getSliceInfo()353 public NetworkSliceInfo getSliceInfo() { 354 return mSliceInfo; 355 } 356 setSliceInfo(NetworkSliceInfo si)357 public void setSliceInfo(NetworkSliceInfo si) { 358 mSliceInfo = si; 359 } 360 isBackoffTimeValid()361 public boolean isBackoffTimeValid() { 362 return mIsBackoffTimeValid; 363 } 364 getBackoffTime()365 public long getBackoffTime() { 366 return mBackoffTime; 367 } 368 setBackoffTime(long backoffTime)369 public void setBackoffTime(long backoffTime) { 370 mIsBackoffTimeValid = true; 371 mBackoffTime = backoffTime; 372 } 373 374 @NonNull getTunnelCallback()375 TunnelCallback getTunnelCallback() { 376 return mTunnelCallback; 377 } 378 379 @NonNull getTunnelMetrics()380 TunnelMetricsInterface getTunnelMetrics() { 381 return mTunnelMetrics; 382 } 383 getPcscfAddrList()384 List<InetAddress> getPcscfAddrList() { 385 return mPcscfAddrList; 386 } 387 setPcscfAddrList(List<InetAddress> pcscfAddrList)388 void setPcscfAddrList(List<InetAddress> pcscfAddrList) { 389 mPcscfAddrList = pcscfAddrList; 390 } 391 getDnsAddrList()392 public List<InetAddress> getDnsAddrList() { 393 return mDnsAddrList; 394 } 395 setDnsAddrList(List<InetAddress> dnsAddrList)396 public void setDnsAddrList(List<InetAddress> dnsAddrList) { 397 this.mDnsAddrList = dnsAddrList; 398 } 399 getInternalAddrList()400 public List<LinkAddress> getInternalAddrList() { 401 return mInternalAddrList; 402 } 403 isPrefixSameAsSrcIP(LinkAddress laddr)404 boolean isPrefixSameAsSrcIP(LinkAddress laddr) { 405 if (laddr.isIpv6() && (laddr.getPrefixLength() == mSrcIpv6AddressPrefixLen)) { 406 IpPrefix assignedPrefix = new IpPrefix(laddr.getAddress(), laddr.getPrefixLength()); 407 IpPrefix srcPrefix = new IpPrefix(mSrcIpv6Address, mSrcIpv6AddressPrefixLen); 408 return assignedPrefix.equals(srcPrefix); 409 } 410 return false; 411 } 412 setInternalAddrList(List<LinkAddress> internalAddrList)413 public void setInternalAddrList(List<LinkAddress> internalAddrList) { 414 mInternalAddrList = new ArrayList<LinkAddress>(internalAddrList); 415 if (getSrcIpv6Address() != null) { 416 // check if we can reuse src ipv6 address (i.e. if prefix is same) 417 for (LinkAddress assignedAddr : internalAddrList) { 418 if (isPrefixSameAsSrcIP(assignedAddr)) { 419 // the assigned IPv6 address is same as pre-Handover IPv6 420 // addr. Just reuse the pre-Handover Address so the IID is 421 // preserved 422 mInternalAddrList.remove(assignedAddr); 423 424 // add original address 425 mInternalAddrList.add( 426 new LinkAddress(mSrcIpv6Address, mSrcIpv6AddressPrefixLen)); 427 428 Log.d( 429 TAG, 430 "Network assigned IP replaced OLD:" 431 + internalAddrList 432 + " NEW:" 433 + mInternalAddrList); 434 break; 435 } 436 } 437 } 438 } 439 440 @NonNull getIkeSession()441 public IkeSession getIkeSession() { 442 return mIkeSession; 443 } 444 getError()445 public IwlanError getError() { 446 return mError; 447 } 448 setError(IwlanError error)449 public void setError(IwlanError error) { 450 this.mError = error; 451 } 452 getIface()453 public IpSecManager.IpSecTunnelInterface getIface() { 454 return mIface; 455 } 456 getSrcIpv6Address()457 public InetAddress getSrcIpv6Address() { 458 return mSrcIpv6Address; 459 } 460 isEmergency()461 public boolean isEmergency() { 462 return mIsEmergency; 463 } 464 getEpdgAddress()465 public InetAddress getEpdgAddress() { 466 return mEpdgAddress; 467 } 468 hasTunnelOpened()469 public boolean hasTunnelOpened() { 470 return mInternalAddrList != null 471 && !mInternalAddrList.isEmpty() /* The child session is opened */ 472 && mIface != null; /* The tunnel interface is bring up */ 473 } 474 475 @Override toString()476 public String toString() { 477 StringBuilder sb = new StringBuilder(); 478 sb.append("TunnelConfig { "); 479 480 if (mSliceInfo != null) { 481 sb.append("mSliceInfo: ").append(mSliceInfo).append(", "); 482 } 483 484 if (mIsBackoffTimeValid) { 485 sb.append("mBackoffTime: ").append(mBackoffTime).append(", "); 486 } 487 sb.append(" }"); 488 return sb.toString(); 489 } 490 } 491 492 @VisibleForTesting 493 class TmIkeSessionCallback implements IkeSessionCallback { 494 495 private final String mApnName; 496 private final int mToken; 497 TmIkeSessionCallback(String apnName, int token)498 TmIkeSessionCallback(String apnName, int token) { 499 this.mApnName = apnName; 500 this.mToken = token; 501 } 502 503 @Override onOpened(IkeSessionConfiguration sessionConfiguration)504 public void onOpened(IkeSessionConfiguration sessionConfiguration) { 505 Log.d(TAG, "Ike session opened for apn: " + mApnName + " with token: " + mToken); 506 mHandler.sendMessage( 507 mHandler.obtainMessage( 508 EVENT_IKE_SESSION_OPENED, 509 new IkeSessionOpenedData(mApnName, mToken, sessionConfiguration))); 510 } 511 512 @Override onClosed()513 public void onClosed() { 514 Log.d(TAG, "Ike session closed for apn: " + mApnName + " with token: " + mToken); 515 mHandler.sendMessage( 516 mHandler.obtainMessage( 517 EVENT_IKE_SESSION_CLOSED, 518 new SessionClosedData(mApnName, mToken, null /* ikeException */))); 519 } 520 521 @Override onClosedWithException(IkeException exception)522 public void onClosedWithException(IkeException exception) { 523 mNextReauthId = null; 524 onSessionClosedWithException(exception, mApnName, mToken, EVENT_IKE_SESSION_CLOSED); 525 } 526 527 @Override onError(IkeProtocolException exception)528 public void onError(IkeProtocolException exception) { 529 Log.d(TAG, "Ike session onError for apn: " + mApnName + " with token: " + mToken); 530 531 mNextReauthId = null; 532 533 Log.d( 534 TAG, 535 "ErrorType:" 536 + exception.getErrorType() 537 + " ErrorData:" 538 + exception.getMessage()); 539 } 540 541 @Override onIkeSessionConnectionInfoChanged( IkeSessionConnectionInfo ikeSessionConnectionInfo)542 public void onIkeSessionConnectionInfoChanged( 543 IkeSessionConnectionInfo ikeSessionConnectionInfo) { 544 Network network = ikeSessionConnectionInfo.getNetwork(); 545 Log.d( 546 TAG, 547 "Ike session connection info changed for apn: " 548 + mApnName 549 + " with token: " 550 + mToken 551 + " Network: " 552 + network); 553 mHandler.sendMessage( 554 mHandler.obtainMessage( 555 EVENT_IKE_SESSION_CONNECTION_INFO_CHANGED, 556 new IkeSessionConnectionInfoData( 557 mApnName, mToken, ikeSessionConnectionInfo))); 558 } 559 560 @Override onLivenessStatusChanged(int status)561 public void onLivenessStatusChanged(int status) { 562 Log.d( 563 TAG, 564 "Ike liveness status changed for apn: " + mApnName + " with status: " + status); 565 @NetworkValidationStatus int validationStatus; 566 switch (status) { 567 case IkeSessionCallback.LIVENESS_STATUS_ON_DEMAND_STARTED: 568 case IkeSessionCallback.LIVENESS_STATUS_BACKGROUND_STARTED: 569 case IkeSessionCallback.LIVENESS_STATUS_ON_DEMAND_ONGOING: 570 case IkeSessionCallback.LIVENESS_STATUS_BACKGROUND_ONGOING: 571 validationStatus = PreciseDataConnectionState.NETWORK_VALIDATION_IN_PROGRESS; 572 break; 573 case IkeSessionCallback.LIVENESS_STATUS_SUCCESS: 574 validationStatus = PreciseDataConnectionState.NETWORK_VALIDATION_SUCCESS; 575 break; 576 case IkeSessionCallback.LIVENESS_STATUS_FAILURE: 577 validationStatus = PreciseDataConnectionState.NETWORK_VALIDATION_FAILURE; 578 break; 579 default: 580 validationStatus = PreciseDataConnectionState.NETWORK_VALIDATION_SUCCESS; 581 } 582 583 mHandler.obtainMessage( 584 EVENT_IKE_LIVENESS_STATUS_CHANGED, 585 new IkeSessionValidationStatusData(mApnName, mToken, validationStatus)) 586 .sendToTarget(); 587 } 588 } 589 590 @VisibleForTesting 591 class TmIke3gppCallback implements Ike3gppExtension.Ike3gppDataListener { 592 private final String mApnName; 593 private final int mToken; 594 TmIke3gppCallback(String apnName, int token)595 private TmIke3gppCallback(String apnName, int token) { 596 mApnName = apnName; 597 mToken = token; 598 } 599 600 @Override onIke3gppDataReceived(List<Ike3gppData> payloads)601 public void onIke3gppDataReceived(List<Ike3gppData> payloads) { 602 mHandler.sendMessage( 603 mHandler.obtainMessage( 604 EVENT_IKE_3GPP_DATA_RECEIVED, 605 new Ike3gppDataReceived(mApnName, mToken, payloads))); 606 } 607 } 608 609 @VisibleForTesting 610 class TmChildSessionCallback implements ChildSessionCallback { 611 612 private final String mApnName; 613 private final int mToken; 614 TmChildSessionCallback(String apnName, int token)615 TmChildSessionCallback(String apnName, int token) { 616 this.mApnName = apnName; 617 this.mToken = token; 618 } 619 620 @Override onOpened(ChildSessionConfiguration sessionConfiguration)621 public void onOpened(ChildSessionConfiguration sessionConfiguration) { 622 Log.d(TAG, "onOpened child session for apn: " + mApnName + " with token: " + mToken); 623 mHandler.sendMessage( 624 mHandler.obtainMessage( 625 EVENT_CHILD_SESSION_OPENED, 626 new TunnelOpenedData( 627 mApnName, 628 mToken, 629 sessionConfiguration.getInternalDnsServers(), 630 sessionConfiguration.getInternalAddresses()))); 631 } 632 633 @Override onClosed()634 public void onClosed() { 635 Log.d(TAG, "onClosed child session for apn: " + mApnName + " with token: " + mToken); 636 mHandler.sendMessage( 637 mHandler.obtainMessage( 638 EVENT_CHILD_SESSION_CLOSED, 639 new SessionClosedData(mApnName, mToken, null /* ikeException */))); 640 } 641 642 @Override onClosedWithException(IkeException exception)643 public void onClosedWithException(IkeException exception) { 644 onSessionClosedWithException(exception, mApnName, mToken, EVENT_CHILD_SESSION_CLOSED); 645 } 646 647 @Override onIpSecTransformsMigrated( IpSecTransform inIpSecTransform, IpSecTransform outIpSecTransform)648 public void onIpSecTransformsMigrated( 649 IpSecTransform inIpSecTransform, IpSecTransform outIpSecTransform) { 650 // migration is similar to addition 651 Log.d(TAG, "Transforms migrated for apn: " + mApnName + " with token: " + mToken); 652 mHandler.sendMessage( 653 mHandler.obtainMessage( 654 EVENT_IPSEC_TRANSFORM_CREATED, 655 new IpsecTransformData( 656 inIpSecTransform, 657 IpSecManager.DIRECTION_IN, 658 mApnName, 659 mToken))); 660 mHandler.sendMessage( 661 mHandler.obtainMessage( 662 EVENT_IPSEC_TRANSFORM_CREATED, 663 new IpsecTransformData( 664 outIpSecTransform, 665 IpSecManager.DIRECTION_OUT, 666 mApnName, 667 mToken))); 668 } 669 670 @Override onIpSecTransformCreated(IpSecTransform ipSecTransform, int direction)671 public void onIpSecTransformCreated(IpSecTransform ipSecTransform, int direction) { 672 Log.d( 673 TAG, 674 "Transform created, direction: " 675 + direction 676 + ", apn: " 677 + mApnName 678 + ", token: " 679 + mToken); 680 mHandler.sendMessage( 681 mHandler.obtainMessage( 682 EVENT_IPSEC_TRANSFORM_CREATED, 683 new IpsecTransformData(ipSecTransform, direction, mApnName, mToken))); 684 } 685 686 @Override onIpSecTransformDeleted(IpSecTransform ipSecTransform, int direction)687 public void onIpSecTransformDeleted(IpSecTransform ipSecTransform, int direction) { 688 Log.d( 689 TAG, 690 "Transform deleted, direction: " 691 + direction 692 + ", apn: " 693 + mApnName 694 + ", token: " 695 + mToken); 696 mHandler.sendMessage( 697 mHandler.obtainMessage( 698 EVENT_IPSEC_TRANSFORM_DELETED, 699 new IpsecTransformData(ipSecTransform, direction, mApnName, mToken))); 700 } 701 } 702 703 @VisibleForTesting EpdgTunnelManager(Context context, int slotId, FeatureFlags featureFlags)704 EpdgTunnelManager(Context context, int slotId, FeatureFlags featureFlags) { 705 mContext = context; 706 mSlotId = slotId; 707 mFeatureFlags = featureFlags; 708 mIkeSessionCreator = new IkeSessionCreator(); 709 mIpSecManager = mContext.getSystemService(IpSecManager.class); 710 TAG = EpdgTunnelManager.class.getSimpleName() + "[" + mSlotId + "]"; 711 initHandler(); 712 } 713 714 @VisibleForTesting initHandler()715 void initHandler() { 716 mHandler = new TmHandler(getLooper()); 717 } 718 719 @VisibleForTesting getLooper()720 Looper getLooper() { 721 HandlerThread handlerThread = new HandlerThread("EpdgTunnelManagerThread"); 722 handlerThread.start(); 723 return handlerThread.getLooper(); 724 } 725 726 /** 727 * Gets a EpdgTunnelManager instance. 728 * 729 * @param context application context 730 * @param subId subscription ID for the tunnel 731 * @return tunnel manager instance corresponding to the sub id 732 */ getInstance(@onNull Context context, int subId)733 public static EpdgTunnelManager getInstance(@NonNull Context context, int subId) { 734 return mTunnelManagerInstances.computeIfAbsent( 735 subId, k -> new EpdgTunnelManager(context, subId, new FeatureFlagsImpl())); 736 } 737 738 @VisibleForTesting resetAllInstances()739 public static void resetAllInstances() { 740 mTunnelManagerInstances.clear(); 741 } 742 743 public interface TunnelCallback { 744 /** 745 * Called when the tunnel is opened. 746 * 747 * @param apnName apn for which the tunnel was opened 748 * @param linkProperties link properties of the tunnel 749 */ onOpened(@onNull String apnName, @NonNull TunnelLinkProperties linkProperties)750 void onOpened(@NonNull String apnName, @NonNull TunnelLinkProperties linkProperties); 751 752 /** 753 * Called when the tunnel is closed OR if bringup fails 754 * 755 * @param apnName apn for which the tunnel was closed 756 * @param error IwlanError carrying details of the error 757 */ onClosed(@onNull String apnName, @NonNull IwlanError error)758 void onClosed(@NonNull String apnName, @NonNull IwlanError error); 759 760 /** 761 * Called when updates upon network validation status change. 762 * 763 * @param apnName APN affected. 764 * @param status The updated validation status of the network. 765 */ onNetworkValidationStatusChanged( @onNull String apnName, @NetworkValidationStatus int status)766 void onNetworkValidationStatusChanged( 767 @NonNull String apnName, @NetworkValidationStatus int status); 768 } 769 770 /** 771 * Close tunnel for an apn. Confirmation of closing will be delivered in TunnelCallback that was 772 * provided in {@link #bringUpTunnel}. If no tunnel was available, callback will be delivered 773 * using client-provided provided tunnelCallback and iwlanTunnelMetrics 774 * 775 * @param apnName APN name 776 * @param forceClose if {@code true}, triggers a local cleanup of the tunnel; if {@code false}, 777 * performs a normal closure procedure 778 * @param tunnelCallback The tunnelCallback for tunnel to be closed 779 * @param iwlanTunnelMetrics The metrics to be reported 780 * @param reason The reason for tunnel to be closed 781 */ closeTunnel( @onNull String apnName, boolean forceClose, @NonNull TunnelCallback tunnelCallback, @NonNull IwlanTunnelMetricsImpl iwlanTunnelMetrics, @TunnelBringDownReason int reason)782 public void closeTunnel( 783 @NonNull String apnName, 784 boolean forceClose, 785 @NonNull TunnelCallback tunnelCallback, 786 @NonNull IwlanTunnelMetricsImpl iwlanTunnelMetrics, 787 @TunnelBringDownReason int reason) { 788 mHandler.sendMessage( 789 mHandler.obtainMessage( 790 EVENT_TUNNEL_BRINGDOWN_REQUEST, 791 new TunnelBringdownRequest( 792 apnName, forceClose, tunnelCallback, iwlanTunnelMetrics, reason))); 793 } 794 795 /** 796 * Update the local Network. This will trigger a revaluation for every tunnel for which tunnel 797 * manager has state. 798 * 799 * @param network the network to be updated 800 * @param network the linkProperties to be updated 801 */ updateNetwork(Network network, LinkProperties linkProperties)802 public void updateNetwork(Network network, LinkProperties linkProperties) { 803 UpdateNetworkWrapper updateNetworkWrapper = 804 new UpdateNetworkWrapper(network, linkProperties); 805 mHandler.sendMessage(mHandler.obtainMessage(EVENT_UPDATE_NETWORK, updateNetworkWrapper)); 806 } 807 808 /** 809 * Bring up epdg tunnel. Only one bring up request per apn is expected. All active tunnel 810 * requests and tunnels are expected to be on the same network. 811 * 812 * @param setupRequest {@link TunnelSetupRequest} tunnel configurations 813 * @param tunnelCallback {@link TunnelCallback} interface to notify clients about the tunnel 814 * state 815 * @return true if params are valid and no existing tunnel. False otherwise. 816 */ bringUpTunnel( @onNull TunnelSetupRequest setupRequest, @NonNull TunnelCallback tunnelCallback, @NonNull TunnelMetricsInterface tunnelMetrics)817 public boolean bringUpTunnel( 818 @NonNull TunnelSetupRequest setupRequest, 819 @NonNull TunnelCallback tunnelCallback, 820 @NonNull TunnelMetricsInterface tunnelMetrics) { 821 String apnName = setupRequest.apnName(); 822 823 if (getTunnelSetupRequestApnName(setupRequest) == null) { 824 Log.e(TAG, "APN is null."); 825 return false; 826 } 827 828 if (isTunnelConfigContainExistApn(apnName)) { 829 Log.e(TAG, "Tunnel exists for apn:" + apnName); 830 return false; 831 } 832 833 if (!isValidApnProtocol(setupRequest.apnIpProtocol())) { 834 Log.e(TAG, "Invalid protocol for APN"); 835 return false; 836 } 837 838 int pduSessionId = setupRequest.pduSessionId(); 839 if (pduSessionId < 0 || pduSessionId > 15) { 840 Log.e(TAG, "Invalid pduSessionId: " + pduSessionId); 841 return false; 842 } 843 844 TunnelRequestWrapper tunnelRequestWrapper = 845 new TunnelRequestWrapper(setupRequest, tunnelCallback, tunnelMetrics); 846 847 mHandler.sendMessage( 848 mHandler.obtainMessage(EVENT_TUNNEL_BRINGUP_REQUEST, tunnelRequestWrapper)); 849 850 return true; 851 } 852 tryBuildIkeSessionParams( TunnelSetupRequest setupRequest, String apnName, int token, InetAddress epdgAddress)853 private IkeSessionParams tryBuildIkeSessionParams( 854 TunnelSetupRequest setupRequest, String apnName, int token, InetAddress epdgAddress) { 855 try { 856 return buildIkeSessionParams(setupRequest, apnName, token, epdgAddress); 857 } catch (IwlanSimNotReadyException e) { 858 return null; 859 } 860 } 861 tryCreateIpSecTunnelInterface()862 private IpSecManager.IpSecTunnelInterface tryCreateIpSecTunnelInterface() { 863 try { 864 return mIpSecManager.createIpSecTunnelInterface( 865 DUMMY_ADDR /* unused */, DUMMY_ADDR /* unused */, mDefaultNetwork); 866 } catch (IpSecManager.ResourceUnavailableException | IOException e) { 867 Log.e(TAG, "Failed to create tunnel interface. " + e); 868 return null; 869 } 870 } 871 onBringUpTunnel( TunnelRequestWrapper tunnelRequestWrapper, InetAddress epdgAddress)872 private void onBringUpTunnel( 873 TunnelRequestWrapper tunnelRequestWrapper, InetAddress epdgAddress) { 874 TunnelSetupRequest setupRequest = tunnelRequestWrapper.getSetupRequest(); 875 TunnelCallback tunnelCallback = tunnelRequestWrapper.getTunnelCallback(); 876 TunnelMetricsInterface tunnelMetrics = tunnelRequestWrapper.getTunnelMetrics(); 877 String apnName = setupRequest.apnName(); 878 IkeSessionParams ikeSessionParams; 879 IpSecManager.IpSecTunnelInterface iface; 880 881 Log.d( 882 TAG, 883 "Bringing up tunnel for apn: " 884 + apnName 885 + " ePDG: " 886 + epdgAddress.getHostAddress()); 887 888 final int token = incrementAndGetCurrentTokenForApn(apnName); 889 890 ikeSessionParams = tryBuildIkeSessionParams(setupRequest, apnName, token, epdgAddress); 891 if (Objects.isNull(ikeSessionParams)) { 892 IwlanError iwlanError = new IwlanError(IwlanError.SIM_NOT_READY_EXCEPTION); 893 reportIwlanError(apnName, iwlanError); 894 tunnelCallback.onClosed(apnName, iwlanError); 895 tunnelMetrics.onClosed(new OnClosedMetrics.Builder().setApnName(apnName).build()); 896 return; 897 } 898 899 iface = tryCreateIpSecTunnelInterface(); 900 if (Objects.isNull(iface)) { 901 IwlanError iwlanError = new IwlanError(IwlanError.TUNNEL_TRANSFORM_FAILED); 902 reportIwlanError(apnName, iwlanError); 903 tunnelCallback.onClosed(apnName, iwlanError); 904 tunnelMetrics.onClosed(new OnClosedMetrics.Builder().setApnName(apnName).build()); 905 return; 906 } 907 908 mIkeTunnelEstablishmentStartTime = System.currentTimeMillis(); 909 IkeSession ikeSession = 910 getIkeSessionCreator() 911 .createIkeSession( 912 mContext, 913 ikeSessionParams, 914 buildChildSessionParams(setupRequest), 915 Executors.newSingleThreadExecutor(), 916 getTmIkeSessionCallback(apnName, token), 917 new TmChildSessionCallback(apnName, token)); 918 919 boolean isSrcIpv6Present = setupRequest.srcIpv6Address().isPresent(); 920 putApnNameToTunnelConfig( 921 apnName, 922 ikeSession, 923 tunnelCallback, 924 tunnelMetrics, 925 iface, 926 isSrcIpv6Present ? setupRequest.srcIpv6Address().get() : null, 927 setupRequest.srcIpv6AddressPrefixLength(), 928 setupRequest.isEmergency(), 929 epdgAddress); 930 } 931 932 /** 933 * Proxy to allow testing 934 * 935 * @hide 936 */ 937 @VisibleForTesting 938 static class IkeSessionCreator { 939 /** Creates a IKE session */ createIkeSession( @onNull Context context, @NonNull IkeSessionParams ikeSessionParams, @NonNull ChildSessionParams firstChildSessionParams, @NonNull Executor userCbExecutor, @NonNull IkeSessionCallback ikeSessionCallback, @NonNull ChildSessionCallback firstChildSessionCallback)940 public IkeSession createIkeSession( 941 @NonNull Context context, 942 @NonNull IkeSessionParams ikeSessionParams, 943 @NonNull ChildSessionParams firstChildSessionParams, 944 @NonNull Executor userCbExecutor, 945 @NonNull IkeSessionCallback ikeSessionCallback, 946 @NonNull ChildSessionCallback firstChildSessionCallback) { 947 return new IkeSession( 948 context, 949 ikeSessionParams, 950 firstChildSessionParams, 951 userCbExecutor, 952 ikeSessionCallback, 953 firstChildSessionCallback); 954 } 955 } 956 buildChildSessionParams(TunnelSetupRequest setupRequest)957 private ChildSessionParams buildChildSessionParams(TunnelSetupRequest setupRequest) { 958 int proto = setupRequest.apnIpProtocol(); 959 int hardTimeSeconds = 960 IwlanCarrierConfig.getConfigInt( 961 mContext, 962 mSlotId, 963 CarrierConfigManager.Iwlan.KEY_CHILD_SA_REKEY_HARD_TIMER_SEC_INT); 964 int softTimeSeconds = 965 IwlanCarrierConfig.getConfigInt( 966 mContext, 967 mSlotId, 968 CarrierConfigManager.Iwlan.KEY_CHILD_SA_REKEY_SOFT_TIMER_SEC_INT); 969 if (!isValidChildSessionLifetime(hardTimeSeconds, softTimeSeconds)) { 970 if (hardTimeSeconds > CHILD_HARD_LIFETIME_SEC_MAXIMUM 971 && softTimeSeconds > CHILD_SOFT_LIFETIME_SEC_MINIMUM) { 972 hardTimeSeconds = CHILD_HARD_LIFETIME_SEC_MAXIMUM; 973 softTimeSeconds = CHILD_HARD_LIFETIME_SEC_MAXIMUM - LIFETIME_MARGIN_SEC_MINIMUM; 974 } else { 975 hardTimeSeconds = 976 IwlanCarrierConfig.getDefaultConfigInt( 977 CarrierConfigManager.Iwlan.KEY_CHILD_SA_REKEY_HARD_TIMER_SEC_INT); 978 softTimeSeconds = 979 IwlanCarrierConfig.getDefaultConfigInt( 980 CarrierConfigManager.Iwlan.KEY_CHILD_SA_REKEY_SOFT_TIMER_SEC_INT); 981 } 982 Log.d( 983 TAG, 984 "Invalid child session lifetime values, set hard: " 985 + hardTimeSeconds 986 + ", soft: " 987 + softTimeSeconds); 988 } 989 990 TunnelModeChildSessionParams.Builder childSessionParamsBuilder = 991 new TunnelModeChildSessionParams.Builder() 992 .setLifetimeSeconds(hardTimeSeconds, softTimeSeconds); 993 994 // Else block and it's related functionality can be removed once 995 // multipleSaProposals, highSecureTransformsPrioritized and aeadAlgosEnabled feature flags 996 // related functionality becomes stable and gets instruction to remove feature flags. 997 if (mFeatureFlags.multipleSaProposals() 998 || mFeatureFlags.highSecureTransformsPrioritized()) { 999 EpdgChildSaProposal epdgChildSaProposal = createEpdgChildSaProposal(); 1000 1001 if (IwlanCarrierConfig.getConfigBoolean( 1002 mContext, 1003 mSlotId, 1004 CarrierConfigManager.Iwlan.KEY_ADD_KE_TO_CHILD_SESSION_REKEY_BOOL)) { 1005 epdgChildSaProposal.enableAddChildSessionRekeyKePayload(); 1006 } 1007 // Adds single SA proposal, priority is for AEAD if configured else non-AEAD proposal. 1008 if (isChildSessionAeadAlgosAvailable()) { 1009 childSessionParamsBuilder.addChildSaProposal( 1010 epdgChildSaProposal.buildProposedChildSaAeadProposal()); 1011 } else { 1012 childSessionParamsBuilder.addChildSaProposal( 1013 epdgChildSaProposal.buildProposedChildSaProposal()); 1014 } 1015 // Adds multiple proposals. If AEAD proposal already added then adds 1016 // configured non-AEAD proposal followed by supported AEAD and non-AEAD proposals. 1017 if (IwlanCarrierConfig.getConfigBoolean( 1018 mContext, 1019 mSlotId, 1020 CarrierConfigManager.Iwlan 1021 .KEY_SUPPORTS_CHILD_SESSION_MULTIPLE_SA_PROPOSALS_BOOL)) { 1022 if (isChildSessionAeadAlgosAvailable() && isChildSessionNonAeadAlgosAvailable()) { 1023 childSessionParamsBuilder.addChildSaProposal( 1024 epdgChildSaProposal.buildProposedChildSaProposal()); 1025 } 1026 childSessionParamsBuilder.addChildSaProposal( 1027 epdgChildSaProposal.buildSupportedChildSaAeadProposal()); 1028 childSessionParamsBuilder.addChildSaProposal( 1029 epdgChildSaProposal.buildSupportedChildSaProposal()); 1030 } 1031 } else { 1032 if (isChildSessionAeadAlgosAvailable()) { 1033 childSessionParamsBuilder.addChildSaProposal(buildAeadChildSaProposal()); 1034 } else { 1035 childSessionParamsBuilder.addChildSaProposal(buildChildSaProposal()); 1036 } 1037 } 1038 1039 boolean handoverIPv4Present = setupRequest.srcIpv4Address().isPresent(); 1040 boolean handoverIPv6Present = setupRequest.srcIpv6Address().isPresent(); 1041 if (handoverIPv4Present || handoverIPv6Present) { 1042 if (handoverIPv4Present) { 1043 childSessionParamsBuilder.addInternalAddressRequest( 1044 (Inet4Address) setupRequest.srcIpv4Address().get()); 1045 childSessionParamsBuilder.addInternalDnsServerRequest(AF_INET); 1046 childSessionParamsBuilder.addInboundTrafficSelectors( 1047 getDefaultTrafficSelectorIpv4()); 1048 childSessionParamsBuilder.addOutboundTrafficSelectors( 1049 getDefaultTrafficSelectorIpv4()); 1050 } 1051 if (handoverIPv6Present) { 1052 childSessionParamsBuilder.addInternalAddressRequest( 1053 (Inet6Address) setupRequest.srcIpv6Address().get(), 1054 setupRequest.srcIpv6AddressPrefixLength()); 1055 childSessionParamsBuilder.addInternalDnsServerRequest(AF_INET6); 1056 childSessionParamsBuilder.addInboundTrafficSelectors( 1057 getDefaultTrafficSelectorIpv6()); 1058 childSessionParamsBuilder.addOutboundTrafficSelectors( 1059 getDefaultTrafficSelectorIpv6()); 1060 } 1061 } else { 1062 // non-handover case 1063 if (proto == ApnSetting.PROTOCOL_IP || proto == ApnSetting.PROTOCOL_IPV4V6) { 1064 childSessionParamsBuilder.addInternalAddressRequest(AF_INET); 1065 childSessionParamsBuilder.addInternalDnsServerRequest(AF_INET); 1066 childSessionParamsBuilder.addInboundTrafficSelectors( 1067 getDefaultTrafficSelectorIpv4()); 1068 childSessionParamsBuilder.addOutboundTrafficSelectors( 1069 getDefaultTrafficSelectorIpv4()); 1070 } 1071 if (proto == ApnSetting.PROTOCOL_IPV6 || proto == ApnSetting.PROTOCOL_IPV4V6) { 1072 childSessionParamsBuilder.addInternalAddressRequest(AF_INET6); 1073 childSessionParamsBuilder.addInternalDnsServerRequest(AF_INET6); 1074 childSessionParamsBuilder.addInboundTrafficSelectors( 1075 getDefaultTrafficSelectorIpv6()); 1076 childSessionParamsBuilder.addOutboundTrafficSelectors( 1077 getDefaultTrafficSelectorIpv6()); 1078 } 1079 } 1080 1081 return childSessionParamsBuilder.build(); 1082 } 1083 getDefaultTrafficSelectorIpv4()1084 private static IkeTrafficSelector getDefaultTrafficSelectorIpv4() { 1085 return new IkeTrafficSelector( 1086 TRAFFIC_SELECTOR_START_PORT, 1087 TRAFFIC_SELECTOR_END_PORT, 1088 InetAddresses.parseNumericAddress(TRAFFIC_SELECTOR_IPV4_START_ADDR), 1089 InetAddresses.parseNumericAddress(TRAFFIC_SELECTOR_IPV4_END_ADDR)); 1090 } 1091 getDefaultTrafficSelectorIpv6()1092 private static IkeTrafficSelector getDefaultTrafficSelectorIpv6() { 1093 return new IkeTrafficSelector( 1094 TRAFFIC_SELECTOR_START_PORT, 1095 TRAFFIC_SELECTOR_END_PORT, 1096 InetAddresses.parseNumericAddress(TRAFFIC_SELECTOR_IPV6_START_ADDR), 1097 InetAddresses.parseNumericAddress(TRAFFIC_SELECTOR_IPV6_END_ADDR)); 1098 } 1099 needIncludeInitialContact(InetAddress epdgAddress)1100 private boolean needIncludeInitialContact(InetAddress epdgAddress) { 1101 return !mEpdgMonitor.isConnectedEpdg(epdgAddress); 1102 } 1103 1104 // Returns the IMEISV or device IMEI, in that order of priority. getMobileDeviceIdentity()1105 private @Nullable String getMobileDeviceIdentity() { 1106 TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class); 1107 telephonyManager = 1108 Objects.requireNonNull(telephonyManager) 1109 .createForSubscriptionId(IwlanHelper.getSubId(mContext, mSlotId)); 1110 if (telephonyManager == null) { 1111 return null; 1112 } 1113 // Queries the 15-digit device IMEI. 1114 String imei = telephonyManager.getImei(); 1115 if (imei == null || imei.length() != DEVICE_IMEI_LEN) { 1116 Log.i(TAG, "Unable to query valid Mobile Device Identity (IMEI)!"); 1117 return null; 1118 } 1119 String imeisv_suffix = telephonyManager.getDeviceSoftwareVersion(); 1120 if (imeisv_suffix == null || imeisv_suffix.length() != DEVICE_IMEISV_SUFFIX_LEN) { 1121 // Unable to retrieve 2-digit suffix for IMEISV, so returns device IMEI. 1122 return imei; 1123 } 1124 // Splices the first 14 digit of device IMEI with 2-digit SV suffix to form IMEISV. 1125 return imei.substring(0, imei.length() - 1) + imeisv_suffix; 1126 } 1127 buildIkeSessionParams( TunnelSetupRequest setupRequest, String apnName, int token, InetAddress epdgAddress)1128 private IkeSessionParams buildIkeSessionParams( 1129 TunnelSetupRequest setupRequest, String apnName, int token, InetAddress epdgAddress) 1130 throws IwlanSimNotReadyException { 1131 int hardTimeSeconds = 1132 IwlanCarrierConfig.getConfigInt( 1133 mContext, 1134 mSlotId, 1135 CarrierConfigManager.Iwlan.KEY_IKE_REKEY_HARD_TIMER_SEC_INT); 1136 int softTimeSeconds = 1137 IwlanCarrierConfig.getConfigInt( 1138 mContext, 1139 mSlotId, 1140 CarrierConfigManager.Iwlan.KEY_IKE_REKEY_SOFT_TIMER_SEC_INT); 1141 if (!isValidIkeSessionLifetime(hardTimeSeconds, softTimeSeconds)) { 1142 if (hardTimeSeconds > IKE_HARD_LIFETIME_SEC_MAXIMUM 1143 && softTimeSeconds > IKE_SOFT_LIFETIME_SEC_MINIMUM) { 1144 hardTimeSeconds = IKE_HARD_LIFETIME_SEC_MAXIMUM; 1145 softTimeSeconds = IKE_HARD_LIFETIME_SEC_MAXIMUM - LIFETIME_MARGIN_SEC_MINIMUM; 1146 } else { 1147 hardTimeSeconds = 1148 IwlanCarrierConfig.getDefaultConfigInt( 1149 CarrierConfigManager.Iwlan.KEY_IKE_REKEY_HARD_TIMER_SEC_INT); 1150 softTimeSeconds = 1151 IwlanCarrierConfig.getDefaultConfigInt( 1152 CarrierConfigManager.Iwlan.KEY_IKE_REKEY_SOFT_TIMER_SEC_INT); 1153 } 1154 Log.d( 1155 TAG, 1156 "Invalid ike session lifetime values, set hard: " 1157 + hardTimeSeconds 1158 + ", soft: " 1159 + softTimeSeconds); 1160 } 1161 1162 IkeSessionParams.Builder builder = 1163 new IkeSessionParams.Builder() 1164 // permanently hardcode DSCP to 46 (Expedited Forwarding class) 1165 // See https://www.iana.org/assignments/dscp-registry/dscp-registry.xhtml 1166 // This will make WiFi prioritize IKE signallig under WMM AC_VO 1167 .setDscp(46) 1168 .setServerHostname(epdgAddress.getHostAddress()) 1169 .setLocalIdentification(getLocalIdentification()) 1170 .setRemoteIdentification(getId(setupRequest.apnName(), false)) 1171 .setAuthEap(null, getEapConfig()) 1172 .setNetwork(mDefaultNetwork) 1173 .addIkeOption(IkeSessionParams.IKE_OPTION_ACCEPT_ANY_REMOTE_ID) 1174 .addIkeOption(IkeSessionParams.IKE_OPTION_MOBIKE) 1175 .addIkeOption(IkeSessionParams.IKE_OPTION_REKEY_MOBILITY) 1176 .setLifetimeSeconds(hardTimeSeconds, softTimeSeconds) 1177 .setRetransmissionTimeoutsMillis(getRetransmissionTimeoutsFromConfig()) 1178 .setDpdDelaySeconds(getDpdDelayFromConfig()); 1179 1180 // Else block and it's related functionality can be removed once 1181 // multipleSaProposals, highSecureTransformsPrioritized and aeadAlgosEnabled feature flags 1182 // related functionality becomes stable and gets instruction to remove feature flags. 1183 if (mFeatureFlags.multipleSaProposals() 1184 || mFeatureFlags.highSecureTransformsPrioritized()) { 1185 EpdgIkeSaProposal epdgIkeSaProposal = createEpdgIkeSaProposal(); 1186 1187 // Adds single SA proposal, priority is for AEAD if configured else non-AEAD proposal. 1188 if (isIkeSessionAeadAlgosAvailable()) { 1189 builder.addIkeSaProposal(epdgIkeSaProposal.buildProposedIkeSaAeadProposal()); 1190 } else { 1191 builder.addIkeSaProposal(epdgIkeSaProposal.buildProposedIkeSaProposal()); 1192 } 1193 // Adds multiple proposals. If AEAD proposal already added then adds 1194 // configured non-AEAD proposal followed by supported AEAD and non-AEAD proposals. 1195 if (IwlanCarrierConfig.getConfigBoolean( 1196 mContext, 1197 mSlotId, 1198 CarrierConfigManager.Iwlan 1199 .KEY_SUPPORTS_IKE_SESSION_MULTIPLE_SA_PROPOSALS_BOOL)) { 1200 if (isIkeSessionAeadAlgosAvailable() && isIkeSessionNonAeadAlgosAvailable()) { 1201 builder.addIkeSaProposal(epdgIkeSaProposal.buildProposedIkeSaProposal()); 1202 } 1203 builder.addIkeSaProposal(epdgIkeSaProposal.buildSupportedIkeSaAeadProposal()); 1204 builder.addIkeSaProposal(epdgIkeSaProposal.buildSupportedIkeSaProposal()); 1205 } 1206 } else { 1207 if (isIkeSessionAeadAlgosAvailable()) { 1208 builder.addIkeSaProposal(buildIkeSaAeadProposal()); 1209 } else { 1210 builder.addIkeSaProposal(buildIkeSaProposal()); 1211 } 1212 } 1213 1214 if (needIncludeInitialContact(epdgAddress)) { 1215 builder.addIkeOption(IkeSessionParams.IKE_OPTION_INITIAL_CONTACT); 1216 Log.d(TAG, "IKE_OPTION_INITIAL_CONTACT"); 1217 } 1218 1219 if (IwlanCarrierConfig.getConfigInt( 1220 mContext, 1221 mSlotId, 1222 CarrierConfigManager.Iwlan.KEY_EPDG_AUTHENTICATION_METHOD_INT) 1223 == CarrierConfigManager.Iwlan.AUTHENTICATION_METHOD_EAP_ONLY) { 1224 builder.addIkeOption(IkeSessionParams.IKE_OPTION_EAP_ONLY_AUTH); 1225 } 1226 1227 if (setupRequest.requestPcscf()) { 1228 int proto = setupRequest.apnIpProtocol(); 1229 if (proto == ApnSetting.PROTOCOL_IP || proto == ApnSetting.PROTOCOL_IPV4V6) { 1230 builder.addPcscfServerRequest(AF_INET); 1231 } 1232 if (proto == ApnSetting.PROTOCOL_IPV6 || proto == ApnSetting.PROTOCOL_IPV4V6) { 1233 builder.addPcscfServerRequest(AF_INET6); 1234 } 1235 } 1236 1237 // If MOBIKE is configured, ePDGs may force IPv6 UDP encapsulation- as specified by 1238 // RFC 4555- which Android connectivity stack presently does not support. 1239 if (epdgAddress instanceof Inet6Address) { 1240 builder.removeIkeOption(IkeSessionParams.IKE_OPTION_MOBIKE); 1241 } 1242 1243 builder.setIke3gppExtension(buildIke3gppExtension(setupRequest, apnName, token)); 1244 1245 int nattKeepAliveTimer = 1246 IwlanCarrierConfig.getConfigInt( 1247 mContext, 1248 mSlotId, 1249 CarrierConfigManager.Iwlan.KEY_NATT_KEEP_ALIVE_TIMER_SEC_INT); 1250 if (nattKeepAliveTimer < NATT_KEEPALIVE_DELAY_SEC_MIN 1251 || nattKeepAliveTimer > NATT_KEEPALIVE_DELAY_SEC_MAX) { 1252 Log.d(TAG, "Falling back to default natt keep alive timer" + nattKeepAliveTimer); 1253 nattKeepAliveTimer = 1254 IwlanCarrierConfig.getDefaultConfigInt( 1255 CarrierConfigManager.Iwlan.KEY_NATT_KEEP_ALIVE_TIMER_SEC_INT); 1256 } 1257 builder.setNattKeepAliveDelaySeconds(nattKeepAliveTimer); 1258 1259 return builder.build(); 1260 } 1261 buildIke3gppExtension( TunnelSetupRequest setupRequest, String apnName, int token)1262 private Ike3gppExtension buildIke3gppExtension( 1263 TunnelSetupRequest setupRequest, String apnName, int token) { 1264 Ike3gppParams.Builder builder3gppParams = new Ike3gppParams.Builder(); 1265 1266 if (IwlanCarrierConfig.getConfigBoolean( 1267 mContext, mSlotId, IwlanCarrierConfig.KEY_IKE_DEVICE_IDENTITY_SUPPORTED_BOOL)) { 1268 String imei = getMobileDeviceIdentity(); 1269 if (imei != null) { 1270 Log.d(TAG, "DEVICE_IDENTITY set in Ike3gppParams"); 1271 builder3gppParams.setMobileDeviceIdentity(imei); 1272 } 1273 } 1274 1275 if (setupRequest.pduSessionId() != PDU_SESSION_ID_UNSET) { 1276 // Includes N1_MODE_CAPABILITY NOTIFY payload in IKE_AUTH exchange when PDU session ID 1277 // is set; otherwise, do not include. 1278 builder3gppParams.setPduSessionId((byte) setupRequest.pduSessionId()); 1279 } 1280 1281 return new Ike3gppExtension( 1282 builder3gppParams.build(), new TmIke3gppCallback(apnName, token)); 1283 } 1284 isChildSessionAeadAlgosAvailable()1285 private boolean isChildSessionAeadAlgosAvailable() { 1286 if (!mFeatureFlags.aeadAlgosEnabled()) { 1287 return false; 1288 } 1289 1290 int[] encryptionAlgos = 1291 IwlanCarrierConfig.getConfigIntArray( 1292 mContext, 1293 mSlotId, 1294 CarrierConfigManager.Iwlan 1295 .KEY_SUPPORTED_CHILD_SESSION_AEAD_ALGORITHMS_INT_ARRAY); 1296 for (int encryptionAlgo : encryptionAlgos) { 1297 if (validateConfig(encryptionAlgo, VALID_AEAD_ALGOS, CONFIG_TYPE_ENCRYPT_ALGO)) { 1298 return true; 1299 } 1300 } 1301 return false; 1302 } 1303 isChildSessionNonAeadAlgosAvailable()1304 private boolean isChildSessionNonAeadAlgosAvailable() { 1305 int[] encryptionAlgos = 1306 IwlanCarrierConfig.getConfigIntArray( 1307 mContext, 1308 mSlotId, 1309 CarrierConfigManager.Iwlan 1310 .KEY_SUPPORTED_CHILD_SESSION_ENCRYPTION_ALGORITHMS_INT_ARRAY); 1311 for (int encryptionAlgo : encryptionAlgos) { 1312 if (validateConfig(encryptionAlgo, VALID_ENCRYPTION_ALGOS, CONFIG_TYPE_ENCRYPT_ALGO)) { 1313 return true; 1314 } 1315 } 1316 return false; 1317 } 1318 isIkeSessionAeadAlgosAvailable()1319 private boolean isIkeSessionAeadAlgosAvailable() { 1320 if (!mFeatureFlags.aeadAlgosEnabled()) { 1321 return false; 1322 } 1323 1324 int[] encryptionAlgos = 1325 IwlanCarrierConfig.getConfigIntArray( 1326 mContext, 1327 mSlotId, 1328 CarrierConfigManager.Iwlan 1329 .KEY_SUPPORTED_IKE_SESSION_AEAD_ALGORITHMS_INT_ARRAY); 1330 for (int encryptionAlgo : encryptionAlgos) { 1331 if (validateConfig(encryptionAlgo, VALID_AEAD_ALGOS, CONFIG_TYPE_ENCRYPT_ALGO)) { 1332 return true; 1333 } 1334 } 1335 return false; 1336 } 1337 isIkeSessionNonAeadAlgosAvailable()1338 private boolean isIkeSessionNonAeadAlgosAvailable() { 1339 int[] encryptionAlgos = 1340 IwlanCarrierConfig.getConfigIntArray( 1341 mContext, 1342 mSlotId, 1343 CarrierConfigManager.Iwlan 1344 .KEY_SUPPORTED_IKE_SESSION_ENCRYPTION_ALGORITHMS_INT_ARRAY); 1345 for (int encryptionAlgo : encryptionAlgos) { 1346 if (validateConfig(encryptionAlgo, VALID_ENCRYPTION_ALGOS, CONFIG_TYPE_ENCRYPT_ALGO)) { 1347 return true; 1348 } 1349 } 1350 return false; 1351 } 1352 isValidChildSessionLifetime(int hardLifetimeSeconds, int softLifetimeSeconds)1353 private boolean isValidChildSessionLifetime(int hardLifetimeSeconds, int softLifetimeSeconds) { 1354 return hardLifetimeSeconds >= CHILD_HARD_LIFETIME_SEC_MINIMUM 1355 && hardLifetimeSeconds <= CHILD_HARD_LIFETIME_SEC_MAXIMUM 1356 && softLifetimeSeconds >= CHILD_SOFT_LIFETIME_SEC_MINIMUM 1357 && hardLifetimeSeconds - softLifetimeSeconds >= LIFETIME_MARGIN_SEC_MINIMUM; 1358 } 1359 isValidIkeSessionLifetime(int hardLifetimeSeconds, int softLifetimeSeconds)1360 private boolean isValidIkeSessionLifetime(int hardLifetimeSeconds, int softLifetimeSeconds) { 1361 return hardLifetimeSeconds >= IKE_HARD_LIFETIME_SEC_MINIMUM 1362 && hardLifetimeSeconds <= IKE_HARD_LIFETIME_SEC_MAXIMUM 1363 && softLifetimeSeconds >= IKE_SOFT_LIFETIME_SEC_MINIMUM 1364 && hardLifetimeSeconds - softLifetimeSeconds >= LIFETIME_MARGIN_SEC_MINIMUM; 1365 } 1366 createEpdgSaProposal(EpdgSaProposal epdgSaProposal, boolean isChildProposal)1367 private void createEpdgSaProposal(EpdgSaProposal epdgSaProposal, boolean isChildProposal) { 1368 epdgSaProposal.addProposedDhGroups( 1369 IwlanCarrierConfig.getConfigIntArray( 1370 mContext, 1371 mSlotId, 1372 CarrierConfigManager.Iwlan.KEY_DIFFIE_HELLMAN_GROUPS_INT_ARRAY)); 1373 1374 int[] encryptionAlgos = 1375 isChildProposal 1376 ? IwlanCarrierConfig.getConfigIntArray( 1377 mContext, 1378 mSlotId, 1379 CarrierConfigManager.Iwlan 1380 .KEY_SUPPORTED_CHILD_SESSION_ENCRYPTION_ALGORITHMS_INT_ARRAY) 1381 : IwlanCarrierConfig.getConfigIntArray( 1382 mContext, 1383 mSlotId, 1384 CarrierConfigManager.Iwlan 1385 .KEY_SUPPORTED_IKE_SESSION_ENCRYPTION_ALGORITHMS_INT_ARRAY); 1386 1387 for (int encryptionAlgo : encryptionAlgos) { 1388 if (encryptionAlgo == SaProposal.ENCRYPTION_ALGORITHM_AES_CBC) { 1389 int[] aesCbcKeyLens = 1390 isChildProposal 1391 ? IwlanCarrierConfig.getConfigIntArray( 1392 mContext, 1393 mSlotId, 1394 CarrierConfigManager.Iwlan 1395 .KEY_CHILD_SESSION_AES_CBC_KEY_SIZE_INT_ARRAY) 1396 : IwlanCarrierConfig.getConfigIntArray( 1397 mContext, 1398 mSlotId, 1399 CarrierConfigManager.Iwlan 1400 .KEY_IKE_SESSION_AES_CBC_KEY_SIZE_INT_ARRAY); 1401 epdgSaProposal.addProposedEncryptionAlgorithm(encryptionAlgo, aesCbcKeyLens); 1402 } 1403 1404 if (encryptionAlgo == SaProposal.ENCRYPTION_ALGORITHM_AES_CTR) { 1405 int[] aesCtrKeyLens = 1406 isChildProposal 1407 ? IwlanCarrierConfig.getConfigIntArray( 1408 mContext, 1409 mSlotId, 1410 CarrierConfigManager.Iwlan 1411 .KEY_CHILD_SESSION_AES_CTR_KEY_SIZE_INT_ARRAY) 1412 : IwlanCarrierConfig.getConfigIntArray( 1413 mContext, 1414 mSlotId, 1415 CarrierConfigManager.Iwlan 1416 .KEY_IKE_SESSION_AES_CTR_KEY_SIZE_INT_ARRAY); 1417 epdgSaProposal.addProposedEncryptionAlgorithm(encryptionAlgo, aesCtrKeyLens); 1418 } 1419 } 1420 1421 if (encryptionAlgos.length > 0) { 1422 epdgSaProposal.addProposedIntegrityAlgorithm( 1423 IwlanCarrierConfig.getConfigIntArray( 1424 mContext, 1425 mSlotId, 1426 CarrierConfigManager.Iwlan 1427 .KEY_SUPPORTED_INTEGRITY_ALGORITHMS_INT_ARRAY)); 1428 } 1429 1430 int[] aeadAlgos = 1431 isChildProposal 1432 ? IwlanCarrierConfig.getConfigIntArray( 1433 mContext, 1434 mSlotId, 1435 CarrierConfigManager.Iwlan 1436 .KEY_SUPPORTED_CHILD_SESSION_AEAD_ALGORITHMS_INT_ARRAY) 1437 : IwlanCarrierConfig.getConfigIntArray( 1438 mContext, 1439 mSlotId, 1440 CarrierConfigManager.Iwlan 1441 .KEY_SUPPORTED_IKE_SESSION_AEAD_ALGORITHMS_INT_ARRAY); 1442 for (int aeadAlgo : aeadAlgos) { 1443 if (!validateConfig(aeadAlgo, VALID_AEAD_ALGOS, CONFIG_TYPE_ENCRYPT_ALGO)) { 1444 continue; 1445 } 1446 if ((aeadAlgo == SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8) 1447 || (aeadAlgo == SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12) 1448 || (aeadAlgo == SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_16)) { 1449 int[] aesGcmKeyLens = 1450 isChildProposal 1451 ? IwlanCarrierConfig.getConfigIntArray( 1452 mContext, 1453 mSlotId, 1454 CarrierConfigManager.Iwlan 1455 .KEY_CHILD_SESSION_AES_GCM_KEY_SIZE_INT_ARRAY) 1456 : IwlanCarrierConfig.getConfigIntArray( 1457 mContext, 1458 mSlotId, 1459 CarrierConfigManager.Iwlan 1460 .KEY_IKE_SESSION_AES_GCM_KEY_SIZE_INT_ARRAY); 1461 epdgSaProposal.addProposedAeadAlgorithm(aeadAlgo, aesGcmKeyLens); 1462 } 1463 } 1464 1465 if (IwlanCarrierConfig.getConfigBoolean( 1466 mContext, mSlotId, IwlanCarrierConfig.KEY_IKE_SA_TRANSFORMS_REORDER_BOOL)) { 1467 epdgSaProposal.enableReorderingSaferProposals(); 1468 } 1469 } 1470 createEpdgChildSaProposal()1471 private EpdgChildSaProposal createEpdgChildSaProposal() { 1472 EpdgChildSaProposal epdgChildSaProposal = new EpdgChildSaProposal(); 1473 createEpdgSaProposal(epdgChildSaProposal, true); 1474 return epdgChildSaProposal; 1475 } 1476 createEpdgIkeSaProposal()1477 private EpdgIkeSaProposal createEpdgIkeSaProposal() { 1478 EpdgIkeSaProposal epdgIkeSaProposal = new EpdgIkeSaProposal(); 1479 1480 createEpdgSaProposal(epdgIkeSaProposal, false); 1481 1482 epdgIkeSaProposal.addProposedPrfAlgorithm( 1483 IwlanCarrierConfig.getConfigIntArray( 1484 mContext, 1485 mSlotId, 1486 CarrierConfigManager.Iwlan.KEY_SUPPORTED_PRF_ALGORITHMS_INT_ARRAY)); 1487 return epdgIkeSaProposal; 1488 } 1489 buildIkeSaProposal()1490 private IkeSaProposal buildIkeSaProposal() { 1491 IkeSaProposal.Builder saProposalBuilder = new IkeSaProposal.Builder(); 1492 1493 int[] dhGroups = 1494 IwlanCarrierConfig.getConfigIntArray( 1495 mContext, 1496 mSlotId, 1497 CarrierConfigManager.Iwlan.KEY_DIFFIE_HELLMAN_GROUPS_INT_ARRAY); 1498 for (int dhGroup : dhGroups) { 1499 if (validateConfig(dhGroup, VALID_DH_GROUPS, CONFIG_TYPE_DH_GROUP)) { 1500 saProposalBuilder.addDhGroup(dhGroup); 1501 } 1502 } 1503 1504 int[] encryptionAlgos = 1505 IwlanCarrierConfig.getConfigIntArray( 1506 mContext, 1507 mSlotId, 1508 CarrierConfigManager.Iwlan 1509 .KEY_SUPPORTED_IKE_SESSION_ENCRYPTION_ALGORITHMS_INT_ARRAY); 1510 for (int encryptionAlgo : encryptionAlgos) { 1511 validateConfig(encryptionAlgo, VALID_ENCRYPTION_ALGOS, CONFIG_TYPE_ENCRYPT_ALGO); 1512 1513 if (encryptionAlgo == SaProposal.ENCRYPTION_ALGORITHM_AES_CBC) { 1514 int[] aesCbcKeyLens = 1515 IwlanCarrierConfig.getConfigIntArray( 1516 mContext, 1517 mSlotId, 1518 CarrierConfigManager.Iwlan 1519 .KEY_IKE_SESSION_AES_CBC_KEY_SIZE_INT_ARRAY); 1520 for (int aesCbcKeyLen : aesCbcKeyLens) { 1521 if (validateConfig(aesCbcKeyLen, VALID_KEY_LENGTHS, CONFIG_TYPE_KEY_LEN)) { 1522 saProposalBuilder.addEncryptionAlgorithm(encryptionAlgo, aesCbcKeyLen); 1523 } 1524 } 1525 } 1526 1527 if (encryptionAlgo == SaProposal.ENCRYPTION_ALGORITHM_AES_CTR) { 1528 int[] aesCtrKeyLens = 1529 IwlanCarrierConfig.getConfigIntArray( 1530 mContext, 1531 mSlotId, 1532 CarrierConfigManager.Iwlan 1533 .KEY_IKE_SESSION_AES_CTR_KEY_SIZE_INT_ARRAY); 1534 for (int aesCtrKeyLen : aesCtrKeyLens) { 1535 if (validateConfig(aesCtrKeyLen, VALID_KEY_LENGTHS, CONFIG_TYPE_KEY_LEN)) { 1536 saProposalBuilder.addEncryptionAlgorithm(encryptionAlgo, aesCtrKeyLen); 1537 } 1538 } 1539 } 1540 } 1541 1542 int[] integrityAlgos = 1543 IwlanCarrierConfig.getConfigIntArray( 1544 mContext, 1545 mSlotId, 1546 CarrierConfigManager.Iwlan.KEY_SUPPORTED_INTEGRITY_ALGORITHMS_INT_ARRAY); 1547 for (int integrityAlgo : integrityAlgos) { 1548 if (validateConfig(integrityAlgo, VALID_INTEGRITY_ALGOS, CONFIG_TYPE_INTEGRITY_ALGO)) { 1549 saProposalBuilder.addIntegrityAlgorithm(integrityAlgo); 1550 } 1551 } 1552 1553 int[] prfAlgos = 1554 IwlanCarrierConfig.getConfigIntArray( 1555 mContext, 1556 mSlotId, 1557 CarrierConfigManager.Iwlan.KEY_SUPPORTED_PRF_ALGORITHMS_INT_ARRAY); 1558 for (int prfAlgo : prfAlgos) { 1559 if (validateConfig(prfAlgo, VALID_PRF_ALGOS, CONFIG_TYPE_PRF_ALGO)) { 1560 saProposalBuilder.addPseudorandomFunction(prfAlgo); 1561 } 1562 } 1563 1564 return saProposalBuilder.build(); 1565 } 1566 buildIkeSaAeadProposal()1567 private IkeSaProposal buildIkeSaAeadProposal() { 1568 IkeSaProposal.Builder saProposalBuilder = new IkeSaProposal.Builder(); 1569 1570 int[] dhGroups = 1571 IwlanCarrierConfig.getConfigIntArray( 1572 mContext, 1573 mSlotId, 1574 CarrierConfigManager.Iwlan.KEY_DIFFIE_HELLMAN_GROUPS_INT_ARRAY); 1575 for (int dhGroup : dhGroups) { 1576 if (validateConfig(dhGroup, VALID_DH_GROUPS, CONFIG_TYPE_DH_GROUP)) { 1577 saProposalBuilder.addDhGroup(dhGroup); 1578 } 1579 } 1580 1581 int[] encryptionAlgos = 1582 IwlanCarrierConfig.getConfigIntArray( 1583 mContext, 1584 mSlotId, 1585 CarrierConfigManager.Iwlan 1586 .KEY_SUPPORTED_IKE_SESSION_AEAD_ALGORITHMS_INT_ARRAY); 1587 for (int encryptionAlgo : encryptionAlgos) { 1588 if (!validateConfig(encryptionAlgo, VALID_AEAD_ALGOS, CONFIG_TYPE_ENCRYPT_ALGO)) { 1589 continue; 1590 } 1591 if ((encryptionAlgo == SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8) 1592 || (encryptionAlgo == SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12) 1593 || (encryptionAlgo == SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_16)) { 1594 int[] aesGcmKeyLens = 1595 IwlanCarrierConfig.getConfigIntArray( 1596 mContext, 1597 mSlotId, 1598 CarrierConfigManager.Iwlan 1599 .KEY_IKE_SESSION_AES_GCM_KEY_SIZE_INT_ARRAY); 1600 for (int aesGcmKeyLen : aesGcmKeyLens) { 1601 if (validateConfig(aesGcmKeyLen, VALID_KEY_LENGTHS, CONFIG_TYPE_KEY_LEN)) { 1602 saProposalBuilder.addEncryptionAlgorithm(encryptionAlgo, aesGcmKeyLen); 1603 } 1604 } 1605 } 1606 } 1607 1608 int[] prfAlgos = 1609 IwlanCarrierConfig.getConfigIntArray( 1610 mContext, 1611 mSlotId, 1612 CarrierConfigManager.Iwlan.KEY_SUPPORTED_PRF_ALGORITHMS_INT_ARRAY); 1613 for (int prfAlgo : prfAlgos) { 1614 if (validateConfig(prfAlgo, VALID_PRF_ALGOS, CONFIG_TYPE_PRF_ALGO)) { 1615 saProposalBuilder.addPseudorandomFunction(prfAlgo); 1616 } 1617 } 1618 1619 return saProposalBuilder.build(); 1620 } 1621 validateConfig(int config, Set<Integer> validConfigValues, String configType)1622 private boolean validateConfig(int config, Set<Integer> validConfigValues, String configType) { 1623 if (validConfigValues.contains(config)) { 1624 return true; 1625 } 1626 1627 Log.e(TAG, "Invalid config value for " + configType + ":" + config); 1628 return false; 1629 } 1630 buildChildSaProposal()1631 private ChildSaProposal buildChildSaProposal() { 1632 ChildSaProposal.Builder saProposalBuilder = new ChildSaProposal.Builder(); 1633 1634 // IKE library doesn't add KE payload if dh groups are not set in child session params. 1635 // Use the same groups as that of IKE session. 1636 if (IwlanCarrierConfig.getConfigBoolean( 1637 mContext, 1638 mSlotId, 1639 CarrierConfigManager.Iwlan.KEY_ADD_KE_TO_CHILD_SESSION_REKEY_BOOL)) { 1640 int[] dhGroups = 1641 IwlanCarrierConfig.getConfigIntArray( 1642 mContext, 1643 mSlotId, 1644 CarrierConfigManager.Iwlan.KEY_DIFFIE_HELLMAN_GROUPS_INT_ARRAY); 1645 for (int dhGroup : dhGroups) { 1646 if (validateConfig(dhGroup, VALID_DH_GROUPS, CONFIG_TYPE_DH_GROUP)) { 1647 saProposalBuilder.addDhGroup(dhGroup); 1648 } 1649 } 1650 } 1651 1652 int[] encryptionAlgos = 1653 IwlanCarrierConfig.getConfigIntArray( 1654 mContext, 1655 mSlotId, 1656 CarrierConfigManager.Iwlan 1657 .KEY_SUPPORTED_CHILD_SESSION_ENCRYPTION_ALGORITHMS_INT_ARRAY); 1658 for (int encryptionAlgo : encryptionAlgos) { 1659 if (validateConfig(encryptionAlgo, VALID_ENCRYPTION_ALGOS, CONFIG_TYPE_ENCRYPT_ALGO)) { 1660 if (ChildSaProposal.getSupportedEncryptionAlgorithms().contains(encryptionAlgo)) { 1661 if (encryptionAlgo == SaProposal.ENCRYPTION_ALGORITHM_AES_CBC) { 1662 int[] aesCbcKeyLens = 1663 IwlanCarrierConfig.getConfigIntArray( 1664 mContext, 1665 mSlotId, 1666 CarrierConfigManager.Iwlan 1667 .KEY_CHILD_SESSION_AES_CBC_KEY_SIZE_INT_ARRAY); 1668 for (int aesCbcKeyLen : aesCbcKeyLens) { 1669 if (validateConfig( 1670 aesCbcKeyLen, VALID_KEY_LENGTHS, CONFIG_TYPE_KEY_LEN)) { 1671 saProposalBuilder.addEncryptionAlgorithm( 1672 encryptionAlgo, aesCbcKeyLen); 1673 } 1674 } 1675 } 1676 1677 if (encryptionAlgo == SaProposal.ENCRYPTION_ALGORITHM_AES_CTR) { 1678 int[] aesCtrKeyLens = 1679 IwlanCarrierConfig.getConfigIntArray( 1680 mContext, 1681 mSlotId, 1682 CarrierConfigManager.Iwlan 1683 .KEY_CHILD_SESSION_AES_CTR_KEY_SIZE_INT_ARRAY); 1684 for (int aesCtrKeyLen : aesCtrKeyLens) { 1685 if (validateConfig( 1686 aesCtrKeyLen, VALID_KEY_LENGTHS, CONFIG_TYPE_KEY_LEN)) { 1687 saProposalBuilder.addEncryptionAlgorithm( 1688 encryptionAlgo, aesCtrKeyLen); 1689 } 1690 } 1691 } 1692 } else { 1693 Log.w(TAG, "Device does not support encryption algo: " + encryptionAlgo); 1694 } 1695 } 1696 } 1697 1698 int[] integrityAlgos = 1699 IwlanCarrierConfig.getConfigIntArray( 1700 mContext, 1701 mSlotId, 1702 CarrierConfigManager.Iwlan.KEY_SUPPORTED_INTEGRITY_ALGORITHMS_INT_ARRAY); 1703 for (int integrityAlgo : integrityAlgos) { 1704 if (validateConfig(integrityAlgo, VALID_INTEGRITY_ALGOS, CONFIG_TYPE_INTEGRITY_ALGO)) { 1705 if (ChildSaProposal.getSupportedIntegrityAlgorithms().contains(integrityAlgo)) { 1706 saProposalBuilder.addIntegrityAlgorithm(integrityAlgo); 1707 } else { 1708 Log.w(TAG, "Device does not support integrity algo: " + integrityAlgo); 1709 } 1710 } 1711 } 1712 1713 return saProposalBuilder.build(); 1714 } 1715 buildAeadChildSaProposal()1716 private ChildSaProposal buildAeadChildSaProposal() { 1717 ChildSaProposal.Builder saProposalBuilder = new ChildSaProposal.Builder(); 1718 1719 int[] dhGroups = 1720 IwlanCarrierConfig.getConfigIntArray( 1721 mContext, 1722 mSlotId, 1723 CarrierConfigManager.Iwlan.KEY_DIFFIE_HELLMAN_GROUPS_INT_ARRAY); 1724 for (int dhGroup : dhGroups) { 1725 if (validateConfig(dhGroup, VALID_DH_GROUPS, CONFIG_TYPE_DH_GROUP)) { 1726 saProposalBuilder.addDhGroup(dhGroup); 1727 } 1728 } 1729 1730 int[] encryptionAlgos = 1731 IwlanCarrierConfig.getConfigIntArray( 1732 mContext, 1733 mSlotId, 1734 CarrierConfigManager.Iwlan 1735 .KEY_SUPPORTED_CHILD_SESSION_AEAD_ALGORITHMS_INT_ARRAY); 1736 for (int encryptionAlgo : encryptionAlgos) { 1737 if (!validateConfig(encryptionAlgo, VALID_AEAD_ALGOS, CONFIG_TYPE_ENCRYPT_ALGO)) { 1738 continue; 1739 } 1740 if ((encryptionAlgo == SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8) 1741 || (encryptionAlgo == SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12) 1742 || (encryptionAlgo == SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_16)) { 1743 int[] aesGcmKeyLens = 1744 IwlanCarrierConfig.getConfigIntArray( 1745 mContext, 1746 mSlotId, 1747 CarrierConfigManager.Iwlan 1748 .KEY_CHILD_SESSION_AES_GCM_KEY_SIZE_INT_ARRAY); 1749 for (int aesGcmKeyLen : aesGcmKeyLens) { 1750 if (validateConfig(aesGcmKeyLen, VALID_KEY_LENGTHS, CONFIG_TYPE_KEY_LEN)) { 1751 saProposalBuilder.addEncryptionAlgorithm(encryptionAlgo, aesGcmKeyLen); 1752 } 1753 } 1754 } 1755 } 1756 1757 return saProposalBuilder.build(); 1758 } 1759 getLocalIdentification()1760 private IkeIdentification getLocalIdentification() throws IwlanSimNotReadyException { 1761 String nai; 1762 1763 nai = IwlanHelper.getNai(mContext, mSlotId, mNextReauthId); 1764 1765 if (nai == null) { 1766 throw new IwlanSimNotReadyException("Nai is null."); 1767 } 1768 1769 Log.d(TAG, "getLocalIdentification: Nai: " + nai); 1770 return getId(nai, true); 1771 } 1772 getId(String id, boolean isLocal)1773 private IkeIdentification getId(String id, boolean isLocal) { 1774 String idTypeConfig = 1775 isLocal 1776 ? CarrierConfigManager.Iwlan.KEY_IKE_LOCAL_ID_TYPE_INT 1777 : CarrierConfigManager.Iwlan.KEY_IKE_REMOTE_ID_TYPE_INT; 1778 int idType = IwlanCarrierConfig.getConfigInt(mContext, mSlotId, idTypeConfig); 1779 switch (idType) { 1780 case CarrierConfigManager.Iwlan.ID_TYPE_FQDN: 1781 return new IkeFqdnIdentification(id); 1782 case CarrierConfigManager.Iwlan.ID_TYPE_KEY_ID: 1783 return new IkeKeyIdIdentification(id.getBytes(StandardCharsets.US_ASCII)); 1784 case CarrierConfigManager.Iwlan.ID_TYPE_RFC822_ADDR: 1785 return new IkeRfc822AddrIdentification(id); 1786 default: 1787 throw new IllegalArgumentException("Invalid local Identity type: " + idType); 1788 } 1789 } 1790 getEapConfig()1791 private EapSessionConfig getEapConfig() throws IwlanSimNotReadyException { 1792 int subId = IwlanHelper.getSubId(mContext, mSlotId); 1793 String nai = IwlanHelper.getNai(mContext, mSlotId, null); 1794 1795 if (nai == null) { 1796 throw new IwlanSimNotReadyException("Nai is null."); 1797 } 1798 1799 EapSessionConfig.EapAkaOption option = null; 1800 if (mNextReauthId != null) { 1801 option = new EapSessionConfig.EapAkaOption.Builder().setReauthId(mNextReauthId).build(); 1802 } 1803 1804 Log.d(TAG, "getEapConfig: Nai: " + nai); 1805 return new EapSessionConfig.Builder() 1806 .setEapAkaConfig(subId, TelephonyManager.APPTYPE_USIM, option) 1807 .setEapIdentity(nai.getBytes(StandardCharsets.US_ASCII)) 1808 .build(); 1809 } 1810 onSessionClosedWithException( IkeException exception, String apnName, int token, int sessionType)1811 private void onSessionClosedWithException( 1812 IkeException exception, String apnName, int token, int sessionType) { 1813 Log.e( 1814 TAG, 1815 "Closing tunnel with exception for apn: " 1816 + apnName 1817 + " with token: " 1818 + token 1819 + " sessionType:" 1820 + sessionType); 1821 exception.printStackTrace(); 1822 1823 mHandler.sendMessage( 1824 mHandler.obtainMessage( 1825 sessionType, new SessionClosedData(apnName, token, exception))); 1826 } 1827 isEpdgSelectionOrFirstTunnelBringUpInProgress()1828 private boolean isEpdgSelectionOrFirstTunnelBringUpInProgress() { 1829 // Tunnel config is created but not connected to an ePDG. i.e., The first bring-up request 1830 // in progress. 1831 // No bring-up request in progress but pending queue is not empty. i.e. ePDG selection in 1832 // progress 1833 return (!mHasConnectedToEpdg && !mApnNameToTunnelConfig.isEmpty()) 1834 || !mPendingBringUpRequests.isEmpty(); 1835 } 1836 getErrorFromIkeException( IkeException ikeException, IkeSessionState ikeSessionState)1837 private IwlanError getErrorFromIkeException( 1838 IkeException ikeException, IkeSessionState ikeSessionState) { 1839 IwlanError error; 1840 if (ikeException instanceof IkeIOException) { 1841 error = new IwlanError(ikeSessionState.getErrorType(), ikeException); 1842 } else { 1843 error = new IwlanError(ikeException); 1844 } 1845 Log.e(TAG, "Closing tunnel: error: " + error + " state: " + ikeSessionState); 1846 return error; 1847 } 1848 1849 private final class TmHandler extends Handler { 1850 1851 @Override handleMessage(Message msg)1852 public void handleMessage(Message msg) { 1853 Log.d(TAG, "msg.what = " + eventToString(msg.what)); 1854 1855 String apnName; 1856 TunnelConfig tunnelConfig; 1857 OnClosedMetrics.Builder onClosedMetricsBuilder; 1858 TunnelRequestWrapper tunnelRequestWrapper; 1859 ConnectivityManager connectivityManager; 1860 NetworkCapabilities networkCapabilities; 1861 boolean isNetworkValidated; 1862 switch (msg.what) { 1863 case EVENT_CHILD_SESSION_OPENED: 1864 case EVENT_IKE_SESSION_CLOSED: 1865 case EVENT_IPSEC_TRANSFORM_CREATED: 1866 case EVENT_IPSEC_TRANSFORM_DELETED: 1867 case EVENT_CHILD_SESSION_CLOSED: 1868 case EVENT_IKE_SESSION_OPENED: 1869 case EVENT_IKE_SESSION_CONNECTION_INFO_CHANGED: 1870 case EVENT_IKE_3GPP_DATA_RECEIVED: 1871 case EVENT_IKE_LIVENESS_STATUS_CHANGED: 1872 IkeEventData ikeEventData = (IkeEventData) msg.obj; 1873 if (isObsoleteToken(ikeEventData.mApnName, ikeEventData.mToken)) { 1874 Log.d( 1875 TAG, 1876 eventToString(msg.what) 1877 + " for obsolete token " 1878 + ikeEventData.mToken); 1879 return; 1880 } 1881 } 1882 1883 long mIkeTunnelEstablishmentDuration; 1884 switch (msg.what) { 1885 case EVENT_TUNNEL_BRINGUP_REQUEST: 1886 handleTunnelBringUpRequest((TunnelRequestWrapper) msg.obj); 1887 break; 1888 1889 case EVENT_EPDG_ADDRESS_SELECTION_REQUEST_COMPLETE: 1890 EpdgSelectorResult selectorResult = (EpdgSelectorResult) msg.obj; 1891 printRequestQueue("EVENT_EPDG_ADDRESS_SELECTION_REQUEST_COMPLETE"); 1892 1893 if (selectorResult.getTransactionId() != mTransactionId) { 1894 Log.e(TAG, "Mismatched transactionId"); 1895 break; 1896 } 1897 1898 if (mPendingBringUpRequests.isEmpty()) { 1899 Log.d(TAG, "Empty request queue"); 1900 break; 1901 } 1902 1903 if (selectorResult.getEpdgError().getErrorType() == IwlanError.NO_ERROR 1904 && selectorResult.getValidIpList() != null) { 1905 tunnelRequestWrapper = mPendingBringUpRequests.remove(); 1906 onBringUpTunnel( 1907 tunnelRequestWrapper, 1908 validateAndSetEpdgAddress(selectorResult.getValidIpList())); 1909 } else { 1910 IwlanError error = 1911 (selectorResult.getEpdgError().getErrorType() 1912 == IwlanError.NO_ERROR) 1913 ? new IwlanError( 1914 IwlanError.EPDG_SELECTOR_SERVER_SELECTION_FAILED) 1915 : selectorResult.getEpdgError(); 1916 failAllPendingRequests(error); 1917 } 1918 break; 1919 1920 case EVENT_CHILD_SESSION_OPENED: 1921 TunnelOpenedData tunnelOpenedData = (TunnelOpenedData) msg.obj; 1922 apnName = tunnelOpenedData.mApnName; 1923 tunnelConfig = mApnNameToTunnelConfig.get(apnName); 1924 1925 tunnelConfig.setDnsAddrList(tunnelOpenedData.mInternalDnsServers); 1926 tunnelConfig.setInternalAddrList(tunnelOpenedData.mInternalAddresses); 1927 1928 IpSecManager.IpSecTunnelInterface tunnelInterface = tunnelConfig.getIface(); 1929 1930 for (LinkAddress address : tunnelConfig.getInternalAddrList()) { 1931 try { 1932 tunnelInterface.addAddress( 1933 address.getAddress(), address.getPrefixLength()); 1934 } catch (IOException e) { 1935 Log.e(TAG, "Adding internal addresses to interface failed."); 1936 } 1937 } 1938 1939 TunnelLinkProperties linkProperties = 1940 TunnelLinkProperties.builder() 1941 .setInternalAddresses(tunnelConfig.getInternalAddrList()) 1942 .setDnsAddresses(tunnelConfig.getDnsAddrList()) 1943 .setPcscfAddresses(tunnelConfig.getPcscfAddrList()) 1944 .setIfaceName(tunnelConfig.getIface().getInterfaceName()) 1945 .setSliceInfo(tunnelConfig.getSliceInfo()) 1946 .build(); 1947 tunnelConfig.getTunnelCallback().onOpened(apnName, linkProperties); 1948 1949 reportIwlanError(apnName, new IwlanError(IwlanError.NO_ERROR)); 1950 getEpdgSelector().onEpdgConnectedSuccessfully(); 1951 1952 mIkeTunnelEstablishmentDuration = 1953 System.currentTimeMillis() - mIkeTunnelEstablishmentStartTime; 1954 mIkeTunnelEstablishmentStartTime = 0; 1955 connectivityManager = mContext.getSystemService(ConnectivityManager.class); 1956 networkCapabilities = 1957 connectivityManager.getNetworkCapabilities(mIkeSessionNetwork); 1958 isNetworkValidated = 1959 (networkCapabilities != null) 1960 && networkCapabilities.hasCapability( 1961 NetworkCapabilities.NET_CAPABILITY_VALIDATED); 1962 tunnelConfig 1963 .getTunnelMetrics() 1964 .onOpened( 1965 new OnOpenedMetrics.Builder() 1966 .setApnName(apnName) 1967 .setEpdgServerAddress(tunnelConfig.getEpdgAddress()) 1968 .setEpdgServerSelectionDuration( 1969 (int) mEpdgServerSelectionDuration) 1970 .setIkeTunnelEstablishmentDuration( 1971 (int) mIkeTunnelEstablishmentDuration) 1972 .setIsNetworkValidated(isNetworkValidated) 1973 .build()); 1974 1975 mEpdgMonitor.onApnConnectToEpdg(apnName, tunnelConfig.getEpdgAddress()); 1976 onConnectedToEpdg(true); 1977 mValidEpdgInfo.resetIndex(); 1978 printRequestQueue("EVENT_CHILD_SESSION_OPENED"); 1979 serviceAllPendingRequests(); 1980 tunnelConfig.setIkeSessionState(IkeSessionState.CHILD_SESSION_OPENED); 1981 break; 1982 1983 case EVENT_IKE_SESSION_CLOSED: 1984 printRequestQueue("EVENT_IKE_SESSION_CLOSED"); 1985 SessionClosedData sessionClosedData = (SessionClosedData) msg.obj; 1986 apnName = sessionClosedData.mApnName; 1987 1988 tunnelConfig = mApnNameToTunnelConfig.get(apnName); 1989 if (tunnelConfig == null) { 1990 Log.e(TAG, "No callback found for apn: " + apnName); 1991 return; 1992 } 1993 1994 // If IKE session closed exceptionally, we retrieve IwlanError directly from the 1995 // exception; otherwise, it is still possible that we triggered an IKE session 1996 // close due to an error (e.g. IwlanError.TUNNEL_TRANSFORM_FAILED), or because 1997 // the Child session closed exceptionally; in which case, we attempt to retrieve 1998 // the stored error (if any) from TunnelConfig. 1999 IwlanError iwlanError; 2000 if (sessionClosedData.mIkeException != null) { 2001 iwlanError = 2002 getErrorFromIkeException( 2003 sessionClosedData.mIkeException, 2004 tunnelConfig.getIkeSessionState()); 2005 } else { 2006 // If IKE session opened, then closed before child session (and IWLAN 2007 // tunnel) opened. 2008 // Iwlan reports IKE_SESSION_CLOSED_BEFORE_CHILD_SESSION_OPENED 2009 // instead of NO_ERROR 2010 if (!tunnelConfig.hasTunnelOpened()) { 2011 iwlanError = new IwlanError( 2012 IwlanError.IKE_SESSION_CLOSED_BEFORE_CHILD_SESSION_OPENED); 2013 } else { 2014 iwlanError = tunnelConfig.getError(); 2015 } 2016 } 2017 2018 IpSecManager.IpSecTunnelInterface iface = tunnelConfig.getIface(); 2019 if (iface != null) { 2020 iface.close(); 2021 } 2022 2023 if (!tunnelConfig.hasTunnelOpened()) { 2024 if (tunnelConfig.isBackoffTimeValid()) { 2025 reportIwlanError(apnName, iwlanError, tunnelConfig.getBackoffTime()); 2026 } else { 2027 reportIwlanError(apnName, iwlanError); 2028 } 2029 mEpdgMonitor.onEpdgConnectionFailed( 2030 tunnelConfig.isEmergency(), tunnelConfig.getEpdgAddress()); 2031 getEpdgSelector().onEpdgConnectionFailed(tunnelConfig.getEpdgAddress()); 2032 } 2033 2034 Log.d(TAG, "Tunnel Closed: " + iwlanError); 2035 tunnelConfig.setIkeSessionState(IkeSessionState.NO_IKE_SESSION); 2036 tunnelConfig.getTunnelCallback().onClosed(apnName, iwlanError); 2037 onClosedMetricsBuilder = new OnClosedMetrics.Builder().setApnName(apnName); 2038 2039 if (!mEpdgMonitor.hasEpdgConnected()) { 2040 failAllPendingRequests(iwlanError); 2041 tunnelConfig.getTunnelMetrics().onClosed(onClosedMetricsBuilder.build()); 2042 } else { 2043 mIkeTunnelEstablishmentDuration = 2044 mIkeTunnelEstablishmentStartTime > 0 2045 ? System.currentTimeMillis() 2046 - mIkeTunnelEstablishmentStartTime 2047 : 0; 2048 mIkeTunnelEstablishmentStartTime = 0; 2049 2050 connectivityManager = mContext.getSystemService(ConnectivityManager.class); 2051 networkCapabilities = 2052 connectivityManager.getNetworkCapabilities(mIkeSessionNetwork); 2053 isNetworkValidated = 2054 (networkCapabilities != null) 2055 && networkCapabilities.hasCapability( 2056 NetworkCapabilities.NET_CAPABILITY_VALIDATED); 2057 onClosedMetricsBuilder 2058 .setEpdgServerAddress(tunnelConfig.getEpdgAddress()) 2059 .setEpdgServerSelectionDuration((int) mEpdgServerSelectionDuration) 2060 .setIkeTunnelEstablishmentDuration( 2061 (int) mIkeTunnelEstablishmentDuration) 2062 .setIsNetworkValidated(isNetworkValidated); 2063 tunnelConfig.getTunnelMetrics().onClosed(onClosedMetricsBuilder.build()); 2064 } 2065 2066 mApnNameToTunnelConfig.remove(apnName); 2067 mEpdgMonitor.onApnDisconnectFromEpdg(apnName); 2068 if (mApnNameToTunnelConfig.isEmpty() && mPendingBringUpRequests.isEmpty()) { 2069 onConnectedToEpdg(false); 2070 } 2071 break; 2072 2073 case EVENT_UPDATE_NETWORK: 2074 UpdateNetworkWrapper updatedNetwork = (UpdateNetworkWrapper) msg.obj; 2075 mDefaultNetwork = updatedNetwork.getNetwork(); 2076 LinkProperties defaultLinkProperties = updatedNetwork.getLinkProperties(); 2077 String paraString = "Network: " + mDefaultNetwork; 2078 2079 if (mEpdgMonitor.hasEpdgConnected()) { 2080 if (Objects.isNull(mDefaultNetwork)) { 2081 Log.w(TAG, "The default network has been removed."); 2082 } else if (Objects.isNull(defaultLinkProperties)) { 2083 Log.w( 2084 TAG, 2085 "The default network's LinkProperties is not ready ." 2086 + paraString); 2087 } else if (Objects.equals(mDefaultNetwork, mIkeSessionNetwork)) { 2088 Log.w( 2089 TAG, 2090 "The default network has not changed from the IKE session" 2091 + " network. " 2092 + paraString); 2093 } else { 2094 for (var entry : mApnNameToTunnelConfig.entrySet()) { 2095 String apn = entry.getKey(); 2096 TunnelConfig config = entry.getValue(); 2097 if (!defaultLinkProperties.isReachable(config.getEpdgAddress())) { 2098 Log.w( 2099 TAG, 2100 "The default network link " 2101 + defaultLinkProperties 2102 + " doesn't have a route to the ePDG " 2103 + config.getEpdgAddress() 2104 + paraString); 2105 } else { 2106 Log.d( 2107 TAG, 2108 "The Underlying Network is updating for APN (+" 2109 + apn 2110 + "). " 2111 + paraString); 2112 config.getIkeSession().setNetwork(mDefaultNetwork); 2113 config.setIkeSessionState( 2114 IkeSessionState.IKE_MOBILITY_IN_PROGRESS); 2115 mIkeSessionNetwork = mDefaultNetwork; 2116 } 2117 } 2118 } 2119 } 2120 break; 2121 2122 case EVENT_TUNNEL_BRINGDOWN_REQUEST: 2123 TunnelBringdownRequest bringdownRequest = (TunnelBringdownRequest) msg.obj; 2124 apnName = bringdownRequest.mApnName; 2125 boolean forceClose = bringdownRequest.mForceClose; 2126 int reason = bringdownRequest.mBringDownReason; 2127 tunnelConfig = mApnNameToTunnelConfig.get(apnName); 2128 if (tunnelConfig == null) { 2129 Log.w( 2130 TAG, 2131 "Bringdown request: No tunnel exists for apn: " 2132 + apnName 2133 + ", forced: " 2134 + forceClose 2135 + ", bringdown reason: " 2136 + bringdownReasonToString(reason)); 2137 } else { 2138 if (forceClose) { 2139 tunnelConfig.getIkeSession().kill(); 2140 } else { 2141 tunnelConfig.getIkeSession().close(); 2142 } 2143 } 2144 // TODO(b/309867892): Include tunnel bring down reason in metrics. 2145 int numClosed = closePendingRequestsForApn(apnName); 2146 if (numClosed > 0) { 2147 Log.d( 2148 TAG, 2149 "Closed " 2150 + numClosed 2151 + " pending requests for apn: " 2152 + apnName 2153 + ", bringdown reason: " 2154 + bringdownReasonToString(reason)); 2155 } 2156 if (tunnelConfig == null && numClosed == 0) { 2157 // IwlanDataService expected to close a (pending or up) tunnel but was not 2158 // found. Recovers state in IwlanDataService through TunnelCallback. 2159 iwlanError = new IwlanError(IwlanError.TUNNEL_NOT_FOUND); 2160 reportIwlanError(apnName, iwlanError); 2161 bringdownRequest.mTunnelCallback.onClosed(apnName, iwlanError); 2162 bringdownRequest.mIwlanTunnelMetrics.onClosed( 2163 new OnClosedMetrics.Builder().setApnName(apnName).build()); 2164 } 2165 break; 2166 2167 case EVENT_IPSEC_TRANSFORM_CREATED: 2168 IpsecTransformData transformData = (IpsecTransformData) msg.obj; 2169 apnName = transformData.getApnName(); 2170 tunnelConfig = mApnNameToTunnelConfig.get(apnName); 2171 2172 try { 2173 mIpSecManager.applyTunnelModeTransform( 2174 tunnelConfig.getIface(), 2175 transformData.getDirection(), 2176 transformData.getTransform()); 2177 } catch (IOException | IllegalArgumentException e) { 2178 // If the IKE session was closed before the transform could be applied, the 2179 // IpSecService will throw an IAE on processing the IpSecTunnelInterface id. 2180 Log.e(TAG, "Failed to apply tunnel transform." + e); 2181 closeIkeSession( 2182 apnName, new IwlanError(IwlanError.TUNNEL_TRANSFORM_FAILED)); 2183 } 2184 if (tunnelConfig.getIkeSessionState() 2185 == IkeSessionState.IKE_MOBILITY_IN_PROGRESS) { 2186 tunnelConfig.setIkeSessionState(IkeSessionState.CHILD_SESSION_OPENED); 2187 } 2188 break; 2189 2190 case EVENT_IPSEC_TRANSFORM_DELETED: 2191 transformData = (IpsecTransformData) msg.obj; 2192 IpSecTransform transform = transformData.getTransform(); 2193 transform.close(); 2194 break; 2195 2196 case EVENT_CHILD_SESSION_CLOSED: 2197 sessionClosedData = (SessionClosedData) msg.obj; 2198 apnName = sessionClosedData.mApnName; 2199 2200 tunnelConfig = mApnNameToTunnelConfig.get(apnName); 2201 if (tunnelConfig == null) { 2202 Log.d(TAG, "No tunnel callback for apn: " + apnName); 2203 return; 2204 } 2205 if (sessionClosedData.mIkeException != null) { 2206 tunnelConfig.setError( 2207 getErrorFromIkeException( 2208 sessionClosedData.mIkeException, 2209 tunnelConfig.getIkeSessionState())); 2210 } 2211 tunnelConfig.getIkeSession().close(); 2212 break; 2213 2214 case EVENT_IKE_SESSION_OPENED: 2215 IkeSessionOpenedData ikeSessionOpenedData = (IkeSessionOpenedData) msg.obj; 2216 apnName = ikeSessionOpenedData.mApnName; 2217 IkeSessionConfiguration sessionConfiguration = 2218 ikeSessionOpenedData.mIkeSessionConfiguration; 2219 2220 tunnelConfig = mApnNameToTunnelConfig.get(apnName); 2221 tunnelConfig.setPcscfAddrList(sessionConfiguration.getPcscfServers()); 2222 2223 boolean enabledFastReauth = 2224 IwlanCarrierConfig.getConfigBoolean( 2225 mContext, 2226 mSlotId, 2227 CarrierConfigManager.Iwlan 2228 .KEY_SUPPORTS_EAP_AKA_FAST_REAUTH_BOOL); 2229 Log.d( 2230 TAG, 2231 "CarrierConfigManager.Iwlan.KEY_SUPPORTS_EAP_AKA_FAST_REAUTH_BOOL " 2232 + enabledFastReauth); 2233 2234 if (enabledFastReauth) { 2235 EapInfo eapInfo = sessionConfiguration.getEapInfo(); 2236 if (eapInfo instanceof EapAkaInfo) { 2237 mNextReauthId = ((EapAkaInfo) eapInfo).getReauthId(); 2238 Log.d(TAG, "Update ReauthId: " + Arrays.toString(mNextReauthId)); 2239 } else { 2240 mNextReauthId = null; 2241 } 2242 } 2243 break; 2244 2245 case EVENT_IKE_SESSION_CONNECTION_INFO_CHANGED: 2246 IkeSessionConnectionInfoData ikeSessionConnectionInfoData = 2247 (IkeSessionConnectionInfoData) msg.obj; 2248 Network network = 2249 ikeSessionConnectionInfoData.mIkeSessionConnectionInfo.getNetwork(); 2250 apnName = ikeSessionConnectionInfoData.mApnName; 2251 2252 connectivityManager = mContext.getSystemService(ConnectivityManager.class); 2253 if (Objects.requireNonNull(connectivityManager).getLinkProperties(network) 2254 == null) { 2255 Log.e(TAG, "Network " + network + " has null LinkProperties!"); 2256 return; 2257 } 2258 2259 tunnelConfig = mApnNameToTunnelConfig.get(apnName); 2260 tunnelInterface = tunnelConfig.getIface(); 2261 try { 2262 tunnelInterface.setUnderlyingNetwork(network); 2263 } catch (IOException | IllegalArgumentException e) { 2264 Log.e( 2265 TAG, 2266 "Failed to update underlying network for apn: " 2267 + apnName 2268 + " exception: " 2269 + e); 2270 } 2271 break; 2272 2273 case EVENT_IKE_3GPP_DATA_RECEIVED: 2274 Ike3gppDataReceived ike3gppDataReceived = (Ike3gppDataReceived) msg.obj; 2275 apnName = ike3gppDataReceived.mApnName; 2276 List<Ike3gppData> ike3gppData = ike3gppDataReceived.mIke3gppData; 2277 if (ike3gppData != null && !ike3gppData.isEmpty()) { 2278 tunnelConfig = mApnNameToTunnelConfig.get(apnName); 2279 for (Ike3gppData payload : ike3gppData) { 2280 if (payload.getDataType() == DATA_TYPE_NOTIFY_N1_MODE_INFORMATION) { 2281 Log.d(TAG, "Got payload DATA_TYPE_NOTIFY_N1_MODE_INFORMATION"); 2282 NetworkSliceInfo si = 2283 NetworkSliceSelectionAssistanceInformation.getSliceInfo( 2284 ((Ike3gppN1ModeInformation) payload).getSnssai()); 2285 if (si != null) { 2286 tunnelConfig.setSliceInfo(si); 2287 Log.d(TAG, "SliceInfo: " + si); 2288 } 2289 } else if (payload.getDataType() == DATA_TYPE_NOTIFY_BACKOFF_TIMER) { 2290 Log.d(TAG, "Got payload DATA_TYPE_NOTIFY_BACKOFF_TIMER"); 2291 long backoffTime = 2292 decodeBackoffTime( 2293 ((Ike3gppBackoffTimer) payload).getBackoffTimer()); 2294 if (backoffTime > 0) { 2295 tunnelConfig.setBackoffTime(backoffTime); 2296 Log.d(TAG, "Backoff Timer: " + backoffTime); 2297 } 2298 } 2299 } 2300 } else { 2301 Log.e(TAG, "Null or empty payloads received:"); 2302 } 2303 break; 2304 2305 case EVENT_IKE_LIVENESS_STATUS_CHANGED: 2306 IkeSessionValidationStatusData ikeLivenessData = 2307 (IkeSessionValidationStatusData) msg.obj; 2308 @NetworkValidationStatus int validationStatus = ikeLivenessData.mStatus; 2309 apnName = ikeLivenessData.mApnName; 2310 tunnelConfig = mApnNameToTunnelConfig.get(apnName); 2311 if (tunnelConfig == null) { 2312 Log.e(TAG, "No tunnel config found for apn: " + apnName); 2313 return; 2314 } 2315 tunnelConfig 2316 .getTunnelCallback() 2317 .onNetworkValidationStatusChanged(apnName, validationStatus); 2318 break; 2319 2320 case EVENT_REQUEST_NETWORK_VALIDATION_CHECK: 2321 apnName = (String) msg.obj; 2322 tunnelConfig = mApnNameToTunnelConfig.get(apnName); 2323 if (tunnelConfig == null) { 2324 Log.e(TAG, "No tunnel config found for apn: " + apnName); 2325 return; 2326 } 2327 tunnelConfig.getIkeSession().requestLivenessCheck(); 2328 break; 2329 2330 default: 2331 throw new IllegalStateException("Unexpected value: " + msg.what); 2332 } 2333 } 2334 handleTunnelBringUpRequest(TunnelRequestWrapper tunnelRequestWrapper)2335 private void handleTunnelBringUpRequest(TunnelRequestWrapper tunnelRequestWrapper) { 2336 TunnelSetupRequest setupRequest = tunnelRequestWrapper.getSetupRequest(); 2337 String apnName = setupRequest.apnName(); 2338 OnClosedMetrics.Builder onClosedMetricsBuilder = 2339 new OnClosedMetrics.Builder().setApnName(apnName); 2340 2341 IwlanError bringUpError = canBringUpTunnel(apnName, setupRequest.isEmergency()); 2342 if (Objects.nonNull(bringUpError)) { 2343 tunnelRequestWrapper.getTunnelCallback().onClosed(apnName, bringUpError); 2344 tunnelRequestWrapper.getTunnelMetrics().onClosed(onClosedMetricsBuilder.build()); 2345 return; 2346 } 2347 serviceTunnelBringUpRequest(tunnelRequestWrapper); 2348 } 2349 serviceTunnelBringUpRequest(TunnelRequestWrapper tunnelRequestWrapper)2350 private void serviceTunnelBringUpRequest(TunnelRequestWrapper tunnelRequestWrapper) { 2351 if (mEpdgMonitor.hasEpdgConnected()) { 2352 InetAddress epdgAddress = selectConnectedEpdgForTunnelBringUp(tunnelRequestWrapper); 2353 if (epdgAddress != null) { 2354 onBringUpTunnel(tunnelRequestWrapper, epdgAddress); 2355 return; 2356 } 2357 } 2358 2359 if (!isEpdgSelectionOrFirstTunnelBringUpInProgress()) { 2360 // No tunnel bring-up in progress Or emergency request has attempted ePDG for normal 2361 // session but failed, select the ePDG address. 2362 selectEpdgAddress(tunnelRequestWrapper.getSetupRequest()); 2363 } 2364 2365 // Another bring-up or ePDG selection is in progress, pending this request. 2366 mPendingBringUpRequests.add(tunnelRequestWrapper); 2367 } 2368 selectConnectedEpdgForTunnelBringUp( TunnelRequestWrapper tunnelRequestWrapper)2369 private InetAddress selectConnectedEpdgForTunnelBringUp( 2370 TunnelRequestWrapper tunnelRequestWrapper) { 2371 if (!mFeatureFlags.distinctEpdgSelectionForEmergencySessions() 2372 || !IwlanCarrierConfig.getConfigBoolean( 2373 mContext, 2374 mSlotId, 2375 IwlanCarrierConfig.KEY_DISTINCT_EPDG_FOR_EMERGENCY_ALLOWED_BOOL)) { 2376 // Attempt on ePDG for normal session since feature not enabled 2377 return mEpdgMonitor.getEpdgAddressForNormalSession(); 2378 } 2379 2380 if (!tunnelRequestWrapper.getSetupRequest().isEmergency()) { 2381 if (mEpdgMonitor.hasSeparateEpdgConnectedForEmergencySession()) { 2382 // Attempt on ePDG for emergency session 2383 return mEpdgMonitor.getEpdgAddressForEmergencySession(); 2384 } else { 2385 // Attempt on ePDG for normal session. 2386 return mEpdgMonitor.getEpdgAddressForNormalSession(); 2387 } 2388 } 2389 2390 if (!mEpdgMonitor.hasEmergencyPdnFailedWithConnectedEpdg()) { 2391 // First emergnecy attempt on ePDG for normal session. 2392 return mEpdgMonitor.getEpdgAddressForNormalSession(); 2393 } 2394 return null; // no suitable ePDG address found. Select new ePDG address needed. 2395 } 2396 TmHandler(Looper looper)2397 TmHandler(Looper looper) { 2398 super(looper); 2399 } 2400 } 2401 closeIkeSession(String apnName, IwlanError error)2402 private void closeIkeSession(String apnName, IwlanError error) { 2403 TunnelConfig tunnelConfig = mApnNameToTunnelConfig.get(apnName); 2404 tunnelConfig.setError(error); 2405 tunnelConfig.getIkeSession().close(); 2406 } 2407 selectEpdgAddress(TunnelSetupRequest setupRequest)2408 private void selectEpdgAddress(TunnelSetupRequest setupRequest) { 2409 ++mTransactionId; 2410 mEpdgServerSelectionStartTime = System.currentTimeMillis(); 2411 2412 final int ipPreference = 2413 IwlanCarrierConfig.getConfigInt( 2414 mContext, 2415 mSlotId, 2416 CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_IP_TYPE_PREFERENCE_INT); 2417 2418 IpPreferenceConflict ipPreferenceConflict = 2419 isIpPreferenceConflictsWithNetwork(ipPreference); 2420 if (ipPreferenceConflict.mIsConflict) { 2421 sendSelectionRequestComplete( 2422 null, new IwlanError(ipPreferenceConflict.mErrorType), mTransactionId); 2423 return; 2424 } 2425 2426 int protoFilter = EpdgSelector.PROTO_FILTER_IPV4V6; 2427 int epdgAddressOrder = EpdgSelector.SYSTEM_PREFERRED; 2428 switch (ipPreference) { 2429 case CarrierConfigManager.Iwlan.EPDG_ADDRESS_IPV4_PREFERRED: 2430 epdgAddressOrder = EpdgSelector.IPV4_PREFERRED; 2431 break; 2432 case CarrierConfigManager.Iwlan.EPDG_ADDRESS_IPV6_PREFERRED: 2433 epdgAddressOrder = EpdgSelector.IPV6_PREFERRED; 2434 break; 2435 case CarrierConfigManager.Iwlan.EPDG_ADDRESS_IPV4_ONLY: 2436 protoFilter = EpdgSelector.PROTO_FILTER_IPV4; 2437 break; 2438 case CarrierConfigManager.Iwlan.EPDG_ADDRESS_IPV6_ONLY: 2439 protoFilter = EpdgSelector.PROTO_FILTER_IPV6; 2440 break; 2441 case CarrierConfigManager.Iwlan.EPDG_ADDRESS_SYSTEM_PREFERRED: 2442 break; 2443 default: 2444 Log.w(TAG, "Invalid Ip preference : " + ipPreference); 2445 } 2446 2447 EpdgSelector epdgSelector = getEpdgSelector(); 2448 IwlanError epdgError = 2449 epdgSelector.getValidatedServerList( 2450 mTransactionId, 2451 protoFilter, 2452 epdgAddressOrder, 2453 setupRequest.isRoaming(), 2454 setupRequest.isEmergency(), 2455 mDefaultNetwork, 2456 mSelectorCallback); 2457 2458 if (epdgError.getErrorType() != IwlanError.NO_ERROR) { 2459 Log.e(TAG, "Epdg address selection failed with error:" + epdgError); 2460 sendSelectionRequestComplete(null, epdgError, mTransactionId); 2461 } 2462 } 2463 2464 @VisibleForTesting getEpdgSelector()2465 EpdgSelector getEpdgSelector() { 2466 return EpdgSelector.getSelectorInstance(mContext, mSlotId); 2467 } 2468 2469 @VisibleForTesting closePendingRequestsForApn(String apnName)2470 int closePendingRequestsForApn(String apnName) { 2471 int numRequestsClosed = 0; 2472 int queueSize = mPendingBringUpRequests.size(); 2473 if (queueSize == 0) { 2474 return numRequestsClosed; 2475 } 2476 2477 for (int count = 0; count < queueSize; count++) { 2478 TunnelRequestWrapper requestWrapper = mPendingBringUpRequests.remove(); 2479 if (requestWrapper.getSetupRequest().apnName().equals(apnName)) { 2480 requestWrapper 2481 .getTunnelCallback() 2482 .onClosed(apnName, new IwlanError(IwlanError.NO_ERROR)); 2483 requestWrapper 2484 .getTunnelMetrics() 2485 .onClosed( 2486 new OnClosedMetrics.Builder() 2487 .setApnName(apnName) 2488 .setEpdgServerAddress(null) 2489 .build()); 2490 numRequestsClosed++; 2491 } else { 2492 mPendingBringUpRequests.add(requestWrapper); 2493 } 2494 } 2495 return numRequestsClosed; 2496 } 2497 validateAndSetEpdgAddressLegacy(List<InetAddress> selectorResultList)2498 InetAddress validateAndSetEpdgAddressLegacy(List<InetAddress> selectorResultList) { 2499 List<InetAddress> addrList = mValidEpdgInfo.getAddrList(); 2500 if (addrList == null || !addrList.equals(selectorResultList)) { 2501 Log.d(TAG, "Update ePDG address list."); 2502 mValidEpdgInfo.setAddrList(selectorResultList); 2503 addrList = mValidEpdgInfo.getAddrList(); 2504 } 2505 2506 int index = mValidEpdgInfo.getIndex(); 2507 Log.d( 2508 TAG, 2509 "Valid ePDG Address List: " 2510 + Arrays.toString(addrList.toArray()) 2511 + ", index = " 2512 + index); 2513 mValidEpdgInfo.incrementIndex(); 2514 return addrList.get(index); 2515 } 2516 2517 @VisibleForTesting validateAndSetEpdgAddress(List<InetAddress> selectorResultList)2518 InetAddress validateAndSetEpdgAddress(List<InetAddress> selectorResultList) { 2519 if (!mFeatureFlags.epdgSelectionExcludeFailedIpAddress()) { 2520 return validateAndSetEpdgAddressLegacy(selectorResultList); 2521 } 2522 2523 if (mEpdgMonitor.hasEmergencyPdnFailedWithConnectedEpdg() 2524 && selectorResultList 2525 .get(0) 2526 .equals(mEpdgMonitor.getEpdgAddressForNormalSession())) { 2527 List<InetAddress> sublist = selectorResultList.subList(1, selectorResultList.size()); 2528 Log.d( 2529 TAG, 2530 "Selected separate ePDG address for emergency session " 2531 + sublist.get(0) 2532 + " from available ePDG address list: " 2533 + Arrays.toString(selectorResultList.toArray())); 2534 mValidEpdgInfo.setAddrList(sublist); 2535 return sublist.get(0); 2536 } 2537 2538 Log.d( 2539 TAG, 2540 "Selected first ePDG address " 2541 + selectorResultList.get(0) 2542 + " from available ePDG address list: " 2543 + Arrays.toString(selectorResultList.toArray())); 2544 mValidEpdgInfo.setAddrList(selectorResultList); 2545 return selectorResultList.get(0); 2546 } 2547 serviceAllPendingRequests()2548 private void serviceAllPendingRequests() { 2549 while (!mPendingBringUpRequests.isEmpty()) { 2550 Log.d(TAG, "serviceAllPendingRequests"); 2551 TunnelRequestWrapper requestWrapper = mPendingBringUpRequests.remove(); 2552 onBringUpTunnel(requestWrapper, mEpdgMonitor.getEpdgAddressForNormalSession()); 2553 } 2554 } 2555 failAllPendingRequests(IwlanError error)2556 private void failAllPendingRequests(IwlanError error) { 2557 while (!mPendingBringUpRequests.isEmpty()) { 2558 Log.d(TAG, "failAllPendingRequests"); 2559 TunnelRequestWrapper request = mPendingBringUpRequests.remove(); 2560 TunnelSetupRequest setupRequest = request.getSetupRequest(); 2561 String apnName = setupRequest.apnName(); 2562 reportIwlanError(apnName, error); 2563 request.getTunnelCallback().onClosed(apnName, error); 2564 request.getTunnelMetrics() 2565 .onClosed( 2566 new OnClosedMetrics.Builder() 2567 .setApnName(apnName) 2568 .setEpdgServerAddress(null) 2569 .build()); 2570 } 2571 } 2572 2573 // Prints mPendingBringUpRequests printRequestQueue(String info)2574 private void printRequestQueue(String info) { 2575 Log.d(TAG, info); 2576 Log.d( 2577 TAG, 2578 "mPendingBringUpRequests: " + Arrays.toString(mPendingBringUpRequests.toArray())); 2579 } 2580 2581 // Update Network wrapper 2582 private static final class UpdateNetworkWrapper { 2583 private final Network mNetwork; 2584 private final LinkProperties mLinkProperties; 2585 UpdateNetworkWrapper(Network network, LinkProperties linkProperties)2586 private UpdateNetworkWrapper(Network network, LinkProperties linkProperties) { 2587 mNetwork = network; 2588 mLinkProperties = linkProperties; 2589 } 2590 getNetwork()2591 public Network getNetwork() { 2592 return mNetwork; 2593 } 2594 getLinkProperties()2595 public LinkProperties getLinkProperties() { 2596 return mLinkProperties; 2597 } 2598 } 2599 2600 // Tunnel request + tunnel callback 2601 private static final class TunnelRequestWrapper { 2602 private final TunnelSetupRequest mSetupRequest; 2603 private final TunnelCallback mTunnelCallback; 2604 private final TunnelMetricsInterface mTunnelMetrics; 2605 TunnelRequestWrapper( TunnelSetupRequest setupRequest, TunnelCallback tunnelCallback, TunnelMetricsInterface tunnelMetrics)2606 private TunnelRequestWrapper( 2607 TunnelSetupRequest setupRequest, 2608 TunnelCallback tunnelCallback, 2609 TunnelMetricsInterface tunnelMetrics) { 2610 mTunnelCallback = tunnelCallback; 2611 mSetupRequest = setupRequest; 2612 mTunnelMetrics = tunnelMetrics; 2613 } 2614 getSetupRequest()2615 public TunnelSetupRequest getSetupRequest() { 2616 return mSetupRequest; 2617 } 2618 getTunnelCallback()2619 public TunnelCallback getTunnelCallback() { 2620 return mTunnelCallback; 2621 } 2622 getTunnelMetrics()2623 public TunnelMetricsInterface getTunnelMetrics() { 2624 return mTunnelMetrics; 2625 } 2626 } 2627 2628 private static final class TunnelBringdownRequest { 2629 final String mApnName; 2630 final boolean mForceClose; 2631 final TunnelCallback mTunnelCallback; 2632 final IwlanTunnelMetricsImpl mIwlanTunnelMetrics; 2633 final int mBringDownReason; 2634 TunnelBringdownRequest( String apnName, boolean forceClose, TunnelCallback tunnelCallback, IwlanTunnelMetricsImpl iwlanTunnelMetrics, @TunnelBringDownReason int reason)2635 private TunnelBringdownRequest( 2636 String apnName, 2637 boolean forceClose, 2638 TunnelCallback tunnelCallback, 2639 IwlanTunnelMetricsImpl iwlanTunnelMetrics, 2640 @TunnelBringDownReason int reason) { 2641 mApnName = apnName; 2642 mForceClose = forceClose; 2643 mTunnelCallback = tunnelCallback; 2644 mIwlanTunnelMetrics = iwlanTunnelMetrics; 2645 mBringDownReason = reason; 2646 } 2647 } 2648 2649 private static final class EpdgSelectorResult { 2650 private final List<InetAddress> mValidIpList; 2651 getValidIpList()2652 public List<InetAddress> getValidIpList() { 2653 return mValidIpList; 2654 } 2655 getEpdgError()2656 public IwlanError getEpdgError() { 2657 return mEpdgError; 2658 } 2659 getTransactionId()2660 public int getTransactionId() { 2661 return mTransactionId; 2662 } 2663 2664 private final IwlanError mEpdgError; 2665 private final int mTransactionId; 2666 EpdgSelectorResult( List<InetAddress> validIpList, IwlanError epdgError, int transactionId)2667 private EpdgSelectorResult( 2668 List<InetAddress> validIpList, IwlanError epdgError, int transactionId) { 2669 mValidIpList = validIpList; 2670 mEpdgError = epdgError; 2671 mTransactionId = transactionId; 2672 } 2673 } 2674 2675 // Data received from IkeSessionStateMachine on successful EVENT_CHILD_SESSION_OPENED. 2676 private static final class TunnelOpenedData extends IkeEventData { 2677 final List<InetAddress> mInternalDnsServers; 2678 final List<LinkAddress> mInternalAddresses; 2679 TunnelOpenedData( String apnName, int token, List<InetAddress> internalDnsServers, List<LinkAddress> internalAddresses)2680 private TunnelOpenedData( 2681 String apnName, 2682 int token, 2683 List<InetAddress> internalDnsServers, 2684 List<LinkAddress> internalAddresses) { 2685 super(apnName, token); 2686 mInternalDnsServers = internalDnsServers; 2687 mInternalAddresses = internalAddresses; 2688 } 2689 } 2690 2691 // Data received from IkeSessionStateMachine on successful EVENT_IKE_SESSION_OPENED. 2692 private static final class IkeSessionOpenedData extends IkeEventData { 2693 final IkeSessionConfiguration mIkeSessionConfiguration; 2694 IkeSessionOpenedData( String apnName, int token, IkeSessionConfiguration ikeSessionConfiguration)2695 private IkeSessionOpenedData( 2696 String apnName, int token, IkeSessionConfiguration ikeSessionConfiguration) { 2697 super(apnName, token); 2698 mIkeSessionConfiguration = ikeSessionConfiguration; 2699 } 2700 } 2701 2702 private static final class IkeSessionConnectionInfoData extends IkeEventData { 2703 final IkeSessionConnectionInfo mIkeSessionConnectionInfo; 2704 IkeSessionConnectionInfoData( String apnName, int token, IkeSessionConnectionInfo ikeSessionConnectionInfo)2705 private IkeSessionConnectionInfoData( 2706 String apnName, int token, IkeSessionConnectionInfo ikeSessionConnectionInfo) { 2707 super(apnName, token); 2708 mIkeSessionConnectionInfo = ikeSessionConnectionInfo; 2709 } 2710 } 2711 2712 private static final class Ike3gppDataReceived extends IkeEventData { 2713 final List<Ike3gppData> mIke3gppData; 2714 Ike3gppDataReceived(String apnName, int token, List<Ike3gppData> ike3gppData)2715 private Ike3gppDataReceived(String apnName, int token, List<Ike3gppData> ike3gppData) { 2716 super(apnName, token); 2717 mIke3gppData = ike3gppData; 2718 } 2719 } 2720 2721 // Data received from IkeSessionStateMachine if either IKE session or Child session have been 2722 // closed, normally or exceptionally. 2723 private static final class SessionClosedData extends IkeEventData { 2724 final IkeException mIkeException; 2725 SessionClosedData(String apnName, int token, IkeException ikeException)2726 private SessionClosedData(String apnName, int token, IkeException ikeException) { 2727 super(apnName, token); 2728 mIkeException = ikeException; 2729 } 2730 } 2731 2732 private static final class IkeSessionValidationStatusData extends IkeEventData { 2733 @NetworkValidationStatus final int mStatus; 2734 IkeSessionValidationStatusData(String apnName, int token, int status)2735 private IkeSessionValidationStatusData(String apnName, int token, int status) { 2736 super(apnName, token); 2737 mStatus = status; 2738 } 2739 } 2740 2741 private static final class IpsecTransformData extends IkeEventData { 2742 private final IpSecTransform mTransform; 2743 private final int mDirection; 2744 IpsecTransformData( IpSecTransform transform, int direction, String apnName, int token)2745 private IpsecTransformData( 2746 IpSecTransform transform, int direction, String apnName, int token) { 2747 super(apnName, token); 2748 mTransform = transform; 2749 mDirection = direction; 2750 } 2751 getTransform()2752 public IpSecTransform getTransform() { 2753 return mTransform; 2754 } 2755 getDirection()2756 public int getDirection() { 2757 return mDirection; 2758 } 2759 getApnName()2760 public String getApnName() { 2761 return super.mApnName; 2762 } 2763 } 2764 2765 private abstract static class IkeEventData { 2766 final String mApnName; 2767 final int mToken; 2768 IkeEventData(String apnName, int token)2769 private IkeEventData(String apnName, int token) { 2770 mApnName = apnName; 2771 mToken = token; 2772 } 2773 } 2774 2775 private static final class EpdgInfo { 2776 private List<InetAddress> mAddrList; 2777 private int mIndex; 2778 EpdgInfo()2779 private EpdgInfo() { 2780 mAddrList = null; 2781 mIndex = 0; 2782 } 2783 getAddrList()2784 public List<InetAddress> getAddrList() { 2785 return mAddrList; 2786 } 2787 setAddrList(@onNull List<InetAddress> AddrList)2788 public void setAddrList(@NonNull List<InetAddress> AddrList) { 2789 mAddrList = AddrList; 2790 resetIndex(); 2791 } 2792 getIndex()2793 public int getIndex() { 2794 return mIndex; 2795 } 2796 incrementIndex()2797 public void incrementIndex() { 2798 if (getIndex() >= getAddrList().size() - 1) { 2799 resetIndex(); 2800 } else { 2801 mIndex++; 2802 } 2803 } 2804 resetIndex()2805 public void resetIndex() { 2806 mIndex = 0; 2807 } 2808 } 2809 2810 private static class IpPreferenceConflict { 2811 final boolean mIsConflict; 2812 final int mErrorType; 2813 IpPreferenceConflict(boolean isConflict, int errorType)2814 private IpPreferenceConflict(boolean isConflict, int errorType) { 2815 mIsConflict = isConflict; 2816 mErrorType = errorType; 2817 } 2818 IpPreferenceConflict()2819 private IpPreferenceConflict() { 2820 mIsConflict = false; 2821 mErrorType = IwlanError.NO_ERROR; 2822 } 2823 } 2824 getRetransmissionTimeoutsFromConfig()2825 private int[] getRetransmissionTimeoutsFromConfig() { 2826 int[] timeList = 2827 IwlanCarrierConfig.getConfigIntArray( 2828 mContext, 2829 mSlotId, 2830 CarrierConfigManager.Iwlan.KEY_RETRANSMIT_TIMER_MSEC_INT_ARRAY); 2831 boolean isValid = 2832 timeList != null 2833 && timeList.length != 0 2834 && timeList.length <= IKE_RETRANS_MAX_ATTEMPTS_MAX; 2835 for (int time : Objects.requireNonNull(timeList)) { 2836 if (time < IKE_RETRANS_TIMEOUT_MS_MIN || time > IKE_RETRANS_TIMEOUT_MS_MAX) { 2837 isValid = false; 2838 break; 2839 } 2840 } 2841 if (!isValid) { 2842 timeList = 2843 IwlanCarrierConfig.getDefaultConfigIntArray( 2844 CarrierConfigManager.Iwlan.KEY_RETRANSMIT_TIMER_MSEC_INT_ARRAY); 2845 } 2846 Log.d(TAG, "getRetransmissionTimeoutsFromConfig: " + Arrays.toString(timeList)); 2847 return timeList; 2848 } 2849 getDpdDelayFromConfig()2850 private int getDpdDelayFromConfig() { 2851 int dpdDelay = 2852 IwlanCarrierConfig.getConfigInt( 2853 mContext, mSlotId, CarrierConfigManager.Iwlan.KEY_DPD_TIMER_SEC_INT); 2854 if (dpdDelay < IKE_DPD_DELAY_SEC_MIN || dpdDelay > IKE_DPD_DELAY_SEC_MAX) { 2855 dpdDelay = 2856 IwlanCarrierConfig.getDefaultConfigInt( 2857 CarrierConfigManager.Iwlan.KEY_DPD_TIMER_SEC_INT); 2858 } 2859 return dpdDelay; 2860 } 2861 2862 /** 2863 * Decodes backoff time as per TS 124 008 10.5.7.4a Bits 5 to 1 represent the binary coded timer 2864 * value 2865 * 2866 * <p>Bits 6 to 8 defines the timer value unit for the GPRS timer as follows: Bits 8 7 6 0 0 0 2867 * value is incremented in multiples of 10 minutes 0 0 1 value is incremented in multiples of 1 2868 * hour 0 1 0 value is incremented in multiples of 10 hours 0 1 1 value is incremented in 2869 * multiples of 2 seconds 1 0 0 value is incremented in multiples of 30 seconds 1 0 1 value is 2870 * incremented in multiples of 1 minute 1 1 0 value is incremented in multiples of 1 hour 1 1 1 2871 * value indicates that the timer is deactivated. 2872 * 2873 * @param backoffTimeByte Byte value obtained from ike 2874 * @return long time value in seconds. -1 if the timer needs to be deactivated. 2875 */ decodeBackoffTime(byte backoffTimeByte)2876 private static long decodeBackoffTime(byte backoffTimeByte) { 2877 final int BACKOFF_TIME_VALUE_MASK = 0x1F; 2878 final int BACKOFF_TIMER_UNIT_MASK = 0xE0; 2879 final Long[] BACKOFF_TIMER_UNIT_INCREMENT_SECS = { 2880 10L * 60L, // 10 minutes 2881 60L * 60L, // 1 hour 2882 10L * 60L * 60L, // 10 hours 2883 2L, // 2 seconds 2884 30L, // 30 seconds 2885 60L, // 1 minute 2886 60L * 60L, // 1 hour 2887 }; 2888 2889 long time = backoffTimeByte & BACKOFF_TIME_VALUE_MASK; 2890 int timerUnit = (backoffTimeByte & BACKOFF_TIMER_UNIT_MASK) >> 5; 2891 if (timerUnit >= BACKOFF_TIMER_UNIT_INCREMENT_SECS.length) { 2892 return -1; 2893 } 2894 time *= BACKOFF_TIMER_UNIT_INCREMENT_SECS[timerUnit]; 2895 return time; 2896 } 2897 2898 @VisibleForTesting getTunnelSetupRequestApnName(TunnelSetupRequest setupRequest)2899 String getTunnelSetupRequestApnName(TunnelSetupRequest setupRequest) { 2900 return setupRequest.apnName(); 2901 } 2902 2903 @VisibleForTesting putApnNameToTunnelConfig( String apnName, IkeSession ikeSession, TunnelCallback tunnelCallback, TunnelMetricsInterface tunnelMetrics, IpSecManager.IpSecTunnelInterface iface, InetAddress srcIpv6Addr, int srcIPv6AddrPrefixLen, boolean isEmergency, InetAddress epdgAddress)2904 void putApnNameToTunnelConfig( 2905 String apnName, 2906 IkeSession ikeSession, 2907 TunnelCallback tunnelCallback, 2908 TunnelMetricsInterface tunnelMetrics, 2909 IpSecManager.IpSecTunnelInterface iface, 2910 InetAddress srcIpv6Addr, 2911 int srcIPv6AddrPrefixLen, 2912 boolean isEmergency, 2913 InetAddress epdgAddress) { 2914 mApnNameToTunnelConfig.put( 2915 apnName, 2916 new TunnelConfig( 2917 ikeSession, 2918 tunnelCallback, 2919 tunnelMetrics, 2920 iface, 2921 srcIpv6Addr, 2922 srcIPv6AddrPrefixLen, 2923 isEmergency, 2924 epdgAddress)); 2925 Log.d(TAG, "Added APN: " + apnName + " to TunnelConfig"); 2926 } 2927 2928 @VisibleForTesting incrementAndGetCurrentTokenForApn(String apnName)2929 int incrementAndGetCurrentTokenForApn(String apnName) { 2930 final int currentToken = 2931 mApnNameToCurrentToken.compute( 2932 apnName, (apn, token) -> token == null ? 0 : token + 1); 2933 Log.d(TAG, "Added token: " + currentToken + " for apn: " + apnName); 2934 return currentToken; 2935 } 2936 2937 @VisibleForTesting isTunnelConfigContainExistApn(String apnName)2938 boolean isTunnelConfigContainExistApn(String apnName) { 2939 return mApnNameToTunnelConfig.containsKey(apnName); 2940 } 2941 2942 @VisibleForTesting getAddressForNetwork(Network network)2943 List<InetAddress> getAddressForNetwork(Network network) { 2944 return IwlanHelper.getAllAddressesForNetwork(mContext, network); 2945 } 2946 2947 @VisibleForTesting getIkeSessionCreator()2948 IkeSessionCreator getIkeSessionCreator() { 2949 return mIkeSessionCreator; 2950 } 2951 2952 @VisibleForTesting sendSelectionRequestComplete( List<InetAddress> validIPList, IwlanError result, int transactionId)2953 void sendSelectionRequestComplete( 2954 List<InetAddress> validIPList, IwlanError result, int transactionId) { 2955 mEpdgServerSelectionDuration = System.currentTimeMillis() - mEpdgServerSelectionStartTime; 2956 mEpdgServerSelectionStartTime = 0; 2957 EpdgSelectorResult epdgSelectorResult = 2958 new EpdgSelectorResult(validIPList, result, transactionId); 2959 mHandler.sendMessage( 2960 mHandler.obtainMessage( 2961 EVENT_EPDG_ADDRESS_SELECTION_REQUEST_COMPLETE, epdgSelectorResult)); 2962 } 2963 isValidApnProtocol(int proto)2964 static boolean isValidApnProtocol(int proto) { 2965 return (proto == ApnSetting.PROTOCOL_IP 2966 || proto == ApnSetting.PROTOCOL_IPV4V6 2967 || proto == ApnSetting.PROTOCOL_IPV6); 2968 } 2969 isObsoleteToken(String apnName, int token)2970 boolean isObsoleteToken(String apnName, int token) { 2971 if (!mApnNameToCurrentToken.containsKey(apnName)) { 2972 return true; 2973 } 2974 return token != mApnNameToCurrentToken.get(apnName); 2975 } 2976 eventToString(int event)2977 private static String eventToString(int event) { 2978 switch (event) { 2979 case EVENT_TUNNEL_BRINGUP_REQUEST: 2980 return "EVENT_TUNNEL_BRINGUP_REQUEST"; 2981 case EVENT_TUNNEL_BRINGDOWN_REQUEST: 2982 return "EVENT_TUNNEL_BRINGDOWN_REQUEST"; 2983 case EVENT_CHILD_SESSION_OPENED: 2984 return "EVENT_CHILD_SESSION_OPENED"; 2985 case EVENT_CHILD_SESSION_CLOSED: 2986 return "EVENT_CHILD_SESSION_CLOSED"; 2987 case EVENT_IKE_SESSION_CLOSED: 2988 return "EVENT_IKE_SESSION_CLOSED"; 2989 case EVENT_EPDG_ADDRESS_SELECTION_REQUEST_COMPLETE: 2990 return "EVENT_EPDG_ADDRESS_SELECTION_REQUEST_COMPLETE"; 2991 case EVENT_IPSEC_TRANSFORM_CREATED: 2992 return "EVENT_IPSEC_TRANSFORM_CREATED"; 2993 case EVENT_IPSEC_TRANSFORM_DELETED: 2994 return "EVENT_IPSEC_TRANSFORM_DELETED"; 2995 case EVENT_UPDATE_NETWORK: 2996 return "EVENT_UPDATE_NETWORK"; 2997 case EVENT_IKE_SESSION_OPENED: 2998 return "EVENT_IKE_SESSION_OPENED"; 2999 case EVENT_IKE_SESSION_CONNECTION_INFO_CHANGED: 3000 return "EVENT_IKE_SESSION_CONNECTION_INFO_CHANGED"; 3001 case EVENT_IKE_3GPP_DATA_RECEIVED: 3002 return "EVENT_IKE_3GPP_DATA_RECEIVED"; 3003 case EVENT_IKE_LIVENESS_STATUS_CHANGED: 3004 return "EVENT_IKE_LIVENESS_STATUS_CHANGED"; 3005 case EVENT_REQUEST_NETWORK_VALIDATION_CHECK: 3006 return "EVENT_REQUEST_NETWORK_VALIDATION_CHECK"; 3007 default: 3008 return "Unknown(" + event + ")"; 3009 } 3010 } 3011 3012 @VisibleForTesting getTmIkeSessionCallback(String apnName, int token)3013 TmIkeSessionCallback getTmIkeSessionCallback(String apnName, int token) { 3014 return new TmIkeSessionCallback(apnName, token); 3015 } 3016 3017 @VisibleForTesting onConnectedToEpdg(boolean hasConnected)3018 void onConnectedToEpdg(boolean hasConnected) { 3019 mHasConnectedToEpdg = hasConnected; 3020 if (mHasConnectedToEpdg) { 3021 mIkeSessionNetwork = mDefaultNetwork; 3022 } else { 3023 mIkeSessionNetwork = null; 3024 } 3025 } 3026 3027 @VisibleForTesting getTunnelConfigForApn(String apnName)3028 TunnelConfig getTunnelConfigForApn(String apnName) { 3029 return mApnNameToTunnelConfig.get(apnName); 3030 } 3031 3032 @VisibleForTesting getCurrentTokenForApn(String apnName)3033 int getCurrentTokenForApn(String apnName) { 3034 if (!mApnNameToCurrentToken.containsKey(apnName)) { 3035 throw new IllegalArgumentException("There is no token for apn: " + apnName); 3036 } 3037 return mApnNameToCurrentToken.get(apnName); 3038 } 3039 3040 @VisibleForTesting reportIwlanError(String apnName, IwlanError error)3041 long reportIwlanError(String apnName, IwlanError error) { 3042 return ErrorPolicyManager.getInstance(mContext, mSlotId).reportIwlanError(apnName, error); 3043 } 3044 3045 @VisibleForTesting reportIwlanError(String apnName, IwlanError error, long backOffTime)3046 long reportIwlanError(String apnName, IwlanError error, long backOffTime) { 3047 return ErrorPolicyManager.getInstance(mContext, mSlotId) 3048 .reportIwlanError(apnName, error, backOffTime); 3049 } 3050 3051 @VisibleForTesting getLastError(String apnName)3052 IwlanError getLastError(String apnName) { 3053 return ErrorPolicyManager.getInstance(mContext, mSlotId).getLastError(apnName); 3054 } 3055 3056 @VisibleForTesting canBringUpTunnel(String apnName, boolean isEmergency)3057 IwlanError canBringUpTunnel(String apnName, boolean isEmergency) { 3058 IwlanError bringUpError = null; 3059 if (IwlanHelper.getSubId(mContext, mSlotId) 3060 == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 3061 Log.e(TAG, "SIM isn't ready"); 3062 bringUpError = new IwlanError(IwlanError.SIM_NOT_READY_EXCEPTION); 3063 reportIwlanError(apnName, bringUpError); 3064 } else if (Objects.isNull(mDefaultNetwork)) { 3065 Log.e(TAG, "The default network is not ready"); 3066 bringUpError = new IwlanError(IwlanError.IKE_INTERNAL_IO_EXCEPTION); 3067 reportIwlanError(apnName, bringUpError); 3068 } else if (!isEmergency 3069 && !ErrorPolicyManager.getInstance(mContext, mSlotId).canBringUpTunnel(apnName)) { 3070 // TODO(b/343962773): Need to refactor emergency condition into ErrorPolicyManager 3071 Log.d(TAG, "Cannot bring up tunnel as retry time has not passed"); 3072 bringUpError = getLastError(apnName); 3073 } 3074 return bringUpError; 3075 } 3076 3077 @VisibleForTesting isIpPreferenceConflictsWithNetwork( @arrierConfigManager.Iwlan.EpdgAddressIpPreference int ipPreference)3078 IpPreferenceConflict isIpPreferenceConflictsWithNetwork( 3079 @CarrierConfigManager.Iwlan.EpdgAddressIpPreference int ipPreference) { 3080 List<InetAddress> localAddresses = getAddressForNetwork(mDefaultNetwork); 3081 if (localAddresses == null || localAddresses.size() == 0) { 3082 Log.e(TAG, "No local addresses available for Network " + mDefaultNetwork); 3083 return new IpPreferenceConflict(true, IwlanError.EPDG_SELECTOR_SERVER_SELECTION_FAILED); 3084 } else if (!IwlanHelper.hasIpv6Address(localAddresses) 3085 && ipPreference == CarrierConfigManager.Iwlan.EPDG_ADDRESS_IPV6_ONLY) { 3086 Log.e( 3087 TAG, 3088 "ePDG IP preference: " 3089 + ipPreference 3090 + " conflicts with source IP type: " 3091 + EpdgSelector.PROTO_FILTER_IPV4); 3092 return new IpPreferenceConflict(true, IwlanError.EPDG_ADDRESS_ONLY_IPV6_ALLOWED); 3093 } else if (!IwlanHelper.hasIpv4Address(localAddresses) 3094 && ipPreference == CarrierConfigManager.Iwlan.EPDG_ADDRESS_IPV4_ONLY) { 3095 // b/209938719 allows Iwlan to support VoWiFi for IPv4 ePDG server while on IPv6 WiFi. 3096 // Iwlan will receive a IPv4 address which is embedded in stacked IPv6 address. By using 3097 // this IPv4 address, UE will connect to IPv4 ePDG server through XLAT. However, there 3098 // are issues on connecting ePDG server through XLAT. Will allow IPV4_ONLY on IPv6 WiFi 3099 // after the issues are resolved. 3100 Log.e( 3101 TAG, 3102 "ePDG IP preference: " 3103 + ipPreference 3104 + " conflicts with source IP type: " 3105 + EpdgSelector.PROTO_FILTER_IPV6); 3106 return new IpPreferenceConflict(true, IwlanError.EPDG_ADDRESS_ONLY_IPV4_ALLOWED); 3107 } 3108 return new IpPreferenceConflict(); 3109 } 3110 3111 /** 3112 * Performs network validation check 3113 * 3114 * @param apnName APN for which to perform validation check 3115 */ requestNetworkValidationForApn(String apnName)3116 public void requestNetworkValidationForApn(String apnName) { 3117 mHandler.obtainMessage(EVENT_REQUEST_NETWORK_VALIDATION_CHECK, apnName).sendToTarget(); 3118 } 3119 3120 @VisibleForTesting removeApnNameInTunnelConfig(String apnName)3121 protected void removeApnNameInTunnelConfig(String apnName) { 3122 mApnNameToTunnelConfig.remove(apnName); 3123 } 3124 dump(PrintWriter pw)3125 public void dump(PrintWriter pw) { 3126 pw.println("---- EpdgTunnelManager ----"); 3127 pw.println( 3128 "Has ePDG connected for normal session: " 3129 + mEpdgMonitor.hasEpdgConnectedForNormalSession()); 3130 pw.println( 3131 "Has Separate ePDG connected for emergency session: " 3132 + mEpdgMonitor.hasSeparateEpdgConnectedForEmergencySession()); 3133 pw.println("mIkeSessionNetwork: " + mIkeSessionNetwork); 3134 if (mEpdgMonitor.getEpdgAddressForNormalSession() != null) { 3135 pw.println( 3136 "EpdgAddressForNormalSession: " 3137 + mEpdgMonitor.getEpdgAddressForNormalSession()); 3138 } 3139 if (mEpdgMonitor.getEpdgAddressForEmergencySession() != null) { 3140 pw.println( 3141 "SeparateEpdgAddressForEmergencySession: " 3142 + mEpdgMonitor.getEpdgAddressForEmergencySession()); 3143 } 3144 pw.println("mApnNameToTunnelConfig:\n"); 3145 for (Map.Entry<String, TunnelConfig> entry : mApnNameToTunnelConfig.entrySet()) { 3146 pw.println("APN: " + entry.getKey()); 3147 pw.println("TunnelConfig: " + entry.getValue()); 3148 pw.println(); 3149 } 3150 pw.println("---------------------------"); 3151 } 3152 } 3153