mirror of
https://github.com/tailscale/tailscale.git
synced 2025-05-07 16:16:54 +00:00
ipn, ipn/ipnserver: add support for serving in error-message-only mode
So Windows service failures can be propagated to the Windows UI client.
This commit is contained in:
parent
5280d039c4
commit
3984f9be2f
@ -33,15 +33,19 @@ type Options struct {
|
|||||||
// SocketPath, on unix systems, is the unix socket path to listen
|
// SocketPath, on unix systems, is the unix socket path to listen
|
||||||
// on for frontend connections.
|
// on for frontend connections.
|
||||||
SocketPath string
|
SocketPath string
|
||||||
|
|
||||||
// Port, on windows, is the localhost TCP port to listen on for
|
// Port, on windows, is the localhost TCP port to listen on for
|
||||||
// frontend connections.
|
// frontend connections.
|
||||||
Port int
|
Port int
|
||||||
|
|
||||||
// StatePath is the path to the stored agent state.
|
// StatePath is the path to the stored agent state.
|
||||||
StatePath string
|
StatePath string
|
||||||
|
|
||||||
// AutostartStateKey, if non-empty, immediately starts the agent
|
// AutostartStateKey, if non-empty, immediately starts the agent
|
||||||
// using the given StateKey. If empty, the agent stays idle and
|
// using the given StateKey. If empty, the agent stays idle and
|
||||||
// waits for a frontend to start it.
|
// waits for a frontend to start it.
|
||||||
AutostartStateKey ipn.StateKey
|
AutostartStateKey ipn.StateKey
|
||||||
|
|
||||||
// LegacyConfigPath optionally specifies the old-style relaynode
|
// LegacyConfigPath optionally specifies the old-style relaynode
|
||||||
// relay.conf location. If both LegacyConfigPath and
|
// relay.conf location. If both LegacyConfigPath and
|
||||||
// AutostartStateKey are specified and the requested state doesn't
|
// AutostartStateKey are specified and the requested state doesn't
|
||||||
@ -51,6 +55,7 @@ type Options struct {
|
|||||||
// TODO(danderson): remove some time after the transition to
|
// TODO(danderson): remove some time after the transition to
|
||||||
// tailscaled is done.
|
// tailscaled is done.
|
||||||
LegacyConfigPath string
|
LegacyConfigPath string
|
||||||
|
|
||||||
// SurviveDisconnects specifies how the server reacts to its
|
// SurviveDisconnects specifies how the server reacts to its
|
||||||
// frontend disconnecting. If true, the server keeps running on
|
// frontend disconnecting. If true, the server keeps running on
|
||||||
// its existing state, and accepts new frontend connections. If
|
// its existing state, and accepts new frontend connections. If
|
||||||
@ -60,6 +65,10 @@ type Options struct {
|
|||||||
// DebugMux, if non-nil, specifies an HTTP ServeMux in which
|
// DebugMux, if non-nil, specifies an HTTP ServeMux in which
|
||||||
// to register a debug handler.
|
// to register a debug handler.
|
||||||
DebugMux *http.ServeMux
|
DebugMux *http.ServeMux
|
||||||
|
|
||||||
|
// ErrorMessage, if not empty, signals that the server will exist
|
||||||
|
// only to relay the provided critical error message to the user.
|
||||||
|
ErrorMessage string
|
||||||
}
|
}
|
||||||
|
|
||||||
func pump(logf logger.Logf, ctx context.Context, bs *ipn.BackendServer, s net.Conn) {
|
func pump(logf logger.Logf, ctx context.Context, bs *ipn.BackendServer, s net.Conn) {
|
||||||
@ -79,9 +88,9 @@ func pump(logf logger.Logf, ctx context.Context, bs *ipn.BackendServer, s net.Co
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Run(rctx context.Context, logf logger.Logf, logid string, opts Options, e wgengine.Engine) (err error) {
|
func Run(rctx context.Context, logf logger.Logf, logid string, opts Options, e wgengine.Engine) error {
|
||||||
runDone := make(chan error, 1)
|
runDone := make(chan struct{})
|
||||||
defer func() { runDone <- err }()
|
defer close(runDone)
|
||||||
|
|
||||||
listen, _, err := safesocket.Listen(opts.SocketPath, uint16(opts.Port))
|
listen, _, err := safesocket.Listen(opts.SocketPath, uint16(opts.Port))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -98,6 +107,29 @@ func Run(rctx context.Context, logf logger.Logf, logid string, opts Options, e w
|
|||||||
}()
|
}()
|
||||||
logf("Listening on %v", listen.Addr())
|
logf("Listening on %v", listen.Addr())
|
||||||
|
|
||||||
|
bo := backoff.NewBackoff("ipnserver", logf)
|
||||||
|
|
||||||
|
if opts.ErrorMessage != "" {
|
||||||
|
for i := 1; rctx.Err() == nil; i++ {
|
||||||
|
s, err := listen.Accept()
|
||||||
|
if err != nil {
|
||||||
|
logf("%d: Accept: %v", i, err)
|
||||||
|
bo.BackOff(rctx, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
serverToClient := func(b []byte) {
|
||||||
|
ipn.WriteMsg(s, b)
|
||||||
|
}
|
||||||
|
go func() {
|
||||||
|
defer s.Close()
|
||||||
|
bs := ipn.NewBackendServer(logf, nil, serverToClient)
|
||||||
|
bs.SendErrorMessage(opts.ErrorMessage)
|
||||||
|
s.Read(make([]byte, 1))
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
return rctx.Err()
|
||||||
|
}
|
||||||
|
|
||||||
var store ipn.StateStore
|
var store ipn.StateStore
|
||||||
if opts.StatePath != "" {
|
if opts.StatePath != "" {
|
||||||
store, err = ipn.NewFileStore(opts.StatePath)
|
store, err = ipn.NewFileStore(opts.StatePath)
|
||||||
@ -164,8 +196,6 @@ func Run(rctx context.Context, logf logger.Logf, logid string, opts Options, e w
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bo := backoff.NewBackoff("ipnserver", logf)
|
|
||||||
|
|
||||||
for i := 1; rctx.Err() == nil; i++ {
|
for i := 1; rctx.Err() == nil; i++ {
|
||||||
s, err = listen.Accept()
|
s, err = listen.Accept()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -80,6 +80,10 @@ func (bs *BackendServer) send(n Notify) {
|
|||||||
bs.sendNotifyMsg(b)
|
bs.sendNotifyMsg(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (bs *BackendServer) SendErrorMessage(msg string) {
|
||||||
|
bs.send(Notify{ErrMessage: &msg})
|
||||||
|
}
|
||||||
|
|
||||||
// GotCommandMsg parses the incoming message b as a JSON Command and
|
// GotCommandMsg parses the incoming message b as a JSON Command and
|
||||||
// calls GotCommand with it.
|
// calls GotCommand with it.
|
||||||
func (bs *BackendServer) GotCommandMsg(b []byte) error {
|
func (bs *BackendServer) GotCommandMsg(b []byte) error {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user