1330e1089da80cddcd68758512370d217b19f8890Nathan Harold/* 2330e1089da80cddcd68758512370d217b19f8890Nathan Harold * Copyright (C) 2017 The Android Open Source Project 3330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 4330e1089da80cddcd68758512370d217b19f8890Nathan Harold * Licensed under the Apache License, Version 2.0 (the "License"); 5330e1089da80cddcd68758512370d217b19f8890Nathan Harold * you may not use this file except in compliance with the License. 6330e1089da80cddcd68758512370d217b19f8890Nathan Harold * You may obtain a copy of the License at 7330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 8330e1089da80cddcd68758512370d217b19f8890Nathan Harold * http://www.apache.org/licenses/LICENSE-2.0 9330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 10330e1089da80cddcd68758512370d217b19f8890Nathan Harold * Unless required by applicable law or agreed to in writing, software 11330e1089da80cddcd68758512370d217b19f8890Nathan Harold * distributed under the License is distributed on an "AS IS" BASIS, 12330e1089da80cddcd68758512370d217b19f8890Nathan Harold * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13330e1089da80cddcd68758512370d217b19f8890Nathan Harold * See the License for the specific language governing permissions and 14330e1089da80cddcd68758512370d217b19f8890Nathan Harold * limitations under the License. 15330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 16330e1089da80cddcd68758512370d217b19f8890Nathan Haroldpackage android.net; 17330e1089da80cddcd68758512370d217b19f8890Nathan Harold 1893962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Haroldimport static android.net.IpSecManager.INVALID_RESOURCE_ID; 1993962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold 20330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport android.annotation.IntDef; 2193962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Haroldimport android.annotation.NonNull; 22330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport android.annotation.SystemApi; 23330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport android.content.Context; 2493962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Haroldimport android.os.Binder; 2593962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Haroldimport android.os.IBinder; 2693962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Haroldimport android.os.RemoteException; 2793962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Haroldimport android.os.ServiceManager; 28330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport android.util.Log; 2993962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Haroldimport com.android.internal.util.Preconditions; 30330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport dalvik.system.CloseGuard; 31330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport java.io.IOException; 32330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport java.lang.annotation.Retention; 33330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport java.lang.annotation.RetentionPolicy; 34330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport java.net.InetAddress; 35330e1089da80cddcd68758512370d217b19f8890Nathan Harold 36330e1089da80cddcd68758512370d217b19f8890Nathan Harold/** 37330e1089da80cddcd68758512370d217b19f8890Nathan Harold * This class represents an IpSecTransform, which encapsulates both properties and state of IPsec. 38330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 39330e1089da80cddcd68758512370d217b19f8890Nathan Harold * <p>IpSecTransforms must be built from an IpSecTransform.Builder, and they must persist throughout 40330e1089da80cddcd68758512370d217b19f8890Nathan Harold * the lifetime of the underlying transform. If a transform object leaves scope, the underlying 41330e1089da80cddcd68758512370d217b19f8890Nathan Harold * transform may be disabled automatically, with likely undesirable results. 42330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 43330e1089da80cddcd68758512370d217b19f8890Nathan Harold * <p>An IpSecTransform may either represent a tunnel mode transform that operates on a wide array 44330e1089da80cddcd68758512370d217b19f8890Nathan Harold * of traffic or may represent a transport mode transform operating on a Socket or Sockets. 45ac11ccb1f66d5dadb6c6fd1d47408e36c48c94ceNathan Harold * 46ac11ccb1f66d5dadb6c6fd1d47408e36c48c94ceNathan Harold * @hide 47330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 48330e1089da80cddcd68758512370d217b19f8890Nathan Haroldpublic final class IpSecTransform implements AutoCloseable { 49330e1089da80cddcd68758512370d217b19f8890Nathan Harold private static final String TAG = "IpSecTransform"; 50330e1089da80cddcd68758512370d217b19f8890Nathan Harold 51330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 52330e1089da80cddcd68758512370d217b19f8890Nathan Harold * For direction-specific attributes of an IpSecTransform, indicates that an attribute applies 53330e1089da80cddcd68758512370d217b19f8890Nathan Harold * to traffic towards the host. 54330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 55330e1089da80cddcd68758512370d217b19f8890Nathan Harold public static final int DIRECTION_IN = 0; 56330e1089da80cddcd68758512370d217b19f8890Nathan Harold 57330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 58330e1089da80cddcd68758512370d217b19f8890Nathan Harold * For direction-specific attributes of an IpSecTransform, indicates that an attribute applies 59330e1089da80cddcd68758512370d217b19f8890Nathan Harold * to traffic from the host. 60330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 61330e1089da80cddcd68758512370d217b19f8890Nathan Harold public static final int DIRECTION_OUT = 1; 62330e1089da80cddcd68758512370d217b19f8890Nathan Harold 63330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** @hide */ 64330e1089da80cddcd68758512370d217b19f8890Nathan Harold @IntDef(value = {DIRECTION_IN, DIRECTION_OUT}) 65330e1089da80cddcd68758512370d217b19f8890Nathan Harold @Retention(RetentionPolicy.SOURCE) 66330e1089da80cddcd68758512370d217b19f8890Nathan Harold public @interface TransformDirection {} 67330e1089da80cddcd68758512370d217b19f8890Nathan Harold 68330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** @hide */ 69330e1089da80cddcd68758512370d217b19f8890Nathan Harold private static final int MODE_TUNNEL = 0; 70330e1089da80cddcd68758512370d217b19f8890Nathan Harold 71330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** @hide */ 72330e1089da80cddcd68758512370d217b19f8890Nathan Harold private static final int MODE_TRANSPORT = 1; 73330e1089da80cddcd68758512370d217b19f8890Nathan Harold 74330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** @hide */ 75330e1089da80cddcd68758512370d217b19f8890Nathan Harold public static final int ENCAP_NONE = 0; 76330e1089da80cddcd68758512370d217b19f8890Nathan Harold 77330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 788dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold * IpSec traffic will be encapsulated within a UDP header with an additional 8-byte header pad 798dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold * (of '0'-value bytes) that prevents traffic from being interpreted as IKE or as ESP over UDP. 80330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 81330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @hide 82330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 838dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold public static final int ENCAP_ESPINUDP_NON_IKE = 1; 84330e1089da80cddcd68758512370d217b19f8890Nathan Harold 85330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 868dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold * IpSec traffic will be encapsulated within UDP as per <a 878dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold * href="https://tools.ietf.org/html/rfc3948">RFC3498</a>. 88330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 89330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @hide 90330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 918dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold public static final int ENCAP_ESPINUDP = 2; 92330e1089da80cddcd68758512370d217b19f8890Nathan Harold 93330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** @hide */ 948dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold @IntDef(value = {ENCAP_NONE, ENCAP_ESPINUDP, ENCAP_ESPINUDP_NON_IKE}) 95330e1089da80cddcd68758512370d217b19f8890Nathan Harold @Retention(RetentionPolicy.SOURCE) 96330e1089da80cddcd68758512370d217b19f8890Nathan Harold public @interface EncapType {} 97330e1089da80cddcd68758512370d217b19f8890Nathan Harold 98330e1089da80cddcd68758512370d217b19f8890Nathan Harold private IpSecTransform(Context context, IpSecConfig config) { 99330e1089da80cddcd68758512370d217b19f8890Nathan Harold mContext = context; 100330e1089da80cddcd68758512370d217b19f8890Nathan Harold mConfig = config; 10193962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold mResourceId = INVALID_RESOURCE_ID; 10293962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold } 10393962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold 10493962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold private IIpSecService getIpSecService() { 10593962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold IBinder b = ServiceManager.getService(android.content.Context.IPSEC_SERVICE); 10693962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold if (b == null) { 10793962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold throw new RemoteException("Failed to connect to IpSecService") 10893962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold .rethrowAsRuntimeException(); 10993962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold } 11093962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold 11193962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold return IIpSecService.Stub.asInterface(b); 11293962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold } 11393962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold 11493962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold private void checkResultStatusAndThrow(int status) 11593962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold throws IOException, IpSecManager.ResourceUnavailableException, 11693962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold IpSecManager.SpiUnavailableException { 11793962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold switch (status) { 11893962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold case IpSecManager.Status.OK: 11993962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold return; 12093962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold // TODO: Pass Error string back from bundle so that errors can be more specific 12193962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold case IpSecManager.Status.RESOURCE_UNAVAILABLE: 12293962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold throw new IpSecManager.ResourceUnavailableException( 12393962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold "Failed to allocate a new IpSecTransform"); 12493962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold case IpSecManager.Status.SPI_UNAVAILABLE: 12593962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold Log.wtf(TAG, "Attempting to use an SPI that was somehow not reserved"); 12693962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold // Fall through 12793962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold default: 12893962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold throw new IllegalStateException( 12993962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold "Failed to Create a Transform with status code " + status); 13093962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold } 131330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 132330e1089da80cddcd68758512370d217b19f8890Nathan Harold 133330e1089da80cddcd68758512370d217b19f8890Nathan Harold private IpSecTransform activate() 134330e1089da80cddcd68758512370d217b19f8890Nathan Harold throws IOException, IpSecManager.ResourceUnavailableException, 135330e1089da80cddcd68758512370d217b19f8890Nathan Harold IpSecManager.SpiUnavailableException { 136330e1089da80cddcd68758512370d217b19f8890Nathan Harold synchronized (this) { 13793962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold try { 13893962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold IIpSecService svc = getIpSecService(); 1398dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold IpSecTransformResponse result = 1408dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold svc.createTransportModeTransform(mConfig, new Binder()); 1418dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold int status = result.status; 14293962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold checkResultStatusAndThrow(status); 1438dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold mResourceId = result.resourceId; 14493962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold 14593962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold /* Keepalive will silently fail if not needed by the config; but, if needed and 14693962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold * it fails to start, we need to bail because a transform will not be reliable 14793962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold * to use if keepalive is expected to offload and fails. 14893962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold */ 14993962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold // FIXME: if keepalive fails, we need to fail spectacularly 15093962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold startKeepalive(mContext); 15193962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold Log.d(TAG, "Added Transform with Id " + mResourceId); 15293962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold mCloseGuard.open("build"); 15393962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold } catch (RemoteException e) { 15493962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold throw e.rethrowAsRuntimeException(); 155330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 156330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 157330e1089da80cddcd68758512370d217b19f8890Nathan Harold 158330e1089da80cddcd68758512370d217b19f8890Nathan Harold return this; 159330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 160330e1089da80cddcd68758512370d217b19f8890Nathan Harold 161330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 162330e1089da80cddcd68758512370d217b19f8890Nathan Harold * Deactivate an IpSecTransform and free all resources for that transform that are managed by 163330e1089da80cddcd68758512370d217b19f8890Nathan Harold * the system for this Transform. 164330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 165330e1089da80cddcd68758512370d217b19f8890Nathan Harold * <p>Deactivating a transform while it is still applied to any Socket will result in sockets 166330e1089da80cddcd68758512370d217b19f8890Nathan Harold * refusing to send or receive data. This method will silently succeed if the specified 167330e1089da80cddcd68758512370d217b19f8890Nathan Harold * transform has already been removed; thus, it is always safe to attempt cleanup when a 168330e1089da80cddcd68758512370d217b19f8890Nathan Harold * transform is no longer needed. 169330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 170330e1089da80cddcd68758512370d217b19f8890Nathan Harold public void close() { 17193962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold Log.d(TAG, "Removing Transform with Id " + mResourceId); 172330e1089da80cddcd68758512370d217b19f8890Nathan Harold 173330e1089da80cddcd68758512370d217b19f8890Nathan Harold // Always safe to attempt cleanup 17493962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold if (mResourceId == INVALID_RESOURCE_ID) { 17593962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold mCloseGuard.close(); 176330e1089da80cddcd68758512370d217b19f8890Nathan Harold return; 177330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 17893962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold try { 17993962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold /* Order matters here because the keepalive is best-effort but could fail in some 18093962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold * horrible way to be removed if the wifi (or cell) subsystem has crashed, and we 18193962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold * still want to clear out the transform. 18293962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold */ 18393962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold IIpSecService svc = getIpSecService(); 18493962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold svc.deleteTransportModeTransform(mResourceId); 18593962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold stopKeepalive(); 18693962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold } catch (RemoteException e) { 18793962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold throw e.rethrowAsRuntimeException(); 18893962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold } finally { 18993962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold mResourceId = INVALID_RESOURCE_ID; 19093962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold mCloseGuard.close(); 19193962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold } 192330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 193330e1089da80cddcd68758512370d217b19f8890Nathan Harold 194330e1089da80cddcd68758512370d217b19f8890Nathan Harold @Override 195330e1089da80cddcd68758512370d217b19f8890Nathan Harold protected void finalize() throws Throwable { 196330e1089da80cddcd68758512370d217b19f8890Nathan Harold if (mCloseGuard != null) { 197330e1089da80cddcd68758512370d217b19f8890Nathan Harold mCloseGuard.warnIfOpen(); 198330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 199330e1089da80cddcd68758512370d217b19f8890Nathan Harold close(); 200330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 201330e1089da80cddcd68758512370d217b19f8890Nathan Harold 202330e1089da80cddcd68758512370d217b19f8890Nathan Harold /* Package */ 203330e1089da80cddcd68758512370d217b19f8890Nathan Harold IpSecConfig getConfig() { 204330e1089da80cddcd68758512370d217b19f8890Nathan Harold return mConfig; 205330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 206330e1089da80cddcd68758512370d217b19f8890Nathan Harold 207330e1089da80cddcd68758512370d217b19f8890Nathan Harold private final IpSecConfig mConfig; 20893962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold private int mResourceId; 209330e1089da80cddcd68758512370d217b19f8890Nathan Harold private final Context mContext; 210330e1089da80cddcd68758512370d217b19f8890Nathan Harold private final CloseGuard mCloseGuard = CloseGuard.get(); 211330e1089da80cddcd68758512370d217b19f8890Nathan Harold private ConnectivityManager.PacketKeepalive mKeepalive; 212330e1089da80cddcd68758512370d217b19f8890Nathan Harold private int mKeepaliveStatus = ConnectivityManager.PacketKeepalive.NO_KEEPALIVE; 213330e1089da80cddcd68758512370d217b19f8890Nathan Harold private Object mKeepaliveSyncLock = new Object(); 214330e1089da80cddcd68758512370d217b19f8890Nathan Harold private ConnectivityManager.PacketKeepaliveCallback mKeepaliveCallback = 215330e1089da80cddcd68758512370d217b19f8890Nathan Harold new ConnectivityManager.PacketKeepaliveCallback() { 216330e1089da80cddcd68758512370d217b19f8890Nathan Harold 217330e1089da80cddcd68758512370d217b19f8890Nathan Harold @Override 218330e1089da80cddcd68758512370d217b19f8890Nathan Harold public void onStarted() { 219330e1089da80cddcd68758512370d217b19f8890Nathan Harold synchronized (mKeepaliveSyncLock) { 220330e1089da80cddcd68758512370d217b19f8890Nathan Harold mKeepaliveStatus = ConnectivityManager.PacketKeepalive.SUCCESS; 221330e1089da80cddcd68758512370d217b19f8890Nathan Harold mKeepaliveSyncLock.notifyAll(); 222330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 223330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 224330e1089da80cddcd68758512370d217b19f8890Nathan Harold 225330e1089da80cddcd68758512370d217b19f8890Nathan Harold @Override 226330e1089da80cddcd68758512370d217b19f8890Nathan Harold public void onStopped() { 227330e1089da80cddcd68758512370d217b19f8890Nathan Harold synchronized (mKeepaliveSyncLock) { 228330e1089da80cddcd68758512370d217b19f8890Nathan Harold mKeepaliveStatus = ConnectivityManager.PacketKeepalive.NO_KEEPALIVE; 229330e1089da80cddcd68758512370d217b19f8890Nathan Harold mKeepaliveSyncLock.notifyAll(); 230330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 231330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 232330e1089da80cddcd68758512370d217b19f8890Nathan Harold 233330e1089da80cddcd68758512370d217b19f8890Nathan Harold @Override 234330e1089da80cddcd68758512370d217b19f8890Nathan Harold public void onError(int error) { 235330e1089da80cddcd68758512370d217b19f8890Nathan Harold synchronized (mKeepaliveSyncLock) { 236330e1089da80cddcd68758512370d217b19f8890Nathan Harold mKeepaliveStatus = error; 237330e1089da80cddcd68758512370d217b19f8890Nathan Harold mKeepaliveSyncLock.notifyAll(); 238330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 239330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 240330e1089da80cddcd68758512370d217b19f8890Nathan Harold }; 241330e1089da80cddcd68758512370d217b19f8890Nathan Harold 242330e1089da80cddcd68758512370d217b19f8890Nathan Harold /* Package */ 243330e1089da80cddcd68758512370d217b19f8890Nathan Harold void startKeepalive(Context c) { 24493962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold // FIXME: NO_KEEPALIVE needs to be a constant 245330e1089da80cddcd68758512370d217b19f8890Nathan Harold if (mConfig.getNattKeepaliveInterval() == 0) { 246330e1089da80cddcd68758512370d217b19f8890Nathan Harold return; 247330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 248330e1089da80cddcd68758512370d217b19f8890Nathan Harold 249330e1089da80cddcd68758512370d217b19f8890Nathan Harold ConnectivityManager cm = 250330e1089da80cddcd68758512370d217b19f8890Nathan Harold (ConnectivityManager) c.getSystemService(Context.CONNECTIVITY_SERVICE); 251330e1089da80cddcd68758512370d217b19f8890Nathan Harold 252330e1089da80cddcd68758512370d217b19f8890Nathan Harold if (mKeepalive != null) { 25393962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold Log.wtf(TAG, "Keepalive already started for this IpSecTransform."); 254330e1089da80cddcd68758512370d217b19f8890Nathan Harold return; 255330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 256330e1089da80cddcd68758512370d217b19f8890Nathan Harold 257330e1089da80cddcd68758512370d217b19f8890Nathan Harold synchronized (mKeepaliveSyncLock) { 258330e1089da80cddcd68758512370d217b19f8890Nathan Harold mKeepalive = 259330e1089da80cddcd68758512370d217b19f8890Nathan Harold cm.startNattKeepalive( 260330e1089da80cddcd68758512370d217b19f8890Nathan Harold mConfig.getNetwork(), 261330e1089da80cddcd68758512370d217b19f8890Nathan Harold mConfig.getNattKeepaliveInterval(), 262330e1089da80cddcd68758512370d217b19f8890Nathan Harold mKeepaliveCallback, 26393962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold mConfig.getLocalAddress(), 2648dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold 0x1234, /* FIXME: get the real port number again, 2658dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold which we need to retrieve from the provided 2668dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold EncapsulationSocket, and which isn't currently 2678dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold stashed in IpSecConfig */ 26893962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold mConfig.getRemoteAddress()); 269330e1089da80cddcd68758512370d217b19f8890Nathan Harold try { 27093962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold // FIXME: this is still a horrible way to fudge the synchronous callback 271330e1089da80cddcd68758512370d217b19f8890Nathan Harold mKeepaliveSyncLock.wait(2000); 272330e1089da80cddcd68758512370d217b19f8890Nathan Harold } catch (InterruptedException e) { 273330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 274330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 275330e1089da80cddcd68758512370d217b19f8890Nathan Harold if (mKeepaliveStatus != ConnectivityManager.PacketKeepalive.SUCCESS) { 276330e1089da80cddcd68758512370d217b19f8890Nathan Harold throw new UnsupportedOperationException("Packet Keepalive cannot be started"); 277330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 278330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 279330e1089da80cddcd68758512370d217b19f8890Nathan Harold 280330e1089da80cddcd68758512370d217b19f8890Nathan Harold /* Package */ 28193962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold int getResourceId() { 28293962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold return mResourceId; 28393962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold } 28493962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold 28593962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold /* Package */ 286330e1089da80cddcd68758512370d217b19f8890Nathan Harold void stopKeepalive() { 287330e1089da80cddcd68758512370d217b19f8890Nathan Harold if (mKeepalive == null) { 288330e1089da80cddcd68758512370d217b19f8890Nathan Harold return; 289330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 290330e1089da80cddcd68758512370d217b19f8890Nathan Harold mKeepalive.stop(); 291330e1089da80cddcd68758512370d217b19f8890Nathan Harold synchronized (mKeepaliveSyncLock) { 292330e1089da80cddcd68758512370d217b19f8890Nathan Harold if (mKeepaliveStatus == ConnectivityManager.PacketKeepalive.SUCCESS) { 293330e1089da80cddcd68758512370d217b19f8890Nathan Harold try { 294330e1089da80cddcd68758512370d217b19f8890Nathan Harold mKeepaliveSyncLock.wait(2000); 295330e1089da80cddcd68758512370d217b19f8890Nathan Harold } catch (InterruptedException e) { 296330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 297330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 298330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 299330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 300330e1089da80cddcd68758512370d217b19f8890Nathan Harold 301330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 302330e1089da80cddcd68758512370d217b19f8890Nathan Harold * Builder object to facilitate the creation of IpSecTransform objects. 303330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 304330e1089da80cddcd68758512370d217b19f8890Nathan Harold * <p>Apply additional properties to the transform and then call a build() method to return an 305330e1089da80cddcd68758512370d217b19f8890Nathan Harold * IpSecTransform object. 306330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 307330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @see Builder#buildTransportModeTransform(InetAddress) 308330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 309330e1089da80cddcd68758512370d217b19f8890Nathan Harold public static class Builder { 310330e1089da80cddcd68758512370d217b19f8890Nathan Harold private Context mContext; 311330e1089da80cddcd68758512370d217b19f8890Nathan Harold private IpSecConfig mConfig; 312330e1089da80cddcd68758512370d217b19f8890Nathan Harold 313330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 314330e1089da80cddcd68758512370d217b19f8890Nathan Harold * Add an encryption algorithm to the transform for the given direction. 315330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 316330e1089da80cddcd68758512370d217b19f8890Nathan Harold * <p>If encryption is set for a given direction without also providing an SPI for that 317330e1089da80cddcd68758512370d217b19f8890Nathan Harold * direction, creation of an IpSecTransform will fail upon calling a build() method. 318330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 319330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @param direction either {@link #DIRECTION_IN or #DIRECTION_OUT} 320330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @param algo {@link IpSecAlgorithm} specifying the encryption to be applied. 321330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 322330e1089da80cddcd68758512370d217b19f8890Nathan Harold public IpSecTransform.Builder setEncryption( 323330e1089da80cddcd68758512370d217b19f8890Nathan Harold @TransformDirection int direction, IpSecAlgorithm algo) { 32493962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold mConfig.flow[direction].encryption = algo; 325330e1089da80cddcd68758512370d217b19f8890Nathan Harold return this; 326330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 327330e1089da80cddcd68758512370d217b19f8890Nathan Harold 328330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 329330e1089da80cddcd68758512370d217b19f8890Nathan Harold * Add an authentication/integrity algorithm to the transform. 330330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 331330e1089da80cddcd68758512370d217b19f8890Nathan Harold * <p>If authentication is set for a given direction without also providing an SPI for that 332330e1089da80cddcd68758512370d217b19f8890Nathan Harold * direction, creation of an IpSecTransform will fail upon calling a build() method. 333330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 334330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @param direction either {@link #DIRECTION_IN or #DIRECTION_OUT} 335330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @param algo {@link IpSecAlgorithm} specifying the authentication to be applied. 336330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 337330e1089da80cddcd68758512370d217b19f8890Nathan Harold public IpSecTransform.Builder setAuthentication( 338330e1089da80cddcd68758512370d217b19f8890Nathan Harold @TransformDirection int direction, IpSecAlgorithm algo) { 33993962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold mConfig.flow[direction].authentication = algo; 340330e1089da80cddcd68758512370d217b19f8890Nathan Harold return this; 341330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 342330e1089da80cddcd68758512370d217b19f8890Nathan Harold 343330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 344330e1089da80cddcd68758512370d217b19f8890Nathan Harold * Set the SPI, which uniquely identifies a particular IPsec session from others. Because 345330e1089da80cddcd68758512370d217b19f8890Nathan Harold * IPsec operates at the IP layer, this 32-bit identifier uniquely identifies packets to a 346330e1089da80cddcd68758512370d217b19f8890Nathan Harold * given destination address. 347330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 348330e1089da80cddcd68758512370d217b19f8890Nathan Harold * <p>Care should be chosen when selecting an SPI to ensure that is is as unique as 34948b566557d5a66d4476008b3c59b815eb78cb373Nathan Harold * possible. To reserve a value call {@link IpSecManager#reserveSecurityParameterIndex(int, 35048b566557d5a66d4476008b3c59b815eb78cb373Nathan Harold * InetAddress, int)}. Otherwise, SPI collisions would prevent a transform from being 35148b566557d5a66d4476008b3c59b815eb78cb373Nathan Harold * activated. IpSecManager#reserveSecurityParameterIndex(int, InetAddres$s, int)}. 352330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 353330e1089da80cddcd68758512370d217b19f8890Nathan Harold * <p>Unless an SPI is set for a given direction, traffic in that direction will be 354330e1089da80cddcd68758512370d217b19f8890Nathan Harold * sent/received without any IPsec applied. 355330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 356330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @param direction either {@link #DIRECTION_IN or #DIRECTION_OUT} 357330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @param spi a unique {@link IpSecManager.SecurityParameterIndex} to identify transformed 358330e1089da80cddcd68758512370d217b19f8890Nathan Harold * traffic 359330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 360330e1089da80cddcd68758512370d217b19f8890Nathan Harold public IpSecTransform.Builder setSpi( 361330e1089da80cddcd68758512370d217b19f8890Nathan Harold @TransformDirection int direction, IpSecManager.SecurityParameterIndex spi) { 36293962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold // TODO: convert to using the resource Id of the SPI. Then build() can validate 36393962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold // the owner in the IpSecService 3648dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold mConfig.flow[direction].spiResourceId = spi.getResourceId(); 365330e1089da80cddcd68758512370d217b19f8890Nathan Harold return this; 366330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 367330e1089da80cddcd68758512370d217b19f8890Nathan Harold 368330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 369330e1089da80cddcd68758512370d217b19f8890Nathan Harold * Specify the network on which this transform will emit its traffic; (otherwise it will 370330e1089da80cddcd68758512370d217b19f8890Nathan Harold * emit on the default network). 371330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 372330e1089da80cddcd68758512370d217b19f8890Nathan Harold * <p>Restricts the transformed traffic to a particular {@link Network}. This is required in 373330e1089da80cddcd68758512370d217b19f8890Nathan Harold * tunnel mode. 374330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 375330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @hide 376330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 377330e1089da80cddcd68758512370d217b19f8890Nathan Harold @SystemApi 378330e1089da80cddcd68758512370d217b19f8890Nathan Harold public IpSecTransform.Builder setUnderlyingNetwork(Network net) { 379330e1089da80cddcd68758512370d217b19f8890Nathan Harold mConfig.network = net; 380330e1089da80cddcd68758512370d217b19f8890Nathan Harold return this; 381330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 382330e1089da80cddcd68758512370d217b19f8890Nathan Harold 383330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 384330e1089da80cddcd68758512370d217b19f8890Nathan Harold * Add UDP encapsulation to an IPv4 transform 385330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 386330e1089da80cddcd68758512370d217b19f8890Nathan Harold * <p>This option allows IPsec traffic to pass through NAT. Refer to RFC 3947 and 3948 for 387330e1089da80cddcd68758512370d217b19f8890Nathan Harold * details on how UDP should be applied to IPsec. 388330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 389330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @param localSocket a {@link IpSecManager.UdpEncapsulationSocket} for sending and 390330e1089da80cddcd68758512370d217b19f8890Nathan Harold * receiving encapsulating traffic. 391330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @param remotePort the UDP port number of the remote that will send and receive 392330e1089da80cddcd68758512370d217b19f8890Nathan Harold * encapsulated traffic. In the case of IKE, this is likely port 4500. 393330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 394330e1089da80cddcd68758512370d217b19f8890Nathan Harold public IpSecTransform.Builder setIpv4Encapsulation( 395330e1089da80cddcd68758512370d217b19f8890Nathan Harold IpSecManager.UdpEncapsulationSocket localSocket, int remotePort) { 396330e1089da80cddcd68758512370d217b19f8890Nathan Harold // TODO: check encap type is valid. 397330e1089da80cddcd68758512370d217b19f8890Nathan Harold mConfig.encapType = ENCAP_ESPINUDP; 3988dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold mConfig.encapLocalPortResourceId = localSocket.getResourceId(); 399330e1089da80cddcd68758512370d217b19f8890Nathan Harold mConfig.encapRemotePort = remotePort; 400330e1089da80cddcd68758512370d217b19f8890Nathan Harold return this; 401330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 402330e1089da80cddcd68758512370d217b19f8890Nathan Harold 403330e1089da80cddcd68758512370d217b19f8890Nathan Harold // TODO: Decrease the minimum keepalive to maybe 10? 404330e1089da80cddcd68758512370d217b19f8890Nathan Harold // TODO: Probably a better exception to throw for NATTKeepalive failure 405330e1089da80cddcd68758512370d217b19f8890Nathan Harold // TODO: Specify the needed NATT keepalive permission. 406330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 407330e1089da80cddcd68758512370d217b19f8890Nathan Harold * Send a NATT Keepalive packet with a given maximum interval. This will create an offloaded 408330e1089da80cddcd68758512370d217b19f8890Nathan Harold * request to do power-efficient NATT Keepalive. If NATT keepalive is requested but cannot 409330e1089da80cddcd68758512370d217b19f8890Nathan Harold * be activated, then the transform will fail to activate and throw an IOException. 410330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 411330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @param intervalSeconds the maximum number of seconds between keepalive packets, no less 412330e1089da80cddcd68758512370d217b19f8890Nathan Harold * than 20s and no more than 3600s. 413330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @hide 414330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 415330e1089da80cddcd68758512370d217b19f8890Nathan Harold @SystemApi 416330e1089da80cddcd68758512370d217b19f8890Nathan Harold public IpSecTransform.Builder setNattKeepalive(int intervalSeconds) { 417330e1089da80cddcd68758512370d217b19f8890Nathan Harold mConfig.nattKeepaliveInterval = intervalSeconds; 418330e1089da80cddcd68758512370d217b19f8890Nathan Harold return this; 419330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 420330e1089da80cddcd68758512370d217b19f8890Nathan Harold 421330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 422330e1089da80cddcd68758512370d217b19f8890Nathan Harold * Build and return an active {@link IpSecTransform} object as a Transport Mode Transform. 423330e1089da80cddcd68758512370d217b19f8890Nathan Harold * Some parameters have interdependencies that are checked at build time. If a well-formed 424330e1089da80cddcd68758512370d217b19f8890Nathan Harold * transform cannot be created from the supplied parameters, this method will throw an 425330e1089da80cddcd68758512370d217b19f8890Nathan Harold * Exception. 426330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 427330e1089da80cddcd68758512370d217b19f8890Nathan Harold * <p>Upon a successful return from this call, the provided IpSecTransform will be active 428330e1089da80cddcd68758512370d217b19f8890Nathan Harold * and may be applied to sockets. If too many IpSecTransform objects are active for a given 429330e1089da80cddcd68758512370d217b19f8890Nathan Harold * user this operation will fail and throw ResourceUnavailableException. To avoid these 430330e1089da80cddcd68758512370d217b19f8890Nathan Harold * exceptions, unused Transform objects must be cleaned up by calling {@link 431330e1089da80cddcd68758512370d217b19f8890Nathan Harold * IpSecTransform#close()} when they are no longer needed. 432330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 433330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @param remoteAddress the {@link InetAddress} that, when matched on traffic to/from this 434330e1089da80cddcd68758512370d217b19f8890Nathan Harold * socket will cause the transform to be applied. 435330e1089da80cddcd68758512370d217b19f8890Nathan Harold * <p>Note that an active transform will not impact any network traffic until it has 436330e1089da80cddcd68758512370d217b19f8890Nathan Harold * been applied to one or more Sockets. Calling this method is a necessary precondition 437330e1089da80cddcd68758512370d217b19f8890Nathan Harold * for applying it to a socket, but is not sufficient to actually apply IPsec. 438330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @throws IllegalArgumentException indicating that a particular combination of transform 439330e1089da80cddcd68758512370d217b19f8890Nathan Harold * properties is invalid. 440330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @throws IpSecManager.ResourceUnavailableException in the event that no more Transforms 441330e1089da80cddcd68758512370d217b19f8890Nathan Harold * may be allocated 442330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @throws SpiUnavailableException if the SPI collides with an existing transform 443330e1089da80cddcd68758512370d217b19f8890Nathan Harold * (unlikely). 444330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @throws ResourceUnavailableException if the current user currently has exceeded the 445330e1089da80cddcd68758512370d217b19f8890Nathan Harold * number of allowed active transforms. 446330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 447330e1089da80cddcd68758512370d217b19f8890Nathan Harold public IpSecTransform buildTransportModeTransform(InetAddress remoteAddress) 448330e1089da80cddcd68758512370d217b19f8890Nathan Harold throws IpSecManager.ResourceUnavailableException, 449330e1089da80cddcd68758512370d217b19f8890Nathan Harold IpSecManager.SpiUnavailableException, IOException { 450330e1089da80cddcd68758512370d217b19f8890Nathan Harold //FIXME: argument validation here 451330e1089da80cddcd68758512370d217b19f8890Nathan Harold //throw new IllegalArgumentException("Natt Keepalive requires UDP Encapsulation"); 452330e1089da80cddcd68758512370d217b19f8890Nathan Harold mConfig.mode = MODE_TRANSPORT; 453330e1089da80cddcd68758512370d217b19f8890Nathan Harold mConfig.remoteAddress = remoteAddress; 454330e1089da80cddcd68758512370d217b19f8890Nathan Harold return new IpSecTransform(mContext, mConfig).activate(); 455330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 456330e1089da80cddcd68758512370d217b19f8890Nathan Harold 457330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 458330e1089da80cddcd68758512370d217b19f8890Nathan Harold * Build and return an {@link IpSecTransform} object as a Tunnel Mode Transform. Some 459330e1089da80cddcd68758512370d217b19f8890Nathan Harold * parameters have interdependencies that are checked at build time. 460330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 461330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @param localAddress the {@link InetAddress} that provides the local endpoint for this 462330e1089da80cddcd68758512370d217b19f8890Nathan Harold * IPsec tunnel. This is almost certainly an address belonging to the {@link Network} 463330e1089da80cddcd68758512370d217b19f8890Nathan Harold * that will originate the traffic, which is set as the {@link #setUnderlyingNetwork}. 464330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @param remoteAddress the {@link InetAddress} representing the remote endpoint of this 465330e1089da80cddcd68758512370d217b19f8890Nathan Harold * IPsec tunnel. 466330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @throws IllegalArgumentException indicating that a particular combination of transform 467330e1089da80cddcd68758512370d217b19f8890Nathan Harold * properties is invalid. 468330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @hide 469330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 470330e1089da80cddcd68758512370d217b19f8890Nathan Harold public IpSecTransform buildTunnelModeTransform( 471330e1089da80cddcd68758512370d217b19f8890Nathan Harold InetAddress localAddress, InetAddress remoteAddress) { 472330e1089da80cddcd68758512370d217b19f8890Nathan Harold //FIXME: argument validation here 473330e1089da80cddcd68758512370d217b19f8890Nathan Harold //throw new IllegalArgumentException("Natt Keepalive requires UDP Encapsulation"); 474330e1089da80cddcd68758512370d217b19f8890Nathan Harold mConfig.localAddress = localAddress; 475330e1089da80cddcd68758512370d217b19f8890Nathan Harold mConfig.remoteAddress = remoteAddress; 476330e1089da80cddcd68758512370d217b19f8890Nathan Harold mConfig.mode = MODE_TUNNEL; 477330e1089da80cddcd68758512370d217b19f8890Nathan Harold return new IpSecTransform(mContext, mConfig); 478330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 479330e1089da80cddcd68758512370d217b19f8890Nathan Harold 480330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 481330e1089da80cddcd68758512370d217b19f8890Nathan Harold * Create a new IpSecTransform.Builder to construct an IpSecTransform 482330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 483330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @param context current Context 484330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 48593962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold public Builder(@NonNull Context context) { 48693962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold Preconditions.checkNotNull(context); 487330e1089da80cddcd68758512370d217b19f8890Nathan Harold mContext = context; 488330e1089da80cddcd68758512370d217b19f8890Nathan Harold mConfig = new IpSecConfig(); 489330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 490330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 491330e1089da80cddcd68758512370d217b19f8890Nathan Harold} 492