65 lines
1.5 KiB
Go
65 lines
1.5 KiB
Go
![]() |
// 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.
|
||
|
|
||
|
package main // import "tailscale.com/cmd/tailscaled"
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"log"
|
||
|
|
||
|
"golang.org/x/sys/windows"
|
||
|
"golang.org/x/sys/windows/svc"
|
||
|
"tailscale.com/ipn/ipnserver"
|
||
|
"tailscale.com/logpolicy"
|
||
|
)
|
||
|
|
||
|
const serviceName = "Tailscale IPN"
|
||
|
|
||
|
func isWindowsService() bool {
|
||
|
v, err := svc.IsWindowsService()
|
||
|
if err != nil {
|
||
|
log.Fatalf("svc.IsWindowsService failed: %v", err)
|
||
|
}
|
||
|
return v
|
||
|
}
|
||
|
|
||
|
func runWindowsService(pol *logpolicy.Policy) error {
|
||
|
return svc.Run(serviceName, &ipnService{Policy: pol})
|
||
|
}
|
||
|
|
||
|
type ipnService struct {
|
||
|
Policy *logpolicy.Policy
|
||
|
}
|
||
|
|
||
|
// Called by Windows to execute the windows service.
|
||
|
func (service *ipnService) Execute(args []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (bool, uint32) {
|
||
|
changes <- svc.Status{State: svc.StartPending}
|
||
|
|
||
|
ctx, cancel := context.WithCancel(context.Background())
|
||
|
doneCh := make(chan struct{})
|
||
|
go func() {
|
||
|
defer close(doneCh)
|
||
|
args := []string{"/subproc", service.Policy.PublicID.String()}
|
||
|
ipnserver.BabysitProc(ctx, args, log.Printf)
|
||
|
}()
|
||
|
|
||
|
changes <- svc.Status{State: svc.Running, Accepts: svc.AcceptStop}
|
||
|
|
||
|
for ctx.Err() == nil {
|
||
|
select {
|
||
|
case <-doneCh:
|
||
|
case cmd := <-r:
|
||
|
switch cmd.Cmd {
|
||
|
case svc.Stop:
|
||
|
cancel()
|
||
|
case svc.Interrogate:
|
||
|
changes <- cmd.CurrentStatus
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
changes <- svc.Status{State: svc.StopPending}
|
||
|
return false, windows.NO_ERROR
|
||
|
}
|