use syscall.Open with O_NONBLOCK flag and os.NewFile after ioctls

so that the file is pollable.
This commit is contained in:
Song Gao 2019-01-06 20:50:07 +00:00
parent ab2cda57af
commit 5d0ec8c62b
2 changed files with 11 additions and 9 deletions

View file

@ -88,7 +88,7 @@ func TestCloseUnblockPendingRead(t *testing.T) {
close(c) close(c)
}() }()
// make sure ifce.Close() happens after ifce.Read() // make sure ifce.Close() happens after ifce.Read() blocks
time.Sleep(1 * time.Second) time.Sleep(1 * time.Second)
ifce.Close() ifce.Close()

View file

@ -31,50 +31,52 @@ func ioctl(fd uintptr, request uintptr, argp uintptr) error {
} }
func newTAP(config Config) (ifce *Interface, err error) { func newTAP(config Config) (ifce *Interface, err error) {
file, err := os.OpenFile("/dev/net/tun", os.O_RDWR, 0) fdInt, err := syscall.Open("/dev/net/tun", os.O_RDWR|syscall.O_NONBLOCK, 0)
if err != nil { if err != nil {
return nil, err return nil, err
} }
fd := uintptr(fdInt)
var flags uint16 var flags uint16
flags = cIFFTAP | cIFFNOPI flags = cIFFTAP | cIFFNOPI
if config.PlatformSpecificParams.MultiQueue { if config.PlatformSpecificParams.MultiQueue {
flags |= cIFFMULTIQUEUE flags |= cIFFMULTIQUEUE
} }
name, err := createInterface(file.Fd(), config.Name, flags) name, err := createInterface(fd, config.Name, flags)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if err = setDeviceOptions(file.Fd(), config); err != nil { if err = setDeviceOptions(fd, config); err != nil {
return nil, err return nil, err
} }
ifce = &Interface{isTAP: true, ReadWriteCloser: file, name: name} ifce = &Interface{isTAP: true, ReadWriteCloser: os.NewFile(fd, "tun"), name: name}
return return
} }
func newTUN(config Config) (ifce *Interface, err error) { func newTUN(config Config) (ifce *Interface, err error) {
file, err := os.OpenFile("/dev/net/tun", os.O_RDWR, 0) fdInt, err := syscall.Open("/dev/net/tun", os.O_RDWR|syscall.O_NONBLOCK, 0)
if err != nil { if err != nil {
return nil, err return nil, err
} }
fd := uintptr(fdInt)
var flags uint16 var flags uint16
flags = cIFFTUN | cIFFNOPI flags = cIFFTUN | cIFFNOPI
if config.PlatformSpecificParams.MultiQueue { if config.PlatformSpecificParams.MultiQueue {
flags |= cIFFMULTIQUEUE flags |= cIFFMULTIQUEUE
} }
name, err := createInterface(file.Fd(), config.Name, flags) name, err := createInterface(fd, config.Name, flags)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if err = setDeviceOptions(file.Fd(), config); err != nil { if err = setDeviceOptions(fd, config); err != nil {
return nil, err return nil, err
} }
ifce = &Interface{isTAP: false, ReadWriteCloser: file, name: name} ifce = &Interface{isTAP: false, ReadWriteCloser: os.NewFile(fd, "tun"), name: name}
return return
} }