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