VpnService.java revision 9a1da68bf7980449a5ee5d6fa9d9686b04d667ff
1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.net;
18
19import static android.system.OsConstants.AF_INET;
20import static android.system.OsConstants.AF_INET6;
21
22import android.annotation.SystemApi;
23import android.app.Activity;
24import android.app.PendingIntent;
25import android.app.Service;
26import android.content.Context;
27import android.content.Intent;
28import android.content.pm.IPackageManager;
29import android.content.pm.PackageManager;
30import android.net.NetworkUtils;
31import android.os.Binder;
32import android.os.IBinder;
33import android.os.Parcel;
34import android.os.ParcelFileDescriptor;
35import android.os.RemoteException;
36import android.os.ServiceManager;
37import android.os.UserHandle;
38
39import com.android.internal.net.VpnConfig;
40
41import java.net.DatagramSocket;
42import java.net.Inet4Address;
43import java.net.Inet6Address;
44import java.net.InetAddress;
45import java.net.Socket;
46import java.util.ArrayList;
47import java.util.List;
48
49/**
50 * VpnService is a base class for applications to extend and build their
51 * own VPN solutions. In general, it creates a virtual network interface,
52 * configures addresses and routing rules, and returns a file descriptor
53 * to the application. Each read from the descriptor retrieves an outgoing
54 * packet which was routed to the interface. Each write to the descriptor
55 * injects an incoming packet just like it was received from the interface.
56 * The interface is running on Internet Protocol (IP), so packets are
57 * always started with IP headers. The application then completes a VPN
58 * connection by processing and exchanging packets with the remote server
59 * over a tunnel.
60 *
61 * <p>Letting applications intercept packets raises huge security concerns.
62 * A VPN application can easily break the network. Besides, two of them may
63 * conflict with each other. The system takes several actions to address
64 * these issues. Here are some key points:
65 * <ul>
66 *   <li>User action is required the first time an application creates a VPN
67 *       connection.</li>
68 *   <li>There can be only one VPN connection running at the same time. The
69 *       existing interface is deactivated when a new one is created.</li>
70 *   <li>A system-managed notification is shown during the lifetime of a
71 *       VPN connection.</li>
72 *   <li>A system-managed dialog gives the information of the current VPN
73 *       connection. It also provides a button to disconnect.</li>
74 *   <li>The network is restored automatically when the file descriptor is
75 *       closed. It also covers the cases when a VPN application is crashed
76 *       or killed by the system.</li>
77 * </ul>
78 *
79 * <p>There are two primary methods in this class: {@link #prepare} and
80 * {@link Builder#establish}. The former deals with user action and stops
81 * the VPN connection created by another application. The latter creates
82 * a VPN interface using the parameters supplied to the {@link Builder}.
83 * An application must call {@link #prepare} to grant the right to use
84 * other methods in this class, and the right can be revoked at any time.
85 * Here are the general steps to create a VPN connection:
86 * <ol>
87 *   <li>When the user presses the button to connect, call {@link #prepare}
88 *       and launch the returned intent, if non-null.</li>
89 *   <li>When the application becomes prepared, start the service.</li>
90 *   <li>Create a tunnel to the remote server and negotiate the network
91 *       parameters for the VPN connection.</li>
92 *   <li>Supply those parameters to a {@link Builder} and create a VPN
93 *       interface by calling {@link Builder#establish}.</li>
94 *   <li>Process and exchange packets between the tunnel and the returned
95 *       file descriptor.</li>
96 *   <li>When {@link #onRevoke} is invoked, close the file descriptor and
97 *       shut down the tunnel gracefully.</li>
98 * </ol>
99 *
100 * <p>Services extended this class need to be declared with appropriate
101 * permission and intent filter. Their access must be secured by
102 * {@link android.Manifest.permission#BIND_VPN_SERVICE} permission, and
103 * their intent filter must match {@link #SERVICE_INTERFACE} action. Here
104 * is an example of declaring a VPN service in {@code AndroidManifest.xml}:
105 * <pre>
106 * &lt;service android:name=".ExampleVpnService"
107 *         android:permission="android.permission.BIND_VPN_SERVICE"&gt;
108 *     &lt;intent-filter&gt;
109 *         &lt;action android:name="android.net.VpnService"/&gt;
110 *     &lt;/intent-filter&gt;
111 * &lt;/service&gt;</pre>
112 *
113 * @see Builder
114 */
115public class VpnService extends Service {
116
117    /**
118     * The action must be matched by the intent filter of this service. It also
119     * needs to require {@link android.Manifest.permission#BIND_VPN_SERVICE}
120     * permission so that other applications cannot abuse it.
121     */
122    public static final String SERVICE_INTERFACE = VpnConfig.SERVICE_INTERFACE;
123
124    /**
125     * Use IConnectivityManager since those methods are hidden and not
126     * available in ConnectivityManager.
127     */
128    private static IConnectivityManager getService() {
129        return IConnectivityManager.Stub.asInterface(
130                ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
131    }
132
133    /**
134     * Prepare to establish a VPN connection. This method returns {@code null}
135     * if the VPN application is already prepared or if the user has previously
136     * consented to the VPN application. Otherwise, it returns an
137     * {@link Intent} to a system activity. The application should launch the
138     * activity using {@link Activity#startActivityForResult} to get itself
139     * prepared. The activity may pop up a dialog to require user action, and
140     * the result will come back via its {@link Activity#onActivityResult}.
141     * If the result is {@link Activity#RESULT_OK}, the application becomes
142     * prepared and is granted to use other methods in this class.
143     *
144     * <p>Only one application can be granted at the same time. The right
145     * is revoked when another application is granted. The application
146     * losing the right will be notified via its {@link #onRevoke}. Unless
147     * it becomes prepared again, subsequent calls to other methods in this
148     * class will fail.
149     *
150     * <p>The user may disable the VPN at any time while it is activated, in
151     * which case this method will return an intent the next time it is
152     * executed to obtain the user's consent again.
153     *
154     * @see #onRevoke
155     */
156    public static Intent prepare(Context context) {
157        try {
158            if (getService().prepareVpn(context.getPackageName(), null)) {
159                return null;
160            }
161        } catch (RemoteException e) {
162            // ignore
163        }
164        return VpnConfig.getIntentForConfirmation();
165    }
166
167    /**
168     * Version of {@link #prepare(Context)} which does not require user consent.
169     *
170     * <p>Requires {@link android.Manifest.permission#CONTROL_VPN} and should generally not be
171     * used. Only acceptable in situations where user consent has been obtained through other means.
172     *
173     * <p>Once this is run, future preparations may be done with the standard prepare method as this
174     * will authorize the package to prepare the VPN without consent in the future.
175     *
176     * @hide
177     */
178    @SystemApi
179    public static void prepareAndAuthorize(Context context) {
180        IConnectivityManager cm = getService();
181        String packageName = context.getPackageName();
182        try {
183            // Only prepare if we're not already prepared.
184            if (!cm.prepareVpn(packageName, null)) {
185                cm.prepareVpn(null, packageName);
186            }
187            cm.setVpnPackageAuthorization(true);
188        } catch (RemoteException e) {
189            // ignore
190        }
191    }
192
193    /**
194     * Protect a socket from VPN connections. After protecting, data sent
195     * through this socket will go directly to the underlying network,
196     * so its traffic will not be forwarded through the VPN.
197     * This method is useful if some connections need to be kept
198     * outside of VPN. For example, a VPN tunnel should protect itself if its
199     * destination is covered by VPN routes. Otherwise its outgoing packets
200     * will be sent back to the VPN interface and cause an infinite loop. This
201     * method will fail if the application is not prepared or is revoked.
202     *
203     * <p class="note">The socket is NOT closed by this method.
204     *
205     * @return {@code true} on success.
206     */
207    public boolean protect(int socket) {
208        return NetworkUtils.protectFromVpn(socket);
209    }
210
211    /**
212     * Convenience method to protect a {@link Socket} from VPN connections.
213     *
214     * @return {@code true} on success.
215     * @see #protect(int)
216     */
217    public boolean protect(Socket socket) {
218        return protect(socket.getFileDescriptor$().getInt$());
219    }
220
221    /**
222     * Convenience method to protect a {@link DatagramSocket} from VPN
223     * connections.
224     *
225     * @return {@code true} on success.
226     * @see #protect(int)
227     */
228    public boolean protect(DatagramSocket socket) {
229        return protect(socket.getFileDescriptor$().getInt$());
230    }
231
232    /**
233     * Adds a network address to the VPN interface.
234     *
235     * Both IPv4 and IPv6 addresses are supported. The VPN must already be established. Fails if the
236     * address is already in use or cannot be assigned to the interface for any other reason.
237     *
238     * Adding an address implicitly allows traffic from that address family (i.e., IPv4 or IPv6) to
239     * be routed over the VPN. @see Builder#allowFamily
240     *
241     * @throws {@link IllegalArgumentException} if the address is invalid.
242     *
243     * @param address The IP address (IPv4 or IPv6) to assign to the VPN interface.
244     * @param prefixLength The prefix length of the address.
245     *
246     * @return {@code true} on success.
247     * @see Builder#addAddress
248     *
249     * @hide
250     */
251    public boolean addAddress(InetAddress address, int prefixLength) {
252        check(address, prefixLength);
253        try {
254            return getService().addVpnAddress(address.getHostAddress(), prefixLength);
255        } catch (RemoteException e) {
256            throw new IllegalStateException(e);
257        }
258    }
259
260    /**
261     * Removes a network address from the VPN interface.
262     *
263     * Both IPv4 and IPv6 addresses are supported. The VPN must already be established. Fails if the
264     * address is not assigned to the VPN interface, or if it is the only address assigned (thus
265     * cannot be removed), or if the address cannot be removed for any other reason.
266     *
267     * After removing an address, if there are no addresses, routes or DNS servers of a particular
268     * address family (i.e., IPv4 or IPv6) configured on the VPN, that <b>DOES NOT</b> block that
269     * family from being routed. In other words, once an address family has been allowed, it stays
270     * allowed for the rest of the VPN's session. @see Builder#allowFamily
271     *
272     * @throws {@link IllegalArgumentException} if the address is invalid.
273     *
274     * @param address The IP address (IPv4 or IPv6) to assign to the VPN interface.
275     * @param prefixLength The prefix length of the address.
276     *
277     * @return {@code true} on success.
278     *
279     * @hide
280     */
281    public boolean removeAddress(InetAddress address, int prefixLength) {
282        check(address, prefixLength);
283        try {
284            return getService().removeVpnAddress(address.getHostAddress(), prefixLength);
285        } catch (RemoteException e) {
286            throw new IllegalStateException(e);
287        }
288    }
289
290    /**
291     * Return the communication interface to the service. This method returns
292     * {@code null} on {@link Intent}s other than {@link #SERVICE_INTERFACE}
293     * action. Applications overriding this method must identify the intent
294     * and return the corresponding interface accordingly.
295     *
296     * @see Service#onBind
297     */
298    @Override
299    public IBinder onBind(Intent intent) {
300        if (intent != null && SERVICE_INTERFACE.equals(intent.getAction())) {
301            return new Callback();
302        }
303        return null;
304    }
305
306    /**
307     * Invoked when the application is revoked. At this moment, the VPN
308     * interface is already deactivated by the system. The application should
309     * close the file descriptor and shut down gracefully. The default
310     * implementation of this method is calling {@link Service#stopSelf()}.
311     *
312     * <p class="note">Calls to this method may not happen on the main thread
313     * of the process.
314     *
315     * @see #prepare
316     */
317    public void onRevoke() {
318        stopSelf();
319    }
320
321    /**
322     * Use raw Binder instead of AIDL since now there is only one usage.
323     */
324    private class Callback extends Binder {
325        @Override
326        protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) {
327            if (code == IBinder.LAST_CALL_TRANSACTION) {
328                onRevoke();
329                return true;
330            }
331            return false;
332        }
333    }
334
335    /**
336     * Private method to validate address and prefixLength.
337     */
338    private static void check(InetAddress address, int prefixLength) {
339        if (address.isLoopbackAddress()) {
340            throw new IllegalArgumentException("Bad address");
341        }
342        if (address instanceof Inet4Address) {
343            if (prefixLength < 0 || prefixLength > 32) {
344                throw new IllegalArgumentException("Bad prefixLength");
345            }
346        } else if (address instanceof Inet6Address) {
347            if (prefixLength < 0 || prefixLength > 128) {
348                throw new IllegalArgumentException("Bad prefixLength");
349            }
350        } else {
351            throw new IllegalArgumentException("Unsupported family");
352        }
353    }
354
355    /**
356     * Helper class to create a VPN interface. This class should be always
357     * used within the scope of the outer {@link VpnService}.
358     *
359     * @see VpnService
360     */
361    public class Builder {
362
363        private final VpnConfig mConfig = new VpnConfig();
364        private final List<LinkAddress> mAddresses = new ArrayList<LinkAddress>();
365        private final List<RouteInfo> mRoutes = new ArrayList<RouteInfo>();
366
367        public Builder() {
368            mConfig.user = VpnService.this.getClass().getName();
369        }
370
371        /**
372         * Set the name of this session. It will be displayed in
373         * system-managed dialogs and notifications. This is recommended
374         * not required.
375         */
376        public Builder setSession(String session) {
377            mConfig.session = session;
378            return this;
379        }
380
381        /**
382         * Set the {@link PendingIntent} to an activity for users to
383         * configure the VPN connection. If it is not set, the button
384         * to configure will not be shown in system-managed dialogs.
385         */
386        public Builder setConfigureIntent(PendingIntent intent) {
387            mConfig.configureIntent = intent;
388            return this;
389        }
390
391        /**
392         * Set the maximum transmission unit (MTU) of the VPN interface. If
393         * it is not set, the default value in the operating system will be
394         * used.
395         *
396         * @throws IllegalArgumentException if the value is not positive.
397         */
398        public Builder setMtu(int mtu) {
399            if (mtu <= 0) {
400                throw new IllegalArgumentException("Bad mtu");
401            }
402            mConfig.mtu = mtu;
403            return this;
404        }
405
406        /**
407         * Add a network address to the VPN interface. Both IPv4 and IPv6
408         * addresses are supported. At least one address must be set before
409         * calling {@link #establish}.
410         *
411         * Adding an address implicitly allows traffic from that address family
412         * (i.e., IPv4 or IPv6) to be routed over the VPN. @see #allowFamily
413         *
414         * @throws IllegalArgumentException if the address is invalid.
415         */
416        public Builder addAddress(InetAddress address, int prefixLength) {
417            check(address, prefixLength);
418
419            if (address.isAnyLocalAddress()) {
420                throw new IllegalArgumentException("Bad address");
421            }
422            mAddresses.add(new LinkAddress(address, prefixLength));
423            mConfig.updateAllowedFamilies(address);
424            return this;
425        }
426
427        /**
428         * Convenience method to add a network address to the VPN interface
429         * using a numeric address string. See {@link InetAddress} for the
430         * definitions of numeric address formats.
431         *
432         * Adding an address implicitly allows traffic from that address family
433         * (i.e., IPv4 or IPv6) to be routed over the VPN. @see #allowFamily
434         *
435         * @throws IllegalArgumentException if the address is invalid.
436         * @see #addAddress(InetAddress, int)
437         */
438        public Builder addAddress(String address, int prefixLength) {
439            return addAddress(InetAddress.parseNumericAddress(address), prefixLength);
440        }
441
442        /**
443         * Add a network route to the VPN interface. Both IPv4 and IPv6
444         * routes are supported.
445         *
446         * Adding a route implicitly allows traffic from that address family
447         * (i.e., IPv4 or IPv6) to be routed over the VPN. @see #allowFamily
448         *
449         * @throws IllegalArgumentException if the route is invalid.
450         */
451        public Builder addRoute(InetAddress address, int prefixLength) {
452            check(address, prefixLength);
453
454            int offset = prefixLength / 8;
455            byte[] bytes = address.getAddress();
456            if (offset < bytes.length) {
457                for (bytes[offset] <<= prefixLength % 8; offset < bytes.length; ++offset) {
458                    if (bytes[offset] != 0) {
459                        throw new IllegalArgumentException("Bad address");
460                    }
461                }
462            }
463            mRoutes.add(new RouteInfo(new LinkAddress(address, prefixLength), null));
464            mConfig.updateAllowedFamilies(address);
465            return this;
466        }
467
468        /**
469         * Convenience method to add a network route to the VPN interface
470         * using a numeric address string. See {@link InetAddress} for the
471         * definitions of numeric address formats.
472         *
473         * Adding a route implicitly allows traffic from that address family
474         * (i.e., IPv4 or IPv6) to be routed over the VPN. @see #allowFamily
475         *
476         * @throws IllegalArgumentException if the route is invalid.
477         * @see #addRoute(InetAddress, int)
478         */
479        public Builder addRoute(String address, int prefixLength) {
480            return addRoute(InetAddress.parseNumericAddress(address), prefixLength);
481        }
482
483        /**
484         * Add a DNS server to the VPN connection. Both IPv4 and IPv6
485         * addresses are supported. If none is set, the DNS servers of
486         * the default network will be used.
487         *
488         * Adding a server implicitly allows traffic from that address family
489         * (i.e., IPv4 or IPv6) to be routed over the VPN. @see #allowFamily
490         *
491         * @throws IllegalArgumentException if the address is invalid.
492         */
493        public Builder addDnsServer(InetAddress address) {
494            if (address.isLoopbackAddress() || address.isAnyLocalAddress()) {
495                throw new IllegalArgumentException("Bad address");
496            }
497            if (mConfig.dnsServers == null) {
498                mConfig.dnsServers = new ArrayList<String>();
499            }
500            mConfig.dnsServers.add(address.getHostAddress());
501            return this;
502        }
503
504        /**
505         * Convenience method to add a DNS server to the VPN connection
506         * using a numeric address string. See {@link InetAddress} for the
507         * definitions of numeric address formats.
508         *
509         * Adding a server implicitly allows traffic from that address family
510         * (i.e., IPv4 or IPv6) to be routed over the VPN. @see #allowFamily
511         *
512         * @throws IllegalArgumentException if the address is invalid.
513         * @see #addDnsServer(InetAddress)
514         */
515        public Builder addDnsServer(String address) {
516            return addDnsServer(InetAddress.parseNumericAddress(address));
517        }
518
519        /**
520         * Add a search domain to the DNS resolver.
521         */
522        public Builder addSearchDomain(String domain) {
523            if (mConfig.searchDomains == null) {
524                mConfig.searchDomains = new ArrayList<String>();
525            }
526            mConfig.searchDomains.add(domain);
527            return this;
528        }
529
530        /**
531         * Allows traffic from the specified address family.
532         *
533         * By default, if no address, route or DNS server of a specific family (IPv4 or IPv6) is
534         * added to this VPN, then all outgoing traffic of that family is blocked. If any address,
535         * route or DNS server is added, that family is allowed.
536         *
537         * This method allows an address family to be unblocked even without adding an address,
538         * route or DNS server of that family. Traffic of that family will then typically
539         * fall-through to the underlying network if it's supported.
540         *
541         * {@code family} must be either {@code AF_INET} (for IPv4) or {@code AF_INET6} (for IPv6).
542         * {@link IllegalArgumentException} is thrown if it's neither.
543         *
544         * @param family The address family ({@code AF_INET} or {@code AF_INET6}) to allow.
545         *
546         * @return this {@link Builder} object to facilitate chaining of method calls.
547         */
548        public Builder allowFamily(int family) {
549            if (family == AF_INET) {
550                mConfig.allowIPv4 = true;
551            } else if (family == AF_INET6) {
552                mConfig.allowIPv6 = true;
553            } else {
554                throw new IllegalArgumentException(family + " is neither " + AF_INET + " nor " +
555                        AF_INET6);
556            }
557            return this;
558        }
559
560        private void verifyApp(String packageName) throws PackageManager.NameNotFoundException {
561            IPackageManager pm = IPackageManager.Stub.asInterface(
562                    ServiceManager.getService("package"));
563            try {
564                pm.getApplicationInfo(packageName, 0, UserHandle.getCallingUserId());
565            } catch (RemoteException e) {
566                throw new IllegalStateException(e);
567            }
568        }
569
570        /**
571         * Adds an application that's allowed to access the VPN connection.
572         *
573         * If this method is called at least once, only applications added through this method (and
574         * no others) are allowed access. Else (if this method is never called), all applications
575         * are allowed by default.  If some applications are added, other, un-added applications
576         * will use networking as if the VPN wasn't running.
577         *
578         * A {@link Builder} may have only a set of allowed applications OR a set of disallowed
579         * ones, but not both. Calling this method after {@link #addDisallowedApplication} has
580         * already been called, or vice versa, will throw an {@link UnsupportedOperationException}.
581         *
582         * {@code packageName} must be the canonical name of a currently installed application.
583         * {@link PackageManager.NameNotFoundException} is thrown if there's no such application.
584         *
585         * @throws {@link PackageManager.NameNotFoundException} If the application isn't installed.
586         *
587         * @param packageName The full name (e.g.: "com.google.apps.contacts") of an application.
588         *
589         * @return this {@link Builder} object to facilitate chaining method calls.
590         */
591        public Builder addAllowedApplication(String packageName)
592                throws PackageManager.NameNotFoundException {
593            if (mConfig.disallowedApplications != null) {
594                throw new UnsupportedOperationException("addDisallowedApplication already called");
595            }
596            verifyApp(packageName);
597            if (mConfig.allowedApplications == null) {
598                mConfig.allowedApplications = new ArrayList<String>();
599            }
600            mConfig.allowedApplications.add(packageName);
601            return this;
602        }
603
604        /**
605         * Adds an application that's denied access to the VPN connection.
606         *
607         * By default, all applications are allowed access, except for those denied through this
608         * method.  Denied applications will use networking as if the VPN wasn't running.
609         *
610         * A {@link Builder} may have only a set of allowed applications OR a set of disallowed
611         * ones, but not both. Calling this method after {@link #addAllowedApplication} has already
612         * been called, or vice versa, will throw an {@link UnsupportedOperationException}.
613         *
614         * {@code packageName} must be the canonical name of a currently installed application.
615         * {@link PackageManager.NameNotFoundException} is thrown if there's no such application.
616         *
617         * @throws {@link PackageManager.NameNotFoundException} If the application isn't installed.
618         *
619         * @param packageName The full name (e.g.: "com.google.apps.contacts") of an application.
620         *
621         * @return this {@link Builder} object to facilitate chaining method calls.
622         */
623        public Builder addDisallowedApplication(String packageName)
624                throws PackageManager.NameNotFoundException {
625            if (mConfig.allowedApplications != null) {
626                throw new UnsupportedOperationException("addAllowedApplication already called");
627            }
628            verifyApp(packageName);
629            if (mConfig.disallowedApplications == null) {
630                mConfig.disallowedApplications = new ArrayList<String>();
631            }
632            mConfig.disallowedApplications.add(packageName);
633            return this;
634        }
635
636        /**
637         * Allows all apps to bypass this VPN connection.
638         *
639         * By default, all traffic from apps is forwarded through the VPN interface and it is not
640         * possible for apps to side-step the VPN. If this method is called, apps may use methods
641         * such as {@link ConnectivityManager#setProcessDefaultNetwork} to instead send/receive
642         * directly over the underlying network or any other network they have permissions for.
643         *
644         * @return this {@link Builder} object to facilitate chaining of method calls.
645         */
646        public Builder allowBypass() {
647            mConfig.allowBypass = true;
648            return this;
649        }
650
651        /**
652         * Sets the VPN interface's file descriptor to be in blocking/non-blocking mode.
653         *
654         * By default, the file descriptor returned by {@link #establish} is non-blocking.
655         *
656         * @param blocking True to put the descriptor into blocking mode; false for non-blocking.
657         *
658         * @return this {@link Builder} object to facilitate chaining method calls.
659         */
660        public Builder setBlocking(boolean blocking) {
661            mConfig.blocking = blocking;
662            return this;
663        }
664
665        /**
666         * Create a VPN interface using the parameters supplied to this
667         * builder. The interface works on IP packets, and a file descriptor
668         * is returned for the application to access them. Each read
669         * retrieves an outgoing packet which was routed to the interface.
670         * Each write injects an incoming packet just like it was received
671         * from the interface. The file descriptor is put into non-blocking
672         * mode by default to avoid blocking Java threads. To use the file
673         * descriptor completely in native space, see
674         * {@link ParcelFileDescriptor#detachFd()}. The application MUST
675         * close the file descriptor when the VPN connection is terminated.
676         * The VPN interface will be removed and the network will be
677         * restored by the system automatically.
678         *
679         * <p>To avoid conflicts, there can be only one active VPN interface
680         * at the same time. Usually network parameters are never changed
681         * during the lifetime of a VPN connection. It is also common for an
682         * application to create a new file descriptor after closing the
683         * previous one. However, it is rare but not impossible to have two
684         * interfaces while performing a seamless handover. In this case, the
685         * old interface will be deactivated when the new one is created
686         * successfully. Both file descriptors are valid but now outgoing
687         * packets will be routed to the new interface. Therefore, after
688         * draining the old file descriptor, the application MUST close it
689         * and start using the new file descriptor. If the new interface
690         * cannot be created, the existing interface and its file descriptor
691         * remain untouched.
692         *
693         * <p>An exception will be thrown if the interface cannot be created
694         * for any reason. However, this method returns {@code null} if the
695         * application is not prepared or is revoked. This helps solve
696         * possible race conditions between other VPN applications.
697         *
698         * @return {@link ParcelFileDescriptor} of the VPN interface, or
699         *         {@code null} if the application is not prepared.
700         * @throws IllegalArgumentException if a parameter is not accepted
701         *         by the operating system.
702         * @throws IllegalStateException if a parameter cannot be applied
703         *         by the operating system.
704         * @throws SecurityException if the service is not properly declared
705         *         in {@code AndroidManifest.xml}.
706         * @see VpnService
707         */
708        public ParcelFileDescriptor establish() {
709            mConfig.addresses = mAddresses;
710            mConfig.routes = mRoutes;
711
712            try {
713                return getService().establishVpn(mConfig);
714            } catch (RemoteException e) {
715                throw new IllegalStateException(e);
716            }
717        }
718    }
719}
720