IpSecManager.java revision 6045429b35ca4c1cbd920e5e0872dec9de493fde
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;
2193962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Haroldimport android.os.Binder;
2293962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Haroldimport android.os.Bundle;
23330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport android.os.ParcelFileDescriptor;
2493962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Haroldimport android.os.RemoteException;
25330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport android.util.AndroidException;
26330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport dalvik.system.CloseGuard;
27330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport java.io.FileDescriptor;
28330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport java.io.IOException;
29330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport java.net.DatagramSocket;
30330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport java.net.InetAddress;
31330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport java.net.Socket;
32330e1089da80cddcd68758512370d217b19f8890Nathan Harold
33330e1089da80cddcd68758512370d217b19f8890Nathan Harold/**
34330e1089da80cddcd68758512370d217b19f8890Nathan Harold * This class contains methods for managing IPsec sessions, which will perform kernel-space
35330e1089da80cddcd68758512370d217b19f8890Nathan Harold * encryption and decryption of socket or Network traffic.
36330e1089da80cddcd68758512370d217b19f8890Nathan Harold *
37330e1089da80cddcd68758512370d217b19f8890Nathan Harold * <p>An IpSecManager may be obtained by calling {@link
38330e1089da80cddcd68758512370d217b19f8890Nathan Harold * android.content.Context#getSystemService(String) Context#getSystemService(String)} with {@link
39330e1089da80cddcd68758512370d217b19f8890Nathan Harold * android.content.Context#IPSEC_SERVICE Context#IPSEC_SERVICE}
40330e1089da80cddcd68758512370d217b19f8890Nathan Harold */
41330e1089da80cddcd68758512370d217b19f8890Nathan Haroldpublic final class IpSecManager {
42330e1089da80cddcd68758512370d217b19f8890Nathan Harold    private static final String TAG = "IpSecManager";
43330e1089da80cddcd68758512370d217b19f8890Nathan Harold
44330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /**
4593962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold     * The Security Parameter Index, SPI, 0 indicates an unknown or invalid index.
4693962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold     *
4793962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold     * <p>No IPsec packet may contain an SPI of 0.
4893962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold     */
4993962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold    public static final int INVALID_SECURITY_PARAMETER_INDEX = 0;
5093962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold
5193962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold    /** @hide */
5293962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold    public interface Status {
5393962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold        public static final int OK = 0;
5493962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold        public static final int RESOURCE_UNAVAILABLE = 1;
5593962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold        public static final int SPI_UNAVAILABLE = 2;
5693962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold    }
5793962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold
5893962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold    /** @hide */
5993962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold    public static final String KEY_STATUS = "status";
6093962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold    /** @hide */
6193962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold    public static final String KEY_RESOURCE_ID = "resourceId";
6293962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold    /** @hide */
6393962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold    public static final String KEY_SPI = "spi";
6493962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold    /** @hide */
6593962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold    public static final int INVALID_RESOURCE_ID = 0;
6693962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold
6793962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold    /**
68330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Indicates that the combination of remote InetAddress and SPI was non-unique for a given
69330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * request. If encountered, selection of a new SPI is required before a transform may be
70330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * created. Note, this should happen very rarely if the SPI is chosen to be sufficiently random
71330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * or reserved using reserveSecurityParameterIndex.
72330e1089da80cddcd68758512370d217b19f8890Nathan Harold     */
73330e1089da80cddcd68758512370d217b19f8890Nathan Harold    public static final class SpiUnavailableException extends AndroidException {
74330e1089da80cddcd68758512370d217b19f8890Nathan Harold        private final int mSpi;
75330e1089da80cddcd68758512370d217b19f8890Nathan Harold
76330e1089da80cddcd68758512370d217b19f8890Nathan Harold        /**
77330e1089da80cddcd68758512370d217b19f8890Nathan Harold         * Construct an exception indicating that a transform with the given SPI is already in use
78330e1089da80cddcd68758512370d217b19f8890Nathan Harold         * or otherwise unavailable.
79330e1089da80cddcd68758512370d217b19f8890Nathan Harold         *
80330e1089da80cddcd68758512370d217b19f8890Nathan Harold         * @param msg Description indicating the colliding SPI
81330e1089da80cddcd68758512370d217b19f8890Nathan Harold         * @param spi the SPI that could not be used due to a collision
82330e1089da80cddcd68758512370d217b19f8890Nathan Harold         */
83330e1089da80cddcd68758512370d217b19f8890Nathan Harold        SpiUnavailableException(String msg, int spi) {
84330e1089da80cddcd68758512370d217b19f8890Nathan Harold            super(msg + "(spi: " + spi + ")");
85330e1089da80cddcd68758512370d217b19f8890Nathan Harold            mSpi = spi;
86330e1089da80cddcd68758512370d217b19f8890Nathan Harold        }
87330e1089da80cddcd68758512370d217b19f8890Nathan Harold
88330e1089da80cddcd68758512370d217b19f8890Nathan Harold        /** Retrieve the SPI that caused a collision */
89330e1089da80cddcd68758512370d217b19f8890Nathan Harold        public int getSpi() {
90330e1089da80cddcd68758512370d217b19f8890Nathan Harold            return mSpi;
91330e1089da80cddcd68758512370d217b19f8890Nathan Harold        }
92330e1089da80cddcd68758512370d217b19f8890Nathan Harold    }
93330e1089da80cddcd68758512370d217b19f8890Nathan Harold
94330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /**
95330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Indicates that the requested system resource for IPsec, such as a socket or other system
96330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * resource is unavailable. If this exception is thrown, try releasing allocated objects of the
97330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * type requested.
98330e1089da80cddcd68758512370d217b19f8890Nathan Harold     */
99330e1089da80cddcd68758512370d217b19f8890Nathan Harold    public static final class ResourceUnavailableException extends AndroidException {
100330e1089da80cddcd68758512370d217b19f8890Nathan Harold
101330e1089da80cddcd68758512370d217b19f8890Nathan Harold        ResourceUnavailableException(String msg) {
102330e1089da80cddcd68758512370d217b19f8890Nathan Harold            super(msg);
103330e1089da80cddcd68758512370d217b19f8890Nathan Harold        }
104330e1089da80cddcd68758512370d217b19f8890Nathan Harold    }
105330e1089da80cddcd68758512370d217b19f8890Nathan Harold
1061afbef40c68373f3871eed087c546cfe1911ee36Nathan Harold    private final IIpSecService mService;
107330e1089da80cddcd68758512370d217b19f8890Nathan Harold
108330e1089da80cddcd68758512370d217b19f8890Nathan Harold    public static final class SecurityParameterIndex implements AutoCloseable {
1091afbef40c68373f3871eed087c546cfe1911ee36Nathan Harold        private final IIpSecService mService;
110c4f879925b58b1b5ca9a3cfdc898c20cbf56355aNathan Harold        private final InetAddress mRemoteAddress;
111330e1089da80cddcd68758512370d217b19f8890Nathan Harold        private final CloseGuard mCloseGuard = CloseGuard.get();
11293962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold        private int mSpi = INVALID_SECURITY_PARAMETER_INDEX;
11393962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold        private int mResourceId;
114330e1089da80cddcd68758512370d217b19f8890Nathan Harold
115330e1089da80cddcd68758512370d217b19f8890Nathan Harold        /** Return the underlying SPI held by this object */
116330e1089da80cddcd68758512370d217b19f8890Nathan Harold        public int getSpi() {
117330e1089da80cddcd68758512370d217b19f8890Nathan Harold            return mSpi;
118330e1089da80cddcd68758512370d217b19f8890Nathan Harold        }
119330e1089da80cddcd68758512370d217b19f8890Nathan Harold
120330e1089da80cddcd68758512370d217b19f8890Nathan Harold        /**
121330e1089da80cddcd68758512370d217b19f8890Nathan Harold         * Release an SPI that was previously reserved.
122330e1089da80cddcd68758512370d217b19f8890Nathan Harold         *
123c4f879925b58b1b5ca9a3cfdc898c20cbf56355aNathan Harold         * <p>Release an SPI for use by other users in the system. If a SecurityParameterIndex is
124c4f879925b58b1b5ca9a3cfdc898c20cbf56355aNathan Harold         * applied to an IpSecTransform, it will become unusable for future transforms but should
125c4f879925b58b1b5ca9a3cfdc898c20cbf56355aNathan Harold         * still be closed to ensure system resources are released.
126330e1089da80cddcd68758512370d217b19f8890Nathan Harold         */
127330e1089da80cddcd68758512370d217b19f8890Nathan Harold        @Override
128330e1089da80cddcd68758512370d217b19f8890Nathan Harold        public void close() {
12993962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold            mSpi = INVALID_SECURITY_PARAMETER_INDEX;
130330e1089da80cddcd68758512370d217b19f8890Nathan Harold            mCloseGuard.close();
131330e1089da80cddcd68758512370d217b19f8890Nathan Harold        }
132330e1089da80cddcd68758512370d217b19f8890Nathan Harold
133330e1089da80cddcd68758512370d217b19f8890Nathan Harold        @Override
134330e1089da80cddcd68758512370d217b19f8890Nathan Harold        protected void finalize() {
135330e1089da80cddcd68758512370d217b19f8890Nathan Harold            if (mCloseGuard != null) {
136330e1089da80cddcd68758512370d217b19f8890Nathan Harold                mCloseGuard.warnIfOpen();
137330e1089da80cddcd68758512370d217b19f8890Nathan Harold            }
138330e1089da80cddcd68758512370d217b19f8890Nathan Harold
139330e1089da80cddcd68758512370d217b19f8890Nathan Harold            close();
140330e1089da80cddcd68758512370d217b19f8890Nathan Harold        }
141330e1089da80cddcd68758512370d217b19f8890Nathan Harold
14293962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold        private SecurityParameterIndex(
14393962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold                @NonNull IIpSecService service, int direction, InetAddress remoteAddress, int spi)
14493962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold                throws ResourceUnavailableException, SpiUnavailableException {
14593962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold            mService = service;
14693962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold            mRemoteAddress = remoteAddress;
14793962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold            try {
14893962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold                Bundle result =
14993962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold                        mService.reserveSecurityParameterIndex(
15093962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold                                direction, remoteAddress.getHostAddress(), spi, new Binder());
15193962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold
15293962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold                if (result == null) {
15393962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold                    throw new NullPointerException("Received null response from IpSecService");
15493962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold                }
15593962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold
15693962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold                int status = result.getInt(KEY_STATUS);
15793962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold                switch (status) {
15893962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold                    case Status.OK:
15993962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold                        break;
16093962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold                    case Status.RESOURCE_UNAVAILABLE:
16193962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold                        throw new ResourceUnavailableException(
16293962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold                                "No more SPIs may be allocated by this requester.");
16393962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold                    case Status.SPI_UNAVAILABLE:
16493962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold                        throw new SpiUnavailableException("Requested SPI is unavailable", spi);
16593962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold                    default:
16693962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold                        throw new RuntimeException(
16793962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold                                "Unknown status returned by IpSecService: " + status);
16893962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold                }
16993962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold                mSpi = result.getInt(KEY_SPI);
17093962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold                mResourceId = result.getInt(KEY_RESOURCE_ID);
17193962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold
17293962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold                if (mSpi == INVALID_SECURITY_PARAMETER_INDEX) {
17393962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold                    throw new RuntimeException("Invalid SPI returned by IpSecService: " + status);
17493962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold                }
17593962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold
17693962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold                if (mResourceId == INVALID_RESOURCE_ID) {
17793962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold                    throw new RuntimeException(
17893962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold                            "Invalid Resource ID returned by IpSecService: " + status);
17993962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold                }
18093962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold
18193962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold            } catch (RemoteException e) {
18293962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold                throw e.rethrowFromSystemServer();
18393962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold            }
18493962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold            mCloseGuard.open("open");
18593962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold        }
18693962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold    }
187330e1089da80cddcd68758512370d217b19f8890Nathan Harold
188330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /**
189c4f879925b58b1b5ca9a3cfdc898c20cbf56355aNathan Harold     * Reserve an SPI for traffic bound towards the specified remote address.
190330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
191330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * <p>If successful, this SPI is guaranteed available until released by a call to {@link
192330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * SecurityParameterIndex#close()}.
193330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
194c4f879925b58b1b5ca9a3cfdc898c20cbf56355aNathan Harold     * @param direction {@link IpSecTransform#DIRECTION_IN} or {@link IpSecTransform#DIRECTION_OUT}
195c4f879925b58b1b5ca9a3cfdc898c20cbf56355aNathan Harold     * @param remoteAddress address of the remote. SPIs must be unique for each remoteAddress.
196330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @return the reserved SecurityParameterIndex
197330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @throws ResourceUnavailableException indicating that too many SPIs are currently allocated
198330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *     for this user
199330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @throws SpiUnavailableException indicating that a particular SPI cannot be reserved
200330e1089da80cddcd68758512370d217b19f8890Nathan Harold     */
201330e1089da80cddcd68758512370d217b19f8890Nathan Harold    public SecurityParameterIndex reserveSecurityParameterIndex(
2026045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold            int direction, InetAddress remoteAddress)
2036045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold            throws ResourceUnavailableException {
2046045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold        try {
2056045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold            return new SecurityParameterIndex(
2066045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold                    mService,
2076045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold                    direction,
2086045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold                    remoteAddress,
2096045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold                    IpSecManager.INVALID_SECURITY_PARAMETER_INDEX);
2106045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold        } catch (SpiUnavailableException unlikely) {
2116045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold            throw new ResourceUnavailableException("No SPIs available");
2126045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold        }
2136045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold    }
2146045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold
2156045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold    /**
2166045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold     * Reserve an SPI for traffic bound towards the specified remote address.
2176045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold     *
2186045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold     * <p>If successful, this SPI is guaranteed available until released by a call to {@link
2196045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold     * SecurityParameterIndex#close()}.
2206045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold     *
2216045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold     * @param direction {@link IpSecTransform#DIRECTION_IN} or {@link IpSecTransform#DIRECTION_OUT}
2226045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold     * @param remoteAddress address of the remote. SPIs must be unique for each remoteAddress.
2236045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold     * @param requestedSpi the requested SPI, or '0' to allocate a random SPI.
2246045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold     * @return the reserved SecurityParameterIndex
2256045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold     * @throws ResourceUnavailableException indicating that too many SPIs are currently allocated
2266045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold     *     for this user
2276045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold     */
2286045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold    public SecurityParameterIndex reserveSecurityParameterIndex(
229c4f879925b58b1b5ca9a3cfdc898c20cbf56355aNathan Harold            int direction, InetAddress remoteAddress, int requestedSpi)
230330e1089da80cddcd68758512370d217b19f8890Nathan Harold            throws SpiUnavailableException, ResourceUnavailableException {
2316045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold        if (requestedSpi == IpSecManager.INVALID_SECURITY_PARAMETER_INDEX) {
2326045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold            throw new IllegalArgumentException("Requested SPI must be a valid (non-zero) SPI");
2336045429b35ca4c1cbd920e5e0872dec9de493fdeNathan Harold        }
234c4f879925b58b1b5ca9a3cfdc898c20cbf56355aNathan Harold        return new SecurityParameterIndex(mService, direction, remoteAddress, requestedSpi);
235330e1089da80cddcd68758512370d217b19f8890Nathan Harold    }
236330e1089da80cddcd68758512370d217b19f8890Nathan Harold
237330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /**
238330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Apply an active Transport Mode IPsec Transform to a stream socket to perform IPsec
239330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * encapsulation of the traffic flowing between the socket and the remote InetAddress of that
240330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * transform. For security reasons, attempts to send traffic to any IP address other than the
241330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * address associated with that transform will throw an IOException. In addition, if the
242330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * IpSecTransform is later deactivated, the socket will throw an IOException on any calls to
243330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * send() or receive() until the transform is removed from the socket by calling {@link
244330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * #removeTransportModeTransform(Socket, IpSecTransform)};
245330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
246330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param socket a stream socket
247330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param transform an {@link IpSecTransform}, which must be an active Transport Mode transform.
248330e1089da80cddcd68758512370d217b19f8890Nathan Harold     */
249330e1089da80cddcd68758512370d217b19f8890Nathan Harold    public void applyTransportModeTransform(Socket socket, IpSecTransform transform)
250330e1089da80cddcd68758512370d217b19f8890Nathan Harold            throws IOException {
251330e1089da80cddcd68758512370d217b19f8890Nathan Harold        applyTransportModeTransform(ParcelFileDescriptor.fromSocket(socket), transform);
252330e1089da80cddcd68758512370d217b19f8890Nathan Harold    }
253330e1089da80cddcd68758512370d217b19f8890Nathan Harold
254330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /**
255330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Apply an active Transport Mode IPsec Transform to a datagram socket to perform IPsec
256330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * encapsulation of the traffic flowing between the socket and the remote InetAddress of that
257330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * transform. For security reasons, attempts to send traffic to any IP address other than the
258330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * address associated with that transform will throw an IOException. In addition, if the
259330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * IpSecTransform is later deactivated, the socket will throw an IOException on any calls to
260330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * send() or receive() until the transform is removed from the socket by calling {@link
261330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * #removeTransportModeTransform(DatagramSocket, IpSecTransform)};
262330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
263330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param socket a datagram socket
264330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param transform an {@link IpSecTransform}, which must be an active Transport Mode transform.
265330e1089da80cddcd68758512370d217b19f8890Nathan Harold     */
266330e1089da80cddcd68758512370d217b19f8890Nathan Harold    public void applyTransportModeTransform(DatagramSocket socket, IpSecTransform transform)
267330e1089da80cddcd68758512370d217b19f8890Nathan Harold            throws IOException {
268330e1089da80cddcd68758512370d217b19f8890Nathan Harold        applyTransportModeTransform(ParcelFileDescriptor.fromDatagramSocket(socket), transform);
269330e1089da80cddcd68758512370d217b19f8890Nathan Harold    }
270330e1089da80cddcd68758512370d217b19f8890Nathan Harold
271330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /* Call down to activate a transform */
27293962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold    private void applyTransportModeTransform(ParcelFileDescriptor pfd, IpSecTransform transform) {
27393962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold        try {
27493962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold            mService.applyTransportModeTransform(pfd, transform.getResourceId());
27593962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold        } catch (RemoteException e) {
27693962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold            throw e.rethrowFromSystemServer();
27793962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold        }
27893962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold    }
279330e1089da80cddcd68758512370d217b19f8890Nathan Harold
280330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /**
281330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Apply an active Tunnel Mode IPsec Transform to a network, which will tunnel all traffic to
282330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * and from that network's interface with IPsec (applies an outer IP header and IPsec Header to
283330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * all traffic, and expects an additional IP header and IPsec Header on all inbound traffic).
284330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Applications should probably not use this API directly. Instead, they should use {@link
285330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * VpnService} to provide VPN capability in a more generic fashion.
286330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
287330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param net a {@link Network} that will be tunneled via IP Sec.
288330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param transform an {@link IpSecTransform}, which must be an active Tunnel Mode transform.
289330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @hide
290330e1089da80cddcd68758512370d217b19f8890Nathan Harold     */
291330e1089da80cddcd68758512370d217b19f8890Nathan Harold    public void applyTunnelModeTransform(Network net, IpSecTransform transform) {}
292330e1089da80cddcd68758512370d217b19f8890Nathan Harold
293330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /**
294330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Remove a transform from a given stream socket. Once removed, traffic on the socket will not
295330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * be encypted. This allows sockets that have been used for IPsec to be reclaimed for
296330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * communication in the clear in the event socket reuse is desired. This operation will succeed
297330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * regardless of the underlying state of a transform. If a transform is removed, communication
298330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * on all sockets to which that transform was applied will fail until this method is called.
299330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
300330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param socket a socket that previously had a transform applied to it.
301330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param transform the IPsec Transform that was previously applied to the given socket
302330e1089da80cddcd68758512370d217b19f8890Nathan Harold     */
303330e1089da80cddcd68758512370d217b19f8890Nathan Harold    public void removeTransportModeTransform(Socket socket, IpSecTransform transform) {
304330e1089da80cddcd68758512370d217b19f8890Nathan Harold        removeTransportModeTransform(ParcelFileDescriptor.fromSocket(socket), transform);
305330e1089da80cddcd68758512370d217b19f8890Nathan Harold    }
306330e1089da80cddcd68758512370d217b19f8890Nathan Harold
307330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /**
308330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Remove a transform from a given datagram socket. Once removed, traffic on the socket will not
309330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * be encypted. This allows sockets that have been used for IPsec to be reclaimed for
310330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * communication in the clear in the event socket reuse is desired. This operation will succeed
311330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * regardless of the underlying state of a transform. If a transform is removed, communication
312330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * on all sockets to which that transform was applied will fail until this method is called.
313330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
314330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param socket a socket that previously had a transform applied to it.
315330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param transform the IPsec Transform that was previously applied to the given socket
316330e1089da80cddcd68758512370d217b19f8890Nathan Harold     */
317330e1089da80cddcd68758512370d217b19f8890Nathan Harold    public void removeTransportModeTransform(DatagramSocket socket, IpSecTransform transform) {
318330e1089da80cddcd68758512370d217b19f8890Nathan Harold        removeTransportModeTransform(ParcelFileDescriptor.fromDatagramSocket(socket), transform);
319330e1089da80cddcd68758512370d217b19f8890Nathan Harold    }
320330e1089da80cddcd68758512370d217b19f8890Nathan Harold
321330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /* Call down to activate a transform */
32293962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold    private void removeTransportModeTransform(ParcelFileDescriptor pfd, IpSecTransform transform) {
32393962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold        try {
32493962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold            mService.removeTransportModeTransform(pfd, transform.getResourceId());
32593962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold        } catch (RemoteException e) {
32693962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold            throw e.rethrowFromSystemServer();
32793962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold        }
32893962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold    }
329330e1089da80cddcd68758512370d217b19f8890Nathan Harold
330330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /**
331330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Remove a Tunnel Mode IPsec Transform from a {@link Network}. This must be used as part of
332330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * cleanup if a tunneled Network experiences a change in default route. The Network will drop
333330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * all traffic that cannot be routed to the Tunnel's outbound interface. If that interface is
334330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * lost, all traffic will drop.
335330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
336330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param net a network that currently has transform applied to it.
337330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param transform a Tunnel Mode IPsec Transform that has been previously applied to the given
338330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *     network
339330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @hide
340330e1089da80cddcd68758512370d217b19f8890Nathan Harold     */
341330e1089da80cddcd68758512370d217b19f8890Nathan Harold    public void removeTunnelModeTransform(Network net, IpSecTransform transform) {}
342330e1089da80cddcd68758512370d217b19f8890Nathan Harold
343330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /**
344330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Class providing access to a system-provided UDP Encapsulation Socket, which may be used for
345330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * IKE signalling as well as for inbound and outbound UDP encapsulated IPsec traffic.
346330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
347330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * <p>The socket provided by this class cannot be re-bound or closed via the inner
348330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * FileDescriptor. Instead, disposing of this socket requires a call to close().
349330e1089da80cddcd68758512370d217b19f8890Nathan Harold     */
350330e1089da80cddcd68758512370d217b19f8890Nathan Harold    public static final class UdpEncapsulationSocket implements AutoCloseable {
351330e1089da80cddcd68758512370d217b19f8890Nathan Harold        private final FileDescriptor mFd;
3521afbef40c68373f3871eed087c546cfe1911ee36Nathan Harold        private final IIpSecService mService;
353330e1089da80cddcd68758512370d217b19f8890Nathan Harold        private final CloseGuard mCloseGuard = CloseGuard.get();
354330e1089da80cddcd68758512370d217b19f8890Nathan Harold
35593962f34ce21f5aac825afbcebf2f3e8c7a30910Nathan Harold        private UdpEncapsulationSocket(@NonNull IIpSecService service, int port)
356330e1089da80cddcd68758512370d217b19f8890Nathan Harold                throws ResourceUnavailableException {
3571afbef40c68373f3871eed087c546cfe1911ee36Nathan Harold            mService = service;
358330e1089da80cddcd68758512370d217b19f8890Nathan Harold            mCloseGuard.open("constructor");
359330e1089da80cddcd68758512370d217b19f8890Nathan Harold            // TODO: go down to the kernel and get a socket on the specified
360330e1089da80cddcd68758512370d217b19f8890Nathan Harold            mFd = new FileDescriptor();
361330e1089da80cddcd68758512370d217b19f8890Nathan Harold        }
362330e1089da80cddcd68758512370d217b19f8890Nathan Harold
3631afbef40c68373f3871eed087c546cfe1911ee36Nathan Harold        private UdpEncapsulationSocket(IIpSecService service) throws ResourceUnavailableException {
3641afbef40c68373f3871eed087c546cfe1911ee36Nathan Harold            mService = service;
365330e1089da80cddcd68758512370d217b19f8890Nathan Harold            mCloseGuard.open("constructor");
366330e1089da80cddcd68758512370d217b19f8890Nathan Harold            // TODO: go get a random socket on a random port
367330e1089da80cddcd68758512370d217b19f8890Nathan Harold            mFd = new FileDescriptor();
368330e1089da80cddcd68758512370d217b19f8890Nathan Harold        }
369330e1089da80cddcd68758512370d217b19f8890Nathan Harold
370330e1089da80cddcd68758512370d217b19f8890Nathan Harold        /** Access the inner UDP Encapsulation Socket */
371330e1089da80cddcd68758512370d217b19f8890Nathan Harold        public FileDescriptor getSocket() {
372330e1089da80cddcd68758512370d217b19f8890Nathan Harold            return mFd;
373330e1089da80cddcd68758512370d217b19f8890Nathan Harold        }
374330e1089da80cddcd68758512370d217b19f8890Nathan Harold
375330e1089da80cddcd68758512370d217b19f8890Nathan Harold        /** Retrieve the port number of the inner encapsulation socket */
376330e1089da80cddcd68758512370d217b19f8890Nathan Harold        public int getPort() {
377330e1089da80cddcd68758512370d217b19f8890Nathan Harold            return 0; // TODO get the port number from the Socket;
378330e1089da80cddcd68758512370d217b19f8890Nathan Harold        }
379330e1089da80cddcd68758512370d217b19f8890Nathan Harold
380330e1089da80cddcd68758512370d217b19f8890Nathan Harold        @Override
381330e1089da80cddcd68758512370d217b19f8890Nathan Harold        /**
382330e1089da80cddcd68758512370d217b19f8890Nathan Harold         * Release the resources that have been reserved for this Socket.
383330e1089da80cddcd68758512370d217b19f8890Nathan Harold         *
384330e1089da80cddcd68758512370d217b19f8890Nathan Harold         * <p>This method closes the underlying socket, reducing a user's allocated sockets in the
385330e1089da80cddcd68758512370d217b19f8890Nathan Harold         * system. This must be done as part of cleanup following use of a socket. Failure to do so
386330e1089da80cddcd68758512370d217b19f8890Nathan Harold         * will cause the socket to count against a total allocation limit for IpSec and eventually
387330e1089da80cddcd68758512370d217b19f8890Nathan Harold         * fail due to resource limits.
388330e1089da80cddcd68758512370d217b19f8890Nathan Harold         *
389330e1089da80cddcd68758512370d217b19f8890Nathan Harold         * @param fd a file descriptor previously returned as a UDP Encapsulation socket.
390330e1089da80cddcd68758512370d217b19f8890Nathan Harold         */
391330e1089da80cddcd68758512370d217b19f8890Nathan Harold        public void close() {
392330e1089da80cddcd68758512370d217b19f8890Nathan Harold            // TODO: Go close the socket
393330e1089da80cddcd68758512370d217b19f8890Nathan Harold            mCloseGuard.close();
394330e1089da80cddcd68758512370d217b19f8890Nathan Harold        }
395330e1089da80cddcd68758512370d217b19f8890Nathan Harold
396330e1089da80cddcd68758512370d217b19f8890Nathan Harold        @Override
397330e1089da80cddcd68758512370d217b19f8890Nathan Harold        protected void finalize() throws Throwable {
398330e1089da80cddcd68758512370d217b19f8890Nathan Harold            if (mCloseGuard != null) {
399330e1089da80cddcd68758512370d217b19f8890Nathan Harold                mCloseGuard.warnIfOpen();
400330e1089da80cddcd68758512370d217b19f8890Nathan Harold            }
401330e1089da80cddcd68758512370d217b19f8890Nathan Harold
402330e1089da80cddcd68758512370d217b19f8890Nathan Harold            close();
403330e1089da80cddcd68758512370d217b19f8890Nathan Harold        }
404330e1089da80cddcd68758512370d217b19f8890Nathan Harold    };
405330e1089da80cddcd68758512370d217b19f8890Nathan Harold
406330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /**
407330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Open a socket that is bound to a free UDP port on the system.
408330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
409330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * <p>By binding in this manner and holding the FileDescriptor, the socket cannot be un-bound by
410330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * the caller. This provides safe access to a socket on a port that can later be used as a UDP
411330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Encapsulation port.
412330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
413330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * <p>This socket reservation works in conjunction with IpSecTransforms, which may re-use the
414330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * socket port. Explicitly opening this port is only necessary if communication is desired on
415330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * that port.
416330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
417330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param port a local UDP port to be reserved for UDP Encapsulation. is provided, then this
418330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *     method will bind to the specified port or fail. To retrieve the port number, call {@link
419330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *     android.system.Os#getsockname(FileDescriptor)}.
420330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @return a {@link UdpEncapsulationSocket} that is bound to the requested port for the lifetime
421330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *     of the object.
422330e1089da80cddcd68758512370d217b19f8890Nathan Harold     */
423330e1089da80cddcd68758512370d217b19f8890Nathan Harold    // Returning a socket in this fashion that has been created and bound by the system
424330e1089da80cddcd68758512370d217b19f8890Nathan Harold    // is the only safe way to ensure that a socket is both accessible to the user and
425330e1089da80cddcd68758512370d217b19f8890Nathan Harold    // safely usable for Encapsulation without allowing a user to possibly unbind from/close
426330e1089da80cddcd68758512370d217b19f8890Nathan Harold    // the port, which could potentially impact the traffic of the next user who binds to that
427330e1089da80cddcd68758512370d217b19f8890Nathan Harold    // socket.
428330e1089da80cddcd68758512370d217b19f8890Nathan Harold    public UdpEncapsulationSocket openUdpEncapsulationSocket(int port)
429330e1089da80cddcd68758512370d217b19f8890Nathan Harold            throws IOException, ResourceUnavailableException {
430330e1089da80cddcd68758512370d217b19f8890Nathan Harold        // Temporary code
4311afbef40c68373f3871eed087c546cfe1911ee36Nathan Harold        return new UdpEncapsulationSocket(mService, port);
432330e1089da80cddcd68758512370d217b19f8890Nathan Harold    }
433330e1089da80cddcd68758512370d217b19f8890Nathan Harold
434330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /**
435330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Open a socket that is bound to a port selected by the system.
436330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
437330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * <p>By binding in this manner and holding the FileDescriptor, the socket cannot be un-bound by
438330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * the caller. This provides safe access to a socket on a port that can later be used as a UDP
439330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Encapsulation port.
440330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
441330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * <p>This socket reservation works in conjunction with IpSecTransforms, which may re-use the
442330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * socket port. Explicitly opening this port is only necessary if communication is desired on
443330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * that port.
444330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
445330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @return a {@link UdpEncapsulationSocket} that is bound to an arbitrarily selected port
446330e1089da80cddcd68758512370d217b19f8890Nathan Harold     */
447330e1089da80cddcd68758512370d217b19f8890Nathan Harold    // Returning a socket in this fashion that has been created and bound by the system
448330e1089da80cddcd68758512370d217b19f8890Nathan Harold    // is the only safe way to ensure that a socket is both accessible to the user and
449330e1089da80cddcd68758512370d217b19f8890Nathan Harold    // safely usable for Encapsulation without allowing a user to possibly unbind from/close
450330e1089da80cddcd68758512370d217b19f8890Nathan Harold    // the port, which could potentially impact the traffic of the next user who binds to that
451330e1089da80cddcd68758512370d217b19f8890Nathan Harold    // socket.
452330e1089da80cddcd68758512370d217b19f8890Nathan Harold    public UdpEncapsulationSocket openUdpEncapsulationSocket()
453330e1089da80cddcd68758512370d217b19f8890Nathan Harold            throws IOException, ResourceUnavailableException {
454330e1089da80cddcd68758512370d217b19f8890Nathan Harold        // Temporary code
4551afbef40c68373f3871eed087c546cfe1911ee36Nathan Harold        return new UdpEncapsulationSocket(mService);
456330e1089da80cddcd68758512370d217b19f8890Nathan Harold    }
457330e1089da80cddcd68758512370d217b19f8890Nathan Harold
458330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /**
459330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Retrieve an instance of an IpSecManager within you application context
460330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
461330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param context the application context for this manager
462330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @hide
463330e1089da80cddcd68758512370d217b19f8890Nathan Harold     */
4641afbef40c68373f3871eed087c546cfe1911ee36Nathan Harold    public IpSecManager(IIpSecService service) {
465330e1089da80cddcd68758512370d217b19f8890Nathan Harold        mService = checkNotNull(service, "missing service");
466330e1089da80cddcd68758512370d217b19f8890Nathan Harold    }
467330e1089da80cddcd68758512370d217b19f8890Nathan Harold}
468