From e44f64bea0901b551658e512be953a21c01fb364 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Thu, 25 Jan 2018 17:44:56 +0000 Subject: [PATCH] Fix MTU issues with TAP adapters --- src/yggdrasil/tun.go | 17 +++++++++++------ src/yggdrasil/tun_windows.go | 21 ++++++++++++++++++++- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/yggdrasil/tun.go b/src/yggdrasil/tun.go index d23ced7..871fb3c 100644 --- a/src/yggdrasil/tun.go +++ b/src/yggdrasil/tun.go @@ -5,6 +5,7 @@ package yggdrasil import ethernet "github.com/songgao/packets/ethernet" const IPv6_HEADER_LENGTH = 40 +const ETHER_HEADER_LENGTH = 14 type tunInterface interface { IsTUN() bool @@ -40,13 +41,13 @@ func (tun *tunDevice) write() error { ethernet.NotTagged, // VLAN tagging ethernet.IPv6, // Ethertype len(data)) // Payload length - copy(frame[14:], data[:]) + copy(frame[ETHER_HEADER_LENGTH:], data[:]) if _, err := tun.iface.Write(frame); err != nil { - return err + panic(err) } } else { if _, err := tun.iface.Write(data); err != nil { - return err + panic(err) } } util_putBytes(data) @@ -54,15 +55,19 @@ func (tun *tunDevice) write() error { } func (tun *tunDevice) read() error { - buf := make([]byte, tun.mtu) + mtu := tun.mtu + if tun.iface.IsTAP() { + mtu += ETHER_HEADER_LENGTH + } + buf := make([]byte, mtu) for { n, err := tun.iface.Read(buf) if err != nil { - return err + panic(err) } o := 0 if tun.iface.IsTAP() { - o = 14 + o = ETHER_HEADER_LENGTH b := make([]byte, n) copy(b, buf) tun.ndp.recv <- b diff --git a/src/yggdrasil/tun_windows.go b/src/yggdrasil/tun_windows.go index 005806c..b790622 100644 --- a/src/yggdrasil/tun_windows.go +++ b/src/yggdrasil/tun_windows.go @@ -39,12 +39,31 @@ func (tun *tunDevice) setup(ifname string, addr string, mtu int) error { } tun.iface = iface tun.mtu = mtu + err = tun.setupMTU(tun.mtu) + if err != nil { + panic(err) + } return tun.setupAddress(addr) } +func (tun *tunDevice) setupMTU(mtu int) error { + // Set MTU + cmd := exec.Command("netsh", "interface", "ipv6", "set", "subinterface", + fmt.Sprintf("interface=%s", tun.iface.Name()), + fmt.Sprintf("mtu=%d", mtu), + "store=active") + tun.core.log.Printf("netsh command: %v", strings.Join(cmd.Args, " ")) + output, err := cmd.CombinedOutput() + if err != nil { + tun.core.log.Printf("Windows netsh failed: %v.", err) + tun.core.log.Println(string(output)) + return err + } + return nil +} + func (tun *tunDevice) setupAddress(addr string) error { // Set address - // addr = strings.TrimRight(addr, "/8") cmd := exec.Command("netsh", "interface", "ipv6", "add", "address", fmt.Sprintf("interface=%s", tun.iface.Name()), fmt.Sprintf("addr=%s", addr),