mudler 3 years ago
parent
commit
eb0be3a83e
4 changed files with 64 additions and 19 deletions
  1. 1 0
      go.mod
  2. 6 0
      go.sum
  3. 34 8
      pkg/vpn/interface.go
  4. 23 11
      pkg/vpn/vpn.go

+ 1 - 0
go.mod

@@ -42,5 +42,6 @@ require (
 	github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect
 	github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect
 	github.com/xlzd/gotp v0.0.0-20220110052318-fab697c03c2c
 	github.com/xlzd/gotp v0.0.0-20220110052318-fab697c03c2c
 	golang.org/x/net v0.0.0-20220418201149-a630d4f3e7a2
 	golang.org/x/net v0.0.0-20220418201149-a630d4f3e7a2
+	golang.zx2c4.com/wireguard v0.0.0-20220407013110-ef5c587f782d // indirect
 	gopkg.in/yaml.v2 v2.4.0
 	gopkg.in/yaml.v2 v2.4.0
 )
 )

+ 6 - 0
go.sum

@@ -1287,6 +1287,7 @@ golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm
 golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
 golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
 golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
 golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 h1:kUhD7nTDoI3fVd9G4ORWrbV5NY0liEs/Jg2pv5f+bBA=
 golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 h1:kUhD7nTDoI3fVd9G4ORWrbV5NY0liEs/Jg2pv5f+bBA=
 golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
 golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -1489,6 +1490,7 @@ golang.org/x/sys v0.0.0-20211031064116-611d5d643895/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0=
 golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0=
 golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
 golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
@@ -1575,6 +1577,10 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f h1:GGU+dLjvlC3qDwqYgL6UgRmHXhOOgns0bZu2Ty5mm6U=
 golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f h1:GGU+dLjvlC3qDwqYgL6UgRmHXhOOgns0bZu2Ty5mm6U=
 golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 h1:Ug9qvr1myri/zFN6xL17LSCBGFDnphBBhzmILHsM5TY=
+golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
+golang.zx2c4.com/wireguard v0.0.0-20220407013110-ef5c587f782d h1:q4JksJ2n0fmbXC0Aj0eOs6E0AcPqnKglxWXWFqGD6x0=
+golang.zx2c4.com/wireguard v0.0.0-20220407013110-ef5c587f782d/go.mod h1:bVQfyl2sCM/QIIGHpWbFGfHPuDvqnCNkT6MQLTCjO/U=
 google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
 google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
 google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
 google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
 google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y=
 google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y=

+ 34 - 8
pkg/vpn/interface.go

@@ -19,27 +19,48 @@
 package vpn
 package vpn
 
 
 import (
 import (
-	"github.com/songgao/water"
+	"fmt"
+	"io"
+
 	"github.com/vishvananda/netlink"
 	"github.com/vishvananda/netlink"
+	"golang.zx2c4.com/wireguard/tun"
 )
 )
 
 
-func createInterface(c *Config) (*water.Interface, error) {
-	config := water.Config{
-		DeviceType:             c.DeviceType,
-		PlatformSpecificParams: water.PlatformSpecificParams{Persist: !c.NetLinkBootstrap},
-	}
-	config.Name = c.InterfaceName
+type tunWriter struct {
+	tun.Device
+	offset int
+}
+
+func newtunWriter(t tun.Device, offset int) io.WriteCloser {
+	return tunWriter{Device: t, offset: offset}
+}
+
+func (t tunWriter) Write(b []byte) (int, error) {
+	return t.Device.Write(b, t.offset)
+}
 
 
-	return water.New(config)
+func createInterface(c *Config) (tun.Device, error) {
+	ifname := c.InterfaceName
+	if ifname == "auto" {
+		ifname = "\000"
+	}
+	return tun.CreateTUN(ifname, c.InterfaceMTU)
 }
 }
 
 
 func prepareInterface(c *Config) error {
 func prepareInterface(c *Config) error {
+	fmt.Println("Preparing interface")
+
 	link, err := netlink.LinkByName(c.InterfaceName)
 	link, err := netlink.LinkByName(c.InterfaceName)
 	if err != nil {
 	if err != nil {
+		fmt.Println("link", err)
+
 		return err
 		return err
 	}
 	}
+
 	addr, err := netlink.ParseAddr(c.InterfaceAddress)
 	addr, err := netlink.ParseAddr(c.InterfaceAddress)
 	if err != nil {
 	if err != nil {
+		fmt.Println("parse addr", err)
+
 		return err
 		return err
 	}
 	}
 
 
@@ -48,8 +69,11 @@ func prepareInterface(c *Config) error {
 		return err
 		return err
 	}
 	}
 
 
+	fmt.Println(addr)
 	err = netlink.AddrAdd(link, addr)
 	err = netlink.AddrAdd(link, addr)
 	if err != nil {
 	if err != nil {
+		fmt.Println("add addr", err)
+
 		return err
 		return err
 	}
 	}
 
 
@@ -57,5 +81,7 @@ func prepareInterface(c *Config) error {
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
+	fmt.Println("done Preparing interface")
+
 	return nil
 	return nil
 }
 }

+ 23 - 11
pkg/vpn/vpn.go

@@ -28,6 +28,7 @@ import (
 	"github.com/ipfs/go-log"
 	"github.com/ipfs/go-log"
 	"github.com/libp2p/go-libp2p-core/network"
 	"github.com/libp2p/go-libp2p-core/network"
 	"github.com/libp2p/go-libp2p-core/peer"
 	"github.com/libp2p/go-libp2p-core/peer"
+	"golang.zx2c4.com/wireguard/tun"
 
 
 	"github.com/mudler/edgevpn/internal"
 	"github.com/mudler/edgevpn/internal"
 	"github.com/mudler/edgevpn/pkg/blockchain"
 	"github.com/mudler/edgevpn/pkg/blockchain"
@@ -39,8 +40,8 @@ import (
 
 
 	"github.com/pkg/errors"
 	"github.com/pkg/errors"
 	"github.com/songgao/packets/ethernet"
 	"github.com/songgao/packets/ethernet"
-	"github.com/songgao/water"
 	"golang.org/x/net/ipv4"
 	"golang.org/x/net/ipv4"
+	"golang.org/x/net/ipv6"
 )
 )
 
 
 type streamManager interface {
 type streamManager interface {
@@ -128,7 +129,7 @@ func Register(p ...Option) ([]node.Option, error) {
 	return []node.Option{node.WithNetworkService(VPNNetworkService(p...))}, nil
 	return []node.Option{node.WithNetworkService(VPNNetworkService(p...))}, nil
 }
 }
 
 
-func streamHandler(l *blockchain.Ledger, ifce *water.Interface, c *Config) func(stream network.Stream) {
+func streamHandler(l *blockchain.Ledger, ifce tun.Device, c *Config) func(stream network.Stream) {
 	return func(stream network.Stream) {
 	return func(stream network.Stream) {
 		if !l.Exists(protocol.MachinesLedgerKey,
 		if !l.Exists(protocol.MachinesLedgerKey,
 			func(d blockchain.Data) bool {
 			func(d blockchain.Data) bool {
@@ -139,7 +140,8 @@ func streamHandler(l *blockchain.Ledger, ifce *water.Interface, c *Config) func(
 			stream.Reset()
 			stream.Reset()
 			return
 			return
 		}
 		}
-		_, err := io.Copy(ifce.ReadWriteCloser, stream)
+
+		_, err := io.Copy(newtunWriter(ifce, TUN_OFFSET_BYTES), stream)
 		if err != nil {
 		if err != nil {
 			stream.Reset()
 			stream.Reset()
 		}
 		}
@@ -162,12 +164,15 @@ func newBlockChainData(n *node.Node, address string) types.Machine {
 	}
 	}
 }
 }
 
 
-func getFrame(ifce *water.Interface, c *Config) (ethernet.Frame, error) {
+const TUN_OFFSET_BYTES = 4
+
+func getFrame(ifce tun.Device, c *Config) (ethernet.Frame, error) {
 	var frame ethernet.Frame
 	var frame ethernet.Frame
 	frame.Resize(c.MTU)
 	frame.Resize(c.MTU)
 
 
-	n, err := ifce.Read([]byte(frame))
-	if err != nil {
+	n, err := ifce.Read([]byte(frame), TUN_OFFSET_BYTES)
+	if n <= TUN_OFFSET_BYTES || err != nil {
+		ifce.Flush()
 		return frame, errors.Wrap(err, "could not read from interface")
 		return frame, errors.Wrap(err, "could not read from interface")
 	}
 	}
 
 
@@ -175,16 +180,23 @@ func getFrame(ifce *water.Interface, c *Config) (ethernet.Frame, error) {
 	return frame, nil
 	return frame, nil
 }
 }
 
 
-func handleFrame(mgr streamManager, frame ethernet.Frame, c *Config, n *node.Node, ip net.IP, ledger *blockchain.Ledger, ifce *water.Interface) error {
+func handleFrame(mgr streamManager, frame ethernet.Frame, c *Config, n *node.Node, ip net.IP, ledger *blockchain.Ledger, ifce tun.Device) error {
 	ctx, cancel := context.WithTimeout(context.Background(), c.Timeout)
 	ctx, cancel := context.WithTimeout(context.Background(), c.Timeout)
 	defer cancel()
 	defer cancel()
 
 
+	var dst string
+
 	header, err := ipv4.ParseHeader(frame)
 	header, err := ipv4.ParseHeader(frame)
 	if err != nil {
 	if err != nil {
-		return errors.Wrap(err, "could not parse ipv4 header from frame")
+		header, err2 := ipv6.ParseHeader(frame)
+		if err2 != nil {
+			return errors.Wrap(errors.Wrap(err, err2.Error()), "could not parse ipv4 and ipv6 header from frame")
+		}
+		dst = header.Dst.String()
+	} else {
+		dst = header.Dst.String()
 	}
 	}
 
 
-	dst := header.Dst.String()
 	if c.RouterAddress != "" && header.Src.Equal(ip) {
 	if c.RouterAddress != "" && header.Src.Equal(ip) {
 		dst = c.RouterAddress
 		dst = c.RouterAddress
 	}
 	}
@@ -240,7 +252,7 @@ func connectionWorker(
 	ip net.IP,
 	ip net.IP,
 	wg *sync.WaitGroup,
 	wg *sync.WaitGroup,
 	ledger *blockchain.Ledger,
 	ledger *blockchain.Ledger,
-	ifce *water.Interface) {
+	ifce tun.Device) {
 	defer wg.Done()
 	defer wg.Done()
 	for f := range p {
 	for f := range p {
 		if err := handleFrame(mgr, f, c, n, ip, ledger, ifce); err != nil {
 		if err := handleFrame(mgr, f, c, n, ip, ledger, ifce); err != nil {
@@ -250,7 +262,7 @@ func connectionWorker(
 }
 }
 
 
 // redirects packets from the interface to the node using the routing table in the blockchain
 // redirects packets from the interface to the node using the routing table in the blockchain
-func readPackets(ctx context.Context, mgr streamManager, c *Config, n *node.Node, ledger *blockchain.Ledger, ifce *water.Interface) error {
+func readPackets(ctx context.Context, mgr streamManager, c *Config, n *node.Node, ledger *blockchain.Ledger, ifce tun.Device) error {
 	ip, _, err := net.ParseCIDR(c.InterfaceAddress)
 	ip, _, err := net.ParseCIDR(c.InterfaceAddress)
 	if err != nil {
 	if err != nil {
 		return err
 		return err