diff options
author | Mikael Magnusson <mikma@users.sourceforge.net> | 2021-02-03 20:39:58 +0100 |
---|---|---|
committer | Mikael Magnusson <mikma@users.sourceforge.net> | 2021-03-11 23:53:58 +0000 |
commit | 2b56e1ad72312930840f4fbef1532c3b815f460b (patch) | |
tree | 5e758f7253a6da2c7bed969f60f708e7c3d90b30 /tunnel | |
parent | 4d6c8340bcf0a6fc9026166f95f4a00b5b3c64cc (diff) |
WIP working ipv4/ipv6 forward
Diffstat (limited to 'tunnel')
-rw-r--r-- | tunnel/tools/libwg-go/api-android.go | 136 |
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() {} |