6

When I try to create the tunnel interface for my VpnService, I'm getting the following error:

Attempt to invoke virtual method 'java.lang.String android.os.ParcelFileDescriptor.toString()' on a null object reference

The only resolve I currently have is to restart the device when this happens. If I do not, I'm unable to create the tunnel at all.

My code for creating the tunnel:

// This is inside my VpnService implementation 

private ParcelFileDescriptor configureTunnelWithPushOpts(PushOpts popts)
{
    VpnService.Builder builder = this.new Builder();

    builder.setMtu       ( currentServerPrefs.SERVER_MTU );
    builder.addAddress   ( popts.ip, 32                  );
    builder.addDnsServer ( popts.dns1                    );
    builder.addDnsServer ( popts.dns2                    );
    builder.addRoute     ( "0.0.0.0", 0                  );


    // Note: Blocking mode is now enabled in native
    // code under the setFileDescriptor function.
    // builder.setBlocking(true);

    builder.setConfigureIntent(
            PendingIntent.getActivity(
                    this,
                    0,
                    new Intent(
                            this,
                            MainActivity.class
                    ),
            PendingIntent.FLAG_UPDATE_CURRENT)
    );

    final ParcelFileDescriptor vpnInterface;

    synchronized (this) {
        builder.setSession(currentServerPrefs.SERVER_ADDRESS);
        vpnInterface = builder.establish();
    }

    Logger.info("New interface: " + vpnInterface.toString(), this);
    return vpnInterface;
}

Edit:

According to the documentation, the establish function will return null if the VpnService has not been prepared, however I am using this to prepare it prior to running the above function.

// This is inside my MainActivity class

Intent intent = VpnService.prepare(getApplicationContext());
if (intent != null) {
    startActivityForResult(intent, 0);
} else {
    onActivityResult(0, RESULT_OK, null);
}

. . . 

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == RESULT_OK) {
        Intent intent = new Intent(this, MyVpnService.class);
        startService(intent);
    }
}

Phone I'm using for debugging

Google Nexus 5 Running Android 5.0.1

Edit

I figured out how to replicate it so that it's no longer sporadic. Basically, if I uninstall the application while the VPN is connected, and then reinstall it and try to start it back up, I receive a null response when i run builder.establish(). I fear this could pose potential issues when the application is updated through the Google Play Store.

Aside from that, Please do not mark this question as a duplicate. Every other question on this matter has been given the answer that the service needs to be prepared before the builder is established, however I am preparing it in my case and have a different cause for my problem. Any help would be appreciated.

ivan_pozdeev
  • 33,874
  • 19
  • 107
  • 152
Nathan F.
  • 3,250
  • 3
  • 35
  • 69
  • Have you looked at the [OnRevoke](https://developer.android.com/reference/android/net/VpnService.html#onRevoke()) method? it might be possible that something else uses the vpn – Hugo sama Jul 27 '17 at 00:17
  • 1
    I know this is an old question, but have you found the solution for this issue? I'm facing the same behavior (on 5.0.1 Android, Samsung Galaxy S5). Thanks in advance. – CyberMJ Sep 26 '18 at 08:45
  • @CyberMJ still haven't found a solution to it :/. – Nathan F. Sep 26 '18 at 17:22

1 Answers1

3

Thanks a lot for the hint, it brought me to the solution!

I had the same problem in Android 5.0.2: Everything worked fine, and I installed the vpn app I am developing. The next day, suddenly, an unresolvable NullPointerException, although prepare was properly called.

The issue could be solved in my environment with the following steps:

  • Uninstall the app. It does not matter, if the app has still working VPN functionality or not.
  • Restart your phone. Make sure that it was shut off completely.
  • After restart, make sure the app is not installed anymore (I had some strange development issues where an app was reinstalled after rebooting my phone).
  • Install your VPN app again. It should receive a vpn interface now, and not anymore null.
Martin Bories
  • 1,067
  • 17
  • 37
  • The problem with this is that end users might do the same thing, uninstall the app and then re-install it again and experience the same NullPointerException. I don't want to have to tell my end users to restart their phone just to use the application. – Nathan F. Apr 14 '18 at 16:50
  • Maybe one could catch the uninstallation with an even listener and then gracefully deactivate/shutdown the vpn? Does this Problem only occur in a development environment (could also be related to adb), or have you tested it with a production App? – Martin Bories Apr 14 '18 at 16:52
  • @MartinBories This answer is very helpful for me :) and it genuinely worked in my case. – Jarvis__-_-__ Feb 05 '22 at 18:57