Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 30 additions & 4 deletions app/src/main/java/eu/faircode/netguard/ServiceSinkhole.java
Original file line number Diff line number Diff line change
Expand Up @@ -1852,10 +1852,17 @@ private Builder getBuilder(List<Rule> listAllowed, List<Rule> listRule) {
Builder builder = new Builder();
builder.setSession(getString(R.string.app_name));

// Match the physical network's metered status so apps behave the
// same as without the VPN. (Android defaults VPNs to metered.)
// Android defaults VPNs to metered, which makes every app on the device
// treat an unmetered Wi-Fi as metered while the VPN runs (#959). Passing
// false does not force the network unmetered: it tells the platform to
// inherit meteredness from the underlying networks, so the VPN tracks
// the physical network as it changes. Snapshotting isMeteredNetwork()
// here cannot do that — the value is read once per establish, is true
// whenever there is no active network yet (a boot or always-on start
// before Wi-Fi associates), and then never reaches the live interface
// again while the tunnel lives.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
builder.setMetered(Util.isMeteredNetwork(this));
builder.setMetered(false);

// Use blocking I/O on the TUN file descriptor for CPU efficiency
// (avoids polling when there is no traffic)
Expand Down Expand Up @@ -2107,8 +2114,10 @@ private Builder getBlockingBuilder(List<Rule> listRule) {
builder.setSession(getString(R.string.app_name));
builder.setBlocking(true);
builder.setMtu(1280);
// Inherit meteredness from the underlying networks, as getBuilder does:
// the placeholder must not flip apps to metered mid-replacement.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
builder.setMetered(Util.isMeteredNetwork(this));
builder.setMetered(false);

builder.addAddress("192.0.2.1", 32);
builder.addRoute("0.0.0.0", 0);
Expand Down Expand Up @@ -4811,6 +4820,7 @@ private class Builder extends VpnService.Builder {
private Network activeNetwork;
private NetworkInfo networkInfo;
private int mtu;
private boolean metered = true;
private List<String> listAddress = new ArrayList<>();
private List<String> listRoute = new ArrayList<>();
private List<InetAddress> listDns = new ArrayList<>();
Expand All @@ -4823,6 +4833,19 @@ private Builder() {
networkInfo = cm.getActiveNetworkInfo();
}

/**
* Kept in the comparison below so a changed metered flag forces a real
* re-establish instead of the "Native restart" shortcut (#763): the flag
* only reaches apps through {@link VpnService.Builder#establish()}.
*/
@RequiresApi(api = Build.VERSION_CODES.Q)
@Override
public VpnService.Builder setMetered(boolean metered) {
this.metered = metered;
super.setMetered(metered);
return this;
}

@Override
public VpnService.Builder setMtu(int mtu) {
this.mtu = mtu;
Expand Down Expand Up @@ -4890,6 +4913,9 @@ public boolean equals(Object obj) {
if (this.mtu != other.mtu)
return false;

if (this.metered != other.metered)
return false;

if (this.listAddress.size() != other.listAddress.size())
return false;

Expand Down
Loading