blob: 8e90a119fe21aae01a95ddc7a29167909461bc0f [file] [log] [blame]
Remi NGUYEN VANfbbccbc2021-01-15 18:08:24 +09001/*
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.NonNull;
23import android.annotation.Nullable;
24import android.annotation.RequiresPermission;
25import android.annotation.SystemApi;
26import android.app.Activity;
27import android.app.PendingIntent;
28import android.app.Service;
29import android.app.admin.DevicePolicyManager;
30import android.compat.annotation.UnsupportedAppUsage;
31import android.content.ComponentName;
32import android.content.Context;
33import android.content.Intent;
34import android.content.pm.IPackageManager;
35import android.content.pm.PackageManager;
36import android.os.Binder;
37import android.os.IBinder;
38import android.os.Parcel;
39import android.os.ParcelFileDescriptor;
40import android.os.RemoteException;
41import android.os.ServiceManager;
42import android.os.UserHandle;
43
44import com.android.internal.net.VpnConfig;
45
46import java.net.DatagramSocket;
47import java.net.Inet4Address;
48import java.net.Inet6Address;
49import java.net.InetAddress;
50import java.net.Socket;
51import java.util.ArrayList;
52import java.util.List;
53import java.util.Set;
54
55/**
56 * VpnService is a base class for applications to extend and build their
57 * own VPN solutions. In general, it creates a virtual network interface,
58 * configures addresses and routing rules, and returns a file descriptor
59 * to the application. Each read from the descriptor retrieves an outgoing
60 * packet which was routed to the interface. Each write to the descriptor
61 * injects an incoming packet just like it was received from the interface.
62 * The interface is running on Internet Protocol (IP), so packets are
63 * always started with IP headers. The application then completes a VPN
64 * connection by processing and exchanging packets with the remote server
65 * over a tunnel.
66 *
67 * <p>Letting applications intercept packets raises huge security concerns.
68 * A VPN application can easily break the network. Besides, two of them may
69 * conflict with each other. The system takes several actions to address
70 * these issues. Here are some key points:
71 * <ul>
72 * <li>User action is required the first time an application creates a VPN
73 * connection.</li>
74 * <li>There can be only one VPN connection running at the same time. The
75 * existing interface is deactivated when a new one is created.</li>
76 * <li>A system-managed notification is shown during the lifetime of a
77 * VPN connection.</li>
78 * <li>A system-managed dialog gives the information of the current VPN
79 * connection. It also provides a button to disconnect.</li>
80 * <li>The network is restored automatically when the file descriptor is
81 * closed. It also covers the cases when a VPN application is crashed
82 * or killed by the system.</li>
83 * </ul>
84 *
85 * <p>There are two primary methods in this class: {@link #prepare} and
86 * {@link Builder#establish}. The former deals with user action and stops
87 * the VPN connection created by another application. The latter creates
88 * a VPN interface using the parameters supplied to the {@link Builder}.
89 * An application must call {@link #prepare} to grant the right to use
90 * other methods in this class, and the right can be revoked at any time.
91 * Here are the general steps to create a VPN connection:
92 * <ol>
93 * <li>When the user presses the button to connect, call {@link #prepare}
94 * and launch the returned intent, if non-null.</li>
95 * <li>When the application becomes prepared, start the service.</li>
96 * <li>Create a tunnel to the remote server and negotiate the network
97 * parameters for the VPN connection.</li>
98 * <li>Supply those parameters to a {@link Builder} and create a VPN
99 * interface by calling {@link Builder#establish}.</li>
100 * <li>Process and exchange packets between the tunnel and the returned
101 * file descriptor.</li>
102 * <li>When {@link #onRevoke} is invoked, close the file descriptor and
103 * shut down the tunnel gracefully.</li>
104 * </ol>
105 *
106 * <p>Services extending this class need to be declared with an appropriate
107 * permission and intent filter. Their access must be secured by
108 * {@link android.Manifest.permission#BIND_VPN_SERVICE} permission, and
109 * their intent filter must match {@link #SERVICE_INTERFACE} action. Here
110 * is an example of declaring a VPN service in {@code AndroidManifest.xml}:
111 * <pre>
112 * &lt;service android:name=".ExampleVpnService"
113 * android:permission="android.permission.BIND_VPN_SERVICE"&gt;
114 * &lt;intent-filter&gt;
115 * &lt;action android:name="android.net.VpnService"/&gt;
116 * &lt;/intent-filter&gt;
117 * &lt;/service&gt;</pre>
118 *
119 * <p> The Android system starts a VPN in the background by calling
120 * {@link android.content.Context#startService startService()}. In Android 8.0
121 * (API level 26) and higher, the system places VPN apps on the temporary
122 * allowlist for a short period so the app can start in the background. The VPN
123 * app must promote itself to the foreground after it's launched or the system
124 * will shut down the app.
125 *
126 * <h3>Developer's guide</h3>
127 *
128 * <p>To learn more about developing VPN apps, read the
129 * <a href="{@docRoot}guide/topics/connectivity/vpn">VPN developer's guide</a>.
130 *
131 * @see Builder
132 */
133public class VpnService extends Service {
134
135 /**
136 * The action must be matched by the intent filter of this service. It also
137 * needs to require {@link android.Manifest.permission#BIND_VPN_SERVICE}
138 * permission so that other applications cannot abuse it.
139 */
140 public static final String SERVICE_INTERFACE = VpnConfig.SERVICE_INTERFACE;
141
142 /**
143 * Key for boolean meta-data field indicating whether this VpnService supports always-on mode.
144 *
145 * <p>For a VPN app targeting {@link android.os.Build.VERSION_CODES#N API 24} or above, Android
146 * provides users with the ability to set it as always-on, so that VPN connection is
147 * persisted after device reboot and app upgrade. Always-on VPN can also be enabled by device
148 * owner and profile owner apps through
149 * {@link DevicePolicyManager#setAlwaysOnVpnPackage}.
150 *
151 * <p>VPN apps not supporting this feature should opt out by adding this meta-data field to the
152 * {@code VpnService} component of {@code AndroidManifest.xml}. In case there is more than one
153 * {@code VpnService} component defined in {@code AndroidManifest.xml}, opting out any one of
154 * them will opt out the entire app. For example,
155 * <pre> {@code
156 * <service android:name=".ExampleVpnService"
157 * android:permission="android.permission.BIND_VPN_SERVICE">
158 * <intent-filter>
159 * <action android:name="android.net.VpnService"/>
160 * </intent-filter>
161 * <meta-data android:name="android.net.VpnService.SUPPORTS_ALWAYS_ON"
162 * android:value=false/>
163 * </service>
164 * } </pre>
165 *
166 * <p>This meta-data field defaults to {@code true} if absent. It will only have effect on
167 * {@link android.os.Build.VERSION_CODES#O_MR1} or higher.
168 */
169 public static final String SERVICE_META_DATA_SUPPORTS_ALWAYS_ON =
170 "android.net.VpnService.SUPPORTS_ALWAYS_ON";
171
172 /**
173 * Use IConnectivityManager since those methods are hidden and not
174 * available in ConnectivityManager.
175 */
176 private static IConnectivityManager getService() {
177 return IConnectivityManager.Stub.asInterface(
178 ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
179 }
180
181 /**
182 * Prepare to establish a VPN connection. This method returns {@code null}
183 * if the VPN application is already prepared or if the user has previously
184 * consented to the VPN application. Otherwise, it returns an
185 * {@link Intent} to a system activity. The application should launch the
186 * activity using {@link Activity#startActivityForResult} to get itself
187 * prepared. The activity may pop up a dialog to require user action, and
188 * the result will come back via its {@link Activity#onActivityResult}.
189 * If the result is {@link Activity#RESULT_OK}, the application becomes
190 * prepared and is granted to use other methods in this class.
191 *
192 * <p>Only one application can be granted at the same time. The right
193 * is revoked when another application is granted. The application
194 * losing the right will be notified via its {@link #onRevoke}. Unless
195 * it becomes prepared again, subsequent calls to other methods in this
196 * class will fail.
197 *
198 * <p>The user may disable the VPN at any time while it is activated, in
199 * which case this method will return an intent the next time it is
200 * executed to obtain the user's consent again.
201 *
202 * @see #onRevoke
203 */
204 public static Intent prepare(Context context) {
205 try {
206 if (getService().prepareVpn(context.getPackageName(), null, context.getUserId())) {
207 return null;
208 }
209 } catch (RemoteException e) {
210 // ignore
211 }
212 return VpnConfig.getIntentForConfirmation();
213 }
214
215 /**
216 * Version of {@link #prepare(Context)} which does not require user consent.
217 *
218 * <p>Requires {@link android.Manifest.permission#CONTROL_VPN} and should generally not be
219 * used. Only acceptable in situations where user consent has been obtained through other means.
220 *
221 * <p>Once this is run, future preparations may be done with the standard prepare method as this
222 * will authorize the package to prepare the VPN without consent in the future.
223 *
224 * @hide
225 */
226 @SystemApi
227 @RequiresPermission(android.Manifest.permission.CONTROL_VPN)
228 public static void prepareAndAuthorize(Context context) {
229 IConnectivityManager cm = getService();
230 String packageName = context.getPackageName();
231 try {
232 // Only prepare if we're not already prepared.
233 int userId = context.getUserId();
234 if (!cm.prepareVpn(packageName, null, userId)) {
235 cm.prepareVpn(null, packageName, userId);
236 }
237 cm.setVpnPackageAuthorization(packageName, userId, VpnManager.TYPE_VPN_SERVICE);
238 } catch (RemoteException e) {
239 // ignore
240 }
241 }
242
243 /**
244 * Protect a socket from VPN connections. After protecting, data sent
245 * through this socket will go directly to the underlying network,
246 * so its traffic will not be forwarded through the VPN.
247 * This method is useful if some connections need to be kept
248 * outside of VPN. For example, a VPN tunnel should protect itself if its
249 * destination is covered by VPN routes. Otherwise its outgoing packets
250 * will be sent back to the VPN interface and cause an infinite loop. This
251 * method will fail if the application is not prepared or is revoked.
252 *
253 * <p class="note">The socket is NOT closed by this method.
254 *
255 * @return {@code true} on success.
256 */
257 public boolean protect(int socket) {
258 return NetworkUtils.protectFromVpn(socket);
259 }
260
261 /**
262 * Convenience method to protect a {@link Socket} from VPN connections.
263 *
264 * @return {@code true} on success.
265 * @see #protect(int)
266 */
267 public boolean protect(Socket socket) {
268 return protect(socket.getFileDescriptor$().getInt$());
269 }
270
271 /**
272 * Convenience method to protect a {@link DatagramSocket} from VPN
273 * connections.
274 *
275 * @return {@code true} on success.
276 * @see #protect(int)
277 */
278 public boolean protect(DatagramSocket socket) {
279 return protect(socket.getFileDescriptor$().getInt$());
280 }
281
282 /**
283 * Adds a network address to the VPN interface.
284 *
285 * Both IPv4 and IPv6 addresses are supported. The VPN must already be established. Fails if the
286 * address is already in use or cannot be assigned to the interface for any other reason.
287 *
288 * Adding an address implicitly allows traffic from that address family (i.e., IPv4 or IPv6) to
289 * be routed over the VPN. @see Builder#allowFamily
290 *
291 * @throws IllegalArgumentException if the address is invalid.
292 *
293 * @param address The IP address (IPv4 or IPv6) to assign to the VPN interface.
294 * @param prefixLength The prefix length of the address.
295 *
296 * @return {@code true} on success.
297 * @see Builder#addAddress
298 *
299 * @hide
300 */
301 public boolean addAddress(InetAddress address, int prefixLength) {
302 check(address, prefixLength);
303 try {
304 return getService().addVpnAddress(address.getHostAddress(), prefixLength);
305 } catch (RemoteException e) {
306 throw new IllegalStateException(e);
307 }
308 }
309
310 /**
311 * Removes a network address from the VPN interface.
312 *
313 * Both IPv4 and IPv6 addresses are supported. The VPN must already be established. Fails if the
314 * address is not assigned to the VPN interface, or if it is the only address assigned (thus
315 * cannot be removed), or if the address cannot be removed for any other reason.
316 *
317 * After removing an address, if there are no addresses, routes or DNS servers of a particular
318 * address family (i.e., IPv4 or IPv6) configured on the VPN, that <b>DOES NOT</b> block that
319 * family from being routed. In other words, once an address family has been allowed, it stays
320 * allowed for the rest of the VPN's session. @see Builder#allowFamily
321 *
322 * @throws IllegalArgumentException if the address is invalid.
323 *
324 * @param address The IP address (IPv4 or IPv6) to assign to the VPN interface.
325 * @param prefixLength The prefix length of the address.
326 *
327 * @return {@code true} on success.
328 *
329 * @hide
330 */
331 public boolean removeAddress(InetAddress address, int prefixLength) {
332 check(address, prefixLength);
333 try {
334 return getService().removeVpnAddress(address.getHostAddress(), prefixLength);
335 } catch (RemoteException e) {
336 throw new IllegalStateException(e);
337 }
338 }
339
340 /**
341 * Sets the underlying networks used by the VPN for its upstream connections.
342 *
343 * <p>Used by the system to know the actual networks that carry traffic for apps affected by
344 * this VPN in order to present this information to the user (e.g., via status bar icons).
345 *
346 * <p>This method only needs to be called if the VPN has explicitly bound its underlying
347 * communications channels &mdash; such as the socket(s) passed to {@link #protect(int)} &mdash;
348 * to a {@code Network} using APIs such as {@link Network#bindSocket(Socket)} or
349 * {@link Network#bindSocket(DatagramSocket)}. The VPN should call this method every time
350 * the set of {@code Network}s it is using changes.
351 *
352 * <p>{@code networks} is one of the following:
353 * <ul>
354 * <li><strong>a non-empty array</strong>: an array of one or more {@link Network}s, in
355 * decreasing preference order. For example, if this VPN uses both wifi and mobile (cellular)
356 * networks to carry app traffic, but prefers or uses wifi more than mobile, wifi should appear
357 * first in the array.</li>
358 * <li><strong>an empty array</strong>: a zero-element array, meaning that the VPN has no
359 * underlying network connection, and thus, app traffic will not be sent or received.</li>
360 * <li><strong>null</strong>: (default) signifies that the VPN uses whatever is the system's
361 * default network. I.e., it doesn't use the {@code bindSocket} or {@code bindDatagramSocket}
362 * APIs mentioned above to send traffic over specific channels.</li>
363 * </ul>
364 *
365 * <p>This call will succeed only if the VPN is currently established. For setting this value
366 * when the VPN has not yet been established, see {@link Builder#setUnderlyingNetworks}.
367 *
368 * @param networks An array of networks the VPN uses to tunnel traffic to/from its servers.
369 *
370 * @return {@code true} on success.
371 */
372 public boolean setUnderlyingNetworks(Network[] networks) {
373 try {
374 return getService().setUnderlyingNetworksForVpn(networks);
375 } catch (RemoteException e) {
376 throw new IllegalStateException(e);
377 }
378 }
379
380 /**
381 * Returns whether the service is running in always-on VPN mode. In this mode the system ensures
382 * that the service is always running by restarting it when necessary, e.g. after reboot.
383 *
384 * @see DevicePolicyManager#setAlwaysOnVpnPackage(ComponentName, String, boolean, Set)
385 */
386 public final boolean isAlwaysOn() {
387 try {
388 return getService().isCallerCurrentAlwaysOnVpnApp();
389 } catch (RemoteException e) {
390 throw e.rethrowFromSystemServer();
391 }
392 }
393
394 /**
395 * Returns whether the service is running in always-on VPN lockdown mode. In this mode the
396 * system ensures that the service is always running and that the apps aren't allowed to bypass
397 * the VPN.
398 *
399 * @see DevicePolicyManager#setAlwaysOnVpnPackage(ComponentName, String, boolean, Set)
400 */
401 public final boolean isLockdownEnabled() {
402 try {
403 return getService().isCallerCurrentAlwaysOnVpnLockdownApp();
404 } catch (RemoteException e) {
405 throw e.rethrowFromSystemServer();
406 }
407 }
408
409 /**
410 * Return the communication interface to the service. This method returns
411 * {@code null} on {@link Intent}s other than {@link #SERVICE_INTERFACE}
412 * action. Applications overriding this method must identify the intent
413 * and return the corresponding interface accordingly.
414 *
415 * @see Service#onBind
416 */
417 @Override
418 public IBinder onBind(Intent intent) {
419 if (intent != null && SERVICE_INTERFACE.equals(intent.getAction())) {
420 return new Callback();
421 }
422 return null;
423 }
424
425 /**
426 * Invoked when the application is revoked. At this moment, the VPN
427 * interface is already deactivated by the system. The application should
428 * close the file descriptor and shut down gracefully. The default
429 * implementation of this method is calling {@link Service#stopSelf()}.
430 *
431 * <p class="note">Calls to this method may not happen on the main thread
432 * of the process.
433 *
434 * @see #prepare
435 */
436 public void onRevoke() {
437 stopSelf();
438 }
439
440 /**
441 * Use raw Binder instead of AIDL since now there is only one usage.
442 */
443 private class Callback extends Binder {
444 @Override
445 protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) {
446 if (code == IBinder.LAST_CALL_TRANSACTION) {
447 onRevoke();
448 return true;
449 }
450 return false;
451 }
452 }
453
454 /**
455 * Private method to validate address and prefixLength.
456 */
457 private static void check(InetAddress address, int prefixLength) {
458 if (address.isLoopbackAddress()) {
459 throw new IllegalArgumentException("Bad address");
460 }
461 if (address instanceof Inet4Address) {
462 if (prefixLength < 0 || prefixLength > 32) {
463 throw new IllegalArgumentException("Bad prefixLength");
464 }
465 } else if (address instanceof Inet6Address) {
466 if (prefixLength < 0 || prefixLength > 128) {
467 throw new IllegalArgumentException("Bad prefixLength");
468 }
469 } else {
470 throw new IllegalArgumentException("Unsupported family");
471 }
472 }
473
474 /**
475 * Helper class to create a VPN interface. This class should be always
476 * used within the scope of the outer {@link VpnService}.
477 *
478 * @see VpnService
479 */
480 public class Builder {
481
482 private final VpnConfig mConfig = new VpnConfig();
483 @UnsupportedAppUsage
484 private final List<LinkAddress> mAddresses = new ArrayList<LinkAddress>();
485 @UnsupportedAppUsage
486 private final List<RouteInfo> mRoutes = new ArrayList<RouteInfo>();
487
488 public Builder() {
489 mConfig.user = VpnService.this.getClass().getName();
490 }
491
492 /**
493 * Set the name of this session. It will be displayed in
494 * system-managed dialogs and notifications. This is recommended
495 * not required.
496 */
497 @NonNull
498 public Builder setSession(@NonNull String session) {
499 mConfig.session = session;
500 return this;
501 }
502
503 /**
504 * Set the {@link PendingIntent} to an activity for users to
505 * configure the VPN connection. If it is not set, the button
506 * to configure will not be shown in system-managed dialogs.
507 */
508 @NonNull
509 public Builder setConfigureIntent(@NonNull PendingIntent intent) {
510 mConfig.configureIntent = intent;
511 return this;
512 }
513
514 /**
515 * Set the maximum transmission unit (MTU) of the VPN interface. If
516 * it is not set, the default value in the operating system will be
517 * used.
518 *
519 * @throws IllegalArgumentException if the value is not positive.
520 */
521 @NonNull
522 public Builder setMtu(int mtu) {
523 if (mtu <= 0) {
524 throw new IllegalArgumentException("Bad mtu");
525 }
526 mConfig.mtu = mtu;
527 return this;
528 }
529
530 /**
531 * Sets an HTTP proxy for the VPN network. This proxy is only a recommendation
532 * and it is possible that some apps will ignore it.
533 */
534 @NonNull
535 public Builder setHttpProxy(@NonNull ProxyInfo proxyInfo) {
536 mConfig.proxyInfo = proxyInfo;
537 return this;
538 }
539
540 /**
541 * Add a network address to the VPN interface. Both IPv4 and IPv6
542 * addresses are supported. At least one address must be set before
543 * calling {@link #establish}.
544 *
545 * Adding an address implicitly allows traffic from that address family
546 * (i.e., IPv4 or IPv6) to be routed over the VPN. @see #allowFamily
547 *
548 * @throws IllegalArgumentException if the address is invalid.
549 */
550 @NonNull
551 public Builder addAddress(@NonNull InetAddress address, int prefixLength) {
552 check(address, prefixLength);
553
554 if (address.isAnyLocalAddress()) {
555 throw new IllegalArgumentException("Bad address");
556 }
557 mAddresses.add(new LinkAddress(address, prefixLength));
558 mConfig.updateAllowedFamilies(address);
559 return this;
560 }
561
562 /**
563 * Convenience method to add a network address to the VPN interface
564 * using a numeric address string. See {@link InetAddress} for the
565 * definitions of numeric address formats.
566 *
567 * Adding an address implicitly allows traffic from that address family
568 * (i.e., IPv4 or IPv6) to be routed over the VPN. @see #allowFamily
569 *
570 * @throws IllegalArgumentException if the address is invalid.
571 * @see #addAddress(InetAddress, int)
572 */
573 @NonNull
574 public Builder addAddress(@NonNull String address, int prefixLength) {
575 return addAddress(InetAddress.parseNumericAddress(address), prefixLength);
576 }
577
578 /**
579 * Add a network route to the VPN interface. Both IPv4 and IPv6
580 * routes are supported.
581 *
582 * Adding a route implicitly allows traffic from that address family
583 * (i.e., IPv4 or IPv6) to be routed over the VPN. @see #allowFamily
584 *
585 * @throws IllegalArgumentException if the route is invalid.
586 */
587 @NonNull
588 public Builder addRoute(@NonNull InetAddress address, int prefixLength) {
589 check(address, prefixLength);
590
591 int offset = prefixLength / 8;
592 byte[] bytes = address.getAddress();
593 if (offset < bytes.length) {
594 for (bytes[offset] <<= prefixLength % 8; offset < bytes.length; ++offset) {
595 if (bytes[offset] != 0) {
596 throw new IllegalArgumentException("Bad address");
597 }
598 }
599 }
600 mRoutes.add(new RouteInfo(new IpPrefix(address, prefixLength), null));
601 mConfig.updateAllowedFamilies(address);
602 return this;
603 }
604
605 /**
606 * Convenience method to add a network route to the VPN interface
607 * using a numeric address string. See {@link InetAddress} for the
608 * definitions of numeric address formats.
609 *
610 * Adding a route implicitly allows traffic from that address family
611 * (i.e., IPv4 or IPv6) to be routed over the VPN. @see #allowFamily
612 *
613 * @throws IllegalArgumentException if the route is invalid.
614 * @see #addRoute(InetAddress, int)
615 */
616 @NonNull
617 public Builder addRoute(@NonNull String address, int prefixLength) {
618 return addRoute(InetAddress.parseNumericAddress(address), prefixLength);
619 }
620
621 /**
622 * Add a DNS server to the VPN connection. Both IPv4 and IPv6
623 * addresses are supported. If none is set, the DNS servers of
624 * the default network will be used.
625 *
626 * Adding a server implicitly allows traffic from that address family
627 * (i.e., IPv4 or IPv6) to be routed over the VPN. @see #allowFamily
628 *
629 * @throws IllegalArgumentException if the address is invalid.
630 */
631 @NonNull
632 public Builder addDnsServer(@NonNull InetAddress address) {
633 if (address.isLoopbackAddress() || address.isAnyLocalAddress()) {
634 throw new IllegalArgumentException("Bad address");
635 }
636 if (mConfig.dnsServers == null) {
637 mConfig.dnsServers = new ArrayList<String>();
638 }
639 mConfig.dnsServers.add(address.getHostAddress());
640 return this;
641 }
642
643 /**
644 * Convenience method to add a DNS server to the VPN connection
645 * using a numeric address string. See {@link InetAddress} for the
646 * definitions of numeric address formats.
647 *
648 * Adding a server implicitly allows traffic from that address family
649 * (i.e., IPv4 or IPv6) to be routed over the VPN. @see #allowFamily
650 *
651 * @throws IllegalArgumentException if the address is invalid.
652 * @see #addDnsServer(InetAddress)
653 */
654 @NonNull
655 public Builder addDnsServer(@NonNull String address) {
656 return addDnsServer(InetAddress.parseNumericAddress(address));
657 }
658
659 /**
660 * Add a search domain to the DNS resolver.
661 */
662 @NonNull
663 public Builder addSearchDomain(@NonNull String domain) {
664 if (mConfig.searchDomains == null) {
665 mConfig.searchDomains = new ArrayList<String>();
666 }
667 mConfig.searchDomains.add(domain);
668 return this;
669 }
670
671 /**
672 * Allows traffic from the specified address family.
673 *
674 * By default, if no address, route or DNS server of a specific family (IPv4 or IPv6) is
675 * added to this VPN, then all outgoing traffic of that family is blocked. If any address,
676 * route or DNS server is added, that family is allowed.
677 *
678 * This method allows an address family to be unblocked even without adding an address,
679 * route or DNS server of that family. Traffic of that family will then typically
680 * fall-through to the underlying network if it's supported.
681 *
682 * {@code family} must be either {@code AF_INET} (for IPv4) or {@code AF_INET6} (for IPv6).
683 * {@link IllegalArgumentException} is thrown if it's neither.
684 *
685 * @param family The address family ({@code AF_INET} or {@code AF_INET6}) to allow.
686 *
687 * @return this {@link Builder} object to facilitate chaining of method calls.
688 */
689 @NonNull
690 public Builder allowFamily(int family) {
691 if (family == AF_INET) {
692 mConfig.allowIPv4 = true;
693 } else if (family == AF_INET6) {
694 mConfig.allowIPv6 = true;
695 } else {
696 throw new IllegalArgumentException(family + " is neither " + AF_INET + " nor " +
697 AF_INET6);
698 }
699 return this;
700 }
701
702 private void verifyApp(String packageName) throws PackageManager.NameNotFoundException {
703 IPackageManager pm = IPackageManager.Stub.asInterface(
704 ServiceManager.getService("package"));
705 try {
706 pm.getApplicationInfo(packageName, 0, UserHandle.getCallingUserId());
707 } catch (RemoteException e) {
708 throw new IllegalStateException(e);
709 }
710 }
711
712 /**
713 * Adds an application that's allowed to access the VPN connection.
714 *
715 * If this method is called at least once, only applications added through this method (and
716 * no others) are allowed access. Else (if this method is never called), all applications
717 * are allowed by default. If some applications are added, other, un-added applications
718 * will use networking as if the VPN wasn't running.
719 *
720 * A {@link Builder} may have only a set of allowed applications OR a set of disallowed
721 * ones, but not both. Calling this method after {@link #addDisallowedApplication} has
722 * already been called, or vice versa, will throw an {@link UnsupportedOperationException}.
723 *
724 * {@code packageName} must be the canonical name of a currently installed application.
725 * {@link PackageManager.NameNotFoundException} is thrown if there's no such application.
726 *
727 * @throws PackageManager.NameNotFoundException If the application isn't installed.
728 *
729 * @param packageName The full name (e.g.: "com.google.apps.contacts") of an application.
730 *
731 * @return this {@link Builder} object to facilitate chaining method calls.
732 */
733 @NonNull
734 public Builder addAllowedApplication(@NonNull String packageName)
735 throws PackageManager.NameNotFoundException {
736 if (mConfig.disallowedApplications != null) {
737 throw new UnsupportedOperationException("addDisallowedApplication already called");
738 }
739 verifyApp(packageName);
740 if (mConfig.allowedApplications == null) {
741 mConfig.allowedApplications = new ArrayList<String>();
742 }
743 mConfig.allowedApplications.add(packageName);
744 return this;
745 }
746
747 /**
748 * Adds an application that's denied access to the VPN connection.
749 *
750 * By default, all applications are allowed access, except for those denied through this
751 * method. Denied applications will use networking as if the VPN wasn't running.
752 *
753 * A {@link Builder} may have only a set of allowed applications OR a set of disallowed
754 * ones, but not both. Calling this method after {@link #addAllowedApplication} has already
755 * been called, or vice versa, will throw an {@link UnsupportedOperationException}.
756 *
757 * {@code packageName} must be the canonical name of a currently installed application.
758 * {@link PackageManager.NameNotFoundException} is thrown if there's no such application.
759 *
760 * @throws PackageManager.NameNotFoundException If the application isn't installed.
761 *
762 * @param packageName The full name (e.g.: "com.google.apps.contacts") of an application.
763 *
764 * @return this {@link Builder} object to facilitate chaining method calls.
765 */
766 @NonNull
767 public Builder addDisallowedApplication(@NonNull String packageName)
768 throws PackageManager.NameNotFoundException {
769 if (mConfig.allowedApplications != null) {
770 throw new UnsupportedOperationException("addAllowedApplication already called");
771 }
772 verifyApp(packageName);
773 if (mConfig.disallowedApplications == null) {
774 mConfig.disallowedApplications = new ArrayList<String>();
775 }
776 mConfig.disallowedApplications.add(packageName);
777 return this;
778 }
779
780 /**
781 * Allows all apps to bypass this VPN connection.
782 *
783 * By default, all traffic from apps is forwarded through the VPN interface and it is not
784 * possible for apps to side-step the VPN. If this method is called, apps may use methods
785 * such as {@link ConnectivityManager#bindProcessToNetwork} to instead send/receive
786 * directly over the underlying network or any other network they have permissions for.
787 *
788 * @return this {@link Builder} object to facilitate chaining of method calls.
789 */
790 @NonNull
791 public Builder allowBypass() {
792 mConfig.allowBypass = true;
793 return this;
794 }
795
796 /**
797 * Sets the VPN interface's file descriptor to be in blocking/non-blocking mode.
798 *
799 * By default, the file descriptor returned by {@link #establish} is non-blocking.
800 *
801 * @param blocking True to put the descriptor into blocking mode; false for non-blocking.
802 *
803 * @return this {@link Builder} object to facilitate chaining method calls.
804 */
805 @NonNull
806 public Builder setBlocking(boolean blocking) {
807 mConfig.blocking = blocking;
808 return this;
809 }
810
811 /**
812 * Sets the underlying networks used by the VPN for its upstream connections.
813 *
814 * @see VpnService#setUnderlyingNetworks
815 *
816 * @param networks An array of networks the VPN uses to tunnel traffic to/from its servers.
817 *
818 * @return this {@link Builder} object to facilitate chaining method calls.
819 */
820 @NonNull
821 public Builder setUnderlyingNetworks(@Nullable Network[] networks) {
822 mConfig.underlyingNetworks = networks != null ? networks.clone() : null;
823 return this;
824 }
825
826 /**
827 * Marks the VPN network as metered. A VPN network is classified as metered when the user is
828 * sensitive to heavy data usage due to monetary costs and/or data limitations. In such
829 * cases, you should set this to {@code true} so that apps on the system can avoid doing
830 * large data transfers. Otherwise, set this to {@code false}. Doing so would cause VPN
831 * network to inherit its meteredness from its underlying networks.
832 *
833 * <p>VPN apps targeting {@link android.os.Build.VERSION_CODES#Q} or above will be
834 * considered metered by default.
835 *
836 * @param isMetered {@code true} if VPN network should be treated as metered regardless of
837 * underlying network meteredness
838 * @return this {@link Builder} object to facilitate chaining method calls
839 * @see #setUnderlyingNetworks(Network[])
840 * @see ConnectivityManager#isActiveNetworkMetered()
841 */
842 @NonNull
843 public Builder setMetered(boolean isMetered) {
844 mConfig.isMetered = isMetered;
845 return this;
846 }
847
848 /**
849 * Create a VPN interface using the parameters supplied to this
850 * builder. The interface works on IP packets, and a file descriptor
851 * is returned for the application to access them. Each read
852 * retrieves an outgoing packet which was routed to the interface.
853 * Each write injects an incoming packet just like it was received
854 * from the interface. The file descriptor is put into non-blocking
855 * mode by default to avoid blocking Java threads. To use the file
856 * descriptor completely in native space, see
857 * {@link ParcelFileDescriptor#detachFd()}. The application MUST
858 * close the file descriptor when the VPN connection is terminated.
859 * The VPN interface will be removed and the network will be
860 * restored by the system automatically.
861 *
862 * <p>To avoid conflicts, there can be only one active VPN interface
863 * at the same time. Usually network parameters are never changed
864 * during the lifetime of a VPN connection. It is also common for an
865 * application to create a new file descriptor after closing the
866 * previous one. However, it is rare but not impossible to have two
867 * interfaces while performing a seamless handover. In this case, the
868 * old interface will be deactivated when the new one is created
869 * successfully. Both file descriptors are valid but now outgoing
870 * packets will be routed to the new interface. Therefore, after
871 * draining the old file descriptor, the application MUST close it
872 * and start using the new file descriptor. If the new interface
873 * cannot be created, the existing interface and its file descriptor
874 * remain untouched.
875 *
876 * <p>An exception will be thrown if the interface cannot be created
877 * for any reason. However, this method returns {@code null} if the
878 * application is not prepared or is revoked. This helps solve
879 * possible race conditions between other VPN applications.
880 *
881 * @return {@link ParcelFileDescriptor} of the VPN interface, or
882 * {@code null} if the application is not prepared.
883 * @throws IllegalArgumentException if a parameter is not accepted
884 * by the operating system.
885 * @throws IllegalStateException if a parameter cannot be applied
886 * by the operating system.
887 * @throws SecurityException if the service is not properly declared
888 * in {@code AndroidManifest.xml}.
889 * @see VpnService
890 */
891 @Nullable
892 public ParcelFileDescriptor establish() {
893 mConfig.addresses = mAddresses;
894 mConfig.routes = mRoutes;
895
896 try {
897 return getService().establishVpn(mConfig);
898 } catch (RemoteException e) {
899 throw new IllegalStateException(e);
900 }
901 }
902 }
903}