diff options
Diffstat (limited to 'tunnel')
-rw-r--r-- | tunnel/src/main/java/com/wireguard/android/backend/GoBackend.java | 14 | ||||
-rw-r--r-- | tunnel/src/main/java/com/wireguard/util/Resolver.java | 2 | ||||
-rw-r--r-- | tunnel/src/main/proto/libwg.proto | 2 | ||||
-rw-r--r-- | tunnel/tools/libwg-go/dhcp.go | 12 | ||||
-rw-r--r-- | tunnel/tools/libwg-go/service.go | 48 |
5 files changed, 65 insertions, 13 deletions
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 32e3572a..1d900db0 100644 --- a/tunnel/src/main/java/com/wireguard/android/backend/GoBackend.java +++ b/tunnel/src/main/java/com/wireguard/android/backend/GoBackend.java @@ -384,8 +384,20 @@ public final class GoBackend implements Backend { private void Dhcp(VpnService service) throws Exception{ obtainDhcpLease = false; + // Heuristics: Use first ULA address as client address + com.wireguard.android.backend.gen.InetAddress source = null; + + for (final InetNetwork net : currentConfig.getInterface().getAddresses()) { + InetAddress addr = net.getAddress(); + if (addr instanceof Inet6Address) { + if (Resolver.isULA((Inet6Address)addr)) { + source = com.wireguard.android.backend.gen.InetAddress.newBuilder().setAddress(ByteString.copyFrom(addr.getAddress())).build(); + } + } + } + LibwgGrpc.LibwgBlockingStub stub = LibwgGrpc.newBlockingStub(channel); - DhcpRequest request = DhcpRequest.newBuilder().build(); + DhcpRequest request = DhcpRequest.newBuilder().setSource(source).build(); DhcpResponse resp = stub.dhcp(request); Log.i(TAG, "Dhcp: " + resp.getError().getMessage()); diff --git a/tunnel/src/main/java/com/wireguard/util/Resolver.java b/tunnel/src/main/java/com/wireguard/util/Resolver.java index f401b584..301e03e0 100644 --- a/tunnel/src/main/java/com/wireguard/util/Resolver.java +++ b/tunnel/src/main/java/com/wireguard/util/Resolver.java @@ -36,7 +36,7 @@ public class Resolver { } } - static boolean isULA(Inet6Address addr) { + public static boolean isULA(Inet6Address addr) { byte[] raw = addr.getAddress(); return ((raw[0] & 0xfe) == 0xfc); } diff --git a/tunnel/src/main/proto/libwg.proto b/tunnel/src/main/proto/libwg.proto index 349166ca..4fa4468b 100644 --- a/tunnel/src/main/proto/libwg.proto +++ b/tunnel/src/main/proto/libwg.proto @@ -115,6 +115,8 @@ message Lease { } message DhcpRequest { + InetAddress relay = 1; + InetAddress source = 2; } message DhcpResponse { diff --git a/tunnel/tools/libwg-go/dhcp.go b/tunnel/tools/libwg-go/dhcp.go index 83a8c865..f6f25739 100644 --- a/tunnel/tools/libwg-go/dhcp.go +++ b/tunnel/tools/libwg-go/dhcp.go @@ -85,7 +85,7 @@ func isRelayMessageType(t dhcpv6.MessageType, tt ...dhcpv6.MessageType) nclient6 // func New() *dhcp { // } -func RunDhcp(ctx context.Context) ([]*gen.Lease, error) { +func RunDhcp(ctx context.Context, laddr, raddr netip.Addr) ([]*gen.Lease, error) { d := &dhcp{} d.linkAddr = net.ParseIP("fe80::101") @@ -95,25 +95,17 @@ func RunDhcp(ctx context.Context) ([]*gen.Lease, error) { d.fqdn = hostName + ".m7n.se" d.hwAddr = []byte{41, 42, 43, 44, 45, 46} - laddr, err := netip.ParseAddr("fd1c:a56b:a0d7:1260::101") - if err != nil { - return nil, err - } src := net.UDPAddr{IP: laddr.AsSlice(), Port: 0, // Use non-restrict UDP source port } - raddr, err := netip.ParseAddr("fd1c:a56b:a0d7:1260::1") - if err != nil { - return nil, err - } d.serverAddr = net.UDPAddr{IP: raddr.AsSlice(), Port: 547, } - err = d.Start(&src) + err := d.Start(&src) if err != nil { return nil, err } diff --git a/tunnel/tools/libwg-go/service.go b/tunnel/tools/libwg-go/service.go index 2c688e26..38601f14 100644 --- a/tunnel/tools/libwg-go/service.go +++ b/tunnel/tools/libwg-go/service.go @@ -5,6 +5,7 @@ import ( "fmt" "io" "net" + "net/netip" // "net/url" "os" @@ -256,7 +257,52 @@ func (e *LibwgServiceImpl) IpcSet(ctx context.Context, req *gen.IpcSetRequest) ( } func (e *LibwgServiceImpl) Dhcp(ctx context.Context, req *gen.DhcpRequest) (*gen.DhcpResponse, error) { - leases, err := RunDhcp(ctx) + var relayAddr netip.Addr + var sourceAddr netip.Addr + + source := req.GetSource() + if source != nil { + sourceAddr, _ = netip.AddrFromSlice(source.GetAddress()) + } + + if !sourceAddr.IsValid() || !sourceAddr.Is6() { + r := &gen.DhcpResponse{ + Error: &gen.Error{ + Message: fmt.Sprintf("DHCPv6 source address missing"), + }, + } + return r, nil + } + + relay := req.GetRelay() + if relay != nil { + relayAddr, _ = netip.AddrFromSlice(relay.GetAddress()) + } else { + // Construct relay address from source prefix + relayRaw := source.GetAddress()[:8] + relayRaw = append(relayRaw, 0) + relayRaw = append(relayRaw, 0) + relayRaw = append(relayRaw, 0) + relayRaw = append(relayRaw, 0) + relayRaw = append(relayRaw, 0) + relayRaw = append(relayRaw, 0) + relayRaw = append(relayRaw, 0) + relayRaw = append(relayRaw, 1) + relayAddr, _ = netip.AddrFromSlice(relayRaw) + } + + if !relayAddr.IsValid() || !relayAddr.Is6() { + r := &gen.DhcpResponse{ + Error: &gen.Error{ + Message: fmt.Sprintf("DHCPv6 relay address calculation failed"), + }, + } + return r, nil + } + + e.logger.Verbosef("RunDhcp %v %v", sourceAddr, relayAddr) + + leases, err := RunDhcp(ctx, sourceAddr, relayAddr) if err != nil { r := &gen.DhcpResponse{ Error: &gen.Error{ |