mirror of
				https://github.com/yggdrasil-network/yggdrasil-go.git
				synced 2025-11-04 03:05:07 +03:00 
			
		
		
		
	Fix MTU issues with TAP adapters
This commit is contained in:
		
							parent
							
								
									d52fab8af6
								
							
						
					
					
						commit
						e44f64bea0
					
				
					 2 changed files with 31 additions and 7 deletions
				
			
		| 
						 | 
					@ -5,6 +5,7 @@ package yggdrasil
 | 
				
			||||||
import ethernet "github.com/songgao/packets/ethernet"
 | 
					import ethernet "github.com/songgao/packets/ethernet"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const IPv6_HEADER_LENGTH = 40
 | 
					const IPv6_HEADER_LENGTH = 40
 | 
				
			||||||
 | 
					const ETHER_HEADER_LENGTH = 14
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type tunInterface interface {
 | 
					type tunInterface interface {
 | 
				
			||||||
	IsTUN() bool
 | 
						IsTUN() bool
 | 
				
			||||||
| 
						 | 
					@ -40,13 +41,13 @@ func (tun *tunDevice) write() error {
 | 
				
			||||||
				ethernet.NotTagged,  // VLAN tagging
 | 
									ethernet.NotTagged,  // VLAN tagging
 | 
				
			||||||
				ethernet.IPv6,       // Ethertype
 | 
									ethernet.IPv6,       // Ethertype
 | 
				
			||||||
				len(data))           // Payload length
 | 
									len(data))           // Payload length
 | 
				
			||||||
			copy(frame[14:], data[:])
 | 
								copy(frame[ETHER_HEADER_LENGTH:], data[:])
 | 
				
			||||||
			if _, err := tun.iface.Write(frame); err != nil {
 | 
								if _, err := tun.iface.Write(frame); err != nil {
 | 
				
			||||||
				return err
 | 
									panic(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			if _, err := tun.iface.Write(data); err != nil {
 | 
								if _, err := tun.iface.Write(data); err != nil {
 | 
				
			||||||
				return err
 | 
									panic(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		util_putBytes(data)
 | 
							util_putBytes(data)
 | 
				
			||||||
| 
						 | 
					@ -54,15 +55,19 @@ func (tun *tunDevice) write() error {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (tun *tunDevice) read() 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 {
 | 
						for {
 | 
				
			||||||
		n, err := tun.iface.Read(buf)
 | 
							n, err := tun.iface.Read(buf)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return err
 | 
								panic(err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		o := 0
 | 
							o := 0
 | 
				
			||||||
		if tun.iface.IsTAP() {
 | 
							if tun.iface.IsTAP() {
 | 
				
			||||||
			o = 14
 | 
								o = ETHER_HEADER_LENGTH
 | 
				
			||||||
			b := make([]byte, n)
 | 
								b := make([]byte, n)
 | 
				
			||||||
			copy(b, buf)
 | 
								copy(b, buf)
 | 
				
			||||||
			tun.ndp.recv <- b
 | 
								tun.ndp.recv <- b
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -39,12 +39,31 @@ func (tun *tunDevice) setup(ifname string, addr string, mtu int) error {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	tun.iface = iface
 | 
						tun.iface = iface
 | 
				
			||||||
	tun.mtu = mtu
 | 
						tun.mtu = mtu
 | 
				
			||||||
 | 
						err = tun.setupMTU(tun.mtu)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							panic(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return tun.setupAddress(addr)
 | 
						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 {
 | 
					func (tun *tunDevice) setupAddress(addr string) error {
 | 
				
			||||||
	// Set address
 | 
						// Set address
 | 
				
			||||||
	// addr = strings.TrimRight(addr, "/8")
 | 
					 | 
				
			||||||
	cmd := exec.Command("netsh", "interface", "ipv6", "add", "address",
 | 
						cmd := exec.Command("netsh", "interface", "ipv6", "add", "address",
 | 
				
			||||||
		fmt.Sprintf("interface=%s", tun.iface.Name()),
 | 
							fmt.Sprintf("interface=%s", tun.iface.Name()),
 | 
				
			||||||
		fmt.Sprintf("addr=%s", addr),
 | 
							fmt.Sprintf("addr=%s", addr),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue