mirror of
				https://github.com/tailscale/tailscale.git
				synced 2025-10-31 13:05:22 +00:00 
			
		
		
		
	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:
		
							
								
								
									
										65
									
								
								wgengine/monitor/monitor_darwin_tailscaled.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								wgengine/monitor/monitor_darwin_tailscaled.go
									
									
									
									
									
										Normal 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 | ||||
| } | ||||
| @@ -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 | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Brad Fitzpatrick
					Brad Fitzpatrick