mirror of
				https://github.com/yggdrasil-network/yggdrasil-go.git
				synced 2025-11-04 03:05:07 +03:00 
			
		
		
		
	don't panic if we write to a closed tun device because tun.close() was called
This commit is contained in:
		
							parent
							
								
									1a1e0553aa
								
							
						
					
					
						commit
						d9f212dd39
					
				
					 1 changed files with 34 additions and 4 deletions
				
			
		| 
						 | 
					@ -5,6 +5,7 @@ package yggdrasil
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"bytes"
 | 
						"bytes"
 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
 | 
						"sync"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/songgao/packets/ethernet"
 | 
						"github.com/songgao/packets/ethernet"
 | 
				
			||||||
| 
						 | 
					@ -24,6 +25,8 @@ type tunAdapter struct {
 | 
				
			||||||
	icmpv6 icmpv6
 | 
						icmpv6 icmpv6
 | 
				
			||||||
	mtu    int
 | 
						mtu    int
 | 
				
			||||||
	iface  *water.Interface
 | 
						iface  *water.Interface
 | 
				
			||||||
 | 
						mutex  sync.RWMutex // Protects the below
 | 
				
			||||||
 | 
						isOpen bool
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Gets the maximum supported MTU for the platform based on the defaults in
 | 
					// Gets the maximum supported MTU for the platform based on the defaults in
 | 
				
			||||||
| 
						 | 
					@ -50,6 +53,9 @@ func (tun *tunAdapter) start(ifname string, iftapmode bool, addr string, mtu int
 | 
				
			||||||
	if err := tun.setup(ifname, iftapmode, addr, mtu); err != nil {
 | 
						if err := tun.setup(ifname, iftapmode, addr, mtu); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						tun.mutex.Lock()
 | 
				
			||||||
 | 
						tun.isOpen = true
 | 
				
			||||||
 | 
						tun.mutex.Unlock()
 | 
				
			||||||
	go func() { panic(tun.read()) }()
 | 
						go func() { panic(tun.read()) }()
 | 
				
			||||||
	go func() { panic(tun.write()) }()
 | 
						go func() { panic(tun.write()) }()
 | 
				
			||||||
	if iftapmode {
 | 
						if iftapmode {
 | 
				
			||||||
| 
						 | 
					@ -148,14 +154,28 @@ func (tun *tunAdapter) write() error {
 | 
				
			||||||
					len(data))            // Payload length
 | 
										len(data))            // Payload length
 | 
				
			||||||
				copy(frame[tun_ETHER_HEADER_LENGTH:], data[:])
 | 
									copy(frame[tun_ETHER_HEADER_LENGTH:], data[:])
 | 
				
			||||||
				if _, err := tun.iface.Write(frame); err != nil {
 | 
									if _, err := tun.iface.Write(frame); err != nil {
 | 
				
			||||||
 | 
										tun.mutex.RLock()
 | 
				
			||||||
 | 
										open := tun.isOpen
 | 
				
			||||||
 | 
										tun.mutex.RUnlock()
 | 
				
			||||||
 | 
										if !open {
 | 
				
			||||||
 | 
											return nil
 | 
				
			||||||
 | 
										} else {
 | 
				
			||||||
						panic(err)
 | 
											panic(err)
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			if _, err := tun.iface.Write(data); err != nil {
 | 
								if _, err := tun.iface.Write(data); err != nil {
 | 
				
			||||||
 | 
									tun.mutex.RLock()
 | 
				
			||||||
 | 
									open := tun.isOpen
 | 
				
			||||||
 | 
									tun.mutex.RUnlock()
 | 
				
			||||||
 | 
									if !open {
 | 
				
			||||||
 | 
										return nil
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
					panic(err)
 | 
										panic(err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		util.PutBytes(data)
 | 
							util.PutBytes(data)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -173,9 +193,16 @@ func (tun *tunAdapter) read() error {
 | 
				
			||||||
	for {
 | 
						for {
 | 
				
			||||||
		n, err := tun.iface.Read(buf)
 | 
							n, err := tun.iface.Read(buf)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
 | 
								tun.mutex.RLock()
 | 
				
			||||||
 | 
								open := tun.isOpen
 | 
				
			||||||
 | 
								tun.mutex.RUnlock()
 | 
				
			||||||
 | 
								if !open {
 | 
				
			||||||
 | 
									return nil
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
				// panic(err)
 | 
									// panic(err)
 | 
				
			||||||
				return err
 | 
									return err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		o := 0
 | 
							o := 0
 | 
				
			||||||
		if tun.iface.IsTAP() {
 | 
							if tun.iface.IsTAP() {
 | 
				
			||||||
			o = tun_ETHER_HEADER_LENGTH
 | 
								o = tun_ETHER_HEADER_LENGTH
 | 
				
			||||||
| 
						 | 
					@ -202,6 +229,9 @@ func (tun *tunAdapter) read() error {
 | 
				
			||||||
// process stops. Typically this operation will happen quickly, but on macOS
 | 
					// process stops. Typically this operation will happen quickly, but on macOS
 | 
				
			||||||
// it can block until a read operation is completed.
 | 
					// it can block until a read operation is completed.
 | 
				
			||||||
func (tun *tunAdapter) close() error {
 | 
					func (tun *tunAdapter) close() error {
 | 
				
			||||||
 | 
						tun.mutex.Lock()
 | 
				
			||||||
 | 
						tun.isOpen = false
 | 
				
			||||||
 | 
						tun.mutex.Unlock()
 | 
				
			||||||
	if tun.iface == nil {
 | 
						if tun.iface == nil {
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue