summaryrefslogtreecommitdiffhomepage
path: root/tunnel
diff options
context:
space:
mode:
authorMikael Magnusson <mikma@users.sourceforge.net>2021-02-03 20:39:58 +0100
committerMikael Magnusson <mikma@users.sourceforge.net>2021-03-11 23:53:58 +0000
commit2b56e1ad72312930840f4fbef1532c3b815f460b (patch)
tree5e758f7253a6da2c7bed969f60f708e7c3d90b30 /tunnel
parent4d6c8340bcf0a6fc9026166f95f4a00b5b3c64cc (diff)
WIP working ipv4/ipv6 forward
Diffstat (limited to 'tunnel')
-rw-r--r--tunnel/tools/libwg-go/api-android.go136
1 files changed, 105 insertions, 31 deletions
diff --git a/tunnel/tools/libwg-go/api-android.go b/tunnel/tools/libwg-go/api-android.go
index f90d7ef3..986bc177 100644
--- a/tunnel/tools/libwg-go/api-android.go
+++ b/tunnel/tools/libwg-go/api-android.go
@@ -18,6 +18,7 @@ import (
"os/signal"
"runtime"
"runtime/debug"
+ "sort"
"strings"
"unsafe"
@@ -27,10 +28,9 @@ import (
"github.com/insomniacslk/dhcp/iana"
"gvisor.dev/gvisor/pkg/tcpip"
+ "gvisor.dev/gvisor/pkg/tcpip/header"
"gvisor.dev/gvisor/pkg/tcpip/link/fdbased"
- "gvisor.dev/gvisor/pkg/tcpip/link/rawfile"
"gvisor.dev/gvisor/pkg/tcpip/link/sniffer"
- tunlink "gvisor.dev/gvisor/pkg/tcpip/link/tun"
"gvisor.dev/gvisor/pkg/tcpip/network/ipv4"
"gvisor.dev/gvisor/pkg/tcpip/network/ipv6"
"gvisor.dev/gvisor/pkg/tcpip/transport/tcp"
@@ -69,6 +69,8 @@ type TunnelHandle struct {
stack *stack.Stack
tnet *netstack.Net
logger *device.Logger
+ interfaceName string
+ tunFd int
}
var tunnelHandles map[int32]TunnelHandle
@@ -107,6 +109,9 @@ func wgTurnOn(interfaceName string, tunFd int32, settings string) int32 {
return -1
}
+ handle.interfaceName = interfaceName
+ handle.tunFd = int(tunFd)
+
name := "foobar"
logger.Verbosef("Attaching to interface %v", name)
device := device.NewDevice(tun, conn.NewStdNetBind(), logger)
@@ -275,6 +280,15 @@ func NewDHCPv4Query(flags uint32, modifiers ...dhcpv6.Modifier) (*dhcpv6.Message
return msg, nil
}
+func parseIP(s string) tcpip.Address {
+ addr := tcpip.Address(net.ParseIP(s))
+ ip4addr := addr.To4(); if ip4addr != "" {
+ return ip4addr
+ } else {
+ return addr
+ }
+}
+
func newTunnel(logger *device.Logger) (TunnelHandle, tun.Device, error) {
// TODO: Configurable local address
localAddresses := []net.IP{net.ParseIP("fe80::104")}
@@ -402,64 +416,124 @@ func (handle *TunnelHandle) startDHCPv6() {
}
ack := msgOpt.(*dhcpv6.OptDHCPv4Msg).Msg
+ handle.logger.Verbosef("DHCP done")
+
+ var nic tcpip.NICID = 2
+ handle.createNetTUNFromFD(nic)
+
// TODO: Close clients?
// client.Close()
handle.logger.Verbosef("doClient end %v %v", ack.YourIPAddr, ack.SubnetMask())
- if ip4 := ack.YourIPAddr.To4(); ip4 == nil {
- handle.logger.Errorf("Not IPv4! %v", ack.YourIPAddr)
- return
+ if ip4 := ack.YourIPAddr.To4(); ip4 != nil {
+ handle.logger.Errorf("IPv4! %v", ack.YourIPAddr)
+
+ addr := tcpip.Address(ack.YourIPAddr)
+ subnet, err := tcpip.NewSubnet(
+ addr,
+ tcpip.AddressMask(parseIP("255.255.255.255")))
+ if err != nil {
+ handle.logger.Errorf("NewSubnet: %v", err)
+ return
+ }
+
+ // The TUN interface need a link address for some reason
+ linkAddr := tcpip.Address(parseIP("169.254.0.1"))
+ tcperr := handle.stack.AddAddress(nic, ipv4.ProtocolNumber, linkAddr)
+ if tcperr != nil {
+ handle.logger.Errorf("AddAddress: %v", tcperr)
+ return
+ }
+
+ handle.stack.AddRoute(tcpip.Route{
+ Destination: subnet,
+ NIC: nic,
+ })
+ handle.stack.AddRoute(tcpip.Route{
+ Destination: header.IPv4EmptySubnet,
+ NIC: 1,
+ })
}
// tcperr := tnet.AddAddress(ack.YourIPAddr); if tcperr != nil {
// log.Fatal(tcperr)
// }
+ // Maybe
+ // The TUN interface need a link address for some reason
+ linkAddr := tcpip.Address(parseIP("fe80::104"))
+ tcperr := handle.stack.AddAddress(nic, ipv6.ProtocolNumber, linkAddr)
+ if tcperr != nil {
+ handle.logger.Errorf("AddAddress: %v", tcperr)
+ return
+ }
+
+ handle.stack.AddRoute(tcpip.Route{
+ Destination: header.IPv6EmptySubnet,
+ NIC: 1,
+ })
+
iana := msg.GetOneOption(dhcpv6.OptionIANA).(*dhcpv6.OptIANA)
for _, addr := range iana.Options.Get(dhcpv6.OptionIAAddr) {
ip := addr.(*dhcpv6.OptIAAddress).IPv6Addr
str := ip.String() + "/128"
handle.logger.Verbosef("Addr %v", str)
- // err := tnet.AddAddress(ip); if err != nil {
- // log.Fatal(err)
- // }
+ addr := tcpip.Address(ip)
+ subnet, err := tcpip.NewSubnet(
+ addr,
+ tcpip.AddressMask(parseIP("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")))
+ if err != nil {
+ handle.logger.Errorf("NewSubnet: %v", err)
+ return
+ }
+
+ handle.stack.AddRoute(tcpip.Route{
+ Destination: subnet,
+ NIC: nic,
+ })
}
- handle.logger.Verbosef("DHCP done")
-}
+ // Sort route table for longest prefix match
+ routes := handle.stack.GetRouteTable()
+ sort.Slice(routes, func(i, j int) bool {
+ return routes[i].Destination.Prefix() > routes[j].Destination.Prefix()
+ })
+ handle.stack.SetRouteTable(routes)
-func (handle *TunnelHandle) newTun(id tcpip.NICID, tunName string) {
- mtu, err := rawfile.GetMTU(tunName)
- if err != nil {
- handle.logger.Errorf("GetMTU: %v", err)
- return
- }
+ handle.stack.SetForwarding(ipv4.ProtocolNumber, true)
+ handle.stack.SetForwarding(ipv6.ProtocolNumber, true)
+ handle.logger.Verbosef("DHCP addresses set up")
+ // TODO update WireGuard settings
+}
- fd, err := tunlink.Open(tunName)
+func (handle *TunnelHandle) newTun(nic tcpip.NICID) error {
+ err := unix.SetNonblock(handle.tunFd, true)
if err != nil {
- handle.logger.Errorf("Open: %v", err)
- return
+ return err
}
- linkEP, err := fdbased.New(&fdbased.Options{FDs: []int{fd}, MTU: mtu})
+ var mtu uint32 = 1420
+ linkEP, err := fdbased.New(&fdbased.Options{FDs: []int{handle.tunFd}, MTU: mtu})
if err != nil {
handle.logger.Errorf("fdbased.New: %v", err)
- return
+ return err
}
- if err := handle.stack.CreateNIC(id, sniffer.New(linkEP)); err != nil {
+
+ if err := handle.stack.CreateNIC(nic, sniffer.New(linkEP)); err != nil {
handle.logger.Errorf("CreateNIC: %v", err)
- return
+ // TODO: Return error
+ return nil
}
+
+ return nil
}
-func (handle *TunnelHandle) createNetTUNFromFD(tunFd int) {
- // newTun(2, "tun0")
- // tun, name, err := handle.createNetTUNFromFD(int(tunFd))
- // if err != nil {
- // unix.Close(int(tunFd))
- // logger.Errorf("createNetTUNFromFD: %v", err)
- // return -1
- // }
+func (handle *TunnelHandle) createNetTUNFromFD(nic tcpip.NICID) {
+ err := handle.newTun(nic)
+ if err != nil {
+ handle.logger.Errorf("newTun: %v", err)
+ return
+ }
}
func main() {}