From a4a7fd07616032b112d20f3debf89dfb874f9e6d Mon Sep 17 00:00:00 2001 From: Mikael Magnusson Date: Wed, 5 Jul 2023 22:48:28 +0200 Subject: WIP: add cap to grpc --- .../com/wireguard/android/backend/GoBackend.java | 31 ++++++++++++++++++++++ tunnel/src/main/proto/libwg.proto | 14 ++++++++++ tunnel/tools/libwg-go/http-proxy.go | 19 +++++++++++++ tunnel/tools/libwg-go/service.go | 26 ++++++++++++++++++ 4 files changed, 90 insertions(+) diff --git a/tunnel/src/main/java/com/wireguard/android/backend/GoBackend.java b/tunnel/src/main/java/com/wireguard/android/backend/GoBackend.java index 79b724e8..2af43fb2 100644 --- a/tunnel/src/main/java/com/wireguard/android/backend/GoBackend.java +++ b/tunnel/src/main/java/com/wireguard/android/backend/GoBackend.java @@ -34,6 +34,8 @@ import com.google.protobuf.Empty; import com.wireguard.android.backend.BackendException.Reason; import com.wireguard.android.backend.Tunnel.State; +import com.wireguard.android.backend.gen.CapabilitiesChangedRequest; +import com.wireguard.android.backend.gen.CapabilitiesChangedResponse; import com.wireguard.android.backend.gen.DhcpRequest; import com.wireguard.android.backend.gen.DhcpResponse; import com.wireguard.android.backend.gen.GetConnectionOwnerUidResponse; @@ -110,6 +112,7 @@ public final class GoBackend implements Backend { private static final String TAG = "WireGuard/GoBackend"; private static final int STATS_TAG = 2; private static final int MSG_DHCP_EXPIRE = 1; + private static final int MSG_CAPABILITIES_CHANGED = 2; @Nullable private static AlwaysOnCallback alwaysOnCallback; private static GhettoCompletableFuture vpnService = new GhettoCompletableFuture<>(); private final Context context; @@ -125,6 +128,7 @@ public final class GoBackend implements Backend { @Nullable private Bgp bgp; private HandlerThread thread; private Handler handler; + private NetworkCapabilities activeNetworkCapabilities; /** * Public constructor for GoBackend. @@ -363,6 +367,18 @@ public final class GoBackend implements Backend { return buf.toString(); } + private void capabilitiesChanged(NetworkCapabilities capabilities) { + LibwgGrpc.LibwgBlockingStub stub = LibwgGrpc.newBlockingStub(channel); + CapabilitiesChangedRequest.Builder reqBuilder = CapabilitiesChangedRequest.newBuilder(); + + if (capabilities != null && capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)) { + reqBuilder.addCapabilities(CapabilitiesChangedRequest.Capability.NOT_METERED); + } + + CapabilitiesChangedResponse resp = stub.capabilitiesChanged(reqBuilder.build()); + Log.i(TAG, "Capabilities change: " + resp.getError().getMessage()); + } + private int startHttpProxy(String pacFile) { LibwgGrpc.LibwgStub asyncStub = LibwgGrpc.newStub(channel); LibwgGrpc.LibwgBlockingStub stub = LibwgGrpc.newBlockingStub(channel); @@ -386,6 +402,7 @@ public final class GoBackend implements Backend { StartHttpProxyRequest req = reqBuilder.build(); StartHttpProxyResponse resp = stub.startHttpProxy(req); Log.i(TAG, "Start http proxy listen_port:" + resp.getListenPort() + ", error:" + resp.getError().getMessage()); + capabilitiesChanged(activeNetworkCapabilities); streamer.start(); return resp.getListenPort(); } @@ -755,6 +772,10 @@ public final class GoBackend implements Backend { Log.e(TAG, "DHCP failed: " + ex); } break; + case MSG_CAPABILITIES_CHANGED: + Log.w(TAG, "Msg: capabilities changed: " + activeNetworkCapabilities); + capabilitiesChanged(activeNetworkCapabilities); + break; default: Log.w(TAG, "Unknown message: " + msg.what); break; @@ -972,6 +993,16 @@ public final class GoBackend implements Backend { } } } + + @Override + public void onCapabilitiesChanged (Network network, NetworkCapabilities networkCapabilities) { + boolean hasCapNotMetered = networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); + Log.w(TAG, "onCapabilitiesChanged: " + network + " is not metered:" + (hasCapNotMetered)); + if (network.equals(activeNetwork) && handler != null) { + activeNetworkCapabilities = networkCapabilities; + handler.sendEmptyMessage(MSG_CAPABILITIES_CHANGED); + } + } } private AlarmManager.OnAlarmListener alarmListener = new AlarmManager.OnAlarmListener() { diff --git a/tunnel/src/main/proto/libwg.proto b/tunnel/src/main/proto/libwg.proto index 3195690d..bf471599 100644 --- a/tunnel/src/main/proto/libwg.proto +++ b/tunnel/src/main/proto/libwg.proto @@ -18,6 +18,7 @@ service Libwg { rpc Reverse(stream ReverseRequest) returns (stream ReverseResponse); rpc IpcSet(IpcSetRequest) returns (IpcSetResponse); rpc Dhcp(DhcpRequest) returns (DhcpResponse); + rpc CapabilitiesChanged(CapabilitiesChangedRequest) returns (CapabilitiesChangedResponse); } message TunnelHandle { int32 handle = 1; } @@ -123,3 +124,16 @@ message DhcpResponse { Error error = 1; repeated Lease leases = 2; } + +message CapabilitiesChangedRequest { + enum Capability { + NONE = 0; + NOT_METERED = 11; + }; + + repeated Capability capabilities = 1; +} + +message CapabilitiesChangedResponse { + Error error = 1; +} diff --git a/tunnel/tools/libwg-go/http-proxy.go b/tunnel/tools/libwg-go/http-proxy.go index 9c457286..241c7f7d 100644 --- a/tunnel/tools/libwg-go/http-proxy.go +++ b/tunnel/tools/libwg-go/http-proxy.go @@ -451,6 +451,8 @@ func (p *HttpProxy) SetPacFileUrl(pacFileUrl *url.URL) error { p.ctx.Destroy() } p.ctx = ctx + p.logger.Verbosef("SetNotMetered(false) from SetPacFileUrl") + p.SetNotMetered(false) return nil } @@ -465,6 +467,23 @@ func (p *HttpProxy) SetPacFileContent(pacFile string) error { p.ctx.Destroy() } p.ctx = ctx + p.logger.Verbosef("SetNotMetered(false) from SetPacFileContent") + p.SetNotMetered(false) + return nil +} + +func (p *HttpProxy) SetNotMetered(notMetered bool) error { + p.logger.Verbosef("SetNotMetered: %v", notMetered) + + if p.ctx == nil { + return fmt.Errorf("No ductape context") + } + + p.ctx.PushGlobalObject() + p.ctx.PushBoolean(notMetered) + p.ctx.PutPropString(-2, "notMetered") + p.ctx.Pop() + return nil } diff --git a/tunnel/tools/libwg-go/service.go b/tunnel/tools/libwg-go/service.go index f5460486..41834fe0 100644 --- a/tunnel/tools/libwg-go/service.go +++ b/tunnel/tools/libwg-go/service.go @@ -314,3 +314,29 @@ func (e *LibwgServiceImpl) Dhcp(ctx context.Context, req *gen.DhcpRequest) (*gen } return r, nil } + +func (e *LibwgServiceImpl) CapabilitiesChanged(ctx context.Context, req *gen.CapabilitiesChangedRequest) (*gen.CapabilitiesChangedResponse, error) { + if e.httpProxy == nil { + r := &gen.CapabilitiesChangedResponse{ + Error: &gen.Error{ + Message: fmt.Sprintf("Http Proxy not running"), + }, + } + return r, nil + } + + notMetered := false + + for _, cap := range req.Capabilities { + if cap == gen.CapabilitiesChangedRequest_NOT_METERED { + notMetered = true + } + } + + e.logger.Verbosef("Set not metered %v", notMetered) + e.httpProxy.SetNotMetered(notMetered) + + r := &gen.CapabilitiesChangedResponse{ + } + return r, nil +} -- cgit v1.2.3