IpSecManager.java revision d86b8fea43ebb6e5c31691b44d8ceb0d8d3c9072
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
20f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Haroldimport android.annotation.NonNull;
21d86b8fea43ebb6e5c31691b44d8ceb0d8d3c9072Jeff Sharkeyimport android.annotation.SystemService;
22d86b8fea43ebb6e5c31691b44d8ceb0d8d3c9072Jeff Sharkeyimport android.content.Context;
23f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Haroldimport android.os.Binder;
24f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Haroldimport android.os.Bundle;
25330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport android.os.ParcelFileDescriptor;
26f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Haroldimport android.os.RemoteException;
27330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport android.util.AndroidException;
28330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport dalvik.system.CloseGuard;
29330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport java.io.FileDescriptor;
30330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport java.io.IOException;
31330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport java.net.DatagramSocket;
32330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport java.net.InetAddress;
33330e1089da80cddcd68758512370d217b19f8890Nathan Haroldimport java.net.Socket;
34330e1089da80cddcd68758512370d217b19f8890Nathan Harold
35330e1089da80cddcd68758512370d217b19f8890Nathan Harold/**
36330e1089da80cddcd68758512370d217b19f8890Nathan Harold * This class contains methods for managing IPsec sessions, which will perform kernel-space
37330e1089da80cddcd68758512370d217b19f8890Nathan Harold * encryption and decryption of socket or Network traffic.
38330e1089da80cddcd68758512370d217b19f8890Nathan Harold *
39bd62d6aff264b8e8ce4a06ca6417e69bcca3006bNathan Harold * @hide
40330e1089da80cddcd68758512370d217b19f8890Nathan Harold */
41d86b8fea43ebb6e5c31691b44d8ceb0d8d3c9072Jeff Sharkey@SystemService(Context.IPSEC_SERVICE)
42330e1089da80cddcd68758512370d217b19f8890Nathan Haroldpublic final class IpSecManager {
43330e1089da80cddcd68758512370d217b19f8890Nathan Harold    private static final String TAG = "IpSecManager";
44330e1089da80cddcd68758512370d217b19f8890Nathan Harold
45330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /**
46f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold     * The Security Parameter Index, SPI, 0 indicates an unknown or invalid index.
47f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold     *
48f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold     * <p>No IPsec packet may contain an SPI of 0.
49f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold     */
50f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold    public static final int INVALID_SECURITY_PARAMETER_INDEX = 0;
51f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold
52f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold    /** @hide */
53f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold    public interface Status {
54f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold        public static final int OK = 0;
55f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold        public static final int RESOURCE_UNAVAILABLE = 1;
56f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold        public static final int SPI_UNAVAILABLE = 2;
57f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold    }
58f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold
59f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold    /** @hide */
60f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold    public static final String KEY_STATUS = "status";
61f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold    /** @hide */
62f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold    public static final String KEY_RESOURCE_ID = "resourceId";
63f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold    /** @hide */
64f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold    public static final String KEY_SPI = "spi";
65f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold    /** @hide */
66f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold    public static final int INVALID_RESOURCE_ID = 0;
67f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold
68f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan 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
107cbb58ecc866f90b2fe829b808a65652376006c24Nathan Harold    private final IIpSecService mService;
108330e1089da80cddcd68758512370d217b19f8890Nathan Harold
109330e1089da80cddcd68758512370d217b19f8890Nathan Harold    public static final class SecurityParameterIndex implements AutoCloseable {
110cbb58ecc866f90b2fe829b808a65652376006c24Nathan Harold        private final IIpSecService mService;
111eece454de1178260b97e3d5dd99c83003139eb5fNathan Harold        private final InetAddress mRemoteAddress;
112330e1089da80cddcd68758512370d217b19f8890Nathan Harold        private final CloseGuard mCloseGuard = CloseGuard.get();
113f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold        private int mSpi = INVALID_SECURITY_PARAMETER_INDEX;
114f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan 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         *
124eece454de1178260b97e3d5dd99c83003139eb5fNathan Harold         * <p>Release an SPI for use by other users in the system. If a SecurityParameterIndex is
125eece454de1178260b97e3d5dd99c83003139eb5fNathan Harold         * applied to an IpSecTransform, it will become unusable for future transforms but should
126eece454de1178260b97e3d5dd99c83003139eb5fNathan Harold         * still be closed to ensure system resources are released.
127330e1089da80cddcd68758512370d217b19f8890Nathan Harold         */
128330e1089da80cddcd68758512370d217b19f8890Nathan Harold        @Override
129330e1089da80cddcd68758512370d217b19f8890Nathan Harold        public void close() {
130f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold            mSpi = INVALID_SECURITY_PARAMETER_INDEX;
131330e1089da80cddcd68758512370d217b19f8890Nathan Harold            mCloseGuard.close();
132330e1089da80cddcd68758512370d217b19f8890Nathan Harold        }
133330e1089da80cddcd68758512370d217b19f8890Nathan Harold
134330e1089da80cddcd68758512370d217b19f8890Nathan Harold        @Override
135330e1089da80cddcd68758512370d217b19f8890Nathan Harold        protected void finalize() {
136330e1089da80cddcd68758512370d217b19f8890Nathan Harold            if (mCloseGuard != null) {
137330e1089da80cddcd68758512370d217b19f8890Nathan Harold                mCloseGuard.warnIfOpen();
138330e1089da80cddcd68758512370d217b19f8890Nathan Harold            }
139330e1089da80cddcd68758512370d217b19f8890Nathan Harold
140330e1089da80cddcd68758512370d217b19f8890Nathan Harold            close();
141330e1089da80cddcd68758512370d217b19f8890Nathan Harold        }
142330e1089da80cddcd68758512370d217b19f8890Nathan Harold
143f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold        private SecurityParameterIndex(
144f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold                @NonNull IIpSecService service, int direction, InetAddress remoteAddress, int spi)
145f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold                throws ResourceUnavailableException, SpiUnavailableException {
146f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold            mService = service;
147f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold            mRemoteAddress = remoteAddress;
148f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold            try {
149f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold                Bundle result =
150f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold                        mService.reserveSecurityParameterIndex(
151f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold                                direction, remoteAddress.getHostAddress(), spi, new Binder());
152f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold
153f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold                if (result == null) {
154f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold                    throw new NullPointerException("Received null response from IpSecService");
155f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold                }
156f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold
157f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold                int status = result.getInt(KEY_STATUS);
158f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold                switch (status) {
159f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold                    case Status.OK:
160f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold                        break;
161f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold                    case Status.RESOURCE_UNAVAILABLE:
162f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold                        throw new ResourceUnavailableException(
163f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold                                "No more SPIs may be allocated by this requester.");
164f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold                    case Status.SPI_UNAVAILABLE:
165f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold                        throw new SpiUnavailableException("Requested SPI is unavailable", spi);
166f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold                    default:
167f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold                        throw new RuntimeException(
168f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold                                "Unknown status returned by IpSecService: " + status);
169f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold                }
170f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold                mSpi = result.getInt(KEY_SPI);
171f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold                mResourceId = result.getInt(KEY_RESOURCE_ID);
172f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold
173f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold                if (mSpi == INVALID_SECURITY_PARAMETER_INDEX) {
174f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold                    throw new RuntimeException("Invalid SPI returned by IpSecService: " + status);
175f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold                }
176f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold
177f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold                if (mResourceId == INVALID_RESOURCE_ID) {
178f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold                    throw new RuntimeException(
179f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold                            "Invalid Resource ID returned by IpSecService: " + status);
180f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold                }
181f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold
182f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold            } catch (RemoteException e) {
183f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold                throw e.rethrowFromSystemServer();
184f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold            }
185f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold            mCloseGuard.open("open");
186f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold        }
187f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold    }
188330e1089da80cddcd68758512370d217b19f8890Nathan Harold
189330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /**
190eece454de1178260b97e3d5dd99c83003139eb5fNathan Harold     * Reserve an SPI for traffic bound towards the specified remote address.
191330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
192330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * <p>If successful, this SPI is guaranteed available until released by a call to {@link
193330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * SecurityParameterIndex#close()}.
194330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
195eece454de1178260b97e3d5dd99c83003139eb5fNathan Harold     * @param direction {@link IpSecTransform#DIRECTION_IN} or {@link IpSecTransform#DIRECTION_OUT}
196eece454de1178260b97e3d5dd99c83003139eb5fNathan Harold     * @param remoteAddress address of the remote. SPIs must be unique for each remoteAddress.
197330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @return the reserved SecurityParameterIndex
198330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @throws ResourceUnavailableException indicating that too many SPIs are currently allocated
199330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *     for this user
200330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @throws SpiUnavailableException indicating that a particular SPI cannot be reserved
201330e1089da80cddcd68758512370d217b19f8890Nathan Harold     */
202330e1089da80cddcd68758512370d217b19f8890Nathan Harold    public SecurityParameterIndex reserveSecurityParameterIndex(
2035ad768c3b75c5dcc8e8aa90ee27f2beb7fe9590aNathan Harold            int direction, InetAddress remoteAddress)
2045ad768c3b75c5dcc8e8aa90ee27f2beb7fe9590aNathan Harold            throws ResourceUnavailableException {
2055ad768c3b75c5dcc8e8aa90ee27f2beb7fe9590aNathan Harold        try {
2065ad768c3b75c5dcc8e8aa90ee27f2beb7fe9590aNathan Harold            return new SecurityParameterIndex(
2075ad768c3b75c5dcc8e8aa90ee27f2beb7fe9590aNathan Harold                    mService,
2085ad768c3b75c5dcc8e8aa90ee27f2beb7fe9590aNathan Harold                    direction,
2095ad768c3b75c5dcc8e8aa90ee27f2beb7fe9590aNathan Harold                    remoteAddress,
2105ad768c3b75c5dcc8e8aa90ee27f2beb7fe9590aNathan Harold                    IpSecManager.INVALID_SECURITY_PARAMETER_INDEX);
2115ad768c3b75c5dcc8e8aa90ee27f2beb7fe9590aNathan Harold        } catch (SpiUnavailableException unlikely) {
2125ad768c3b75c5dcc8e8aa90ee27f2beb7fe9590aNathan Harold            throw new ResourceUnavailableException("No SPIs available");
2135ad768c3b75c5dcc8e8aa90ee27f2beb7fe9590aNathan Harold        }
2145ad768c3b75c5dcc8e8aa90ee27f2beb7fe9590aNathan Harold    }
2155ad768c3b75c5dcc8e8aa90ee27f2beb7fe9590aNathan Harold
2165ad768c3b75c5dcc8e8aa90ee27f2beb7fe9590aNathan Harold    /**
2175ad768c3b75c5dcc8e8aa90ee27f2beb7fe9590aNathan Harold     * Reserve an SPI for traffic bound towards the specified remote address.
2185ad768c3b75c5dcc8e8aa90ee27f2beb7fe9590aNathan Harold     *
2195ad768c3b75c5dcc8e8aa90ee27f2beb7fe9590aNathan Harold     * <p>If successful, this SPI is guaranteed available until released by a call to {@link
2205ad768c3b75c5dcc8e8aa90ee27f2beb7fe9590aNathan Harold     * SecurityParameterIndex#close()}.
2215ad768c3b75c5dcc8e8aa90ee27f2beb7fe9590aNathan Harold     *
2225ad768c3b75c5dcc8e8aa90ee27f2beb7fe9590aNathan Harold     * @param direction {@link IpSecTransform#DIRECTION_IN} or {@link IpSecTransform#DIRECTION_OUT}
2235ad768c3b75c5dcc8e8aa90ee27f2beb7fe9590aNathan Harold     * @param remoteAddress address of the remote. SPIs must be unique for each remoteAddress.
2245ad768c3b75c5dcc8e8aa90ee27f2beb7fe9590aNathan Harold     * @param requestedSpi the requested SPI, or '0' to allocate a random SPI.
2255ad768c3b75c5dcc8e8aa90ee27f2beb7fe9590aNathan Harold     * @return the reserved SecurityParameterIndex
2265ad768c3b75c5dcc8e8aa90ee27f2beb7fe9590aNathan Harold     * @throws ResourceUnavailableException indicating that too many SPIs are currently allocated
2275ad768c3b75c5dcc8e8aa90ee27f2beb7fe9590aNathan Harold     *     for this user
2285ad768c3b75c5dcc8e8aa90ee27f2beb7fe9590aNathan Harold     */
2295ad768c3b75c5dcc8e8aa90ee27f2beb7fe9590aNathan Harold    public SecurityParameterIndex reserveSecurityParameterIndex(
230eece454de1178260b97e3d5dd99c83003139eb5fNathan Harold            int direction, InetAddress remoteAddress, int requestedSpi)
231330e1089da80cddcd68758512370d217b19f8890Nathan Harold            throws SpiUnavailableException, ResourceUnavailableException {
2325ad768c3b75c5dcc8e8aa90ee27f2beb7fe9590aNathan Harold        if (requestedSpi == IpSecManager.INVALID_SECURITY_PARAMETER_INDEX) {
2335ad768c3b75c5dcc8e8aa90ee27f2beb7fe9590aNathan Harold            throw new IllegalArgumentException("Requested SPI must be a valid (non-zero) SPI");
2345ad768c3b75c5dcc8e8aa90ee27f2beb7fe9590aNathan Harold        }
235eece454de1178260b97e3d5dd99c83003139eb5fNathan Harold        return new SecurityParameterIndex(mService, direction, remoteAddress, requestedSpi);
236330e1089da80cddcd68758512370d217b19f8890Nathan Harold    }
237330e1089da80cddcd68758512370d217b19f8890Nathan Harold
238330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /**
239330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Apply an active Transport Mode IPsec Transform to a stream socket to perform IPsec
240330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * encapsulation of the traffic flowing between the socket and the remote InetAddress of that
241330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * transform. For security reasons, attempts to send traffic to any IP address other than the
242330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * address associated with that transform will throw an IOException. In addition, if the
243330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * IpSecTransform is later deactivated, the socket will throw an IOException on any calls to
244330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * send() or receive() until the transform is removed from the socket by calling {@link
245330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * #removeTransportModeTransform(Socket, IpSecTransform)};
246330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
247330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param socket a stream socket
248330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param transform an {@link IpSecTransform}, which must be an active Transport Mode transform.
24910f051ca91f352acea3ccd329da87db67012bd19Nathan Harold     * @hide
250330e1089da80cddcd68758512370d217b19f8890Nathan Harold     */
251330e1089da80cddcd68758512370d217b19f8890Nathan Harold    public void applyTransportModeTransform(Socket socket, IpSecTransform transform)
252330e1089da80cddcd68758512370d217b19f8890Nathan Harold            throws IOException {
253330e1089da80cddcd68758512370d217b19f8890Nathan Harold        applyTransportModeTransform(ParcelFileDescriptor.fromSocket(socket), transform);
254330e1089da80cddcd68758512370d217b19f8890Nathan Harold    }
255330e1089da80cddcd68758512370d217b19f8890Nathan Harold
256330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /**
257330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Apply an active Transport Mode IPsec Transform to a datagram socket to perform IPsec
258330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * encapsulation of the traffic flowing between the socket and the remote InetAddress of that
259330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * transform. For security reasons, attempts to send traffic to any IP address other than the
260330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * address associated with that transform will throw an IOException. In addition, if the
261330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * IpSecTransform is later deactivated, the socket will throw an IOException on any calls to
262330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * send() or receive() until the transform is removed from the socket by calling {@link
263330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * #removeTransportModeTransform(DatagramSocket, IpSecTransform)};
264330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
265330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param socket a datagram socket
266330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param transform an {@link IpSecTransform}, which must be an active Transport Mode transform.
26710f051ca91f352acea3ccd329da87db67012bd19Nathan Harold     * @hide
268330e1089da80cddcd68758512370d217b19f8890Nathan Harold     */
269330e1089da80cddcd68758512370d217b19f8890Nathan Harold    public void applyTransportModeTransform(DatagramSocket socket, IpSecTransform transform)
270330e1089da80cddcd68758512370d217b19f8890Nathan Harold            throws IOException {
271330e1089da80cddcd68758512370d217b19f8890Nathan Harold        applyTransportModeTransform(ParcelFileDescriptor.fromDatagramSocket(socket), transform);
272330e1089da80cddcd68758512370d217b19f8890Nathan Harold    }
273330e1089da80cddcd68758512370d217b19f8890Nathan Harold
274330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /* Call down to activate a transform */
275f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold    private void applyTransportModeTransform(ParcelFileDescriptor pfd, IpSecTransform transform) {
276f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold        try {
277f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold            mService.applyTransportModeTransform(pfd, transform.getResourceId());
278f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold        } catch (RemoteException e) {
279f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold            throw e.rethrowFromSystemServer();
280f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold        }
281f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold    }
282330e1089da80cddcd68758512370d217b19f8890Nathan Harold
283330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /**
28409098dc441913f30905f6ffd6f73262924858dd0Nathan Harold     * Apply an active Transport Mode IPsec Transform to a stream socket to perform IPsec
28509098dc441913f30905f6ffd6f73262924858dd0Nathan Harold     * encapsulation of the traffic flowing between the socket and the remote InetAddress of that
28609098dc441913f30905f6ffd6f73262924858dd0Nathan Harold     * transform. For security reasons, attempts to send traffic to any IP address other than the
28709098dc441913f30905f6ffd6f73262924858dd0Nathan Harold     * address associated with that transform will throw an IOException. In addition, if the
28809098dc441913f30905f6ffd6f73262924858dd0Nathan Harold     * IpSecTransform is later deactivated, the socket will throw an IOException on any calls to
28909098dc441913f30905f6ffd6f73262924858dd0Nathan Harold     * send() or receive() until the transform is removed from the socket by calling {@link
29010f051ca91f352acea3ccd329da87db67012bd19Nathan Harold     * #removeTransportModeTransform(FileDescriptor, IpSecTransform)};
29109098dc441913f30905f6ffd6f73262924858dd0Nathan Harold     *
29209098dc441913f30905f6ffd6f73262924858dd0Nathan Harold     * @param socket a socket file descriptor
29309098dc441913f30905f6ffd6f73262924858dd0Nathan Harold     * @param transform an {@link IpSecTransform}, which must be an active Transport Mode transform.
29409098dc441913f30905f6ffd6f73262924858dd0Nathan Harold     */
29509098dc441913f30905f6ffd6f73262924858dd0Nathan Harold    public void applyTransportModeTransform(FileDescriptor socket, IpSecTransform transform)
29609098dc441913f30905f6ffd6f73262924858dd0Nathan Harold            throws IOException {
29709098dc441913f30905f6ffd6f73262924858dd0Nathan Harold        applyTransportModeTransform(new ParcelFileDescriptor(socket), transform);
29809098dc441913f30905f6ffd6f73262924858dd0Nathan Harold    }
29909098dc441913f30905f6ffd6f73262924858dd0Nathan Harold
30009098dc441913f30905f6ffd6f73262924858dd0Nathan Harold    /**
301330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Apply an active Tunnel Mode IPsec Transform to a network, which will tunnel all traffic to
302330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * and from that network's interface with IPsec (applies an outer IP header and IPsec Header to
303330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * all traffic, and expects an additional IP header and IPsec Header on all inbound traffic).
304330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Applications should probably not use this API directly. Instead, they should use {@link
305330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * VpnService} to provide VPN capability in a more generic fashion.
306330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
307330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param net a {@link Network} that will be tunneled via IP Sec.
308330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param transform an {@link IpSecTransform}, which must be an active Tunnel Mode transform.
309330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @hide
310330e1089da80cddcd68758512370d217b19f8890Nathan Harold     */
311330e1089da80cddcd68758512370d217b19f8890Nathan Harold    public void applyTunnelModeTransform(Network net, IpSecTransform transform) {}
312330e1089da80cddcd68758512370d217b19f8890Nathan Harold
313330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /**
314330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Remove a transform from a given stream socket. Once removed, traffic on the socket will not
315330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * be encypted. This allows sockets that have been used for IPsec to be reclaimed for
316330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * communication in the clear in the event socket reuse is desired. This operation will succeed
317330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * regardless of the underlying state of a transform. If a transform is removed, communication
318330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * on all sockets to which that transform was applied will fail until this method is called.
319330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
320330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param socket a socket that previously had a transform applied to it.
321330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param transform the IPsec Transform that was previously applied to the given socket
32210f051ca91f352acea3ccd329da87db67012bd19Nathan Harold     * @hide
323330e1089da80cddcd68758512370d217b19f8890Nathan Harold     */
32405c7b5ad7cdba444db3d7813bf69da8f5d7f9058Nathan Harold    public void removeTransportModeTransform(Socket socket, IpSecTransform transform)
32505c7b5ad7cdba444db3d7813bf69da8f5d7f9058Nathan Harold            throws IOException {
326330e1089da80cddcd68758512370d217b19f8890Nathan Harold        removeTransportModeTransform(ParcelFileDescriptor.fromSocket(socket), transform);
327330e1089da80cddcd68758512370d217b19f8890Nathan Harold    }
328330e1089da80cddcd68758512370d217b19f8890Nathan Harold
329330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /**
330330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Remove a transform from a given datagram socket. Once removed, traffic on the socket will not
331330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * be encypted. This allows sockets that have been used for IPsec to be reclaimed for
332330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * communication in the clear in the event socket reuse is desired. This operation will succeed
333330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * regardless of the underlying state of a transform. If a transform is removed, communication
334330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * on all sockets to which that transform was applied will fail until this method is called.
335330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
336330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param socket a socket that previously had a transform applied to it.
337330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param transform the IPsec Transform that was previously applied to the given socket
33810f051ca91f352acea3ccd329da87db67012bd19Nathan Harold     * @hide
339330e1089da80cddcd68758512370d217b19f8890Nathan Harold     */
34005c7b5ad7cdba444db3d7813bf69da8f5d7f9058Nathan Harold    public void removeTransportModeTransform(DatagramSocket socket, IpSecTransform transform)
34105c7b5ad7cdba444db3d7813bf69da8f5d7f9058Nathan Harold            throws IOException {
342330e1089da80cddcd68758512370d217b19f8890Nathan Harold        removeTransportModeTransform(ParcelFileDescriptor.fromDatagramSocket(socket), transform);
343330e1089da80cddcd68758512370d217b19f8890Nathan Harold    }
344330e1089da80cddcd68758512370d217b19f8890Nathan Harold
34509098dc441913f30905f6ffd6f73262924858dd0Nathan Harold    /**
34609098dc441913f30905f6ffd6f73262924858dd0Nathan Harold     * Remove a transform from a given stream socket. Once removed, traffic on the socket will not
34709098dc441913f30905f6ffd6f73262924858dd0Nathan Harold     * be encypted. This allows sockets that have been used for IPsec to be reclaimed for
34809098dc441913f30905f6ffd6f73262924858dd0Nathan Harold     * communication in the clear in the event socket reuse is desired. This operation will succeed
34909098dc441913f30905f6ffd6f73262924858dd0Nathan Harold     * regardless of the underlying state of a transform. If a transform is removed, communication
35009098dc441913f30905f6ffd6f73262924858dd0Nathan Harold     * on all sockets to which that transform was applied will fail until this method is called.
35109098dc441913f30905f6ffd6f73262924858dd0Nathan Harold     *
35209098dc441913f30905f6ffd6f73262924858dd0Nathan Harold     * @param socket a socket file descriptor that previously had a transform applied to it.
35309098dc441913f30905f6ffd6f73262924858dd0Nathan Harold     * @param transform the IPsec Transform that was previously applied to the given socket
35409098dc441913f30905f6ffd6f73262924858dd0Nathan Harold     */
35505c7b5ad7cdba444db3d7813bf69da8f5d7f9058Nathan Harold    public void removeTransportModeTransform(FileDescriptor socket, IpSecTransform transform)
35605c7b5ad7cdba444db3d7813bf69da8f5d7f9058Nathan Harold            throws IOException {
35709098dc441913f30905f6ffd6f73262924858dd0Nathan Harold        removeTransportModeTransform(new ParcelFileDescriptor(socket), transform);
35809098dc441913f30905f6ffd6f73262924858dd0Nathan Harold    }
35909098dc441913f30905f6ffd6f73262924858dd0Nathan Harold
360330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /* Call down to activate a transform */
361f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold    private void removeTransportModeTransform(ParcelFileDescriptor pfd, IpSecTransform transform) {
362f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold        try {
363f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold            mService.removeTransportModeTransform(pfd, transform.getResourceId());
364f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold        } catch (RemoteException e) {
365f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold            throw e.rethrowFromSystemServer();
366f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold        }
367f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold    }
368330e1089da80cddcd68758512370d217b19f8890Nathan Harold
369330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /**
370330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Remove a Tunnel Mode IPsec Transform from a {@link Network}. This must be used as part of
371330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * cleanup if a tunneled Network experiences a change in default route. The Network will drop
372330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * all traffic that cannot be routed to the Tunnel's outbound interface. If that interface is
373330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * lost, all traffic will drop.
374330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
375330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param net a network that currently has transform applied to it.
376330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param transform a Tunnel Mode IPsec Transform that has been previously applied to the given
377330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *     network
378330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @hide
379330e1089da80cddcd68758512370d217b19f8890Nathan Harold     */
380330e1089da80cddcd68758512370d217b19f8890Nathan Harold    public void removeTunnelModeTransform(Network net, IpSecTransform transform) {}
381330e1089da80cddcd68758512370d217b19f8890Nathan Harold
382330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /**
383330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Class providing access to a system-provided UDP Encapsulation Socket, which may be used for
384330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * IKE signalling as well as for inbound and outbound UDP encapsulated IPsec traffic.
385330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
386330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * <p>The socket provided by this class cannot be re-bound or closed via the inner
387330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * FileDescriptor. Instead, disposing of this socket requires a call to close().
388330e1089da80cddcd68758512370d217b19f8890Nathan Harold     */
389330e1089da80cddcd68758512370d217b19f8890Nathan Harold    public static final class UdpEncapsulationSocket implements AutoCloseable {
390330e1089da80cddcd68758512370d217b19f8890Nathan Harold        private final FileDescriptor mFd;
391cbb58ecc866f90b2fe829b808a65652376006c24Nathan Harold        private final IIpSecService mService;
392330e1089da80cddcd68758512370d217b19f8890Nathan Harold        private final CloseGuard mCloseGuard = CloseGuard.get();
393330e1089da80cddcd68758512370d217b19f8890Nathan Harold
394f1dad26972dceac86edfc42bc87753b7ad8ad54fNathan Harold        private UdpEncapsulationSocket(@NonNull IIpSecService service, int port)
395330e1089da80cddcd68758512370d217b19f8890Nathan Harold                throws ResourceUnavailableException {
396cbb58ecc866f90b2fe829b808a65652376006c24Nathan Harold            mService = service;
397330e1089da80cddcd68758512370d217b19f8890Nathan Harold            mCloseGuard.open("constructor");
398330e1089da80cddcd68758512370d217b19f8890Nathan Harold            // TODO: go down to the kernel and get a socket on the specified
399330e1089da80cddcd68758512370d217b19f8890Nathan Harold            mFd = new FileDescriptor();
400330e1089da80cddcd68758512370d217b19f8890Nathan Harold        }
401330e1089da80cddcd68758512370d217b19f8890Nathan Harold
402cbb58ecc866f90b2fe829b808a65652376006c24Nathan Harold        private UdpEncapsulationSocket(IIpSecService service) throws ResourceUnavailableException {
403cbb58ecc866f90b2fe829b808a65652376006c24Nathan Harold            mService = service;
404330e1089da80cddcd68758512370d217b19f8890Nathan Harold            mCloseGuard.open("constructor");
405330e1089da80cddcd68758512370d217b19f8890Nathan Harold            // TODO: go get a random socket on a random port
406330e1089da80cddcd68758512370d217b19f8890Nathan Harold            mFd = new FileDescriptor();
407330e1089da80cddcd68758512370d217b19f8890Nathan Harold        }
408330e1089da80cddcd68758512370d217b19f8890Nathan Harold
409330e1089da80cddcd68758512370d217b19f8890Nathan Harold        /** Access the inner UDP Encapsulation Socket */
410330e1089da80cddcd68758512370d217b19f8890Nathan Harold        public FileDescriptor getSocket() {
411330e1089da80cddcd68758512370d217b19f8890Nathan Harold            return mFd;
412330e1089da80cddcd68758512370d217b19f8890Nathan Harold        }
413330e1089da80cddcd68758512370d217b19f8890Nathan Harold
414330e1089da80cddcd68758512370d217b19f8890Nathan Harold        /** Retrieve the port number of the inner encapsulation socket */
415330e1089da80cddcd68758512370d217b19f8890Nathan Harold        public int getPort() {
416330e1089da80cddcd68758512370d217b19f8890Nathan Harold            return 0; // TODO get the port number from the Socket;
417330e1089da80cddcd68758512370d217b19f8890Nathan Harold        }
418330e1089da80cddcd68758512370d217b19f8890Nathan Harold
419330e1089da80cddcd68758512370d217b19f8890Nathan Harold        @Override
420330e1089da80cddcd68758512370d217b19f8890Nathan Harold        /**
421330e1089da80cddcd68758512370d217b19f8890Nathan Harold         * Release the resources that have been reserved for this Socket.
422330e1089da80cddcd68758512370d217b19f8890Nathan Harold         *
423330e1089da80cddcd68758512370d217b19f8890Nathan Harold         * <p>This method closes the underlying socket, reducing a user's allocated sockets in the
424330e1089da80cddcd68758512370d217b19f8890Nathan Harold         * system. This must be done as part of cleanup following use of a socket. Failure to do so
425330e1089da80cddcd68758512370d217b19f8890Nathan Harold         * will cause the socket to count against a total allocation limit for IpSec and eventually
426330e1089da80cddcd68758512370d217b19f8890Nathan Harold         * fail due to resource limits.
427330e1089da80cddcd68758512370d217b19f8890Nathan Harold         *
428330e1089da80cddcd68758512370d217b19f8890Nathan Harold         * @param fd a file descriptor previously returned as a UDP Encapsulation socket.
429330e1089da80cddcd68758512370d217b19f8890Nathan Harold         */
43005c7b5ad7cdba444db3d7813bf69da8f5d7f9058Nathan Harold        public void close() throws IOException {
431330e1089da80cddcd68758512370d217b19f8890Nathan Harold            // TODO: Go close the socket
432330e1089da80cddcd68758512370d217b19f8890Nathan Harold            mCloseGuard.close();
433330e1089da80cddcd68758512370d217b19f8890Nathan Harold        }
434330e1089da80cddcd68758512370d217b19f8890Nathan Harold
435330e1089da80cddcd68758512370d217b19f8890Nathan Harold        @Override
436330e1089da80cddcd68758512370d217b19f8890Nathan Harold        protected void finalize() throws Throwable {
437330e1089da80cddcd68758512370d217b19f8890Nathan Harold            if (mCloseGuard != null) {
438330e1089da80cddcd68758512370d217b19f8890Nathan Harold                mCloseGuard.warnIfOpen();
439330e1089da80cddcd68758512370d217b19f8890Nathan Harold            }
440330e1089da80cddcd68758512370d217b19f8890Nathan Harold
441330e1089da80cddcd68758512370d217b19f8890Nathan Harold            close();
442330e1089da80cddcd68758512370d217b19f8890Nathan Harold        }
443330e1089da80cddcd68758512370d217b19f8890Nathan Harold    };
444330e1089da80cddcd68758512370d217b19f8890Nathan Harold
445330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /**
446330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Open a socket that is bound to a free UDP port on the system.
447330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
448330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * <p>By binding in this manner and holding the FileDescriptor, the socket cannot be un-bound by
449330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * the caller. This provides safe access to a socket on a port that can later be used as a UDP
450330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Encapsulation port.
451330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
452330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * <p>This socket reservation works in conjunction with IpSecTransforms, which may re-use the
453330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * socket port. Explicitly opening this port is only necessary if communication is desired on
454330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * that port.
455330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
456330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param port a local UDP port to be reserved for UDP Encapsulation. is provided, then this
457330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *     method will bind to the specified port or fail. To retrieve the port number, call {@link
458330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *     android.system.Os#getsockname(FileDescriptor)}.
459330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @return a {@link UdpEncapsulationSocket} that is bound to the requested port for the lifetime
460330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *     of the object.
461330e1089da80cddcd68758512370d217b19f8890Nathan Harold     */
462330e1089da80cddcd68758512370d217b19f8890Nathan Harold    // Returning a socket in this fashion that has been created and bound by the system
463330e1089da80cddcd68758512370d217b19f8890Nathan Harold    // is the only safe way to ensure that a socket is both accessible to the user and
464330e1089da80cddcd68758512370d217b19f8890Nathan Harold    // safely usable for Encapsulation without allowing a user to possibly unbind from/close
465330e1089da80cddcd68758512370d217b19f8890Nathan Harold    // the port, which could potentially impact the traffic of the next user who binds to that
466330e1089da80cddcd68758512370d217b19f8890Nathan Harold    // socket.
467330e1089da80cddcd68758512370d217b19f8890Nathan Harold    public UdpEncapsulationSocket openUdpEncapsulationSocket(int port)
468330e1089da80cddcd68758512370d217b19f8890Nathan Harold            throws IOException, ResourceUnavailableException {
469330e1089da80cddcd68758512370d217b19f8890Nathan Harold        // Temporary code
470cbb58ecc866f90b2fe829b808a65652376006c24Nathan Harold        return new UdpEncapsulationSocket(mService, port);
471330e1089da80cddcd68758512370d217b19f8890Nathan Harold    }
472330e1089da80cddcd68758512370d217b19f8890Nathan Harold
473330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /**
474330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Open a socket that is bound to a port selected by the system.
475330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
476330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * <p>By binding in this manner and holding the FileDescriptor, the socket cannot be un-bound by
477330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * the caller. This provides safe access to a socket on a port that can later be used as a UDP
478330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Encapsulation port.
479330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
480330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * <p>This socket reservation works in conjunction with IpSecTransforms, which may re-use the
481330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * socket port. Explicitly opening this port is only necessary if communication is desired on
482330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * that port.
483330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
484330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @return a {@link UdpEncapsulationSocket} that is bound to an arbitrarily selected port
485330e1089da80cddcd68758512370d217b19f8890Nathan Harold     */
486330e1089da80cddcd68758512370d217b19f8890Nathan Harold    // Returning a socket in this fashion that has been created and bound by the system
487330e1089da80cddcd68758512370d217b19f8890Nathan Harold    // is the only safe way to ensure that a socket is both accessible to the user and
488330e1089da80cddcd68758512370d217b19f8890Nathan Harold    // safely usable for Encapsulation without allowing a user to possibly unbind from/close
489330e1089da80cddcd68758512370d217b19f8890Nathan Harold    // the port, which could potentially impact the traffic of the next user who binds to that
490330e1089da80cddcd68758512370d217b19f8890Nathan Harold    // socket.
491330e1089da80cddcd68758512370d217b19f8890Nathan Harold    public UdpEncapsulationSocket openUdpEncapsulationSocket()
492330e1089da80cddcd68758512370d217b19f8890Nathan Harold            throws IOException, ResourceUnavailableException {
493330e1089da80cddcd68758512370d217b19f8890Nathan Harold        // Temporary code
494cbb58ecc866f90b2fe829b808a65652376006c24Nathan Harold        return new UdpEncapsulationSocket(mService);
495330e1089da80cddcd68758512370d217b19f8890Nathan Harold    }
496330e1089da80cddcd68758512370d217b19f8890Nathan Harold
497330e1089da80cddcd68758512370d217b19f8890Nathan Harold    /**
498330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * Retrieve an instance of an IpSecManager within you application context
499330e1089da80cddcd68758512370d217b19f8890Nathan Harold     *
500330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @param context the application context for this manager
501330e1089da80cddcd68758512370d217b19f8890Nathan Harold     * @hide
502330e1089da80cddcd68758512370d217b19f8890Nathan Harold     */
503cbb58ecc866f90b2fe829b808a65652376006c24Nathan Harold    public IpSecManager(IIpSecService service) {
504330e1089da80cddcd68758512370d217b19f8890Nathan Harold        mService = checkNotNull(service, "missing service");
505330e1089da80cddcd68758512370d217b19f8890Nathan Harold    }
506330e1089da80cddcd68758512370d217b19f8890Nathan Harold}
507