IpSecManager.java revision 440824f7434e1e2c343b21a9ca3e6f405b8e0ea1
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 18330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport static com.android.internal.util.Preconditions.checkNotNull; 19330e1089da80cddcd68758512370d217b19f8890Nathan Harold 2093962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Haroldimport android.annotation.NonNull; 21d86b8fea43ebb6e5c31691b44d8ceb0d8d3c9072Jeff Sharkeyimport android.annotation.SystemService; 22d86b8fea43ebb6e5c31691b44d8ceb0d8d3c9072Jeff Sharkeyimport android.content.Context; 2393962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Haroldimport android.os.Binder; 24330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport android.os.ParcelFileDescriptor; 2593962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Haroldimport android.os.RemoteException; 26330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport android.util.AndroidException; 278dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Haroldimport android.util.Log; 28b72821747cd8cfa9bcaff7f11247ebfce3255fbfNathan Harold 29a10003d5de52339f4d30fedd7294941378e5f13cNathan Haroldimport com.android.internal.annotations.VisibleForTesting; 30a10003d5de52339f4d30fedd7294941378e5f13cNathan Harold 31330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport dalvik.system.CloseGuard; 32b72821747cd8cfa9bcaff7f11247ebfce3255fbfNathan Harold 33330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport java.io.FileDescriptor; 34330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport java.io.IOException; 35330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport java.net.DatagramSocket; 36330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport java.net.InetAddress; 37330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport java.net.Socket; 38330e1089da80cddcd68758512370d217b19f8890Nathan Harold 39330e1089da80cddcd68758512370d217b19f8890Nathan Harold/** 40330e1089da80cddcd68758512370d217b19f8890Nathan Harold * This class contains methods for managing IPsec sessions, which will perform kernel-space 41330e1089da80cddcd68758512370d217b19f8890Nathan Harold * encryption and decryption of socket or Network traffic. 42330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 43d999d225a8ebd5662b61d7f67bb402d8e5cb965bNathan Harold * <p>An IpSecManager may be obtained by calling {@link 44d999d225a8ebd5662b61d7f67bb402d8e5cb965bNathan Harold * android.content.Context#getSystemService(String) Context#getSystemService(String)} with {@link 45d999d225a8ebd5662b61d7f67bb402d8e5cb965bNathan Harold * android.content.Context#IPSEC_SERVICE Context#IPSEC_SERVICE} 46330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 47d86b8fea43ebb6e5c31691b44d8ceb0d8d3c9072Jeff Sharkey@SystemService(Context.IPSEC_SERVICE) 48330e1089da80cddcd68758512370d217b19f8890Nathan Haroldpublic final class IpSecManager { 49330e1089da80cddcd68758512370d217b19f8890Nathan Harold private static final String TAG = "IpSecManager"; 50330e1089da80cddcd68758512370d217b19f8890Nathan Harold 51330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 5293962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold * The Security Parameter Index, SPI, 0 indicates an unknown or invalid index. 5393962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold * 5493962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold * <p>No IPsec packet may contain an SPI of 0. 5593962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold */ 5693962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold public static final int INVALID_SECURITY_PARAMETER_INDEX = 0; 5793962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold 5893962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold /** @hide */ 5993962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold public interface Status { 6093962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold public static final int OK = 0; 6193962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold public static final int RESOURCE_UNAVAILABLE = 1; 6293962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold public static final int SPI_UNAVAILABLE = 2; 6393962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold } 6493962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold 6593962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold /** @hide */ 6693962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold public static final int INVALID_RESOURCE_ID = 0; 6793962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold 6893962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold /** 69330e1089da80cddcd68758512370d217b19f8890Nathan Harold * Indicates that the combination of remote InetAddress and SPI was non-unique for a given 70330e1089da80cddcd68758512370d217b19f8890Nathan Harold * request. If encountered, selection of a new SPI is required before a transform may be 71330e1089da80cddcd68758512370d217b19f8890Nathan Harold * created. Note, this should happen very rarely if the SPI is chosen to be sufficiently random 72330e1089da80cddcd68758512370d217b19f8890Nathan Harold * or reserved using reserveSecurityParameterIndex. 73330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 74330e1089da80cddcd68758512370d217b19f8890Nathan Harold public static final class SpiUnavailableException extends AndroidException { 75330e1089da80cddcd68758512370d217b19f8890Nathan Harold private final int mSpi; 76330e1089da80cddcd68758512370d217b19f8890Nathan Harold 77330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 78330e1089da80cddcd68758512370d217b19f8890Nathan Harold * Construct an exception indicating that a transform with the given SPI is already in use 79330e1089da80cddcd68758512370d217b19f8890Nathan Harold * or otherwise unavailable. 80330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 81330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @param msg Description indicating the colliding SPI 82330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @param spi the SPI that could not be used due to a collision 83330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 84330e1089da80cddcd68758512370d217b19f8890Nathan Harold SpiUnavailableException(String msg, int spi) { 85330e1089da80cddcd68758512370d217b19f8890Nathan Harold super(msg + "(spi: " + spi + ")"); 86330e1089da80cddcd68758512370d217b19f8890Nathan Harold mSpi = spi; 87330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 88330e1089da80cddcd68758512370d217b19f8890Nathan Harold 89330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** Retrieve the SPI that caused a collision */ 90330e1089da80cddcd68758512370d217b19f8890Nathan Harold public int getSpi() { 91330e1089da80cddcd68758512370d217b19f8890Nathan Harold return mSpi; 92330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 93330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 94330e1089da80cddcd68758512370d217b19f8890Nathan Harold 95330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 96330e1089da80cddcd68758512370d217b19f8890Nathan Harold * Indicates that the requested system resource for IPsec, such as a socket or other system 97330e1089da80cddcd68758512370d217b19f8890Nathan Harold * resource is unavailable. If this exception is thrown, try releasing allocated objects of the 98330e1089da80cddcd68758512370d217b19f8890Nathan Harold * type requested. 99330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 100330e1089da80cddcd68758512370d217b19f8890Nathan Harold public static final class ResourceUnavailableException extends AndroidException { 101330e1089da80cddcd68758512370d217b19f8890Nathan Harold 102330e1089da80cddcd68758512370d217b19f8890Nathan Harold ResourceUnavailableException(String msg) { 103330e1089da80cddcd68758512370d217b19f8890Nathan Harold super(msg); 104330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 105330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 106330e1089da80cddcd68758512370d217b19f8890Nathan Harold 1071afbef40c68373f3871eed087c546cfe1911ee36Nathan Harold private final IIpSecService mService; 108330e1089da80cddcd68758512370d217b19f8890Nathan Harold 109330e1089da80cddcd68758512370d217b19f8890Nathan Harold public static final class SecurityParameterIndex implements AutoCloseable { 1101afbef40c68373f3871eed087c546cfe1911ee36Nathan Harold private final IIpSecService mService; 111c4f879925b58b1b5ca9a3cfdc898c20cbf56355aNathan Harold private final InetAddress mRemoteAddress; 112330e1089da80cddcd68758512370d217b19f8890Nathan Harold private final CloseGuard mCloseGuard = CloseGuard.get(); 11393962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold private int mSpi = INVALID_SECURITY_PARAMETER_INDEX; 11493962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold private int mResourceId; 115330e1089da80cddcd68758512370d217b19f8890Nathan Harold 116330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** Return the underlying SPI held by this object */ 117330e1089da80cddcd68758512370d217b19f8890Nathan Harold public int getSpi() { 118330e1089da80cddcd68758512370d217b19f8890Nathan Harold return mSpi; 119330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 120330e1089da80cddcd68758512370d217b19f8890Nathan Harold 121330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 122330e1089da80cddcd68758512370d217b19f8890Nathan Harold * Release an SPI that was previously reserved. 123330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 124c4f879925b58b1b5ca9a3cfdc898c20cbf56355aNathan Harold * <p>Release an SPI for use by other users in the system. If a SecurityParameterIndex is 125c4f879925b58b1b5ca9a3cfdc898c20cbf56355aNathan Harold * applied to an IpSecTransform, it will become unusable for future transforms but should 126c4f879925b58b1b5ca9a3cfdc898c20cbf56355aNathan Harold * still be closed to ensure system resources are released. 127330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 128330e1089da80cddcd68758512370d217b19f8890Nathan Harold @Override 129330e1089da80cddcd68758512370d217b19f8890Nathan Harold public void close() { 1308dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold try { 1318dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold mService.releaseSecurityParameterIndex(mResourceId); 1328dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold } catch (RemoteException e) { 1338dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold throw e.rethrowFromSystemServer(); 1348dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold } 135330e1089da80cddcd68758512370d217b19f8890Nathan Harold mCloseGuard.close(); 136330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 137330e1089da80cddcd68758512370d217b19f8890Nathan Harold 138330e1089da80cddcd68758512370d217b19f8890Nathan Harold @Override 139440824f7434e1e2c343b21a9ca3e6f405b8e0ea1Nathan Harold protected void finalize() throws Throwable { 140330e1089da80cddcd68758512370d217b19f8890Nathan Harold if (mCloseGuard != null) { 141330e1089da80cddcd68758512370d217b19f8890Nathan Harold mCloseGuard.warnIfOpen(); 142330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 143330e1089da80cddcd68758512370d217b19f8890Nathan Harold 144330e1089da80cddcd68758512370d217b19f8890Nathan Harold close(); 145330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 146330e1089da80cddcd68758512370d217b19f8890Nathan Harold 14793962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold private SecurityParameterIndex( 14893962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold @NonNull IIpSecService service, int direction, InetAddress remoteAddress, int spi) 14993962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold throws ResourceUnavailableException, SpiUnavailableException { 15093962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold mService = service; 15193962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold mRemoteAddress = remoteAddress; 15293962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold try { 1538dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold IpSecSpiResponse result = 15493962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold mService.reserveSecurityParameterIndex( 15593962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold direction, remoteAddress.getHostAddress(), spi, new Binder()); 15693962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold 15793962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold if (result == null) { 15893962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold throw new NullPointerException("Received null response from IpSecService"); 15993962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold } 16093962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold 1618dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold int status = result.status; 16293962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold switch (status) { 16393962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold case Status.OK: 16493962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold break; 16593962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold case Status.RESOURCE_UNAVAILABLE: 16693962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold throw new ResourceUnavailableException( 16793962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold "No more SPIs may be allocated by this requester."); 16893962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold case Status.SPI_UNAVAILABLE: 16993962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold throw new SpiUnavailableException("Requested SPI is unavailable", spi); 17093962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold default: 17193962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold throw new RuntimeException( 17293962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold "Unknown status returned by IpSecService: " + status); 17393962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold } 1748dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold mSpi = result.spi; 1758dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold mResourceId = result.resourceId; 17693962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold 17793962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold if (mSpi == INVALID_SECURITY_PARAMETER_INDEX) { 17893962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold throw new RuntimeException("Invalid SPI returned by IpSecService: " + status); 17993962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold } 18093962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold 18193962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold if (mResourceId == INVALID_RESOURCE_ID) { 18293962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold throw new RuntimeException( 18393962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold "Invalid Resource ID returned by IpSecService: " + status); 18493962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold } 18593962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold 18693962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold } catch (RemoteException e) { 18793962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold throw e.rethrowFromSystemServer(); 18893962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold } 18993962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold mCloseGuard.open("open"); 19093962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold } 1918dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold 1928dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold /** @hide */ 193a10003d5de52339f4d30fedd7294941378e5f13cNathan Harold @VisibleForTesting 194a10003d5de52339f4d30fedd7294941378e5f13cNathan Harold public int getResourceId() { 1958dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold return mResourceId; 1968dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold } 19793962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold } 198330e1089da80cddcd68758512370d217b19f8890Nathan Harold 199330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 200c4f879925b58b1b5ca9a3cfdc898c20cbf56355aNathan Harold * Reserve an SPI for traffic bound towards the specified remote address. 201330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 202330e1089da80cddcd68758512370d217b19f8890Nathan Harold * <p>If successful, this SPI is guaranteed available until released by a call to {@link 203330e1089da80cddcd68758512370d217b19f8890Nathan Harold * SecurityParameterIndex#close()}. 204330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 205c4f879925b58b1b5ca9a3cfdc898c20cbf56355aNathan Harold * @param direction {@link IpSecTransform#DIRECTION_IN} or {@link IpSecTransform#DIRECTION_OUT} 206c4f879925b58b1b5ca9a3cfdc898c20cbf56355aNathan Harold * @param remoteAddress address of the remote. SPIs must be unique for each remoteAddress. 207330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @return the reserved SecurityParameterIndex 208330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @throws ResourceUnavailableException indicating that too many SPIs are currently allocated 209330e1089da80cddcd68758512370d217b19f8890Nathan Harold * for this user 210330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @throws SpiUnavailableException indicating that a particular SPI cannot be reserved 211330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 212330e1089da80cddcd68758512370d217b19f8890Nathan Harold public SecurityParameterIndex reserveSecurityParameterIndex( 2138dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold int direction, InetAddress remoteAddress) throws ResourceUnavailableException { 2146045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold try { 2156045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold return new SecurityParameterIndex( 2166045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold mService, 2176045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold direction, 2186045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold remoteAddress, 2196045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold IpSecManager.INVALID_SECURITY_PARAMETER_INDEX); 2206045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold } catch (SpiUnavailableException unlikely) { 2216045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold throw new ResourceUnavailableException("No SPIs available"); 2226045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold } 2236045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold } 2246045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold 2256045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold /** 2266045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold * Reserve an SPI for traffic bound towards the specified remote address. 2276045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold * 2286045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold * <p>If successful, this SPI is guaranteed available until released by a call to {@link 2296045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold * SecurityParameterIndex#close()}. 2306045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold * 2316045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold * @param direction {@link IpSecTransform#DIRECTION_IN} or {@link IpSecTransform#DIRECTION_OUT} 2326045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold * @param remoteAddress address of the remote. SPIs must be unique for each remoteAddress. 2336045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold * @param requestedSpi the requested SPI, or '0' to allocate a random SPI. 2346045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold * @return the reserved SecurityParameterIndex 2356045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold * @throws ResourceUnavailableException indicating that too many SPIs are currently allocated 2366045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold * for this user 2376045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold */ 2386045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold public SecurityParameterIndex reserveSecurityParameterIndex( 239c4f879925b58b1b5ca9a3cfdc898c20cbf56355aNathan Harold int direction, InetAddress remoteAddress, int requestedSpi) 240330e1089da80cddcd68758512370d217b19f8890Nathan Harold throws SpiUnavailableException, ResourceUnavailableException { 2416045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold if (requestedSpi == IpSecManager.INVALID_SECURITY_PARAMETER_INDEX) { 2426045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold throw new IllegalArgumentException("Requested SPI must be a valid (non-zero) SPI"); 2436045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold } 244c4f879925b58b1b5ca9a3cfdc898c20cbf56355aNathan Harold return new SecurityParameterIndex(mService, direction, remoteAddress, requestedSpi); 245330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 246330e1089da80cddcd68758512370d217b19f8890Nathan Harold 247330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 248330e1089da80cddcd68758512370d217b19f8890Nathan Harold * Apply an active Transport Mode IPsec Transform to a stream socket to perform IPsec 249330e1089da80cddcd68758512370d217b19f8890Nathan Harold * encapsulation of the traffic flowing between the socket and the remote InetAddress of that 250330e1089da80cddcd68758512370d217b19f8890Nathan Harold * transform. For security reasons, attempts to send traffic to any IP address other than the 251330e1089da80cddcd68758512370d217b19f8890Nathan Harold * address associated with that transform will throw an IOException. In addition, if the 252330e1089da80cddcd68758512370d217b19f8890Nathan Harold * IpSecTransform is later deactivated, the socket will throw an IOException on any calls to 253330e1089da80cddcd68758512370d217b19f8890Nathan Harold * send() or receive() until the transform is removed from the socket by calling {@link 254330e1089da80cddcd68758512370d217b19f8890Nathan Harold * #removeTransportModeTransform(Socket, IpSecTransform)}; 255330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 256330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @param socket a stream socket 257330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @param transform an {@link IpSecTransform}, which must be an active Transport Mode transform. 258da18b028f85e9a2c969c636aea6abf7f4bac3922Nathan Harold * @hide 259330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 260330e1089da80cddcd68758512370d217b19f8890Nathan Harold public void applyTransportModeTransform(Socket socket, IpSecTransform transform) 261330e1089da80cddcd68758512370d217b19f8890Nathan Harold throws IOException { 2628dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold try (ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(socket)) { 2638dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold applyTransportModeTransform(pfd, transform); 2648dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold } 265330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 266330e1089da80cddcd68758512370d217b19f8890Nathan Harold 267330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 268330e1089da80cddcd68758512370d217b19f8890Nathan Harold * Apply an active Transport Mode IPsec Transform to a datagram socket to perform IPsec 269330e1089da80cddcd68758512370d217b19f8890Nathan Harold * encapsulation of the traffic flowing between the socket and the remote InetAddress of that 270330e1089da80cddcd68758512370d217b19f8890Nathan Harold * transform. For security reasons, attempts to send traffic to any IP address other than the 271330e1089da80cddcd68758512370d217b19f8890Nathan Harold * address associated with that transform will throw an IOException. In addition, if the 272330e1089da80cddcd68758512370d217b19f8890Nathan Harold * IpSecTransform is later deactivated, the socket will throw an IOException on any calls to 273330e1089da80cddcd68758512370d217b19f8890Nathan Harold * send() or receive() until the transform is removed from the socket by calling {@link 274330e1089da80cddcd68758512370d217b19f8890Nathan Harold * #removeTransportModeTransform(DatagramSocket, IpSecTransform)}; 275330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 276330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @param socket a datagram socket 277330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @param transform an {@link IpSecTransform}, which must be an active Transport Mode transform. 278da18b028f85e9a2c969c636aea6abf7f4bac3922Nathan Harold * @hide 279330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 280330e1089da80cddcd68758512370d217b19f8890Nathan Harold public void applyTransportModeTransform(DatagramSocket socket, IpSecTransform transform) 281330e1089da80cddcd68758512370d217b19f8890Nathan Harold throws IOException { 2828dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold try (ParcelFileDescriptor pfd = ParcelFileDescriptor.fromDatagramSocket(socket)) { 2838dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold applyTransportModeTransform(pfd, transform); 28493962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold } 28593962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold } 286330e1089da80cddcd68758512370d217b19f8890Nathan Harold 287330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 288b64993559b049327365bb63e81e8046a892a1033Nathan Harold * Apply an active Transport Mode IPsec Transform to a stream socket to perform IPsec 289b64993559b049327365bb63e81e8046a892a1033Nathan Harold * encapsulation of the traffic flowing between the socket and the remote InetAddress of that 290b64993559b049327365bb63e81e8046a892a1033Nathan Harold * transform. For security reasons, attempts to send traffic to any IP address other than the 291b64993559b049327365bb63e81e8046a892a1033Nathan Harold * address associated with that transform will throw an IOException. In addition, if the 292b64993559b049327365bb63e81e8046a892a1033Nathan Harold * IpSecTransform is later deactivated, the socket will throw an IOException on any calls to 293b64993559b049327365bb63e81e8046a892a1033Nathan Harold * send() or receive() until the transform is removed from the socket by calling {@link 294da18b028f85e9a2c969c636aea6abf7f4bac3922Nathan Harold * #removeTransportModeTransform(FileDescriptor, IpSecTransform)}; 295b64993559b049327365bb63e81e8046a892a1033Nathan Harold * 296b64993559b049327365bb63e81e8046a892a1033Nathan Harold * @param socket a socket file descriptor 297b64993559b049327365bb63e81e8046a892a1033Nathan Harold * @param transform an {@link IpSecTransform}, which must be an active Transport Mode transform. 298b64993559b049327365bb63e81e8046a892a1033Nathan Harold */ 299b64993559b049327365bb63e81e8046a892a1033Nathan Harold public void applyTransportModeTransform(FileDescriptor socket, IpSecTransform transform) 300b64993559b049327365bb63e81e8046a892a1033Nathan Harold throws IOException { 3018dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold // We dup() the FileDescriptor here because if we don't, then the ParcelFileDescriptor() 3028dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold // constructor takes control and closes the user's FD when we exit the method 3038dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold // This is behaviorally the same as the other versions, but the PFD constructor does not 3048dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold // dup() automatically, whereas PFD.fromSocket() and PDF.fromDatagramSocket() do dup(). 3058dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold try (ParcelFileDescriptor pfd = ParcelFileDescriptor.dup(socket)) { 3068dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold applyTransportModeTransform(pfd, transform); 3078dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold } 3088dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold } 3098dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold 3108dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold /* Call down to activate a transform */ 3118dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold private void applyTransportModeTransform(ParcelFileDescriptor pfd, IpSecTransform transform) { 3128dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold try { 3138dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold mService.applyTransportModeTransform(pfd, transform.getResourceId()); 3148dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold } catch (RemoteException e) { 3158dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold throw e.rethrowFromSystemServer(); 3168dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold } 317b64993559b049327365bb63e81e8046a892a1033Nathan Harold } 318b64993559b049327365bb63e81e8046a892a1033Nathan Harold 319b64993559b049327365bb63e81e8046a892a1033Nathan Harold /** 320330e1089da80cddcd68758512370d217b19f8890Nathan Harold * Apply an active Tunnel Mode IPsec Transform to a network, which will tunnel all traffic to 321330e1089da80cddcd68758512370d217b19f8890Nathan Harold * and from that network's interface with IPsec (applies an outer IP header and IPsec Header to 322330e1089da80cddcd68758512370d217b19f8890Nathan Harold * all traffic, and expects an additional IP header and IPsec Header on all inbound traffic). 323330e1089da80cddcd68758512370d217b19f8890Nathan Harold * Applications should probably not use this API directly. Instead, they should use {@link 324330e1089da80cddcd68758512370d217b19f8890Nathan Harold * VpnService} to provide VPN capability in a more generic fashion. 325330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 326330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @param net a {@link Network} that will be tunneled via IP Sec. 327330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @param transform an {@link IpSecTransform}, which must be an active Tunnel Mode transform. 328330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @hide 329330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 330330e1089da80cddcd68758512370d217b19f8890Nathan Harold public void applyTunnelModeTransform(Network net, IpSecTransform transform) {} 331330e1089da80cddcd68758512370d217b19f8890Nathan Harold 332330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 333330e1089da80cddcd68758512370d217b19f8890Nathan Harold * Remove a transform from a given stream socket. Once removed, traffic on the socket will not 334330e1089da80cddcd68758512370d217b19f8890Nathan Harold * be encypted. This allows sockets that have been used for IPsec to be reclaimed for 335330e1089da80cddcd68758512370d217b19f8890Nathan Harold * communication in the clear in the event socket reuse is desired. This operation will succeed 336330e1089da80cddcd68758512370d217b19f8890Nathan Harold * regardless of the underlying state of a transform. If a transform is removed, communication 337330e1089da80cddcd68758512370d217b19f8890Nathan Harold * on all sockets to which that transform was applied will fail until this method is called. 338330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 339330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @param socket a socket that previously had a transform applied to it. 340330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @param transform the IPsec Transform that was previously applied to the given socket 341da18b028f85e9a2c969c636aea6abf7f4bac3922Nathan Harold * @hide 342330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 3430bfb2075320a9f648fc2b3fcdfc58f425c9a685aNathan Harold public void removeTransportModeTransform(Socket socket, IpSecTransform transform) 3440bfb2075320a9f648fc2b3fcdfc58f425c9a685aNathan Harold throws IOException { 3458dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold try (ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(socket)) { 3468dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold removeTransportModeTransform(pfd, transform); 3478dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold } 348330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 349330e1089da80cddcd68758512370d217b19f8890Nathan Harold 350330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 351330e1089da80cddcd68758512370d217b19f8890Nathan Harold * Remove a transform from a given datagram socket. Once removed, traffic on the socket will not 352330e1089da80cddcd68758512370d217b19f8890Nathan Harold * be encypted. This allows sockets that have been used for IPsec to be reclaimed for 353330e1089da80cddcd68758512370d217b19f8890Nathan Harold * communication in the clear in the event socket reuse is desired. This operation will succeed 354330e1089da80cddcd68758512370d217b19f8890Nathan Harold * regardless of the underlying state of a transform. If a transform is removed, communication 355330e1089da80cddcd68758512370d217b19f8890Nathan Harold * on all sockets to which that transform was applied will fail until this method is called. 356330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 357330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @param socket a socket that previously had a transform applied to it. 358330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @param transform the IPsec Transform that was previously applied to the given socket 359da18b028f85e9a2c969c636aea6abf7f4bac3922Nathan Harold * @hide 360330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 3610bfb2075320a9f648fc2b3fcdfc58f425c9a685aNathan Harold public void removeTransportModeTransform(DatagramSocket socket, IpSecTransform transform) 3620bfb2075320a9f648fc2b3fcdfc58f425c9a685aNathan Harold throws IOException { 3638dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold try (ParcelFileDescriptor pfd = ParcelFileDescriptor.fromDatagramSocket(socket)) { 3648dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold removeTransportModeTransform(pfd, transform); 3658dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold } 366330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 367330e1089da80cddcd68758512370d217b19f8890Nathan Harold 368b64993559b049327365bb63e81e8046a892a1033Nathan Harold /** 369b64993559b049327365bb63e81e8046a892a1033Nathan Harold * Remove a transform from a given stream socket. Once removed, traffic on the socket will not 370b64993559b049327365bb63e81e8046a892a1033Nathan Harold * be encypted. This allows sockets that have been used for IPsec to be reclaimed for 371b64993559b049327365bb63e81e8046a892a1033Nathan Harold * communication in the clear in the event socket reuse is desired. This operation will succeed 372b64993559b049327365bb63e81e8046a892a1033Nathan Harold * regardless of the underlying state of a transform. If a transform is removed, communication 373b64993559b049327365bb63e81e8046a892a1033Nathan Harold * on all sockets to which that transform was applied will fail until this method is called. 374b64993559b049327365bb63e81e8046a892a1033Nathan Harold * 375b64993559b049327365bb63e81e8046a892a1033Nathan Harold * @param socket a socket file descriptor that previously had a transform applied to it. 376b64993559b049327365bb63e81e8046a892a1033Nathan Harold * @param transform the IPsec Transform that was previously applied to the given socket 377b64993559b049327365bb63e81e8046a892a1033Nathan Harold */ 3780bfb2075320a9f648fc2b3fcdfc58f425c9a685aNathan Harold public void removeTransportModeTransform(FileDescriptor socket, IpSecTransform transform) 3790bfb2075320a9f648fc2b3fcdfc58f425c9a685aNathan Harold throws IOException { 3808dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold try (ParcelFileDescriptor pfd = ParcelFileDescriptor.dup(socket)) { 3818dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold removeTransportModeTransform(pfd, transform); 3828dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold } 383b64993559b049327365bb63e81e8046a892a1033Nathan Harold } 384b64993559b049327365bb63e81e8046a892a1033Nathan Harold 385330e1089da80cddcd68758512370d217b19f8890Nathan Harold /* Call down to activate a transform */ 38693962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold private void removeTransportModeTransform(ParcelFileDescriptor pfd, IpSecTransform transform) { 38793962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold try { 38893962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold mService.removeTransportModeTransform(pfd, transform.getResourceId()); 38993962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold } catch (RemoteException e) { 39093962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold throw e.rethrowFromSystemServer(); 39193962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold } 39293962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold } 393330e1089da80cddcd68758512370d217b19f8890Nathan Harold 394330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 395330e1089da80cddcd68758512370d217b19f8890Nathan Harold * Remove a Tunnel Mode IPsec Transform from a {@link Network}. This must be used as part of 396330e1089da80cddcd68758512370d217b19f8890Nathan Harold * cleanup if a tunneled Network experiences a change in default route. The Network will drop 397330e1089da80cddcd68758512370d217b19f8890Nathan Harold * all traffic that cannot be routed to the Tunnel's outbound interface. If that interface is 398330e1089da80cddcd68758512370d217b19f8890Nathan Harold * lost, all traffic will drop. 399330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 400330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @param net a network that currently has transform applied to it. 401330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @param transform a Tunnel Mode IPsec Transform that has been previously applied to the given 402330e1089da80cddcd68758512370d217b19f8890Nathan Harold * network 403330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @hide 404330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 405330e1089da80cddcd68758512370d217b19f8890Nathan Harold public void removeTunnelModeTransform(Network net, IpSecTransform transform) {} 406330e1089da80cddcd68758512370d217b19f8890Nathan Harold 407330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 408330e1089da80cddcd68758512370d217b19f8890Nathan Harold * Class providing access to a system-provided UDP Encapsulation Socket, which may be used for 409330e1089da80cddcd68758512370d217b19f8890Nathan Harold * IKE signalling as well as for inbound and outbound UDP encapsulated IPsec traffic. 410330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 411330e1089da80cddcd68758512370d217b19f8890Nathan Harold * <p>The socket provided by this class cannot be re-bound or closed via the inner 412330e1089da80cddcd68758512370d217b19f8890Nathan Harold * FileDescriptor. Instead, disposing of this socket requires a call to close(). 413330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 414330e1089da80cddcd68758512370d217b19f8890Nathan Harold public static final class UdpEncapsulationSocket implements AutoCloseable { 4158dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold private final ParcelFileDescriptor mPfd; 4161afbef40c68373f3871eed087c546cfe1911ee36Nathan Harold private final IIpSecService mService; 4178dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold private final int mResourceId; 4188dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold private final int mPort; 419330e1089da80cddcd68758512370d217b19f8890Nathan Harold private final CloseGuard mCloseGuard = CloseGuard.get(); 420330e1089da80cddcd68758512370d217b19f8890Nathan Harold 42193962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold private UdpEncapsulationSocket(@NonNull IIpSecService service, int port) 4228dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold throws ResourceUnavailableException, IOException { 4231afbef40c68373f3871eed087c546cfe1911ee36Nathan Harold mService = service; 4248dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold try { 4258dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold IpSecUdpEncapResponse result = 4268dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold mService.openUdpEncapsulationSocket(port, new Binder()); 4278dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold switch (result.status) { 4288dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold case Status.OK: 4298dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold break; 4308dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold case Status.RESOURCE_UNAVAILABLE: 4318dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold throw new ResourceUnavailableException( 4328dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold "No more Sockets may be allocated by this requester."); 4338dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold default: 4348dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold throw new RuntimeException( 4358dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold "Unknown status returned by IpSecService: " + result.status); 4368dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold } 4378dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold mResourceId = result.resourceId; 4388dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold mPort = result.port; 4398dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold mPfd = result.fileDescriptor; 4408dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold } catch (RemoteException e) { 4418dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold throw e.rethrowFromSystemServer(); 4428dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold } 443330e1089da80cddcd68758512370d217b19f8890Nathan Harold mCloseGuard.open("constructor"); 444330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 445330e1089da80cddcd68758512370d217b19f8890Nathan Harold 446330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** Access the inner UDP Encapsulation Socket */ 447330e1089da80cddcd68758512370d217b19f8890Nathan Harold public FileDescriptor getSocket() { 4488dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold if (mPfd == null) { 4498dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold return null; 4508dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold } 4518dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold return mPfd.getFileDescriptor(); 452330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 453330e1089da80cddcd68758512370d217b19f8890Nathan Harold 454330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** Retrieve the port number of the inner encapsulation socket */ 455330e1089da80cddcd68758512370d217b19f8890Nathan Harold public int getPort() { 4568dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold return mPort; 457330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 458330e1089da80cddcd68758512370d217b19f8890Nathan Harold 459330e1089da80cddcd68758512370d217b19f8890Nathan Harold @Override 460330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 461330e1089da80cddcd68758512370d217b19f8890Nathan Harold * Release the resources that have been reserved for this Socket. 462330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 463330e1089da80cddcd68758512370d217b19f8890Nathan Harold * <p>This method closes the underlying socket, reducing a user's allocated sockets in the 464330e1089da80cddcd68758512370d217b19f8890Nathan Harold * system. This must be done as part of cleanup following use of a socket. Failure to do so 465330e1089da80cddcd68758512370d217b19f8890Nathan Harold * will cause the socket to count against a total allocation limit for IpSec and eventually 466330e1089da80cddcd68758512370d217b19f8890Nathan Harold * fail due to resource limits. 467330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 468330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @param fd a file descriptor previously returned as a UDP Encapsulation socket. 469330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 4700bfb2075320a9f648fc2b3fcdfc58f425c9a685aNathan Harold public void close() throws IOException { 4718dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold try { 4728dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold mService.closeUdpEncapsulationSocket(mResourceId); 4738dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold } catch (RemoteException e) { 4748dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold throw e.rethrowFromSystemServer(); 4758dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold } 4768dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold 4778dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold try { 4788dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold mPfd.close(); 4798dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold } catch (IOException e) { 4808dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold Log.e(TAG, "Failed to close UDP Encapsulation Socket with Port= " + mPort); 4818dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold throw e; 4828dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold } 483330e1089da80cddcd68758512370d217b19f8890Nathan Harold mCloseGuard.close(); 484330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 485330e1089da80cddcd68758512370d217b19f8890Nathan Harold 486330e1089da80cddcd68758512370d217b19f8890Nathan Harold @Override 487330e1089da80cddcd68758512370d217b19f8890Nathan Harold protected void finalize() throws Throwable { 488330e1089da80cddcd68758512370d217b19f8890Nathan Harold if (mCloseGuard != null) { 489330e1089da80cddcd68758512370d217b19f8890Nathan Harold mCloseGuard.warnIfOpen(); 490330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 491330e1089da80cddcd68758512370d217b19f8890Nathan Harold close(); 492330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 4938dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold 4948dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold /** @hide */ 495a10003d5de52339f4d30fedd7294941378e5f13cNathan Harold @VisibleForTesting 496a10003d5de52339f4d30fedd7294941378e5f13cNathan Harold public int getResourceId() { 4978dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold return mResourceId; 4988dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold } 499330e1089da80cddcd68758512370d217b19f8890Nathan Harold }; 500330e1089da80cddcd68758512370d217b19f8890Nathan Harold 501330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 502330e1089da80cddcd68758512370d217b19f8890Nathan Harold * Open a socket that is bound to a free UDP port on the system. 503330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 504330e1089da80cddcd68758512370d217b19f8890Nathan Harold * <p>By binding in this manner and holding the FileDescriptor, the socket cannot be un-bound by 505330e1089da80cddcd68758512370d217b19f8890Nathan Harold * the caller. This provides safe access to a socket on a port that can later be used as a UDP 506330e1089da80cddcd68758512370d217b19f8890Nathan Harold * Encapsulation port. 507330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 508330e1089da80cddcd68758512370d217b19f8890Nathan Harold * <p>This socket reservation works in conjunction with IpSecTransforms, which may re-use the 509330e1089da80cddcd68758512370d217b19f8890Nathan Harold * socket port. Explicitly opening this port is only necessary if communication is desired on 510330e1089da80cddcd68758512370d217b19f8890Nathan Harold * that port. 511330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 512330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @param port a local UDP port to be reserved for UDP Encapsulation. is provided, then this 513330e1089da80cddcd68758512370d217b19f8890Nathan Harold * method will bind to the specified port or fail. To retrieve the port number, call {@link 514330e1089da80cddcd68758512370d217b19f8890Nathan Harold * android.system.Os#getsockname(FileDescriptor)}. 515330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @return a {@link UdpEncapsulationSocket} that is bound to the requested port for the lifetime 516330e1089da80cddcd68758512370d217b19f8890Nathan Harold * of the object. 517330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 518330e1089da80cddcd68758512370d217b19f8890Nathan Harold // Returning a socket in this fashion that has been created and bound by the system 519330e1089da80cddcd68758512370d217b19f8890Nathan Harold // is the only safe way to ensure that a socket is both accessible to the user and 520330e1089da80cddcd68758512370d217b19f8890Nathan Harold // safely usable for Encapsulation without allowing a user to possibly unbind from/close 521330e1089da80cddcd68758512370d217b19f8890Nathan Harold // the port, which could potentially impact the traffic of the next user who binds to that 522330e1089da80cddcd68758512370d217b19f8890Nathan Harold // socket. 523330e1089da80cddcd68758512370d217b19f8890Nathan Harold public UdpEncapsulationSocket openUdpEncapsulationSocket(int port) 524330e1089da80cddcd68758512370d217b19f8890Nathan Harold throws IOException, ResourceUnavailableException { 5258dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold /* 5268dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold * Most range checking is done in the service, but this version of the constructor expects 5278dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold * a valid port number, and zero cannot be checked after being passed to the service. 5288dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold */ 5298dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold if (port == 0) { 5308dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold throw new IllegalArgumentException("Specified port must be a valid port number!"); 5318dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold } 5321afbef40c68373f3871eed087c546cfe1911ee36Nathan Harold return new UdpEncapsulationSocket(mService, port); 533330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 534330e1089da80cddcd68758512370d217b19f8890Nathan Harold 535330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 536330e1089da80cddcd68758512370d217b19f8890Nathan Harold * Open a socket that is bound to a port selected by the system. 537330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 538330e1089da80cddcd68758512370d217b19f8890Nathan Harold * <p>By binding in this manner and holding the FileDescriptor, the socket cannot be un-bound by 539330e1089da80cddcd68758512370d217b19f8890Nathan Harold * the caller. This provides safe access to a socket on a port that can later be used as a UDP 540330e1089da80cddcd68758512370d217b19f8890Nathan Harold * Encapsulation port. 541330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 542330e1089da80cddcd68758512370d217b19f8890Nathan Harold * <p>This socket reservation works in conjunction with IpSecTransforms, which may re-use the 543330e1089da80cddcd68758512370d217b19f8890Nathan Harold * socket port. Explicitly opening this port is only necessary if communication is desired on 544330e1089da80cddcd68758512370d217b19f8890Nathan Harold * that port. 545330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 546330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @return a {@link UdpEncapsulationSocket} that is bound to an arbitrarily selected port 547330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 548330e1089da80cddcd68758512370d217b19f8890Nathan Harold // Returning a socket in this fashion that has been created and bound by the system 549330e1089da80cddcd68758512370d217b19f8890Nathan Harold // is the only safe way to ensure that a socket is both accessible to the user and 550330e1089da80cddcd68758512370d217b19f8890Nathan Harold // safely usable for Encapsulation without allowing a user to possibly unbind from/close 551330e1089da80cddcd68758512370d217b19f8890Nathan Harold // the port, which could potentially impact the traffic of the next user who binds to that 552330e1089da80cddcd68758512370d217b19f8890Nathan Harold // socket. 553330e1089da80cddcd68758512370d217b19f8890Nathan Harold public UdpEncapsulationSocket openUdpEncapsulationSocket() 554330e1089da80cddcd68758512370d217b19f8890Nathan Harold throws IOException, ResourceUnavailableException { 5558dc1fd0237992e1d693376b4f6eea45e7447e9dbNathan Harold return new UdpEncapsulationSocket(mService, 0); 556330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 557330e1089da80cddcd68758512370d217b19f8890Nathan Harold 558330e1089da80cddcd68758512370d217b19f8890Nathan Harold /** 559330e1089da80cddcd68758512370d217b19f8890Nathan Harold * Retrieve an instance of an IpSecManager within you application context 560330e1089da80cddcd68758512370d217b19f8890Nathan Harold * 561330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @param context the application context for this manager 562330e1089da80cddcd68758512370d217b19f8890Nathan Harold * @hide 563330e1089da80cddcd68758512370d217b19f8890Nathan Harold */ 5641afbef40c68373f3871eed087c546cfe1911ee36Nathan Harold public IpSecManager(IIpSecService service) { 565330e1089da80cddcd68758512370d217b19f8890Nathan Harold mService = checkNotNull(service, "missing service"); 566330e1089da80cddcd68758512370d217b19f8890Nathan Harold } 567330e1089da80cddcd68758512370d217b19f8890Nathan Harold} 568