private void establishVpn(PacketsTransfer packetsTransfer) {
		VpnService.Builder builder = mVpnService.new Builder();
		builder.setBlocking(true);
		builder.setMtu(mConfig.mtu);
		builder.addAddress(mConfig.address.address, mConfig.address.prefixLength);
		if (mConfig.session != null) {
			builder.setSession(mConfig.session);
		}
		if (mConfig.configureIntent != null) {
			builder.setConfigureIntent(mConfig.configureIntent);
		}
		for (IpAddress ip : mConfig.routes) {
			builder.addRoute(ip.address, ip.prefixLength);
		}
		for (String address : mConfig.dnsServers) {
			builder.addDnsServer(address);
		}
		try {
			for (String packageName : mConfig.allowedApplications) {
				builder.addAllowedApplication(packageName);
			}
			for (String packageName : mConfig.disallowedApplications) {
				builder.addDisallowedApplication(packageName);
			}
			// Add self to allowed list.
			if (!mConfig.allowedApplications.isEmpty()) {
				builder.addAllowedApplication(mVpnService.getPackageName());
			}
		} catch (PackageManager.NameNotFoundException e) {
			NetBareLog.wtf(e);
		}
		vpnDescriptor = builder.establish();
		if (vpnDescriptor == null) {
			return;
		}

		// Open io with the VPN descriptor.
		FileDescriptor descriptor = vpnDescriptor.getFileDescriptor();
		if (descriptor == null) {
			return;
		}
		input = new FileInputStream(descriptor);
		output = new FileOutputStream(descriptor);

		packetsTransfer.start();

		try {
			// Read packets from input io and forward them to proxy servers.
			while (!isInterrupted()) {
				packetsTransfer.transfer(input, output);
			}
		} catch (IOException e) {
			if (!isInterrupted()) {
				NetBareLog.wtf(e);
			}
		}
	}
A work thread running NetBare core logic. NetBase established the VPN connection is this thread
and read packets from the VPN file descriptor and transfer them to local proxy servers. Every
IP protocol runs an independent local proxy server to receive the packets.

@author Megatron King
@since 2018-10-08 19:38
netbare-core/src/main/java/com/github/megatronking/netbare/NetBareThread.java