From ae374c0463ea5b1fcc068ac19f7a49fa38acedd3 Mon Sep 17 00:00:00 2001 From: Areg Harutyunyan Date: Fri, 27 Mar 2020 14:39:59 +0000 Subject: [PATCH] TUN-2846: Trigger debug reconnects from stdin commands, not SIGUSR1 --- cmd/cloudflared/tunnel/cmd.go | 34 +++++++++++++++++++++++++++++----- origin/supervisor.go | 9 ++++----- origin/tunnel.go | 7 +++---- 3 files changed, 36 insertions(+), 14 deletions(-) diff --git a/cmd/cloudflared/tunnel/cmd.go b/cmd/cloudflared/tunnel/cmd.go index e901c0bd..d014bdf3 100644 --- a/cmd/cloudflared/tunnel/cmd.go +++ b/cmd/cloudflared/tunnel/cmd.go @@ -1,18 +1,17 @@ package tunnel import ( + "bufio" "context" "fmt" "io/ioutil" "net" "net/url" "os" - ossig "os/signal" "reflect" "runtime" "runtime/trace" "sync" - "syscall" "time" "github.com/cloudflare/cloudflared/awsuploader" @@ -401,9 +400,11 @@ func StartServer(c *cli.Context, version string, shutdownC, graceShutdownC chan return err } - // When the user sends SIGUSR1, disconnect all connections. - reconnectCh := make(chan os.Signal, 1) - ossig.Notify(reconnectCh, syscall.SIGUSR1) + reconnectCh := make(chan struct{}, 1) + if c.IsSet("stdin-control") { + logger.Warn("Enabling control through stdin") + go stdinControl(reconnectCh) + } wg.Add(1) go func() { @@ -1066,5 +1067,28 @@ func tunnelFlags(shouldHide bool) []cli.Flag { EnvVars: []string{"HOST_KEY_PATH"}, Hidden: true, }), + altsrc.NewBoolFlag(&cli.BoolFlag{ + Name: "stdin-control", + Usage: "Control the process using commands sent through stdin", + EnvVars: []string{"STDIN-CONTROL"}, + Hidden: true, + Value: false, + }), + } +} + +func stdinControl(reconnectCh chan struct{}) { + for { + scanner := bufio.NewScanner(os.Stdin) + for scanner.Scan() { + command := scanner.Text() + + switch command { + case "reconnect": + reconnectCh <- struct{}{} + default: + logger.Warn("Unknown command: ", command) + } + } } } diff --git a/origin/supervisor.go b/origin/supervisor.go index 8c3a672e..ee57506d 100644 --- a/origin/supervisor.go +++ b/origin/supervisor.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "net" - "os" "sync" "time" @@ -106,7 +105,7 @@ func NewSupervisor(config *TunnelConfig, u uuid.UUID) (*Supervisor, error) { }, nil } -func (s *Supervisor) Run(ctx context.Context, connectedSignal *signal.Signal, reconnectCh chan os.Signal) error { +func (s *Supervisor) Run(ctx context.Context, connectedSignal *signal.Signal, reconnectCh chan struct{}) error { logger := s.config.Logger if err := s.initialize(ctx, connectedSignal, reconnectCh); err != nil { return err @@ -192,7 +191,7 @@ func (s *Supervisor) Run(ctx context.Context, connectedSignal *signal.Signal, re } // Returns nil if initialization succeeded, else the initialization error. -func (s *Supervisor) initialize(ctx context.Context, connectedSignal *signal.Signal, reconnectCh chan os.Signal) error { +func (s *Supervisor) initialize(ctx context.Context, connectedSignal *signal.Signal, reconnectCh chan struct{}) error { logger := s.logger s.lastResolve = time.Now() @@ -222,7 +221,7 @@ func (s *Supervisor) initialize(ctx context.Context, connectedSignal *signal.Sig // startTunnel starts the first tunnel connection. The resulting error will be sent on // s.tunnelErrors. It will send a signal via connectedSignal if registration succeed -func (s *Supervisor) startFirstTunnel(ctx context.Context, connectedSignal *signal.Signal, reconnectCh chan os.Signal) { +func (s *Supervisor) startFirstTunnel(ctx context.Context, connectedSignal *signal.Signal, reconnectCh chan struct{}) { var ( addr *net.TCPAddr err error @@ -266,7 +265,7 @@ func (s *Supervisor) startFirstTunnel(ctx context.Context, connectedSignal *sign // startTunnel starts a new tunnel connection. The resulting error will be sent on // s.tunnelErrors. -func (s *Supervisor) startTunnel(ctx context.Context, index int, connectedSignal *signal.Signal, reconnectCh chan os.Signal) { +func (s *Supervisor) startTunnel(ctx context.Context, index int, connectedSignal *signal.Signal, reconnectCh chan struct{}) { var ( addr *net.TCPAddr err error diff --git a/origin/tunnel.go b/origin/tunnel.go index 4b5edefa..50dd02cc 100644 --- a/origin/tunnel.go +++ b/origin/tunnel.go @@ -9,7 +9,6 @@ import ( "net" "net/http" "net/url" - "os" "strconv" "strings" "sync" @@ -170,7 +169,7 @@ func (c *TunnelConfig) RegistrationOptions(connectionID uint8, OriginLocalIP str } } -func StartTunnelDaemon(ctx context.Context, config *TunnelConfig, connectedSignal *signal.Signal, cloudflaredID uuid.UUID, reconnectCh chan os.Signal) error { +func StartTunnelDaemon(ctx context.Context, config *TunnelConfig, connectedSignal *signal.Signal, cloudflaredID uuid.UUID, reconnectCh chan struct{}) error { s, err := NewSupervisor(config, cloudflaredID) if err != nil { return err @@ -186,7 +185,7 @@ func ServeTunnelLoop(ctx context.Context, connectedSignal *signal.Signal, u uuid.UUID, bufferPool *buffer.Pool, - reconnectCh chan os.Signal, + reconnectCh chan struct{}, ) error { connectionLogger := config.Logger.WithField("connectionID", connectionID) config.Metrics.incrementHaConnections() @@ -235,7 +234,7 @@ func ServeTunnel( backoff *BackoffHandler, u uuid.UUID, bufferPool *buffer.Pool, - reconnectCh chan os.Signal, + reconnectCh chan struct{}, ) (err error, recoverable bool) { // Treat panics as recoverable errors defer func() {