// NativeTun is a hack to work around the first 4 bytes "packet
// information" because there doesn't seem to be an IFF_NO_PI for darwin.
type NativeTun struct {
- name string
- fd *os.File
- rwcancel *rwcancel.RWCancel
- mtu int
-
- events chan TUNEvent
- errors chan error
+ name string
+ fd *os.File
+ rwcancel *rwcancel.RWCancel
+ mtu int
+ events chan TUNEvent
+ errors chan error
+ statusListenersShutdown chan struct{}
}
var sockaddrCtlSize uintptr = 32
func CreateTUNFromFile(file *os.File) (TUNDevice, error) {
tun := &NativeTun{
- fd: file,
- mtu: 1500,
- events: make(chan TUNEvent, 10),
- errors: make(chan error, 1),
+ fd: file,
+ mtu: 1500,
+ events: make(chan TUNEvent, 10),
+ errors: make(chan error, 1),
+ statusListenersShutdown: make(chan struct{}, 0),
}
_, err := tun.Name()
statusMTU int
)
- for ; ; time.Sleep(time.Second) {
+ for {
intr, err := net.InterfaceByName(tun.name)
if err != nil {
tun.errors <- err
tun.events <- TUNEventMTUUpdate
}
statusMTU = intr.MTU
+
+ select {
+ case <-time.After(time.Second / 10):
+ case <-tun.statusListenersShutdown:
+ return
+ }
}
}(tun)
}
func (tun *NativeTun) Close() error {
+ close(tun.statusListenersShutdown)
err1 := tun.rwcancel.Cancel()
err2 := tun.fd.Close()
close(tun.events)