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.system.OsConstants.AF_INET; 22 import static android.system.OsConstants.AF_INET6; 23 24 import android.content.Context; 25 import android.net.ConnectivityManager; 26 import android.net.InetAddresses; 27 import android.net.IpPrefix; 28 import android.net.IpSecManager; 29 import android.net.IpSecTransform; 30 import android.net.LinkAddress; 31 import android.net.LinkProperties; 32 import android.net.Network; 33 import android.net.eap.EapAkaInfo; 34 import android.net.eap.EapInfo; 35 import android.net.eap.EapSessionConfig; 36 import android.net.ipsec.ike.ChildSaProposal; 37 import android.net.ipsec.ike.ChildSessionCallback; 38 import android.net.ipsec.ike.ChildSessionConfiguration; 39 import android.net.ipsec.ike.ChildSessionParams; 40 import android.net.ipsec.ike.IkeFqdnIdentification; 41 import android.net.ipsec.ike.IkeIdentification; 42 import android.net.ipsec.ike.IkeKeyIdIdentification; 43 import android.net.ipsec.ike.IkeRfc822AddrIdentification; 44 import android.net.ipsec.ike.IkeSaProposal; 45 import android.net.ipsec.ike.IkeSession; 46 import android.net.ipsec.ike.IkeSessionCallback; 47 import android.net.ipsec.ike.IkeSessionConfiguration; 48 import android.net.ipsec.ike.IkeSessionConnectionInfo; 49 import android.net.ipsec.ike.IkeSessionParams; 50 import android.net.ipsec.ike.IkeTrafficSelector; 51 import android.net.ipsec.ike.SaProposal; 52 import android.net.ipsec.ike.TunnelModeChildSessionParams; 53 import android.net.ipsec.ike.exceptions.IkeException; 54 import android.net.ipsec.ike.exceptions.IkeIOException; 55 import android.net.ipsec.ike.exceptions.IkeProtocolException; 56 import android.net.ipsec.ike.ike3gpp.Ike3gppBackoffTimer; 57 import android.net.ipsec.ike.ike3gpp.Ike3gppData; 58 import android.net.ipsec.ike.ike3gpp.Ike3gppExtension; 59 import android.net.ipsec.ike.ike3gpp.Ike3gppN1ModeInformation; 60 import android.net.ipsec.ike.ike3gpp.Ike3gppParams; 61 import android.os.Handler; 62 import android.os.HandlerThread; 63 import android.os.Looper; 64 import android.os.Message; 65 import android.support.annotation.NonNull; 66 import android.support.annotation.Nullable; 67 import android.telephony.CarrierConfigManager; 68 import android.telephony.SubscriptionManager; 69 import android.telephony.TelephonyManager; 70 import android.telephony.data.ApnSetting; 71 import android.telephony.data.NetworkSliceInfo; 72 import android.util.Log; 73 74 import com.android.internal.annotations.VisibleForTesting; 75 76 import com.google.android.iwlan.ErrorPolicyManager; 77 import com.google.android.iwlan.IwlanError; 78 import com.google.android.iwlan.IwlanHelper; 79 import com.google.android.iwlan.IwlanTunnelMetricsImpl; 80 import com.google.android.iwlan.TunnelMetricsInterface; 81 import com.google.android.iwlan.TunnelMetricsInterface.OnClosedMetrics; 82 import com.google.android.iwlan.TunnelMetricsInterface.OnOpenedMetrics; 83 import com.google.android.iwlan.exceptions.IwlanSimNotReadyException; 84 85 import java.io.IOException; 86 import java.io.PrintWriter; 87 import java.net.Inet4Address; 88 import java.net.Inet6Address; 89 import java.net.InetAddress; 90 import java.nio.charset.StandardCharsets; 91 import java.util.ArrayList; 92 import java.util.Arrays; 93 import java.util.LinkedList; 94 import java.util.List; 95 import java.util.Map; 96 import java.util.Objects; 97 import java.util.Queue; 98 import java.util.Set; 99 import java.util.concurrent.ConcurrentHashMap; 100 import java.util.concurrent.Executor; 101 import java.util.concurrent.Executors; 102 import java.util.concurrent.TimeUnit; 103 104 public class EpdgTunnelManager { 105 106 private final Context mContext; 107 private final int mSlotId; 108 private Handler mHandler; 109 110 private static final int EVENT_TUNNEL_BRINGUP_REQUEST = 0; 111 private static final int EVENT_TUNNEL_BRINGDOWN_REQUEST = 1; 112 private static final int EVENT_CHILD_SESSION_OPENED = 2; 113 private static final int EVENT_CHILD_SESSION_CLOSED = 3; 114 private static final int EVENT_IKE_SESSION_CLOSED = 5; 115 private static final int EVENT_EPDG_ADDRESS_SELECTION_REQUEST_COMPLETE = 6; 116 private static final int EVENT_IPSEC_TRANSFORM_CREATED = 7; 117 private static final int EVENT_IPSEC_TRANSFORM_DELETED = 8; 118 private static final int EVENT_UPDATE_NETWORK = 9; 119 private static final int EVENT_IKE_SESSION_OPENED = 10; 120 private static final int EVENT_IKE_SESSION_CONNECTION_INFO_CHANGED = 11; 121 private static final int EVENT_IKE_3GPP_DATA_RECEIVED = 12; 122 private static final int IKE_HARD_LIFETIME_SEC_MINIMUM = 300; 123 private static final int IKE_HARD_LIFETIME_SEC_MAXIMUM = 86400; 124 private static final int IKE_SOFT_LIFETIME_SEC_MINIMUM = 120; 125 private static final int CHILD_HARD_LIFETIME_SEC_MINIMUM = 300; 126 private static final int CHILD_HARD_LIFETIME_SEC_MAXIMUM = 14400; 127 private static final int CHILD_SOFT_LIFETIME_SEC_MINIMUM = 120; 128 private static final int LIFETIME_MARGIN_SEC_MINIMUM = (int) TimeUnit.MINUTES.toSeconds(1L); 129 private static final int IKE_RETRANS_TIMEOUT_MS_MIN = 500; 130 131 private static final int IKE_RETRANS_TIMEOUT_MS_MAX = (int) TimeUnit.MINUTES.toMillis(30L); 132 133 private static final int IKE_RETRANS_MAX_ATTEMPTS_MAX = 10; 134 private static final int IKE_DPD_DELAY_SEC_MIN = 20; 135 private static final int IKE_DPD_DELAY_SEC_MAX = 1800; // 30 minutes 136 private static final int NATT_KEEPALIVE_DELAY_SEC_MIN = 10; 137 private static final int NATT_KEEPALIVE_DELAY_SEC_MAX = 120; 138 139 private static final int DEVICE_IMEI_LEN = 15; 140 private static final int DEVICE_IMEISV_SUFFIX_LEN = 2; 141 142 private static final int TRAFFIC_SELECTOR_START_PORT = 0; 143 private static final int TRAFFIC_SELECTOR_END_PORT = 65535; 144 private static final String TRAFFIC_SELECTOR_IPV4_START_ADDR = "0.0.0.0"; 145 private static final String TRAFFIC_SELECTOR_IPV4_END_ADDR = "255.255.255.255"; 146 private static final String TRAFFIC_SELECTOR_IPV6_START_ADDR = "::"; 147 private static final String TRAFFIC_SELECTOR_IPV6_END_ADDR = 148 "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"; 149 150 // "192.0.2.0" is selected from RFC5737, "IPv4 Address Blocks Reserved for Documentation" 151 private static final InetAddress DUMMY_ADDR = InetAddresses.parseNumericAddress("192.0.2.0"); 152 153 private static final Map<Integer, EpdgTunnelManager> mTunnelManagerInstances = 154 new ConcurrentHashMap<>(); 155 156 private Queue<TunnelRequestWrapper> mPendingBringUpRequests = new LinkedList<>(); 157 158 private final EpdgInfo mValidEpdgInfo = new EpdgInfo(); 159 @Nullable private InetAddress mEpdgAddress; 160 161 // The most recently updated system default network as seen by IwlanDataService. 162 @Nullable private Network mDefaultNetwork; 163 // The latest Network provided to the IKE session. Only for debugging purposes. 164 @Nullable private Network mIkeSessionNetwork; 165 166 private int mTransactionId = 0; 167 private boolean mHasConnectedToEpdg; 168 private final IkeSessionCreator mIkeSessionCreator; 169 170 private Map<String, TunnelConfig> mApnNameToTunnelConfig = new ConcurrentHashMap<>(); 171 private final Map<String, Integer> mApnNameToCurrentToken = new ConcurrentHashMap<>(); 172 173 private final String TAG; 174 175 @Nullable private byte[] mNextReauthId = null; 176 private long mEpdgServerSelectionDuration = 0; 177 private long mEpdgServerSelectionStartTime = 0; 178 private long mIkeTunnelEstablishmentStartTime = 0; 179 180 private static final Set<Integer> VALID_DH_GROUPS; 181 private static final Set<Integer> VALID_KEY_LENGTHS; 182 private static final Set<Integer> VALID_PRF_ALGOS; 183 private static final Set<Integer> VALID_INTEGRITY_ALGOS; 184 private static final Set<Integer> VALID_ENCRYPTION_ALGOS; 185 186 private static final String CONFIG_TYPE_DH_GROUP = "dh group"; 187 private static final String CONFIG_TYPE_KEY_LEN = "algorithm key length"; 188 private static final String CONFIG_TYPE_PRF_ALGO = "prf algorithm"; 189 private static final String CONFIG_TYPE_INTEGRITY_ALGO = "integrity algorithm"; 190 private static final String CONFIG_TYPE_ENCRYPT_ALGO = "encryption algorithm"; 191 192 static { 193 VALID_DH_GROUPS = 194 Set.of( 195 SaProposal.DH_GROUP_1024_BIT_MODP, 196 SaProposal.DH_GROUP_1536_BIT_MODP, 197 SaProposal.DH_GROUP_2048_BIT_MODP, 198 SaProposal.DH_GROUP_3072_BIT_MODP, 199 SaProposal.DH_GROUP_4096_BIT_MODP); 200 VALID_KEY_LENGTHS = 201 Set.of( 202 SaProposal.KEY_LEN_AES_128, 203 SaProposal.KEY_LEN_AES_192, 204 SaProposal.KEY_LEN_AES_256); 205 206 VALID_ENCRYPTION_ALGOS = 207 Set.of( 208 SaProposal.ENCRYPTION_ALGORITHM_AES_CBC, 209 SaProposal.ENCRYPTION_ALGORITHM_AES_CTR); 210 211 VALID_INTEGRITY_ALGOS = 212 Set.of( 213 SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96, 214 SaProposal.INTEGRITY_ALGORITHM_AES_XCBC_96, 215 SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_256_128, 216 SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_384_192, 217 SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_512_256); 218 219 VALID_PRF_ALGOS = 220 Set.of( 221 SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1, 222 SaProposal.PSEUDORANDOM_FUNCTION_AES128_XCBC, 223 SaProposal.PSEUDORANDOM_FUNCTION_SHA2_256, 224 SaProposal.PSEUDORANDOM_FUNCTION_SHA2_384, 225 SaProposal.PSEUDORANDOM_FUNCTION_SHA2_512); 226 } 227 228 private final EpdgSelector.EpdgSelectorCallback mSelectorCallback = 229 new EpdgSelector.EpdgSelectorCallback() { 230 @Override 231 public void onServerListChanged(int transactionId, List<InetAddress> validIPList) { 232 sendSelectionRequestComplete( 233 validIPList, new IwlanError(IwlanError.NO_ERROR), transactionId); 234 } 235 236 @Override 237 public void onError(int transactionId, IwlanError epdgSelectorError) { 238 sendSelectionRequestComplete(null, epdgSelectorError, transactionId); 239 } 240 }; 241 242 @VisibleForTesting 243 class TunnelConfig { 244 @NonNull final TunnelCallback mTunnelCallback; 245 @NonNull final TunnelMetricsInterface mTunnelMetrics; 246 // TODO: Change this to TunnelLinkProperties after removing autovalue 247 private List<InetAddress> mPcscfAddrList; 248 private List<InetAddress> mDnsAddrList; 249 private List<LinkAddress> mInternalAddrList; 250 251 private final InetAddress mSrcIpv6Address; 252 private final int mSrcIpv6AddressPrefixLen; 253 private NetworkSliceInfo mSliceInfo; 254 private boolean mIsBackoffTimeValid = false; 255 private long mBackoffTime; 256 257 private IkeSessionState mIkeSessionState; 258 getIkeSessionState()259 public IkeSessionState getIkeSessionState() { 260 return mIkeSessionState; 261 } 262 setIkeSessionState(IkeSessionState ikeSessionState)263 public void setIkeSessionState(IkeSessionState ikeSessionState) { 264 mIkeSessionState = ikeSessionState; 265 } 266 getSliceInfo()267 public NetworkSliceInfo getSliceInfo() { 268 return mSliceInfo; 269 } 270 setSliceInfo(NetworkSliceInfo si)271 public void setSliceInfo(NetworkSliceInfo si) { 272 mSliceInfo = si; 273 } 274 isBackoffTimeValid()275 public boolean isBackoffTimeValid() { 276 return mIsBackoffTimeValid; 277 } 278 getBackoffTime()279 public long getBackoffTime() { 280 return mBackoffTime; 281 } 282 setBackoffTime(long backoffTime)283 public void setBackoffTime(long backoffTime) { 284 mIsBackoffTimeValid = true; 285 mBackoffTime = backoffTime; 286 } 287 288 @NonNull final IkeSession mIkeSession; 289 IwlanError mError; 290 private IpSecManager.IpSecTunnelInterface mIface; 291 TunnelConfig( IkeSession ikeSession, TunnelCallback tunnelCallback, TunnelMetricsInterface tunnelMetrics, InetAddress srcIpv6Addr, int srcIpv6PrefixLength)292 public TunnelConfig( 293 IkeSession ikeSession, 294 TunnelCallback tunnelCallback, 295 TunnelMetricsInterface tunnelMetrics, 296 InetAddress srcIpv6Addr, 297 int srcIpv6PrefixLength) { 298 mTunnelCallback = tunnelCallback; 299 mTunnelMetrics = tunnelMetrics; 300 mIkeSession = ikeSession; 301 mError = new IwlanError(IwlanError.NO_ERROR); 302 mSrcIpv6Address = srcIpv6Addr; 303 mSrcIpv6AddressPrefixLen = srcIpv6PrefixLength; 304 305 setIkeSessionState(IkeSessionState.IKE_SESSION_INIT_IN_PROGRESS); 306 } 307 308 @NonNull getTunnelCallback()309 TunnelCallback getTunnelCallback() { 310 return mTunnelCallback; 311 } 312 313 @NonNull getTunnelMetrics()314 TunnelMetricsInterface getTunnelMetrics() { 315 return mTunnelMetrics; 316 } 317 getPcscfAddrList()318 List<InetAddress> getPcscfAddrList() { 319 return mPcscfAddrList; 320 } 321 setPcscfAddrList(List<InetAddress> pcscfAddrList)322 void setPcscfAddrList(List<InetAddress> pcscfAddrList) { 323 mPcscfAddrList = pcscfAddrList; 324 } 325 getDnsAddrList()326 public List<InetAddress> getDnsAddrList() { 327 return mDnsAddrList; 328 } 329 setDnsAddrList(List<InetAddress> dnsAddrList)330 public void setDnsAddrList(List<InetAddress> dnsAddrList) { 331 this.mDnsAddrList = dnsAddrList; 332 } 333 getInternalAddrList()334 public List<LinkAddress> getInternalAddrList() { 335 return mInternalAddrList; 336 } 337 isPrefixSameAsSrcIP(LinkAddress laddr)338 boolean isPrefixSameAsSrcIP(LinkAddress laddr) { 339 if (laddr.isIpv6() && (laddr.getPrefixLength() == mSrcIpv6AddressPrefixLen)) { 340 IpPrefix assignedPrefix = new IpPrefix(laddr.getAddress(), laddr.getPrefixLength()); 341 IpPrefix srcPrefix = new IpPrefix(mSrcIpv6Address, mSrcIpv6AddressPrefixLen); 342 return assignedPrefix.equals(srcPrefix); 343 } 344 return false; 345 } 346 setInternalAddrList(List<LinkAddress> internalAddrList)347 public void setInternalAddrList(List<LinkAddress> internalAddrList) { 348 mInternalAddrList = new ArrayList<LinkAddress>(internalAddrList); 349 if (getSrcIpv6Address() != null) { 350 // check if we can reuse src ipv6 address (i.e. if prefix is same) 351 for (LinkAddress assignedAddr : internalAddrList) { 352 if (isPrefixSameAsSrcIP(assignedAddr)) { 353 // the assigned IPv6 address is same as pre-Handover IPv6 354 // addr. Just reuse the pre-Handover Address so the IID is 355 // preserved 356 mInternalAddrList.remove(assignedAddr); 357 358 // add original address 359 mInternalAddrList.add( 360 new LinkAddress(mSrcIpv6Address, mSrcIpv6AddressPrefixLen)); 361 362 Log.d( 363 TAG, 364 "Network assigned IP replaced OLD:" 365 + internalAddrList 366 + " NEW:" 367 + mInternalAddrList); 368 break; 369 } 370 } 371 } 372 } 373 374 @NonNull getIkeSession()375 public IkeSession getIkeSession() { 376 return mIkeSession; 377 } 378 getError()379 public IwlanError getError() { 380 return mError; 381 } 382 setError(IwlanError error)383 public void setError(IwlanError error) { 384 this.mError = error; 385 } 386 getIface()387 public IpSecManager.IpSecTunnelInterface getIface() { 388 return mIface; 389 } 390 setIface(IpSecManager.IpSecTunnelInterface iface)391 public void setIface(IpSecManager.IpSecTunnelInterface iface) { 392 mIface = iface; 393 } 394 getSrcIpv6Address()395 public InetAddress getSrcIpv6Address() { 396 return mSrcIpv6Address; 397 } 398 hasTunnelOpened()399 public boolean hasTunnelOpened() { 400 return mInternalAddrList != null 401 && !mInternalAddrList.isEmpty() /* The child session is opened */ 402 && mIface != null; /* The tunnel interface is bring up */ 403 } 404 405 @Override toString()406 public String toString() { 407 StringBuilder sb = new StringBuilder(); 408 sb.append("TunnelConfig { "); 409 410 if (mSliceInfo != null) { 411 sb.append("mSliceInfo: ").append(mSliceInfo).append(", "); 412 } 413 414 if (mIsBackoffTimeValid) { 415 sb.append("mBackoffTime: ").append(mBackoffTime).append(", "); 416 } 417 sb.append(" }"); 418 return sb.toString(); 419 } 420 } 421 422 @VisibleForTesting 423 class TmIkeSessionCallback implements IkeSessionCallback { 424 425 private final String mApnName; 426 private final int mToken; 427 TmIkeSessionCallback(String apnName, int token)428 TmIkeSessionCallback(String apnName, int token) { 429 this.mApnName = apnName; 430 this.mToken = token; 431 } 432 433 @Override onOpened(IkeSessionConfiguration sessionConfiguration)434 public void onOpened(IkeSessionConfiguration sessionConfiguration) { 435 Log.d(TAG, "Ike session opened for apn: " + mApnName + " with token: " + mToken); 436 mHandler.sendMessage( 437 mHandler.obtainMessage( 438 EVENT_IKE_SESSION_OPENED, 439 new IkeSessionOpenedData(mApnName, mToken, sessionConfiguration))); 440 } 441 442 @Override onClosed()443 public void onClosed() { 444 Log.d(TAG, "Ike session closed for apn: " + mApnName + " with token: " + mToken); 445 mHandler.sendMessage( 446 mHandler.obtainMessage( 447 EVENT_IKE_SESSION_CLOSED, 448 new SessionClosedData(mApnName, mToken, null /* ikeException */))); 449 } 450 451 @Override onClosedWithException(IkeException exception)452 public void onClosedWithException(IkeException exception) { 453 mNextReauthId = null; 454 onSessionClosedWithException(exception, mApnName, mToken, EVENT_IKE_SESSION_CLOSED); 455 } 456 457 @Override onError(IkeProtocolException exception)458 public void onError(IkeProtocolException exception) { 459 Log.d(TAG, "Ike session onError for apn: " + mApnName + " with token: " + mToken); 460 461 mNextReauthId = null; 462 463 Log.d( 464 TAG, 465 "ErrorType:" 466 + exception.getErrorType() 467 + " ErrorData:" 468 + exception.getMessage()); 469 } 470 471 @Override onIkeSessionConnectionInfoChanged( IkeSessionConnectionInfo ikeSessionConnectionInfo)472 public void onIkeSessionConnectionInfoChanged( 473 IkeSessionConnectionInfo ikeSessionConnectionInfo) { 474 Network network = ikeSessionConnectionInfo.getNetwork(); 475 Log.d( 476 TAG, 477 "Ike session connection info changed for apn: " 478 + mApnName 479 + " with token: " 480 + mToken 481 + " Network: " 482 + network); 483 mHandler.sendMessage( 484 mHandler.obtainMessage( 485 EVENT_IKE_SESSION_CONNECTION_INFO_CHANGED, 486 new IkeSessionConnectionInfoData( 487 mApnName, mToken, ikeSessionConnectionInfo))); 488 } 489 } 490 491 @VisibleForTesting 492 class TmIke3gppCallback implements Ike3gppExtension.Ike3gppDataListener { 493 private final String mApnName; 494 private final int mToken; 495 TmIke3gppCallback(String apnName, int token)496 private TmIke3gppCallback(String apnName, int token) { 497 mApnName = apnName; 498 mToken = token; 499 } 500 501 @Override onIke3gppDataReceived(List<Ike3gppData> payloads)502 public void onIke3gppDataReceived(List<Ike3gppData> payloads) { 503 mHandler.sendMessage( 504 mHandler.obtainMessage( 505 EVENT_IKE_3GPP_DATA_RECEIVED, 506 new Ike3gppDataReceived(mApnName, mToken, payloads))); 507 } 508 } 509 510 @VisibleForTesting 511 class TmChildSessionCallback implements ChildSessionCallback { 512 513 private final String mApnName; 514 private final int mToken; 515 TmChildSessionCallback(String apnName, int token)516 TmChildSessionCallback(String apnName, int token) { 517 this.mApnName = apnName; 518 this.mToken = token; 519 } 520 521 @Override onOpened(ChildSessionConfiguration sessionConfiguration)522 public void onOpened(ChildSessionConfiguration sessionConfiguration) { 523 Log.d(TAG, "onOpened child session for apn: " + mApnName + " with token: " + mToken); 524 mHandler.sendMessage( 525 mHandler.obtainMessage( 526 EVENT_CHILD_SESSION_OPENED, 527 new TunnelOpenedData( 528 mApnName, 529 mToken, 530 sessionConfiguration.getInternalDnsServers(), 531 sessionConfiguration.getInternalAddresses()))); 532 } 533 534 @Override onClosed()535 public void onClosed() { 536 Log.d(TAG, "onClosed child session for apn: " + mApnName + " with token: " + mToken); 537 mHandler.sendMessage( 538 mHandler.obtainMessage( 539 EVENT_CHILD_SESSION_CLOSED, 540 new SessionClosedData(mApnName, mToken, null /* ikeException */))); 541 } 542 543 @Override onClosedWithException(IkeException exception)544 public void onClosedWithException(IkeException exception) { 545 onSessionClosedWithException(exception, mApnName, mToken, EVENT_CHILD_SESSION_CLOSED); 546 } 547 548 @Override onIpSecTransformsMigrated( IpSecTransform inIpSecTransform, IpSecTransform outIpSecTransform)549 public void onIpSecTransformsMigrated( 550 IpSecTransform inIpSecTransform, IpSecTransform outIpSecTransform) { 551 // migration is similar to addition 552 Log.d(TAG, "Transforms migrated for apn: " + mApnName + " with token: " + mToken); 553 mHandler.sendMessage( 554 mHandler.obtainMessage( 555 EVENT_IPSEC_TRANSFORM_CREATED, 556 new IpsecTransformData( 557 inIpSecTransform, 558 IpSecManager.DIRECTION_IN, 559 mApnName, 560 mToken))); 561 mHandler.sendMessage( 562 mHandler.obtainMessage( 563 EVENT_IPSEC_TRANSFORM_CREATED, 564 new IpsecTransformData( 565 outIpSecTransform, 566 IpSecManager.DIRECTION_OUT, 567 mApnName, 568 mToken))); 569 } 570 571 @Override onIpSecTransformCreated(IpSecTransform ipSecTransform, int direction)572 public void onIpSecTransformCreated(IpSecTransform ipSecTransform, int direction) { 573 Log.d( 574 TAG, 575 "Transform created, direction: " 576 + direction 577 + ", apn: " 578 + mApnName 579 + ", token: " 580 + mToken); 581 mHandler.sendMessage( 582 mHandler.obtainMessage( 583 EVENT_IPSEC_TRANSFORM_CREATED, 584 new IpsecTransformData(ipSecTransform, direction, mApnName, mToken))); 585 } 586 587 @Override onIpSecTransformDeleted(IpSecTransform ipSecTransform, int direction)588 public void onIpSecTransformDeleted(IpSecTransform ipSecTransform, int direction) { 589 Log.d( 590 TAG, 591 "Transform deleted, direction: " 592 + direction 593 + ", apn: " 594 + mApnName 595 + ", token: " 596 + mToken); 597 mHandler.sendMessage( 598 mHandler.obtainMessage( 599 EVENT_IPSEC_TRANSFORM_DELETED, 600 new IpsecTransformData(ipSecTransform, direction, mApnName, mToken))); 601 } 602 } 603 EpdgTunnelManager(Context context, int slotId)604 private EpdgTunnelManager(Context context, int slotId) { 605 mContext = context; 606 mSlotId = slotId; 607 mIkeSessionCreator = new IkeSessionCreator(); 608 TAG = EpdgTunnelManager.class.getSimpleName() + "[" + mSlotId + "]"; 609 initHandler(); 610 } 611 612 @VisibleForTesting initHandler()613 void initHandler() { 614 mHandler = new TmHandler(getLooper()); 615 } 616 617 @VisibleForTesting getLooper()618 Looper getLooper() { 619 HandlerThread handlerThread = new HandlerThread("EpdgTunnelManagerThread"); 620 handlerThread.start(); 621 return handlerThread.getLooper(); 622 } 623 624 /** 625 * Gets a EpdgTunnelManager instance. 626 * 627 * @param context application context 628 * @param subId subscription ID for the tunnel 629 * @return tunnel manager instance corresponding to the sub id 630 */ getInstance(@onNull Context context, int subId)631 public static EpdgTunnelManager getInstance(@NonNull Context context, int subId) { 632 return mTunnelManagerInstances.computeIfAbsent( 633 subId, k -> new EpdgTunnelManager(context, subId)); 634 } 635 636 @VisibleForTesting resetAllInstances()637 public static void resetAllInstances() { 638 mTunnelManagerInstances.clear(); 639 } 640 641 public interface TunnelCallback { 642 /** 643 * Called when the tunnel is opened. 644 * 645 * @param apnName apn for which the tunnel was opened 646 * @param linkProperties link properties of the tunnel 647 */ onOpened(@onNull String apnName, @NonNull TunnelLinkProperties linkProperties)648 void onOpened(@NonNull String apnName, @NonNull TunnelLinkProperties linkProperties); 649 /** 650 * Called when the tunnel is closed OR if bringup fails 651 * 652 * @param apnName apn for which the tunnel was closed 653 * @param error IwlanError carrying details of the error 654 */ onClosed(@onNull String apnName, @NonNull IwlanError error)655 void onClosed(@NonNull String apnName, @NonNull IwlanError error); 656 } 657 658 /** 659 * Close tunnel for an apn. Confirmation of closing will be delivered in TunnelCallback that was 660 * provided in {@link #bringUpTunnel}. If no tunnel was available, callback will be delivered 661 * using client-provided provided tunnelCallback and iwlanTunnelMetrics 662 * 663 * @param apnName apn name 664 * @param forceClose if true, results in local cleanup of tunnel 665 * @param tunnelCallback Used if no current or pending IWLAN tunnel exists 666 * @param iwlanTunnelMetrics Used to report metrics if no current or pending IWLAN tunnel exists 667 */ closeTunnel( @onNull String apnName, boolean forceClose, @NonNull TunnelCallback tunnelCallback, @NonNull IwlanTunnelMetricsImpl iwlanTunnelMetrics)668 public void closeTunnel( 669 @NonNull String apnName, 670 boolean forceClose, 671 @NonNull TunnelCallback tunnelCallback, 672 @NonNull IwlanTunnelMetricsImpl iwlanTunnelMetrics) { 673 mHandler.sendMessage( 674 mHandler.obtainMessage( 675 EVENT_TUNNEL_BRINGDOWN_REQUEST, 676 new TunnelBringdownRequest( 677 apnName, forceClose, tunnelCallback, iwlanTunnelMetrics))); 678 } 679 680 /** 681 * Update the local Network. This will trigger a revaluation for every tunnel for which tunnel 682 * manager has state. 683 * 684 * @param network the network to be updated 685 * @param network the linkProperties to be updated 686 */ updateNetwork(Network network, LinkProperties linkProperties)687 public void updateNetwork(Network network, LinkProperties linkProperties) { 688 UpdateNetworkWrapper updateNetworkWrapper = 689 new UpdateNetworkWrapper(network, linkProperties); 690 mHandler.sendMessage(mHandler.obtainMessage(EVENT_UPDATE_NETWORK, updateNetworkWrapper)); 691 } 692 /** 693 * Bring up epdg tunnel. Only one bring up request per apn is expected. All active tunnel 694 * requests and tunnels are expected to be on the same network. 695 * 696 * @param setupRequest {@link TunnelSetupRequest} tunnel configurations 697 * @param tunnelCallback {@link TunnelCallback} interface to notify clients about the tunnel 698 * state 699 * @return true if params are valid and no existing tunnel. False otherwise. 700 */ bringUpTunnel( @onNull TunnelSetupRequest setupRequest, @NonNull TunnelCallback tunnelCallback, @NonNull TunnelMetricsInterface tunnelMetrics)701 public boolean bringUpTunnel( 702 @NonNull TunnelSetupRequest setupRequest, 703 @NonNull TunnelCallback tunnelCallback, 704 @NonNull TunnelMetricsInterface tunnelMetrics) { 705 String apnName = setupRequest.apnName(); 706 707 if (getTunnelSetupRequestApnName(setupRequest) == null) { 708 Log.e(TAG, "APN is null."); 709 return false; 710 } 711 712 if (isTunnelConfigContainExistApn(apnName)) { 713 Log.e(TAG, "Tunnel exists for apn:" + apnName); 714 return false; 715 } 716 717 if (!isValidApnProtocol(setupRequest.apnIpProtocol())) { 718 Log.e(TAG, "Invalid protocol for APN"); 719 return false; 720 } 721 722 int pduSessionId = setupRequest.pduSessionId(); 723 if (pduSessionId < 0 || pduSessionId > 15) { 724 Log.e(TAG, "Invalid pduSessionId: " + pduSessionId); 725 return false; 726 } 727 728 TunnelRequestWrapper tunnelRequestWrapper = 729 new TunnelRequestWrapper(setupRequest, tunnelCallback, tunnelMetrics); 730 731 mHandler.sendMessage( 732 mHandler.obtainMessage(EVENT_TUNNEL_BRINGUP_REQUEST, tunnelRequestWrapper)); 733 734 return true; 735 } 736 onBringUpTunnel( TunnelSetupRequest setupRequest, TunnelCallback tunnelCallback, TunnelMetricsInterface tunnelMetrics)737 private void onBringUpTunnel( 738 TunnelSetupRequest setupRequest, 739 TunnelCallback tunnelCallback, 740 TunnelMetricsInterface tunnelMetrics) { 741 String apnName = setupRequest.apnName(); 742 IkeSessionParams ikeSessionParams; 743 744 Log.d( 745 TAG, 746 "Bringing up tunnel for apn: " 747 + apnName 748 + " ePDG: " 749 + mEpdgAddress.getHostAddress()); 750 751 final int token = incrementAndGetCurrentTokenForApn(apnName); 752 753 try { 754 ikeSessionParams = buildIkeSessionParams(setupRequest, apnName, token); 755 } catch (IwlanSimNotReadyException e) { 756 IwlanError iwlanError = new IwlanError(IwlanError.SIM_NOT_READY_EXCEPTION); 757 reportIwlanError(apnName, iwlanError); 758 tunnelCallback.onClosed(apnName, iwlanError); 759 tunnelMetrics.onClosed(new OnClosedMetrics.Builder().setApnName(apnName).build()); 760 return; 761 } 762 763 mIkeTunnelEstablishmentStartTime = System.currentTimeMillis(); 764 IkeSession ikeSession = 765 getIkeSessionCreator() 766 .createIkeSession( 767 mContext, 768 ikeSessionParams, 769 buildChildSessionParams(setupRequest), 770 Executors.newSingleThreadExecutor(), 771 getTmIkeSessionCallback(apnName, token), 772 new TmChildSessionCallback(apnName, token)); 773 774 boolean isSrcIpv6Present = setupRequest.srcIpv6Address().isPresent(); 775 putApnNameToTunnelConfig( 776 apnName, 777 ikeSession, 778 tunnelCallback, 779 tunnelMetrics, 780 isSrcIpv6Present ? setupRequest.srcIpv6Address().get() : null, 781 setupRequest.srcIpv6AddressPrefixLength()); 782 } 783 784 /** 785 * Proxy to allow testing 786 * 787 * @hide 788 */ 789 @VisibleForTesting 790 static class IkeSessionCreator { 791 /** Creates a IKE session */ createIkeSession( @onNull Context context, @NonNull IkeSessionParams ikeSessionParams, @NonNull ChildSessionParams firstChildSessionParams, @NonNull Executor userCbExecutor, @NonNull IkeSessionCallback ikeSessionCallback, @NonNull ChildSessionCallback firstChildSessionCallback)792 public IkeSession createIkeSession( 793 @NonNull Context context, 794 @NonNull IkeSessionParams ikeSessionParams, 795 @NonNull ChildSessionParams firstChildSessionParams, 796 @NonNull Executor userCbExecutor, 797 @NonNull IkeSessionCallback ikeSessionCallback, 798 @NonNull ChildSessionCallback firstChildSessionCallback) { 799 return new IkeSession( 800 context, 801 ikeSessionParams, 802 firstChildSessionParams, 803 userCbExecutor, 804 ikeSessionCallback, 805 firstChildSessionCallback); 806 } 807 } 808 buildChildSessionParams(TunnelSetupRequest setupRequest)809 private ChildSessionParams buildChildSessionParams(TunnelSetupRequest setupRequest) { 810 int proto = setupRequest.apnIpProtocol(); 811 int hardTimeSeconds = 812 getConfig(CarrierConfigManager.Iwlan.KEY_CHILD_SA_REKEY_HARD_TIMER_SEC_INT); 813 int softTimeSeconds = 814 getConfig(CarrierConfigManager.Iwlan.KEY_CHILD_SA_REKEY_SOFT_TIMER_SEC_INT); 815 if (!isValidChildSessionLifetime(hardTimeSeconds, softTimeSeconds)) { 816 if (hardTimeSeconds > CHILD_HARD_LIFETIME_SEC_MAXIMUM 817 && softTimeSeconds > CHILD_SOFT_LIFETIME_SEC_MINIMUM) { 818 hardTimeSeconds = CHILD_HARD_LIFETIME_SEC_MAXIMUM; 819 softTimeSeconds = CHILD_HARD_LIFETIME_SEC_MAXIMUM - LIFETIME_MARGIN_SEC_MINIMUM; 820 } else { 821 hardTimeSeconds = 822 IwlanHelper.getDefaultConfig( 823 CarrierConfigManager.Iwlan.KEY_CHILD_SA_REKEY_HARD_TIMER_SEC_INT); 824 softTimeSeconds = 825 IwlanHelper.getDefaultConfig( 826 CarrierConfigManager.Iwlan.KEY_CHILD_SA_REKEY_SOFT_TIMER_SEC_INT); 827 } 828 Log.d( 829 TAG, 830 "Invalid child session lifetime values, set hard: " 831 + hardTimeSeconds 832 + ", soft: " 833 + softTimeSeconds); 834 } 835 836 TunnelModeChildSessionParams.Builder childSessionParamsBuilder = 837 new TunnelModeChildSessionParams.Builder() 838 .setLifetimeSeconds(hardTimeSeconds, softTimeSeconds); 839 840 childSessionParamsBuilder.addChildSaProposal(buildChildSaProposal()); 841 842 boolean handoverIPv4Present = setupRequest.srcIpv4Address().isPresent(); 843 boolean handoverIPv6Present = setupRequest.srcIpv6Address().isPresent(); 844 if (handoverIPv4Present || handoverIPv6Present) { 845 if (handoverIPv4Present) { 846 childSessionParamsBuilder.addInternalAddressRequest( 847 (Inet4Address) setupRequest.srcIpv4Address().get()); 848 childSessionParamsBuilder.addInternalDnsServerRequest(AF_INET); 849 childSessionParamsBuilder.addInboundTrafficSelectors( 850 getDefaultTrafficSelectorIpv4()); 851 childSessionParamsBuilder.addOutboundTrafficSelectors( 852 getDefaultTrafficSelectorIpv4()); 853 } 854 if (handoverIPv6Present) { 855 childSessionParamsBuilder.addInternalAddressRequest( 856 (Inet6Address) setupRequest.srcIpv6Address().get(), 857 setupRequest.srcIpv6AddressPrefixLength()); 858 childSessionParamsBuilder.addInternalDnsServerRequest(AF_INET6); 859 childSessionParamsBuilder.addInboundTrafficSelectors( 860 getDefaultTrafficSelectorIpv6()); 861 childSessionParamsBuilder.addOutboundTrafficSelectors( 862 getDefaultTrafficSelectorIpv6()); 863 } 864 } else { 865 // non-handover case 866 if (proto == ApnSetting.PROTOCOL_IP || proto == ApnSetting.PROTOCOL_IPV4V6) { 867 childSessionParamsBuilder.addInternalAddressRequest(AF_INET); 868 childSessionParamsBuilder.addInternalDnsServerRequest(AF_INET); 869 childSessionParamsBuilder.addInboundTrafficSelectors( 870 getDefaultTrafficSelectorIpv4()); 871 childSessionParamsBuilder.addOutboundTrafficSelectors( 872 getDefaultTrafficSelectorIpv4()); 873 } 874 if (proto == ApnSetting.PROTOCOL_IPV6 || proto == ApnSetting.PROTOCOL_IPV4V6) { 875 childSessionParamsBuilder.addInternalAddressRequest(AF_INET6); 876 childSessionParamsBuilder.addInternalDnsServerRequest(AF_INET6); 877 childSessionParamsBuilder.addInboundTrafficSelectors( 878 getDefaultTrafficSelectorIpv6()); 879 childSessionParamsBuilder.addOutboundTrafficSelectors( 880 getDefaultTrafficSelectorIpv6()); 881 } 882 } 883 884 return childSessionParamsBuilder.build(); 885 } 886 getDefaultTrafficSelectorIpv4()887 private static IkeTrafficSelector getDefaultTrafficSelectorIpv4() { 888 return new IkeTrafficSelector( 889 TRAFFIC_SELECTOR_START_PORT, 890 TRAFFIC_SELECTOR_END_PORT, 891 InetAddresses.parseNumericAddress(TRAFFIC_SELECTOR_IPV4_START_ADDR), 892 InetAddresses.parseNumericAddress(TRAFFIC_SELECTOR_IPV4_END_ADDR)); 893 } 894 getDefaultTrafficSelectorIpv6()895 private static IkeTrafficSelector getDefaultTrafficSelectorIpv6() { 896 return new IkeTrafficSelector( 897 TRAFFIC_SELECTOR_START_PORT, 898 TRAFFIC_SELECTOR_END_PORT, 899 InetAddresses.parseNumericAddress(TRAFFIC_SELECTOR_IPV6_START_ADDR), 900 InetAddresses.parseNumericAddress(TRAFFIC_SELECTOR_IPV6_END_ADDR)); 901 } 902 numPdnTunnels()903 private int numPdnTunnels() { 904 return mApnNameToTunnelConfig.size(); 905 } 906 907 // Returns the IMEISV or device IMEI, in that order of priority. getMobileDeviceIdentity()908 private @Nullable String getMobileDeviceIdentity() { 909 TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class); 910 telephonyManager = 911 Objects.requireNonNull(telephonyManager) 912 .createForSubscriptionId(IwlanHelper.getSubId(mContext, mSlotId)); 913 if (telephonyManager == null) { 914 return null; 915 } 916 // Queries the 15-digit device IMEI. 917 String imei = telephonyManager.getImei(); 918 if (imei == null || imei.length() != DEVICE_IMEI_LEN) { 919 Log.i(TAG, "Unable to query valid Mobile Device Identity (IMEI)!"); 920 return null; 921 } 922 String imeisv_suffix = telephonyManager.getDeviceSoftwareVersion(); 923 if (imeisv_suffix == null || imeisv_suffix.length() != DEVICE_IMEISV_SUFFIX_LEN) { 924 // Unable to retrieve 2-digit suffix for IMEISV, so returns device IMEI. 925 return imei; 926 } 927 // Splices the first 14 digit of device IMEI with 2-digit SV suffix to form IMEISV. 928 return imei.substring(0, imei.length() - 1) + imeisv_suffix; 929 } 930 buildIkeSessionParams( TunnelSetupRequest setupRequest, String apnName, int token)931 private IkeSessionParams buildIkeSessionParams( 932 TunnelSetupRequest setupRequest, String apnName, int token) 933 throws IwlanSimNotReadyException { 934 int hardTimeSeconds = 935 getConfig(CarrierConfigManager.Iwlan.KEY_IKE_REKEY_HARD_TIMER_SEC_INT); 936 int softTimeSeconds = 937 getConfig(CarrierConfigManager.Iwlan.KEY_IKE_REKEY_SOFT_TIMER_SEC_INT); 938 if (!isValidIkeSessionLifetime(hardTimeSeconds, softTimeSeconds)) { 939 if (hardTimeSeconds > IKE_HARD_LIFETIME_SEC_MAXIMUM 940 && softTimeSeconds > IKE_SOFT_LIFETIME_SEC_MINIMUM) { 941 hardTimeSeconds = IKE_HARD_LIFETIME_SEC_MAXIMUM; 942 softTimeSeconds = IKE_HARD_LIFETIME_SEC_MAXIMUM - LIFETIME_MARGIN_SEC_MINIMUM; 943 } else { 944 hardTimeSeconds = 945 IwlanHelper.getDefaultConfig( 946 CarrierConfigManager.Iwlan.KEY_IKE_REKEY_HARD_TIMER_SEC_INT); 947 softTimeSeconds = 948 IwlanHelper.getDefaultConfig( 949 CarrierConfigManager.Iwlan.KEY_IKE_REKEY_SOFT_TIMER_SEC_INT); 950 } 951 Log.d( 952 TAG, 953 "Invalid ike session lifetime values, set hard: " 954 + hardTimeSeconds 955 + ", soft: " 956 + softTimeSeconds); 957 } 958 959 IkeSessionParams.Builder builder = 960 new IkeSessionParams.Builder(mContext) 961 // permanently hardcode DSCP to 46 (Expedited Forwarding class) 962 // See https://www.iana.org/assignments/dscp-registry/dscp-registry.xhtml 963 // This will make WiFi prioritize IKE signallig under WMM AC_VO 964 .setDscp(46) 965 .setServerHostname(mEpdgAddress.getHostAddress()) 966 .setLocalIdentification(getLocalIdentification()) 967 .setRemoteIdentification(getId(setupRequest.apnName(), false)) 968 .setAuthEap(null, getEapConfig()) 969 .addIkeSaProposal(buildIkeSaProposal()) 970 .setNetwork(mDefaultNetwork) 971 .addIkeOption(IkeSessionParams.IKE_OPTION_ACCEPT_ANY_REMOTE_ID) 972 .addIkeOption(IkeSessionParams.IKE_OPTION_MOBIKE) 973 .addIkeOption(IkeSessionParams.IKE_OPTION_REKEY_MOBILITY) 974 .setLifetimeSeconds(hardTimeSeconds, softTimeSeconds) 975 .setRetransmissionTimeoutsMillis(getRetransmissionTimeoutsFromConfig()) 976 .setDpdDelaySeconds(getDpdDelayFromConfig()); 977 978 if (numPdnTunnels() == 0) { 979 builder.addIkeOption(IkeSessionParams.IKE_OPTION_INITIAL_CONTACT); 980 Log.d(TAG, "IKE_OPTION_INITIAL_CONTACT"); 981 } 982 983 if ((int) getConfig(CarrierConfigManager.Iwlan.KEY_EPDG_AUTHENTICATION_METHOD_INT) 984 == CarrierConfigManager.Iwlan.AUTHENTICATION_METHOD_EAP_ONLY) { 985 builder.addIkeOption(IkeSessionParams.IKE_OPTION_EAP_ONLY_AUTH); 986 } 987 988 if (setupRequest.requestPcscf()) { 989 int proto = setupRequest.apnIpProtocol(); 990 if (proto == ApnSetting.PROTOCOL_IP || proto == ApnSetting.PROTOCOL_IPV4V6) { 991 builder.addPcscfServerRequest(AF_INET); 992 } 993 if (proto == ApnSetting.PROTOCOL_IPV6 || proto == ApnSetting.PROTOCOL_IPV4V6) { 994 builder.addPcscfServerRequest(AF_INET6); 995 } 996 } 997 998 // If MOBIKE is configured, ePDGs may force IPv6 UDP encapsulation- as specified by 999 // RFC 4555- which Android connectivity stack presently does not support. 1000 if (mEpdgAddress instanceof Inet6Address) { 1001 builder.removeIkeOption(IkeSessionParams.IKE_OPTION_MOBIKE); 1002 } 1003 1004 Ike3gppParams.Builder builder3gppParams = null; 1005 1006 // TODO(b/239753287): Telus carrier requests DEVICE_IDENTITY, but errors out when parsing 1007 // the response. Temporarily disabled. 1008 if (false) { 1009 String imei = getMobileDeviceIdentity(); 1010 if (imei != null) { 1011 if (builder3gppParams == null) { 1012 builder3gppParams = new Ike3gppParams.Builder(); 1013 } 1014 Log.d(TAG, "DEVICE_IDENTITY set in Ike3gppParams"); 1015 builder3gppParams.setMobileDeviceIdentity(imei); 1016 } 1017 } 1018 1019 if (isN1ModeSupported()) { 1020 if (setupRequest.pduSessionId() != 0) { 1021 // Configures the PduSession ID in N1_MODE_CAPABILITY payload 1022 // to notify the server that UE supports N1_MODE 1023 builder3gppParams = new Ike3gppParams.Builder(); 1024 builder3gppParams.setPduSessionId((byte) setupRequest.pduSessionId()); 1025 } 1026 } 1027 1028 if (builder3gppParams != null) { 1029 Ike3gppExtension extension = 1030 new Ike3gppExtension( 1031 builder3gppParams.build(), new TmIke3gppCallback(apnName, token)); 1032 builder.setIke3gppExtension(extension); 1033 } 1034 1035 int nattKeepAliveTimer = 1036 getConfig(CarrierConfigManager.Iwlan.KEY_NATT_KEEP_ALIVE_TIMER_SEC_INT); 1037 if (nattKeepAliveTimer < NATT_KEEPALIVE_DELAY_SEC_MIN 1038 || nattKeepAliveTimer > NATT_KEEPALIVE_DELAY_SEC_MAX) { 1039 Log.d(TAG, "Falling back to default natt keep alive timer"); 1040 nattKeepAliveTimer = 1041 IwlanHelper.getDefaultConfig( 1042 CarrierConfigManager.Iwlan.KEY_NATT_KEEP_ALIVE_TIMER_SEC_INT); 1043 } 1044 builder.setNattKeepAliveDelaySeconds(nattKeepAliveTimer); 1045 1046 return builder.build(); 1047 } 1048 isValidChildSessionLifetime(int hardLifetimeSeconds, int softLifetimeSeconds)1049 private boolean isValidChildSessionLifetime(int hardLifetimeSeconds, int softLifetimeSeconds) { 1050 return hardLifetimeSeconds >= CHILD_HARD_LIFETIME_SEC_MINIMUM 1051 && hardLifetimeSeconds <= CHILD_HARD_LIFETIME_SEC_MAXIMUM 1052 && softLifetimeSeconds >= CHILD_SOFT_LIFETIME_SEC_MINIMUM 1053 && hardLifetimeSeconds - softLifetimeSeconds >= LIFETIME_MARGIN_SEC_MINIMUM; 1054 } 1055 isValidIkeSessionLifetime(int hardLifetimeSeconds, int softLifetimeSeconds)1056 private boolean isValidIkeSessionLifetime(int hardLifetimeSeconds, int softLifetimeSeconds) { 1057 return hardLifetimeSeconds >= IKE_HARD_LIFETIME_SEC_MINIMUM 1058 && hardLifetimeSeconds <= IKE_HARD_LIFETIME_SEC_MAXIMUM 1059 && softLifetimeSeconds >= IKE_SOFT_LIFETIME_SEC_MINIMUM 1060 && hardLifetimeSeconds - softLifetimeSeconds >= LIFETIME_MARGIN_SEC_MINIMUM; 1061 } 1062 getConfig(String configKey)1063 private <T> T getConfig(String configKey) { 1064 return IwlanHelper.getConfig(configKey, mContext, mSlotId); 1065 } 1066 buildIkeSaProposal()1067 private IkeSaProposal buildIkeSaProposal() { 1068 IkeSaProposal.Builder saProposalBuilder = new IkeSaProposal.Builder(); 1069 1070 int[] dhGroups = getConfig(CarrierConfigManager.Iwlan.KEY_DIFFIE_HELLMAN_GROUPS_INT_ARRAY); 1071 for (int dhGroup : dhGroups) { 1072 if (validateConfig(dhGroup, VALID_DH_GROUPS, CONFIG_TYPE_DH_GROUP)) { 1073 saProposalBuilder.addDhGroup(dhGroup); 1074 } 1075 } 1076 1077 int[] encryptionAlgos = 1078 getConfig( 1079 CarrierConfigManager.Iwlan 1080 .KEY_SUPPORTED_IKE_SESSION_ENCRYPTION_ALGORITHMS_INT_ARRAY); 1081 for (int encryptionAlgo : encryptionAlgos) { 1082 validateConfig(encryptionAlgo, VALID_ENCRYPTION_ALGOS, CONFIG_TYPE_ENCRYPT_ALGO); 1083 1084 if (encryptionAlgo == SaProposal.ENCRYPTION_ALGORITHM_AES_CBC) { 1085 int[] aesCbcKeyLens = 1086 getConfig( 1087 CarrierConfigManager.Iwlan 1088 .KEY_IKE_SESSION_AES_CBC_KEY_SIZE_INT_ARRAY); 1089 for (int aesCbcKeyLen : aesCbcKeyLens) { 1090 if (validateConfig(aesCbcKeyLen, VALID_KEY_LENGTHS, CONFIG_TYPE_KEY_LEN)) { 1091 saProposalBuilder.addEncryptionAlgorithm(encryptionAlgo, aesCbcKeyLen); 1092 } 1093 } 1094 } 1095 1096 if (encryptionAlgo == SaProposal.ENCRYPTION_ALGORITHM_AES_CTR) { 1097 int[] aesCtrKeyLens = 1098 getConfig( 1099 CarrierConfigManager.Iwlan 1100 .KEY_IKE_SESSION_AES_CTR_KEY_SIZE_INT_ARRAY); 1101 for (int aesCtrKeyLen : aesCtrKeyLens) { 1102 if (validateConfig(aesCtrKeyLen, VALID_KEY_LENGTHS, CONFIG_TYPE_KEY_LEN)) { 1103 saProposalBuilder.addEncryptionAlgorithm(encryptionAlgo, aesCtrKeyLen); 1104 } 1105 } 1106 } 1107 } 1108 1109 int[] integrityAlgos = 1110 getConfig(CarrierConfigManager.Iwlan.KEY_SUPPORTED_INTEGRITY_ALGORITHMS_INT_ARRAY); 1111 for (int integrityAlgo : integrityAlgos) { 1112 if (validateConfig(integrityAlgo, VALID_INTEGRITY_ALGOS, CONFIG_TYPE_INTEGRITY_ALGO)) { 1113 saProposalBuilder.addIntegrityAlgorithm(integrityAlgo); 1114 } 1115 } 1116 1117 int[] prfAlgos = 1118 getConfig(CarrierConfigManager.Iwlan.KEY_SUPPORTED_PRF_ALGORITHMS_INT_ARRAY); 1119 for (int prfAlgo : prfAlgos) { 1120 if (validateConfig(prfAlgo, VALID_PRF_ALGOS, CONFIG_TYPE_PRF_ALGO)) { 1121 saProposalBuilder.addPseudorandomFunction(prfAlgo); 1122 } 1123 } 1124 1125 return saProposalBuilder.build(); 1126 } 1127 validateConfig(int config, Set<Integer> validConfigValues, String configType)1128 private boolean validateConfig(int config, Set<Integer> validConfigValues, String configType) { 1129 if (validConfigValues.contains(config)) { 1130 return true; 1131 } 1132 1133 Log.e(TAG, "Invalid config value for " + configType + ":" + config); 1134 return false; 1135 } 1136 buildChildSaProposal()1137 private ChildSaProposal buildChildSaProposal() { 1138 ChildSaProposal.Builder saProposalBuilder = new ChildSaProposal.Builder(); 1139 1140 // IKE library doesn't add KE payload if dh groups are not set in child session params. 1141 // Use the same groups as that of IKE session. 1142 if (getConfig(CarrierConfigManager.Iwlan.KEY_ADD_KE_TO_CHILD_SESSION_REKEY_BOOL)) { 1143 int[] dhGroups = 1144 getConfig(CarrierConfigManager.Iwlan.KEY_DIFFIE_HELLMAN_GROUPS_INT_ARRAY); 1145 for (int dhGroup : dhGroups) { 1146 if (validateConfig(dhGroup, VALID_DH_GROUPS, CONFIG_TYPE_DH_GROUP)) { 1147 saProposalBuilder.addDhGroup(dhGroup); 1148 } 1149 } 1150 } 1151 1152 int[] encryptionAlgos = 1153 getConfig( 1154 CarrierConfigManager.Iwlan 1155 .KEY_SUPPORTED_CHILD_SESSION_ENCRYPTION_ALGORITHMS_INT_ARRAY); 1156 for (int encryptionAlgo : encryptionAlgos) { 1157 if (validateConfig(encryptionAlgo, VALID_ENCRYPTION_ALGOS, CONFIG_TYPE_ENCRYPT_ALGO)) { 1158 if (ChildSaProposal.getSupportedEncryptionAlgorithms().contains(encryptionAlgo)) { 1159 if (encryptionAlgo == SaProposal.ENCRYPTION_ALGORITHM_AES_CBC) { 1160 int[] aesCbcKeyLens = 1161 getConfig( 1162 CarrierConfigManager.Iwlan 1163 .KEY_CHILD_SESSION_AES_CBC_KEY_SIZE_INT_ARRAY); 1164 for (int aesCbcKeyLen : aesCbcKeyLens) { 1165 if (validateConfig( 1166 aesCbcKeyLen, VALID_KEY_LENGTHS, CONFIG_TYPE_KEY_LEN)) { 1167 saProposalBuilder.addEncryptionAlgorithm( 1168 encryptionAlgo, aesCbcKeyLen); 1169 } 1170 } 1171 } 1172 1173 if (encryptionAlgo == SaProposal.ENCRYPTION_ALGORITHM_AES_CTR) { 1174 int[] aesCtrKeyLens = 1175 getConfig( 1176 CarrierConfigManager.Iwlan 1177 .KEY_CHILD_SESSION_AES_CTR_KEY_SIZE_INT_ARRAY); 1178 for (int aesCtrKeyLen : aesCtrKeyLens) { 1179 if (validateConfig( 1180 aesCtrKeyLen, VALID_KEY_LENGTHS, CONFIG_TYPE_KEY_LEN)) { 1181 saProposalBuilder.addEncryptionAlgorithm( 1182 encryptionAlgo, aesCtrKeyLen); 1183 } 1184 } 1185 } 1186 } else { 1187 Log.w(TAG, "Device does not support encryption alog: " + encryptionAlgo); 1188 } 1189 } 1190 } 1191 1192 int[] integrityAlgos = 1193 getConfig(CarrierConfigManager.Iwlan.KEY_SUPPORTED_INTEGRITY_ALGORITHMS_INT_ARRAY); 1194 for (int integrityAlgo : integrityAlgos) { 1195 if (validateConfig(integrityAlgo, VALID_INTEGRITY_ALGOS, CONFIG_TYPE_INTEGRITY_ALGO)) { 1196 if (ChildSaProposal.getSupportedIntegrityAlgorithms().contains(integrityAlgo)) { 1197 saProposalBuilder.addIntegrityAlgorithm(integrityAlgo); 1198 } else { 1199 Log.w(TAG, "Device does not support integrity alog: " + integrityAlgo); 1200 } 1201 } 1202 } 1203 1204 return saProposalBuilder.build(); 1205 } 1206 getLocalIdentification()1207 private IkeIdentification getLocalIdentification() throws IwlanSimNotReadyException { 1208 String nai; 1209 1210 nai = IwlanHelper.getNai(mContext, mSlotId, mNextReauthId); 1211 1212 if (nai == null) { 1213 throw new IwlanSimNotReadyException("Nai is null."); 1214 } 1215 1216 Log.d(TAG, "getLocalIdentification: Nai: " + nai); 1217 return getId(nai, true); 1218 } 1219 getId(String id, boolean isLocal)1220 private IkeIdentification getId(String id, boolean isLocal) { 1221 String idTypeConfig = 1222 isLocal 1223 ? CarrierConfigManager.Iwlan.KEY_IKE_LOCAL_ID_TYPE_INT 1224 : CarrierConfigManager.Iwlan.KEY_IKE_REMOTE_ID_TYPE_INT; 1225 int idType = getConfig(idTypeConfig); 1226 switch (idType) { 1227 case CarrierConfigManager.Iwlan.ID_TYPE_FQDN: 1228 return new IkeFqdnIdentification(id); 1229 case CarrierConfigManager.Iwlan.ID_TYPE_KEY_ID: 1230 return new IkeKeyIdIdentification(id.getBytes(StandardCharsets.US_ASCII)); 1231 case CarrierConfigManager.Iwlan.ID_TYPE_RFC822_ADDR: 1232 return new IkeRfc822AddrIdentification(id); 1233 default: 1234 throw new IllegalArgumentException("Invalid local Identity type: " + idType); 1235 } 1236 } 1237 getEapConfig()1238 private EapSessionConfig getEapConfig() throws IwlanSimNotReadyException { 1239 int subId = IwlanHelper.getSubId(mContext, mSlotId); 1240 String nai = IwlanHelper.getNai(mContext, mSlotId, null); 1241 1242 if (nai == null) { 1243 throw new IwlanSimNotReadyException("Nai is null."); 1244 } 1245 1246 EapSessionConfig.EapAkaOption option = null; 1247 if (mNextReauthId != null) { 1248 option = new EapSessionConfig.EapAkaOption.Builder().setReauthId(mNextReauthId).build(); 1249 } 1250 1251 Log.d(TAG, "getEapConfig: Nai: " + nai); 1252 return new EapSessionConfig.Builder() 1253 .setEapAkaConfig(subId, TelephonyManager.APPTYPE_USIM, option) 1254 .setEapIdentity(nai.getBytes(StandardCharsets.US_ASCII)) 1255 .build(); 1256 } 1257 onSessionClosedWithException( IkeException exception, String apnName, int token, int sessionType)1258 private void onSessionClosedWithException( 1259 IkeException exception, String apnName, int token, int sessionType) { 1260 Log.e( 1261 TAG, 1262 "Closing tunnel with exception for apn: " 1263 + apnName 1264 + " with token: " 1265 + token 1266 + " sessionType:" 1267 + sessionType); 1268 exception.printStackTrace(); 1269 1270 mHandler.sendMessage( 1271 mHandler.obtainMessage( 1272 sessionType, new SessionClosedData(apnName, token, exception))); 1273 } 1274 isEpdgSelectionOrFirstTunnelBringUpInProgress()1275 private boolean isEpdgSelectionOrFirstTunnelBringUpInProgress() { 1276 // Tunnel config is created but not connected to an ePDG. i.e., The first bring-up request 1277 // in progress. 1278 // No bring-up request in progress but pending queue is not empty. i.e. ePDG selection in 1279 // progress 1280 return (!mHasConnectedToEpdg && !mApnNameToTunnelConfig.isEmpty()) 1281 || !mPendingBringUpRequests.isEmpty(); 1282 } 1283 getErrorFromIkeException( IkeException ikeException, IkeSessionState ikeSessionState)1284 private IwlanError getErrorFromIkeException( 1285 IkeException ikeException, IkeSessionState ikeSessionState) { 1286 IwlanError error; 1287 if (ikeException instanceof IkeIOException) { 1288 error = new IwlanError(ikeSessionState.getErrorType(), ikeException); 1289 } else { 1290 error = new IwlanError(ikeException); 1291 } 1292 Log.e(TAG, "Closing tunnel: error: " + error + " state: " + ikeSessionState); 1293 return error; 1294 } 1295 1296 private final class TmHandler extends Handler { 1297 1298 @Override handleMessage(Message msg)1299 public void handleMessage(Message msg) { 1300 Log.d(TAG, "msg.what = " + eventToString(msg.what)); 1301 1302 String apnName; 1303 TunnelConfig tunnelConfig; 1304 OnClosedMetrics.Builder onClosedMetricsBuilder; 1305 switch (msg.what) { 1306 case EVENT_CHILD_SESSION_OPENED: 1307 case EVENT_IKE_SESSION_CLOSED: 1308 case EVENT_IPSEC_TRANSFORM_CREATED: 1309 case EVENT_IPSEC_TRANSFORM_DELETED: 1310 case EVENT_CHILD_SESSION_CLOSED: 1311 case EVENT_IKE_SESSION_OPENED: 1312 case EVENT_IKE_SESSION_CONNECTION_INFO_CHANGED: 1313 case EVENT_IKE_3GPP_DATA_RECEIVED: 1314 IkeEventData ikeEventData = (IkeEventData) msg.obj; 1315 if (isObsoleteToken(ikeEventData.mApnName, ikeEventData.mToken)) { 1316 Log.d( 1317 TAG, 1318 eventToString(msg.what) 1319 + " for obsolete token " 1320 + ikeEventData.mToken); 1321 return; 1322 } 1323 } 1324 1325 long mIkeTunnelEstablishmentDuration; 1326 switch (msg.what) { 1327 case EVENT_TUNNEL_BRINGUP_REQUEST: 1328 TunnelRequestWrapper tunnelRequestWrapper = (TunnelRequestWrapper) msg.obj; 1329 TunnelSetupRequest setupRequest = tunnelRequestWrapper.getSetupRequest(); 1330 IwlanError bringUpError = null; 1331 1332 onClosedMetricsBuilder = 1333 new OnClosedMetrics.Builder().setApnName(setupRequest.apnName()); 1334 1335 if (IwlanHelper.getSubId(mContext, mSlotId) 1336 == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 1337 Log.e(TAG, "SIM isn't ready"); 1338 bringUpError = new IwlanError(IwlanError.SIM_NOT_READY_EXCEPTION); 1339 reportIwlanError(setupRequest.apnName(), bringUpError); 1340 } else if (Objects.isNull(mDefaultNetwork)) { 1341 Log.e(TAG, "The default network is not ready"); 1342 bringUpError = new IwlanError(IwlanError.IKE_INTERNAL_IO_EXCEPTION); 1343 reportIwlanError(setupRequest.apnName(), bringUpError); 1344 } else if (!canBringUpTunnel(setupRequest.apnName())) { 1345 Log.d(TAG, "Cannot bring up tunnel as retry time has not passed"); 1346 bringUpError = getLastError(setupRequest.apnName()); 1347 } 1348 1349 if (Objects.nonNull(bringUpError)) { 1350 tunnelRequestWrapper 1351 .getTunnelCallback() 1352 .onClosed(setupRequest.apnName(), bringUpError); 1353 tunnelRequestWrapper 1354 .getTunnelMetrics() 1355 .onClosed(onClosedMetricsBuilder.build()); 1356 return; 1357 } 1358 1359 if (mHasConnectedToEpdg) { 1360 // Service the request immediately when epdg address is available 1361 onBringUpTunnel( 1362 setupRequest, 1363 tunnelRequestWrapper.getTunnelCallback(), 1364 tunnelRequestWrapper.getTunnelMetrics()); 1365 break; 1366 } 1367 1368 if (!isEpdgSelectionOrFirstTunnelBringUpInProgress()) { 1369 // No tunnel bring-up in progress. Select the ePDG address first 1370 selectEpdgAddress(setupRequest); 1371 } 1372 1373 // Another bring-up or ePDG selection is in progress, pending this request. 1374 mPendingBringUpRequests.add(tunnelRequestWrapper); 1375 break; 1376 1377 case EVENT_EPDG_ADDRESS_SELECTION_REQUEST_COMPLETE: 1378 EpdgSelectorResult selectorResult = (EpdgSelectorResult) msg.obj; 1379 printRequestQueue("EVENT_EPDG_ADDRESS_SELECTION_REQUEST_COMPLETE"); 1380 1381 if (selectorResult.getTransactionId() != mTransactionId) { 1382 Log.e(TAG, "Mismatched transactionId"); 1383 break; 1384 } 1385 1386 if (mPendingBringUpRequests.isEmpty()) { 1387 Log.d(TAG, "Empty request queue"); 1388 break; 1389 } 1390 1391 if (selectorResult.getEpdgError().getErrorType() == IwlanError.NO_ERROR 1392 && selectorResult.getValidIpList() != null) { 1393 tunnelRequestWrapper = mPendingBringUpRequests.remove(); 1394 validateAndSetEpdgAddress(selectorResult.getValidIpList()); 1395 onBringUpTunnel( 1396 tunnelRequestWrapper.getSetupRequest(), 1397 tunnelRequestWrapper.getTunnelCallback(), 1398 tunnelRequestWrapper.getTunnelMetrics()); 1399 } else { 1400 IwlanError error = 1401 (selectorResult.getEpdgError().getErrorType() 1402 == IwlanError.NO_ERROR) 1403 ? new IwlanError( 1404 IwlanError.EPDG_SELECTOR_SERVER_SELECTION_FAILED) 1405 : selectorResult.getEpdgError(); 1406 failAllPendingRequests(error); 1407 } 1408 break; 1409 1410 case EVENT_CHILD_SESSION_OPENED: 1411 TunnelOpenedData tunnelOpenedData = (TunnelOpenedData) msg.obj; 1412 apnName = tunnelOpenedData.mApnName; 1413 tunnelConfig = mApnNameToTunnelConfig.get(apnName); 1414 1415 tunnelConfig.setDnsAddrList(tunnelOpenedData.mInternalDnsServers); 1416 tunnelConfig.setInternalAddrList(tunnelOpenedData.mInternalAddresses); 1417 1418 IpSecManager.IpSecTunnelInterface tunnelInterface = tunnelConfig.getIface(); 1419 1420 for (LinkAddress address : tunnelConfig.getInternalAddrList()) { 1421 try { 1422 tunnelInterface.addAddress( 1423 address.getAddress(), address.getPrefixLength()); 1424 } catch (IOException e) { 1425 Log.e(TAG, "Adding internal addresses to interface failed."); 1426 } 1427 } 1428 1429 TunnelLinkProperties linkProperties = 1430 TunnelLinkProperties.builder() 1431 .setInternalAddresses(tunnelConfig.getInternalAddrList()) 1432 .setDnsAddresses(tunnelConfig.getDnsAddrList()) 1433 .setPcscfAddresses(tunnelConfig.getPcscfAddrList()) 1434 .setIfaceName(tunnelConfig.getIface().getInterfaceName()) 1435 .setSliceInfo(tunnelConfig.getSliceInfo()) 1436 .build(); 1437 tunnelConfig.getTunnelCallback().onOpened(apnName, linkProperties); 1438 1439 reportIwlanError(apnName, new IwlanError(IwlanError.NO_ERROR)); 1440 1441 mIkeTunnelEstablishmentDuration = 1442 System.currentTimeMillis() - mIkeTunnelEstablishmentStartTime; 1443 mIkeTunnelEstablishmentStartTime = 0; 1444 tunnelConfig 1445 .getTunnelMetrics() 1446 .onOpened( 1447 new OnOpenedMetrics.Builder() 1448 .setApnName(apnName) 1449 .setEpdgServerAddress(mEpdgAddress) 1450 .setEpdgServerSelectionDuration( 1451 (int) mEpdgServerSelectionDuration) 1452 .setIkeTunnelEstablishmentDuration( 1453 (int) mIkeTunnelEstablishmentDuration) 1454 .build()); 1455 1456 onConnectedToEpdg(true); 1457 mValidEpdgInfo.resetIndex(); 1458 printRequestQueue("EVENT_CHILD_SESSION_OPENED"); 1459 serviceAllPendingRequests(); 1460 tunnelConfig.setIkeSessionState(IkeSessionState.CHILD_SESSION_OPENED); 1461 break; 1462 1463 case EVENT_IKE_SESSION_CLOSED: 1464 printRequestQueue("EVENT_IKE_SESSION_CLOSED"); 1465 SessionClosedData sessionClosedData = (SessionClosedData) msg.obj; 1466 apnName = sessionClosedData.mApnName; 1467 1468 tunnelConfig = mApnNameToTunnelConfig.get(apnName); 1469 if (tunnelConfig == null) { 1470 Log.e(TAG, "No callback found for apn: " + apnName); 1471 return; 1472 } 1473 1474 // If IKE session closed exceptionally, we retrieve IwlanError directly from the 1475 // exception; otherwise, it is still possible that we triggered an IKE session 1476 // close due to an error (e.g. IwlanError.TUNNEL_TRANSFORM_FAILED), or because 1477 // the Child session closed exceptionally; in which case, we attempt to retrieve 1478 // the stored error (if any) from TunnelConfig. 1479 IwlanError iwlanError; 1480 if (sessionClosedData.mIkeException != null) { 1481 iwlanError = 1482 getErrorFromIkeException( 1483 sessionClosedData.mIkeException, 1484 tunnelConfig.getIkeSessionState()); 1485 } else { 1486 // If IKE session opened, then closed before child session (and IWLAN 1487 // tunnel) opened. 1488 // Iwlan reports IKE_SESSION_CLOSED_BEFORE_CHILD_SESSION_OPENED 1489 // instead of NO_ERROR 1490 if (!tunnelConfig.hasTunnelOpened()) { 1491 iwlanError = new IwlanError( 1492 IwlanError.IKE_SESSION_CLOSED_BEFORE_CHILD_SESSION_OPENED); 1493 } else { 1494 iwlanError = tunnelConfig.getError(); 1495 } 1496 } 1497 1498 IpSecManager.IpSecTunnelInterface iface = tunnelConfig.getIface(); 1499 if (iface != null) { 1500 iface.close(); 1501 } 1502 1503 if (!tunnelConfig.hasTunnelOpened()) { 1504 if (tunnelConfig.isBackoffTimeValid()) { 1505 reportIwlanError(apnName, iwlanError, tunnelConfig.getBackoffTime()); 1506 } else { 1507 reportIwlanError(apnName, iwlanError); 1508 } 1509 } 1510 1511 Log.d(TAG, "Tunnel Closed: " + iwlanError); 1512 tunnelConfig.setIkeSessionState(IkeSessionState.NO_IKE_SESSION); 1513 tunnelConfig.getTunnelCallback().onClosed(apnName, iwlanError); 1514 onClosedMetricsBuilder = new OnClosedMetrics.Builder().setApnName(apnName); 1515 1516 if (!mHasConnectedToEpdg) { 1517 failAllPendingRequests(iwlanError); 1518 tunnelConfig.getTunnelMetrics().onClosed(onClosedMetricsBuilder.build()); 1519 } else { 1520 mIkeTunnelEstablishmentDuration = 1521 mIkeTunnelEstablishmentStartTime > 0 1522 ? System.currentTimeMillis() 1523 - mIkeTunnelEstablishmentStartTime 1524 : 0; 1525 mIkeTunnelEstablishmentStartTime = 0; 1526 1527 onClosedMetricsBuilder 1528 .setEpdgServerAddress(mEpdgAddress) 1529 .setEpdgServerSelectionDuration((int) mEpdgServerSelectionDuration) 1530 .setIkeTunnelEstablishmentDuration( 1531 (int) mIkeTunnelEstablishmentDuration); 1532 tunnelConfig.getTunnelMetrics().onClosed(onClosedMetricsBuilder.build()); 1533 } 1534 1535 mApnNameToTunnelConfig.remove(apnName); 1536 if (mApnNameToTunnelConfig.size() == 0 && mPendingBringUpRequests.isEmpty()) { 1537 onConnectedToEpdg(false); 1538 } 1539 1540 break; 1541 1542 case EVENT_UPDATE_NETWORK: 1543 UpdateNetworkWrapper updatedNetwork = (UpdateNetworkWrapper) msg.obj; 1544 mDefaultNetwork = updatedNetwork.getNetwork(); 1545 LinkProperties defaultLinkProperties = updatedNetwork.getLinkProperties(); 1546 String paraString = "Network: " + mDefaultNetwork; 1547 1548 if (mHasConnectedToEpdg) { 1549 if (Objects.isNull(mDefaultNetwork)) { 1550 Log.w(TAG, "The default network has been removed."); 1551 } else if (Objects.isNull(defaultLinkProperties)) { 1552 Log.w( 1553 TAG, 1554 "The default network's LinkProperties is not ready ." 1555 + paraString); 1556 } else if (!defaultLinkProperties.isReachable(mEpdgAddress)) { 1557 Log.w( 1558 TAG, 1559 "The default network link " 1560 + defaultLinkProperties 1561 + " doesn't have a route to the ePDG " 1562 + mEpdgAddress 1563 + paraString); 1564 } else if (Objects.equals(mDefaultNetwork, mIkeSessionNetwork)) { 1565 Log.w( 1566 TAG, 1567 "The default network has not changed from the IKE session" 1568 + " network. " 1569 + paraString); 1570 } else { 1571 mApnNameToTunnelConfig.forEach( 1572 (apn, config) -> { 1573 Log.d( 1574 TAG, 1575 "The Underlying Network is updating for APN (+" 1576 + apn 1577 + "). " 1578 + paraString); 1579 config.getIkeSession().setNetwork(mDefaultNetwork); 1580 config.setIkeSessionState( 1581 IkeSessionState.IKE_MOBILITY_IN_PROGRESS); 1582 }); 1583 mIkeSessionNetwork = mDefaultNetwork; 1584 } 1585 } 1586 break; 1587 1588 case EVENT_TUNNEL_BRINGDOWN_REQUEST: 1589 TunnelBringdownRequest bringdownRequest = (TunnelBringdownRequest) msg.obj; 1590 apnName = bringdownRequest.mApnName; 1591 boolean forceClose = bringdownRequest.mForceClose; 1592 tunnelConfig = mApnNameToTunnelConfig.get(apnName); 1593 if (tunnelConfig == null) { 1594 Log.w( 1595 TAG, 1596 "Bringdown request: No tunnel exists for apn: " 1597 + apnName 1598 + "forced: " 1599 + forceClose); 1600 } else { 1601 if (forceClose) { 1602 tunnelConfig.getIkeSession().kill(); 1603 } else { 1604 tunnelConfig.getIkeSession().close(); 1605 } 1606 } 1607 int numClosed = closePendingRequestsForApn(apnName); 1608 if (numClosed > 0) { 1609 Log.d(TAG, "Closed " + numClosed + " pending requests for apn: " + apnName); 1610 } 1611 if (tunnelConfig == null && numClosed == 0) { 1612 // IwlanDataService expected to close a (pending or up) tunnel but was not 1613 // found. Recovers state in IwlanDataService through TunnelCallback. 1614 iwlanError = new IwlanError(IwlanError.TUNNEL_NOT_FOUND); 1615 reportIwlanError(apnName, iwlanError); 1616 bringdownRequest.mTunnelCallback.onClosed(apnName, iwlanError); 1617 bringdownRequest.mIwlanTunnelMetrics.onClosed( 1618 new OnClosedMetrics.Builder().setApnName(apnName).build()); 1619 } 1620 break; 1621 1622 case EVENT_IPSEC_TRANSFORM_CREATED: 1623 IpsecTransformData transformData = (IpsecTransformData) msg.obj; 1624 apnName = transformData.getApnName(); 1625 IpSecManager ipSecManager = mContext.getSystemService(IpSecManager.class); 1626 tunnelConfig = mApnNameToTunnelConfig.get(apnName); 1627 1628 if (tunnelConfig.getIface() == null) { 1629 try { 1630 tunnelConfig.setIface( 1631 ipSecManager.createIpSecTunnelInterface( 1632 DUMMY_ADDR /* unused */, 1633 DUMMY_ADDR /* unused */, 1634 mDefaultNetwork)); 1635 } catch (IpSecManager.ResourceUnavailableException | IOException e) { 1636 Log.e(TAG, "Failed to create tunnel interface. " + e); 1637 closeIkeSession( 1638 apnName, new IwlanError(IwlanError.TUNNEL_TRANSFORM_FAILED)); 1639 return; 1640 } 1641 } 1642 1643 try { 1644 assert ipSecManager != null; 1645 ipSecManager.applyTunnelModeTransform( 1646 tunnelConfig.getIface(), 1647 transformData.getDirection(), 1648 transformData.getTransform()); 1649 } catch (IOException | IllegalArgumentException e) { 1650 // If the IKE session was closed before the transform could be applied, the 1651 // IpSecService will throw an IAE on processing the IpSecTunnelInterface id. 1652 Log.e(TAG, "Failed to apply tunnel transform." + e); 1653 closeIkeSession( 1654 apnName, new IwlanError(IwlanError.TUNNEL_TRANSFORM_FAILED)); 1655 } 1656 if (tunnelConfig.getIkeSessionState() 1657 == IkeSessionState.IKE_MOBILITY_IN_PROGRESS) { 1658 tunnelConfig.setIkeSessionState(IkeSessionState.CHILD_SESSION_OPENED); 1659 } 1660 break; 1661 1662 case EVENT_IPSEC_TRANSFORM_DELETED: 1663 transformData = (IpsecTransformData) msg.obj; 1664 IpSecTransform transform = transformData.getTransform(); 1665 transform.close(); 1666 break; 1667 1668 case EVENT_CHILD_SESSION_CLOSED: 1669 sessionClosedData = (SessionClosedData) msg.obj; 1670 apnName = sessionClosedData.mApnName; 1671 1672 tunnelConfig = mApnNameToTunnelConfig.get(apnName); 1673 if (tunnelConfig == null) { 1674 Log.d(TAG, "No tunnel callback for apn: " + apnName); 1675 return; 1676 } 1677 if (sessionClosedData.mIkeException != null) { 1678 tunnelConfig.setError( 1679 getErrorFromIkeException( 1680 sessionClosedData.mIkeException, 1681 tunnelConfig.getIkeSessionState())); 1682 } 1683 tunnelConfig.getIkeSession().close(); 1684 break; 1685 1686 case EVENT_IKE_SESSION_OPENED: 1687 IkeSessionOpenedData ikeSessionOpenedData = (IkeSessionOpenedData) msg.obj; 1688 apnName = ikeSessionOpenedData.mApnName; 1689 IkeSessionConfiguration sessionConfiguration = 1690 ikeSessionOpenedData.mIkeSessionConfiguration; 1691 1692 tunnelConfig = mApnNameToTunnelConfig.get(apnName); 1693 tunnelConfig.setPcscfAddrList(sessionConfiguration.getPcscfServers()); 1694 1695 boolean enabledFastReauth = 1696 getConfig( 1697 CarrierConfigManager.Iwlan 1698 .KEY_SUPPORTS_EAP_AKA_FAST_REAUTH_BOOL); 1699 Log.d( 1700 TAG, 1701 "CarrierConfigManager.Iwlan.KEY_SUPPORTS_EAP_AKA_FAST_REAUTH_BOOL " 1702 + enabledFastReauth); 1703 1704 if (enabledFastReauth) { 1705 EapInfo eapInfo = sessionConfiguration.getEapInfo(); 1706 if (eapInfo instanceof EapAkaInfo) { 1707 mNextReauthId = ((EapAkaInfo) eapInfo).getReauthId(); 1708 Log.d(TAG, "Update ReauthId: " + Arrays.toString(mNextReauthId)); 1709 } else { 1710 mNextReauthId = null; 1711 } 1712 } 1713 break; 1714 1715 case EVENT_IKE_SESSION_CONNECTION_INFO_CHANGED: 1716 IkeSessionConnectionInfoData ikeSessionConnectionInfoData = 1717 (IkeSessionConnectionInfoData) msg.obj; 1718 Network network = 1719 ikeSessionConnectionInfoData.mIkeSessionConnectionInfo.getNetwork(); 1720 apnName = ikeSessionConnectionInfoData.mApnName; 1721 1722 ConnectivityManager connectivityManager = 1723 mContext.getSystemService(ConnectivityManager.class); 1724 if (Objects.requireNonNull(connectivityManager).getLinkProperties(network) 1725 == null) { 1726 Log.e(TAG, "Network " + network + " has null LinkProperties!"); 1727 return; 1728 } 1729 1730 tunnelConfig = mApnNameToTunnelConfig.get(apnName); 1731 tunnelInterface = tunnelConfig.getIface(); 1732 try { 1733 tunnelInterface.setUnderlyingNetwork(network); 1734 } catch (IOException | IllegalArgumentException e) { 1735 Log.e( 1736 TAG, 1737 "Failed to update underlying network for apn: " 1738 + apnName 1739 + " exception: " 1740 + e); 1741 } 1742 break; 1743 1744 case EVENT_IKE_3GPP_DATA_RECEIVED: 1745 Ike3gppDataReceived ike3gppDataReceived = (Ike3gppDataReceived) msg.obj; 1746 apnName = ike3gppDataReceived.mApnName; 1747 List<Ike3gppData> ike3gppData = ike3gppDataReceived.mIke3gppData; 1748 if (ike3gppData != null && !ike3gppData.isEmpty()) { 1749 tunnelConfig = mApnNameToTunnelConfig.get(apnName); 1750 for (Ike3gppData payload : ike3gppData) { 1751 if (payload.getDataType() == DATA_TYPE_NOTIFY_N1_MODE_INFORMATION) { 1752 Log.d(TAG, "Got payload DATA_TYPE_NOTIFY_N1_MODE_INFORMATION"); 1753 NetworkSliceInfo si = 1754 NetworkSliceSelectionAssistanceInformation.getSliceInfo( 1755 ((Ike3gppN1ModeInformation) payload).getSnssai()); 1756 if (si != null) { 1757 tunnelConfig.setSliceInfo(si); 1758 Log.d(TAG, "SliceInfo: " + si); 1759 } 1760 } else if (payload.getDataType() == DATA_TYPE_NOTIFY_BACKOFF_TIMER) { 1761 Log.d(TAG, "Got payload DATA_TYPE_NOTIFY_BACKOFF_TIMER"); 1762 long backoffTime = 1763 decodeBackoffTime( 1764 ((Ike3gppBackoffTimer) payload).getBackoffTimer()); 1765 if (backoffTime > 0) { 1766 tunnelConfig.setBackoffTime(backoffTime); 1767 Log.d(TAG, "Backoff Timer: " + backoffTime); 1768 } 1769 } 1770 } 1771 } else { 1772 Log.e(TAG, "Null or empty payloads received:"); 1773 } 1774 break; 1775 1776 default: 1777 throw new IllegalStateException("Unexpected value: " + msg.what); 1778 } 1779 } 1780 TmHandler(Looper looper)1781 TmHandler(Looper looper) { 1782 super(looper); 1783 } 1784 } 1785 closeIkeSession(String apnName, IwlanError error)1786 private void closeIkeSession(String apnName, IwlanError error) { 1787 TunnelConfig tunnelConfig = mApnNameToTunnelConfig.get(apnName); 1788 tunnelConfig.setError(error); 1789 tunnelConfig.getIkeSession().close(); 1790 } 1791 selectEpdgAddress(TunnelSetupRequest setupRequest)1792 private void selectEpdgAddress(TunnelSetupRequest setupRequest) { 1793 ++mTransactionId; 1794 mEpdgServerSelectionStartTime = System.currentTimeMillis(); 1795 1796 final int ipPreference = 1797 IwlanHelper.getConfig( 1798 CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_IP_TYPE_PREFERENCE_INT, 1799 mContext, 1800 mSlotId); 1801 1802 IpPreferenceConflict ipPreferenceConflict = 1803 isIpPreferenceConflictsWithNetwork(ipPreference); 1804 if (ipPreferenceConflict.mIsConflict) { 1805 sendSelectionRequestComplete( 1806 null, new IwlanError(ipPreferenceConflict.mErrorType), mTransactionId); 1807 return; 1808 } 1809 1810 int protoFilter = EpdgSelector.PROTO_FILTER_IPV4V6; 1811 int epdgAddressOrder = EpdgSelector.SYSTEM_PREFERRED; 1812 switch (ipPreference) { 1813 case CarrierConfigManager.Iwlan.EPDG_ADDRESS_IPV4_PREFERRED: 1814 epdgAddressOrder = EpdgSelector.IPV4_PREFERRED; 1815 break; 1816 case CarrierConfigManager.Iwlan.EPDG_ADDRESS_IPV6_PREFERRED: 1817 epdgAddressOrder = EpdgSelector.IPV6_PREFERRED; 1818 break; 1819 case CarrierConfigManager.Iwlan.EPDG_ADDRESS_IPV4_ONLY: 1820 protoFilter = EpdgSelector.PROTO_FILTER_IPV4; 1821 break; 1822 case CarrierConfigManager.Iwlan.EPDG_ADDRESS_IPV6_ONLY: 1823 protoFilter = EpdgSelector.PROTO_FILTER_IPV6; 1824 break; 1825 case CarrierConfigManager.Iwlan.EPDG_ADDRESS_SYSTEM_PREFERRED: 1826 break; 1827 default: 1828 Log.w(TAG, "Invalid Ip preference : " + ipPreference); 1829 } 1830 1831 EpdgSelector epdgSelector = getEpdgSelector(); 1832 IwlanError epdgError = 1833 epdgSelector.getValidatedServerList( 1834 mTransactionId, 1835 protoFilter, 1836 epdgAddressOrder, 1837 setupRequest.isRoaming(), 1838 setupRequest.isEmergency(), 1839 mDefaultNetwork, 1840 mSelectorCallback); 1841 1842 if (epdgError.getErrorType() != IwlanError.NO_ERROR) { 1843 Log.e(TAG, "Epdg address selection failed with error:" + epdgError); 1844 sendSelectionRequestComplete(null, epdgError, mTransactionId); 1845 } 1846 } 1847 1848 @VisibleForTesting getEpdgSelector()1849 EpdgSelector getEpdgSelector() { 1850 return EpdgSelector.getSelectorInstance(mContext, mSlotId); 1851 } 1852 1853 @VisibleForTesting closePendingRequestsForApn(String apnName)1854 int closePendingRequestsForApn(String apnName) { 1855 int numRequestsClosed = 0; 1856 int queueSize = mPendingBringUpRequests.size(); 1857 if (queueSize == 0) { 1858 return numRequestsClosed; 1859 } 1860 1861 for (int count = 0; count < queueSize; count++) { 1862 TunnelRequestWrapper requestWrapper = mPendingBringUpRequests.remove(); 1863 if (requestWrapper.getSetupRequest().apnName().equals(apnName)) { 1864 requestWrapper 1865 .getTunnelCallback() 1866 .onClosed(apnName, new IwlanError(IwlanError.NO_ERROR)); 1867 1868 requestWrapper 1869 .getTunnelMetrics() 1870 .onClosed( 1871 new OnClosedMetrics.Builder() 1872 .setApnName(apnName) 1873 .setEpdgServerAddress(mEpdgAddress) 1874 .build()); 1875 numRequestsClosed++; 1876 } else { 1877 mPendingBringUpRequests.add(requestWrapper); 1878 } 1879 } 1880 return numRequestsClosed; 1881 } 1882 1883 @VisibleForTesting validateAndSetEpdgAddress(List<InetAddress> selectorResultList)1884 void validateAndSetEpdgAddress(List<InetAddress> selectorResultList) { 1885 List<InetAddress> addrList = mValidEpdgInfo.getAddrList(); 1886 if (addrList == null || !addrList.equals(selectorResultList)) { 1887 Log.d(TAG, "Update ePDG address list."); 1888 mValidEpdgInfo.setAddrList(selectorResultList); 1889 addrList = mValidEpdgInfo.getAddrList(); 1890 } 1891 1892 int index = mValidEpdgInfo.getIndex(); 1893 Log.d( 1894 TAG, 1895 "Valid ePDG Address List: " 1896 + Arrays.toString(addrList.toArray()) 1897 + ", index = " 1898 + index); 1899 mEpdgAddress = addrList.get(index); 1900 mValidEpdgInfo.incrementIndex(); 1901 } 1902 serviceAllPendingRequests()1903 private void serviceAllPendingRequests() { 1904 while (!mPendingBringUpRequests.isEmpty()) { 1905 Log.d(TAG, "serviceAllPendingRequests"); 1906 TunnelRequestWrapper request = mPendingBringUpRequests.remove(); 1907 onBringUpTunnel( 1908 request.getSetupRequest(), 1909 request.getTunnelCallback(), 1910 request.getTunnelMetrics()); 1911 } 1912 } 1913 failAllPendingRequests(IwlanError error)1914 private void failAllPendingRequests(IwlanError error) { 1915 while (!mPendingBringUpRequests.isEmpty()) { 1916 Log.d(TAG, "failAllPendingRequests"); 1917 TunnelRequestWrapper request = mPendingBringUpRequests.remove(); 1918 TunnelSetupRequest setupRequest = request.getSetupRequest(); 1919 reportIwlanError(setupRequest.apnName(), error); 1920 request.getTunnelCallback().onClosed(setupRequest.apnName(), error); 1921 request.getTunnelMetrics() 1922 .onClosed( 1923 new OnClosedMetrics.Builder() 1924 .setApnName(setupRequest.apnName()) 1925 .setEpdgServerAddress(mEpdgAddress) 1926 .build()); 1927 } 1928 } 1929 1930 // Prints mPendingBringUpRequests printRequestQueue(String info)1931 private void printRequestQueue(String info) { 1932 Log.d(TAG, info); 1933 Log.d( 1934 TAG, 1935 "mPendingBringUpRequests: " + Arrays.toString(mPendingBringUpRequests.toArray())); 1936 } 1937 1938 // Update Network wrapper 1939 private static final class UpdateNetworkWrapper { 1940 private final Network mNetwork; 1941 private final LinkProperties mLinkProperties; 1942 UpdateNetworkWrapper(Network network, LinkProperties linkProperties)1943 private UpdateNetworkWrapper(Network network, LinkProperties linkProperties) { 1944 mNetwork = network; 1945 mLinkProperties = linkProperties; 1946 } 1947 getNetwork()1948 public Network getNetwork() { 1949 return mNetwork; 1950 } 1951 getLinkProperties()1952 public LinkProperties getLinkProperties() { 1953 return mLinkProperties; 1954 } 1955 } 1956 1957 // Tunnel request + tunnel callback 1958 private static final class TunnelRequestWrapper { 1959 private final TunnelSetupRequest mSetupRequest; 1960 1961 private final TunnelCallback mTunnelCallback; 1962 private final TunnelMetricsInterface mTunnelMetrics; 1963 TunnelRequestWrapper( TunnelSetupRequest setupRequest, TunnelCallback tunnelCallback, TunnelMetricsInterface tunnelMetrics)1964 private TunnelRequestWrapper( 1965 TunnelSetupRequest setupRequest, 1966 TunnelCallback tunnelCallback, 1967 TunnelMetricsInterface tunnelMetrics) { 1968 mTunnelCallback = tunnelCallback; 1969 mSetupRequest = setupRequest; 1970 mTunnelMetrics = tunnelMetrics; 1971 } 1972 getSetupRequest()1973 public TunnelSetupRequest getSetupRequest() { 1974 return mSetupRequest; 1975 } 1976 getTunnelCallback()1977 public TunnelCallback getTunnelCallback() { 1978 return mTunnelCallback; 1979 } 1980 getTunnelMetrics()1981 public TunnelMetricsInterface getTunnelMetrics() { 1982 return mTunnelMetrics; 1983 } 1984 } 1985 1986 private static final class TunnelBringdownRequest { 1987 final String mApnName; 1988 final boolean mForceClose; 1989 final TunnelCallback mTunnelCallback; 1990 final IwlanTunnelMetricsImpl mIwlanTunnelMetrics; 1991 TunnelBringdownRequest( String apnName, boolean forceClose, TunnelCallback tunnelCallback, IwlanTunnelMetricsImpl iwlanTunnelMetrics)1992 private TunnelBringdownRequest( 1993 String apnName, 1994 boolean forceClose, 1995 TunnelCallback tunnelCallback, 1996 IwlanTunnelMetricsImpl iwlanTunnelMetrics) { 1997 mApnName = apnName; 1998 mForceClose = forceClose; 1999 mTunnelCallback = tunnelCallback; 2000 mIwlanTunnelMetrics = iwlanTunnelMetrics; 2001 } 2002 } 2003 2004 private static final class EpdgSelectorResult { 2005 private final List<InetAddress> mValidIpList; 2006 getValidIpList()2007 public List<InetAddress> getValidIpList() { 2008 return mValidIpList; 2009 } 2010 getEpdgError()2011 public IwlanError getEpdgError() { 2012 return mEpdgError; 2013 } 2014 getTransactionId()2015 public int getTransactionId() { 2016 return mTransactionId; 2017 } 2018 2019 private final IwlanError mEpdgError; 2020 private final int mTransactionId; 2021 EpdgSelectorResult( List<InetAddress> validIpList, IwlanError epdgError, int transactionId)2022 private EpdgSelectorResult( 2023 List<InetAddress> validIpList, IwlanError epdgError, int transactionId) { 2024 mValidIpList = validIpList; 2025 mEpdgError = epdgError; 2026 mTransactionId = transactionId; 2027 } 2028 } 2029 2030 // Data received from IkeSessionStateMachine on successful EVENT_CHILD_SESSION_OPENED. 2031 private static final class TunnelOpenedData extends IkeEventData { 2032 final List<InetAddress> mInternalDnsServers; 2033 final List<LinkAddress> mInternalAddresses; 2034 TunnelOpenedData( String apnName, int token, List<InetAddress> internalDnsServers, List<LinkAddress> internalAddresses)2035 private TunnelOpenedData( 2036 String apnName, 2037 int token, 2038 List<InetAddress> internalDnsServers, 2039 List<LinkAddress> internalAddresses) { 2040 super(apnName, token); 2041 mInternalDnsServers = internalDnsServers; 2042 mInternalAddresses = internalAddresses; 2043 } 2044 } 2045 2046 // Data received from IkeSessionStateMachine on successful EVENT_IKE_SESSION_OPENED. 2047 private static final class IkeSessionOpenedData extends IkeEventData { 2048 final IkeSessionConfiguration mIkeSessionConfiguration; 2049 IkeSessionOpenedData( String apnName, int token, IkeSessionConfiguration ikeSessionConfiguration)2050 private IkeSessionOpenedData( 2051 String apnName, int token, IkeSessionConfiguration ikeSessionConfiguration) { 2052 super(apnName, token); 2053 mIkeSessionConfiguration = ikeSessionConfiguration; 2054 } 2055 } 2056 2057 private static final class IkeSessionConnectionInfoData extends IkeEventData { 2058 final IkeSessionConnectionInfo mIkeSessionConnectionInfo; 2059 IkeSessionConnectionInfoData( String apnName, int token, IkeSessionConnectionInfo ikeSessionConnectionInfo)2060 private IkeSessionConnectionInfoData( 2061 String apnName, int token, IkeSessionConnectionInfo ikeSessionConnectionInfo) { 2062 super(apnName, token); 2063 mIkeSessionConnectionInfo = ikeSessionConnectionInfo; 2064 } 2065 } 2066 2067 private static final class Ike3gppDataReceived extends IkeEventData { 2068 final List<Ike3gppData> mIke3gppData; 2069 Ike3gppDataReceived(String apnName, int token, List<Ike3gppData> ike3gppData)2070 private Ike3gppDataReceived(String apnName, int token, List<Ike3gppData> ike3gppData) { 2071 super(apnName, token); 2072 mIke3gppData = ike3gppData; 2073 } 2074 } 2075 2076 // Data received from IkeSessionStateMachine if either IKE session or Child session have been 2077 // closed, normally or exceptionally. 2078 private static final class SessionClosedData extends IkeEventData { 2079 final IkeException mIkeException; 2080 SessionClosedData(String apnName, int token, IkeException ikeException)2081 private SessionClosedData(String apnName, int token, IkeException ikeException) { 2082 super(apnName, token); 2083 mIkeException = ikeException; 2084 } 2085 } 2086 2087 private static final class IpsecTransformData extends IkeEventData { 2088 private final IpSecTransform mTransform; 2089 private final int mDirection; 2090 IpsecTransformData( IpSecTransform transform, int direction, String apnName, int token)2091 private IpsecTransformData( 2092 IpSecTransform transform, int direction, String apnName, int token) { 2093 super(apnName, token); 2094 mTransform = transform; 2095 mDirection = direction; 2096 } 2097 getTransform()2098 public IpSecTransform getTransform() { 2099 return mTransform; 2100 } 2101 getDirection()2102 public int getDirection() { 2103 return mDirection; 2104 } 2105 getApnName()2106 public String getApnName() { 2107 return super.mApnName; 2108 } 2109 } 2110 2111 private abstract static class IkeEventData { 2112 final String mApnName; 2113 final int mToken; 2114 IkeEventData(String apnName, int token)2115 private IkeEventData(String apnName, int token) { 2116 mApnName = apnName; 2117 mToken = token; 2118 } 2119 } 2120 2121 private static final class EpdgInfo { 2122 private List<InetAddress> mAddrList; 2123 private int mIndex; 2124 EpdgInfo()2125 private EpdgInfo() { 2126 mAddrList = null; 2127 mIndex = 0; 2128 } 2129 getAddrList()2130 public List<InetAddress> getAddrList() { 2131 return mAddrList; 2132 } 2133 setAddrList(@onNull List<InetAddress> AddrList)2134 public void setAddrList(@NonNull List<InetAddress> AddrList) { 2135 mAddrList = AddrList; 2136 resetIndex(); 2137 } 2138 getIndex()2139 public int getIndex() { 2140 return mIndex; 2141 } 2142 incrementIndex()2143 public void incrementIndex() { 2144 if (getIndex() >= getAddrList().size() - 1) { 2145 resetIndex(); 2146 } else { 2147 mIndex++; 2148 } 2149 } 2150 resetIndex()2151 public void resetIndex() { 2152 mIndex = 0; 2153 } 2154 } 2155 2156 private static class IpPreferenceConflict { 2157 final boolean mIsConflict; 2158 final int mErrorType; 2159 IpPreferenceConflict(boolean isConflict, int errorType)2160 private IpPreferenceConflict(boolean isConflict, int errorType) { 2161 mIsConflict = isConflict; 2162 mErrorType = errorType; 2163 } 2164 IpPreferenceConflict()2165 private IpPreferenceConflict() { 2166 mIsConflict = false; 2167 mErrorType = IwlanError.NO_ERROR; 2168 } 2169 } 2170 getRetransmissionTimeoutsFromConfig()2171 private int[] getRetransmissionTimeoutsFromConfig() { 2172 int[] timeList = getConfig(CarrierConfigManager.Iwlan.KEY_RETRANSMIT_TIMER_MSEC_INT_ARRAY); 2173 boolean isValid = 2174 timeList != null 2175 && timeList.length != 0 2176 && timeList.length <= IKE_RETRANS_MAX_ATTEMPTS_MAX; 2177 for (int time : Objects.requireNonNull(timeList)) { 2178 if (time < IKE_RETRANS_TIMEOUT_MS_MIN || time > IKE_RETRANS_TIMEOUT_MS_MAX) { 2179 isValid = false; 2180 break; 2181 } 2182 } 2183 if (!isValid) { 2184 timeList = 2185 IwlanHelper.getDefaultConfig( 2186 CarrierConfigManager.Iwlan.KEY_RETRANSMIT_TIMER_MSEC_INT_ARRAY); 2187 } 2188 Log.d(TAG, "getRetransmissionTimeoutsFromConfig: " + Arrays.toString(timeList)); 2189 return timeList; 2190 } 2191 getDpdDelayFromConfig()2192 private int getDpdDelayFromConfig() { 2193 int dpdDelay = getConfig(CarrierConfigManager.Iwlan.KEY_DPD_TIMER_SEC_INT); 2194 if (dpdDelay < IKE_DPD_DELAY_SEC_MIN || dpdDelay > IKE_DPD_DELAY_SEC_MAX) { 2195 dpdDelay = 2196 IwlanHelper.getDefaultConfig(CarrierConfigManager.Iwlan.KEY_DPD_TIMER_SEC_INT); 2197 } 2198 return dpdDelay; 2199 } 2200 2201 /** 2202 * Decodes backoff time as per TS 124 008 10.5.7.4a Bits 5 to 1 represent the binary coded timer 2203 * value 2204 * 2205 * <p>Bits 6 to 8 defines the timer value unit for the GPRS timer as follows: Bits 8 7 6 0 0 0 2206 * value is incremented in multiples of 10 minutes 0 0 1 value is incremented in multiples of 1 2207 * hour 0 1 0 value is incremented in multiples of 10 hours 0 1 1 value is incremented in 2208 * multiples of 2 seconds 1 0 0 value is incremented in multiples of 30 seconds 1 0 1 value is 2209 * incremented in multiples of 1 minute 1 1 0 value is incremented in multiples of 1 hour 1 1 1 2210 * value indicates that the timer is deactivated. 2211 * 2212 * @param backoffTimeByte Byte value obtained from ike 2213 * @return long time value in seconds. -1 if the timer needs to be deactivated. 2214 */ decodeBackoffTime(byte backoffTimeByte)2215 private static long decodeBackoffTime(byte backoffTimeByte) { 2216 final int BACKOFF_TIME_VALUE_MASK = 0x1F; 2217 final int BACKOFF_TIMER_UNIT_MASK = 0xE0; 2218 final Long[] BACKOFF_TIMER_UNIT_INCREMENT_SECS = { 2219 10L * 60L, // 10 mins 2220 60L * 60L, // 1 hour 2221 10L * 60L * 60L, // 10 hours 2222 2L, // 2 seconds 2223 30L, // 30 seconds 2224 60L, // 1 minute 2225 60L * 60L, // 1 hour 2226 }; 2227 2228 long time = backoffTimeByte & BACKOFF_TIME_VALUE_MASK; 2229 int timerUnit = (backoffTimeByte & BACKOFF_TIMER_UNIT_MASK) >> 5; 2230 if (timerUnit >= BACKOFF_TIMER_UNIT_INCREMENT_SECS.length) { 2231 return -1; 2232 } 2233 time *= BACKOFF_TIMER_UNIT_INCREMENT_SECS[timerUnit]; 2234 return time; 2235 } 2236 2237 @VisibleForTesting getTunnelSetupRequestApnName(TunnelSetupRequest setupRequest)2238 String getTunnelSetupRequestApnName(TunnelSetupRequest setupRequest) { 2239 return setupRequest.apnName(); 2240 } 2241 2242 @VisibleForTesting putApnNameToTunnelConfig( String apnName, IkeSession ikeSession, TunnelCallback tunnelCallback, TunnelMetricsInterface tunnelMetrics, InetAddress srcIpv6Addr, int srcIPv6AddrPrefixLen)2243 void putApnNameToTunnelConfig( 2244 String apnName, 2245 IkeSession ikeSession, 2246 TunnelCallback tunnelCallback, 2247 TunnelMetricsInterface tunnelMetrics, 2248 InetAddress srcIpv6Addr, 2249 int srcIPv6AddrPrefixLen) { 2250 mApnNameToTunnelConfig.put( 2251 apnName, 2252 new TunnelConfig( 2253 ikeSession, 2254 tunnelCallback, 2255 tunnelMetrics, 2256 srcIpv6Addr, 2257 srcIPv6AddrPrefixLen)); 2258 Log.d(TAG, "Added apn: " + apnName + " to TunnelConfig"); 2259 } 2260 2261 @VisibleForTesting incrementAndGetCurrentTokenForApn(String apnName)2262 int incrementAndGetCurrentTokenForApn(String apnName) { 2263 final int currentToken = 2264 mApnNameToCurrentToken.compute( 2265 apnName, (apn, token) -> token == null ? 0 : token + 1); 2266 Log.d(TAG, "Added token: " + currentToken + " for apn: " + apnName); 2267 return currentToken; 2268 } 2269 2270 @VisibleForTesting isN1ModeSupported()2271 boolean isN1ModeSupported() { 2272 int[] nrCarrierCaps = 2273 getConfig(CarrierConfigManager.KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY); 2274 Log.d(TAG, "KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY : " + Arrays.toString(nrCarrierCaps)); 2275 if (Arrays.stream(nrCarrierCaps) 2276 .anyMatch(cap -> cap == CarrierConfigManager.CARRIER_NR_AVAILABILITY_SA)) { 2277 return true; 2278 } else return false; 2279 } 2280 2281 @VisibleForTesting isTunnelConfigContainExistApn(String apnName)2282 boolean isTunnelConfigContainExistApn(String apnName) { 2283 return mApnNameToTunnelConfig.containsKey(apnName); 2284 } 2285 2286 @VisibleForTesting getAddressForNetwork(Network network, Context context)2287 List<InetAddress> getAddressForNetwork(Network network, Context context) { 2288 return IwlanHelper.getAllAddressesForNetwork(network, context); 2289 } 2290 2291 @VisibleForTesting getIkeSessionCreator()2292 IkeSessionCreator getIkeSessionCreator() { 2293 return mIkeSessionCreator; 2294 } 2295 2296 @VisibleForTesting sendSelectionRequestComplete( List<InetAddress> validIPList, IwlanError result, int transactionId)2297 void sendSelectionRequestComplete( 2298 List<InetAddress> validIPList, IwlanError result, int transactionId) { 2299 mEpdgServerSelectionDuration = System.currentTimeMillis() - mEpdgServerSelectionStartTime; 2300 mEpdgServerSelectionStartTime = 0; 2301 EpdgSelectorResult epdgSelectorResult = 2302 new EpdgSelectorResult(validIPList, result, transactionId); 2303 mHandler.sendMessage( 2304 mHandler.obtainMessage( 2305 EVENT_EPDG_ADDRESS_SELECTION_REQUEST_COMPLETE, epdgSelectorResult)); 2306 } 2307 isValidApnProtocol(int proto)2308 static boolean isValidApnProtocol(int proto) { 2309 return (proto == ApnSetting.PROTOCOL_IP 2310 || proto == ApnSetting.PROTOCOL_IPV4V6 2311 || proto == ApnSetting.PROTOCOL_IPV6); 2312 } 2313 isObsoleteToken(String apnName, int token)2314 boolean isObsoleteToken(String apnName, int token) { 2315 if (!mApnNameToCurrentToken.containsKey(apnName)) { 2316 return true; 2317 } 2318 return token != mApnNameToCurrentToken.get(apnName); 2319 } 2320 eventToString(int event)2321 private static String eventToString(int event) { 2322 switch (event) { 2323 case EVENT_TUNNEL_BRINGUP_REQUEST: 2324 return "EVENT_TUNNEL_BRINGUP_REQUEST"; 2325 case EVENT_TUNNEL_BRINGDOWN_REQUEST: 2326 return "EVENT_TUNNEL_BRINGDOWN_REQUEST"; 2327 case EVENT_CHILD_SESSION_OPENED: 2328 return "EVENT_CHILD_SESSION_OPENED"; 2329 case EVENT_CHILD_SESSION_CLOSED: 2330 return "EVENT_CHILD_SESSION_CLOSED"; 2331 case EVENT_IKE_SESSION_CLOSED: 2332 return "EVENT_IKE_SESSION_CLOSED"; 2333 case EVENT_EPDG_ADDRESS_SELECTION_REQUEST_COMPLETE: 2334 return "EVENT_EPDG_ADDRESS_SELECTION_REQUEST_COMPLETE"; 2335 case EVENT_IPSEC_TRANSFORM_CREATED: 2336 return "EVENT_IPSEC_TRANSFORM_CREATED"; 2337 case EVENT_IPSEC_TRANSFORM_DELETED: 2338 return "EVENT_IPSEC_TRANSFORM_DELETED"; 2339 case EVENT_UPDATE_NETWORK: 2340 return "EVENT_UPDATE_NETWORK"; 2341 case EVENT_IKE_SESSION_OPENED: 2342 return "EVENT_IKE_SESSION_OPENED"; 2343 case EVENT_IKE_SESSION_CONNECTION_INFO_CHANGED: 2344 return "EVENT_IKE_SESSION_CONNECTION_INFO_CHANGED"; 2345 case EVENT_IKE_3GPP_DATA_RECEIVED: 2346 return "EVENT_IKE_3GPP_DATA_RECEIVED"; 2347 default: 2348 return "Unknown(" + event + ")"; 2349 } 2350 } 2351 2352 @VisibleForTesting getTmIkeSessionCallback(String apnName, int token)2353 TmIkeSessionCallback getTmIkeSessionCallback(String apnName, int token) { 2354 return new TmIkeSessionCallback(apnName, token); 2355 } 2356 2357 @VisibleForTesting onConnectedToEpdg(boolean hasConnected)2358 void onConnectedToEpdg(boolean hasConnected) { 2359 mHasConnectedToEpdg = hasConnected; 2360 if (mHasConnectedToEpdg) { 2361 mIkeSessionNetwork = mDefaultNetwork; 2362 } else { 2363 mIkeSessionNetwork = null; 2364 mEpdgAddress = null; 2365 } 2366 } 2367 2368 @VisibleForTesting getTunnelConfigForApn(String apnName)2369 TunnelConfig getTunnelConfigForApn(String apnName) { 2370 return mApnNameToTunnelConfig.get(apnName); 2371 } 2372 2373 @VisibleForTesting getCurrentTokenForApn(String apnName)2374 int getCurrentTokenForApn(String apnName) { 2375 if (!mApnNameToCurrentToken.containsKey(apnName)) { 2376 throw new IllegalArgumentException("There is no token for apn: " + apnName); 2377 } 2378 return mApnNameToCurrentToken.get(apnName); 2379 } 2380 2381 @VisibleForTesting reportIwlanError(String apnName, IwlanError error)2382 long reportIwlanError(String apnName, IwlanError error) { 2383 return ErrorPolicyManager.getInstance(mContext, mSlotId).reportIwlanError(apnName, error); 2384 } 2385 2386 @VisibleForTesting reportIwlanError(String apnName, IwlanError error, long backOffTime)2387 long reportIwlanError(String apnName, IwlanError error, long backOffTime) { 2388 return ErrorPolicyManager.getInstance(mContext, mSlotId) 2389 .reportIwlanError(apnName, error, backOffTime); 2390 } 2391 2392 @VisibleForTesting getLastError(String apnName)2393 IwlanError getLastError(String apnName) { 2394 return ErrorPolicyManager.getInstance(mContext, mSlotId).getLastError(apnName); 2395 } 2396 2397 @VisibleForTesting canBringUpTunnel(String apnName)2398 boolean canBringUpTunnel(String apnName) { 2399 return ErrorPolicyManager.getInstance(mContext, mSlotId).canBringUpTunnel(apnName); 2400 } 2401 2402 @VisibleForTesting setEpdgAddress(InetAddress inetAddress)2403 void setEpdgAddress(InetAddress inetAddress) { 2404 mEpdgAddress = inetAddress; 2405 } 2406 2407 @VisibleForTesting isIpPreferenceConflictsWithNetwork( @arrierConfigManager.Iwlan.EpdgAddressIpPreference int ipPreference)2408 IpPreferenceConflict isIpPreferenceConflictsWithNetwork( 2409 @CarrierConfigManager.Iwlan.EpdgAddressIpPreference int ipPreference) { 2410 List<InetAddress> localAddresses = getAddressForNetwork(mDefaultNetwork, mContext); 2411 if (localAddresses == null || localAddresses.size() == 0) { 2412 Log.e(TAG, "No local addresses available for Network " + mDefaultNetwork); 2413 return new IpPreferenceConflict(true, IwlanError.EPDG_SELECTOR_SERVER_SELECTION_FAILED); 2414 } else if (!IwlanHelper.hasIpv6Address(localAddresses) 2415 && ipPreference == CarrierConfigManager.Iwlan.EPDG_ADDRESS_IPV6_ONLY) { 2416 Log.e( 2417 TAG, 2418 "ePDG IP preference: " 2419 + ipPreference 2420 + " conflicts with source IP type: " 2421 + EpdgSelector.PROTO_FILTER_IPV4); 2422 return new IpPreferenceConflict(true, IwlanError.EPDG_ADDRESS_ONLY_IPV6_ALLOWED); 2423 } else if (!IwlanHelper.hasIpv4Address(localAddresses) 2424 && ipPreference == CarrierConfigManager.Iwlan.EPDG_ADDRESS_IPV4_ONLY) { 2425 // b/209938719 allows Iwlan to support VoWiFi for IPv4 ePDG server while on IPv6 WiFi. 2426 // Iwlan will receive a IPv4 address which is embedded in stacked IPv6 address. By using 2427 // this IPv4 address, UE will connect to IPv4 ePDG server through XLAT. However, there 2428 // are issues on connecting ePDG server through XLAT. Will allow IPV4_ONLY on IPv6 WiFi 2429 // after the issues are resolved. 2430 Log.e( 2431 TAG, 2432 "ePDG IP preference: " 2433 + ipPreference 2434 + " conflicts with source IP type: " 2435 + EpdgSelector.PROTO_FILTER_IPV6); 2436 return new IpPreferenceConflict(true, IwlanError.EPDG_ADDRESS_ONLY_IPV4_ALLOWED); 2437 } 2438 return new IpPreferenceConflict(); 2439 } 2440 dump(PrintWriter pw)2441 public void dump(PrintWriter pw) { 2442 pw.println("---- EpdgTunnelManager ----"); 2443 pw.println("mHasConnectedToEpdg: " + mHasConnectedToEpdg); 2444 pw.println("mIkeSessionNetwork: " + mIkeSessionNetwork); 2445 if (mEpdgAddress != null) { 2446 pw.println("mEpdgAddress: " + mEpdgAddress); 2447 } 2448 pw.println("mApnNameToTunnelConfig:\n"); 2449 for (Map.Entry<String, TunnelConfig> entry : mApnNameToTunnelConfig.entrySet()) { 2450 pw.println("APN: " + entry.getKey()); 2451 pw.println("TunnelConfig: " + entry.getValue()); 2452 pw.println(); 2453 } 2454 pw.println("---------------------------"); 2455 } 2456 } 2457