wgengine/monitor: add a darwin implementation for tailscaled mode

Tangentially related to #987, #177, #594, #925, #505

Motivated by rebooting a launchd-controlled tailscaled and it going
into SetNetworkUp(false) mode immediately because there really is no
network up at system boot, but then it got stuck in that paused state
forever, without a monitor implementation.
This commit is contained in:
Brad Fitzpatrick 2021-02-13 21:06:27 -08:00
parent 29b028b9c4
commit 4f7d60ad42
2 changed files with 66 additions and 1 deletions

View File

@ -0,0 +1,65 @@
// Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin,!redo
package monitor
import (
"bufio"
"os/exec"
"tailscale.com/types/logger"
)
// unspecifiedMessage is a minimal message implementation that should not
// be ignored. In general, OS-specific implementations should use better
// types and avoid this if they can.
type unspecifiedMessage struct{}
func (unspecifiedMessage) ignore() bool { return false }
func newOSMon(logf logger.Logf) (osMon, error) {
return new(routeMonitorSubProcMon), nil
}
// routeMonitorSubProcMon is a very simple (temporary? but I know
// better) monitor implementation for darwin in tailscaled-mode where
// we can just shell out to "route -n monitor". It waits for any input
// but doesn't parse it. Then we poll to see if something is different.
type routeMonitorSubProcMon struct {
cmd *exec.Cmd // of "/sbin/route -n monitor"
br *bufio.Reader
buf []byte
}
func (m *routeMonitorSubProcMon) Close() error {
if m.cmd != nil {
m.cmd.Process.Kill()
m.cmd = nil
}
return nil
}
func (m *routeMonitorSubProcMon) Receive() (message, error) {
if m.cmd == nil {
cmd := exec.Command("/sbin/route", "-n", "monitor")
outPipe, err := cmd.StdoutPipe()
if err != nil {
return nil, err
}
if err := cmd.Start(); err != nil {
return nil, err
}
m.br = bufio.NewReader(outPipe)
m.cmd = cmd
m.buf = make([]byte, 16<<10)
}
_, err := m.br.Read(m.buf)
if err != nil {
m.Close()
return nil, err
}
return unspecifiedMessage{}, nil
}

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !linux,!freebsd,!windows android
// +build !linux,!freebsd,!windows,!darwin android darwin,redo
package monitor