mirror of
https://github.com/cloudflare/cloudflared
synced 2026-06-08 13:33:07 +00:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 99713e3439 | |||
| 27c6977746 | |||
| 200f9a3786 | |||
| 92defa26d4 | |||
| c9f1c1ec70 | |||
| 10e4a2940c | |||
| 77f12c7c34 | |||
| ca33ed9f6a |
@@ -1,3 +1,11 @@
|
||||
2019.2.0
|
||||
- 2019-01-24 AUTH-1462: better curl arg parsing
|
||||
- 2019-02-01 TUN-1456: Only make one UUID
|
||||
- 2019-01-30 cloudflared/linux_service: Add missing /etc/init.d shebang
|
||||
- 2019-02-07 AUTH-1511: Add custom headers for ssh command
|
||||
- 2019-02-01 AUTH-1503: Added RDP support
|
||||
- 2019-02-01 AUTH-1403: Print the paths in the ssh-config instructions
|
||||
|
||||
2019.1.0
|
||||
- 2018-12-10 TUN-1231: Horizontal overflow wrapping on the Hello page
|
||||
- 2018-12-17 TUN-1140: Show usage if invoked with no args or config
|
||||
|
||||
+10
-9
@@ -34,13 +34,13 @@ func (c *StdinoutStream) Write(p []byte) (int, error) {
|
||||
|
||||
// StartClient will copy the data from stdin/stdout over a WebSocket connection
|
||||
// to the edge (originURL)
|
||||
func StartClient(logger *logrus.Logger, originURL string, stream io.ReadWriter) error {
|
||||
return serveStream(logger, originURL, stream)
|
||||
func StartClient(logger *logrus.Logger, originURL string, stream io.ReadWriter, headers http.Header) error {
|
||||
return serveStream(logger, originURL, stream, headers)
|
||||
}
|
||||
|
||||
// StartServer will setup a server on a specified port and copy data over a WebSocket connection
|
||||
// to the edge (originURL)
|
||||
func StartServer(logger *logrus.Logger, address, originURL string, shutdownC <-chan struct{}) error {
|
||||
func StartServer(logger *logrus.Logger, address, originURL string, shutdownC <-chan struct{}, headers http.Header) error {
|
||||
listener, err := net.Listen("tcp", address)
|
||||
if err != nil {
|
||||
logger.WithError(err).Error("failed to start forwarding server")
|
||||
@@ -56,20 +56,20 @@ func StartServer(logger *logrus.Logger, address, originURL string, shutdownC <-c
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
go serveConnection(logger, conn, originURL)
|
||||
go serveConnection(logger, conn, originURL, headers)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// serveConnection handles connections for the StartServer call
|
||||
func serveConnection(logger *logrus.Logger, c net.Conn, originURL string) {
|
||||
func serveConnection(logger *logrus.Logger, c net.Conn, originURL string, headers http.Header) {
|
||||
defer c.Close()
|
||||
serveStream(logger, originURL, c)
|
||||
serveStream(logger, originURL, c, headers)
|
||||
}
|
||||
|
||||
// serveStream will serve the data over the WebSocket stream
|
||||
func serveStream(logger *logrus.Logger, originURL string, conn io.ReadWriter) error {
|
||||
wsConn, err := createWebsocketStream(originURL)
|
||||
func serveStream(logger *logrus.Logger, originURL string, conn io.ReadWriter, headers http.Header) error {
|
||||
wsConn, err := createWebsocketStream(originURL, headers)
|
||||
if err != nil {
|
||||
logger.WithError(err).Errorf("failed to connect to %s\n", originURL)
|
||||
return err
|
||||
@@ -84,11 +84,12 @@ func serveStream(logger *logrus.Logger, originURL string, conn io.ReadWriter) er
|
||||
// createWebsocketStream will create a WebSocket connection to stream data over
|
||||
// It also handles redirects from Access and will present that flow if
|
||||
// the token is not present on the request
|
||||
func createWebsocketStream(originURL string) (*websocket.Conn, error) {
|
||||
func createWebsocketStream(originURL string, headers http.Header) (*websocket.Conn, error) {
|
||||
req, err := http.NewRequest(http.MethodGet, originURL, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header = headers
|
||||
|
||||
wsConn, resp, err := websocket.ClientConnect(req, nil)
|
||||
if err != nil && resp != nil && resp.StatusCode > 300 {
|
||||
|
||||
@@ -48,7 +48,7 @@ func TestStartClient(t *testing.T) {
|
||||
defer ts.Close()
|
||||
|
||||
buf := newTestStream()
|
||||
err := StartClient(logger, "http://"+ts.Listener.Addr().String(), buf)
|
||||
err := StartClient(logger, "http://"+ts.Listener.Addr().String(), buf, nil)
|
||||
assert.NoError(t, err)
|
||||
buf.Write([]byte(message))
|
||||
|
||||
@@ -66,7 +66,7 @@ func TestStartServer(t *testing.T) {
|
||||
defer ts.Close()
|
||||
|
||||
go func() {
|
||||
err := StartServer(logger, listenerAddress, "http://"+ts.Listener.Addr().String(), shutdownC)
|
||||
err := StartServer(logger, listenerAddress, "http://"+ts.Listener.Addr().String(), shutdownC, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("Error starting server: %v", err)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package access
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/cloudflare/cloudflared/carrier"
|
||||
"github.com/cloudflare/cloudflared/cmd/cloudflared/config"
|
||||
@@ -19,6 +21,7 @@ func ssh(c *cli.Context) error {
|
||||
if err != nil || c.String("hostname") == "" {
|
||||
return cli.ShowCommandHelp(c, "ssh")
|
||||
}
|
||||
headers := buildRequestHeaders(c.StringSlice("header"))
|
||||
|
||||
if c.NArg() > 0 || c.IsSet("url") {
|
||||
localForwarder, err := config.ValidateUrl(c)
|
||||
@@ -31,8 +34,19 @@ func ssh(c *cli.Context) error {
|
||||
logger.WithError(err).Error("Error validating origin URL")
|
||||
return errors.Wrap(err, "error validating origin URL")
|
||||
}
|
||||
return carrier.StartServer(logger, forwarder.Host, "https://"+hostname, shutdownC)
|
||||
return carrier.StartServer(logger, forwarder.Host, "https://"+hostname, shutdownC, headers)
|
||||
}
|
||||
|
||||
return carrier.StartClient(logger, "https://"+hostname, &carrier.StdinoutStream{})
|
||||
return carrier.StartClient(logger, "https://"+hostname, &carrier.StdinoutStream{}, headers)
|
||||
}
|
||||
|
||||
func buildRequestHeaders(values []string) http.Header {
|
||||
headers := make(http.Header)
|
||||
for _, valuePair := range values {
|
||||
split := strings.Split(valuePair, ":")
|
||||
if len(split) > 1 {
|
||||
headers.Add(strings.TrimSpace(split[0]), strings.TrimSpace(split[1]))
|
||||
}
|
||||
}
|
||||
return headers
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package access
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestBuildRequestHeaders(t *testing.T) {
|
||||
headers := make(http.Header)
|
||||
headers.Add("client", "value")
|
||||
headers.Add("secret", "safe-value")
|
||||
|
||||
values := buildRequestHeaders([]string{"client: value", "secret: safe-value", "trash"})
|
||||
assert.Equal(t, headers.Get("client"), values.Get("client"))
|
||||
assert.Equal(t, headers.Get("secret"), values.Get("secret"))
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/cloudflare/cloudflared/cmd/cloudflared/shell"
|
||||
"github.com/cloudflare/cloudflared/cmd/cloudflared/token"
|
||||
@@ -65,7 +66,7 @@ func Commands() []*cli.Command {
|
||||
{
|
||||
Name: "curl",
|
||||
Action: curl,
|
||||
Usage: "curl <args>",
|
||||
Usage: "curl [--allow-request, -ar] <url> [<curl args>...]",
|
||||
Description: `The curl subcommand wraps curl and automatically injects the JWT into a cf-access-token
|
||||
header when using curl to reach an application behind Access.`,
|
||||
ArgsUsage: "allow-request will allow the curl request to continue even if the jwt is not present.",
|
||||
@@ -86,6 +87,7 @@ func Commands() []*cli.Command {
|
||||
{
|
||||
Name: "ssh",
|
||||
Action: ssh,
|
||||
Aliases: []string{"rdp"},
|
||||
Usage: "",
|
||||
ArgsUsage: "",
|
||||
Description: `The ssh subcommand sends data over a proxy to the Cloudflare edge.`,
|
||||
@@ -96,6 +98,10 @@ func Commands() []*cli.Command {
|
||||
&cli.StringFlag{
|
||||
Name: "url",
|
||||
},
|
||||
&cli.StringSliceFlag{
|
||||
Name: "header",
|
||||
Aliases: []string{"H"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -139,7 +145,8 @@ func curl(c *cli.Context) error {
|
||||
return errors.New("incorrect args")
|
||||
}
|
||||
|
||||
cmdArgs, appURL, allowRequest, err := buildCurlCmdArgs(args.Slice())
|
||||
cmdArgs, allowRequest := parseAllowRequest(args.Slice())
|
||||
appURL, err := getAppURL(cmdArgs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -185,10 +192,37 @@ func generateToken(c *cli.Context) error {
|
||||
|
||||
// sshConfig prints an example SSH config to stdout
|
||||
func sshConfig(c *cli.Context) error {
|
||||
_, err := os.Stdout.Write([]byte(`Add this configuration block to your $HOME/.ssh/config
|
||||
Host <your hostname>
|
||||
ProxyCommand cloudflared access ssh --hostname %h` + "\n"))
|
||||
return err
|
||||
outputMessage := "Add this configuration block to your %s/.ssh/config:\n\nHost [your hostname]\n\tProxyCommand %s access ssh --hostname %%h\n"
|
||||
logger.Printf(outputMessage, os.Getenv("HOME"), cloudflaredPath())
|
||||
return nil
|
||||
}
|
||||
|
||||
// getAppURL will pull the appURL needed for fetching a user's Access token
|
||||
func getAppURL(cmdArgs []string) (*url.URL, error) {
|
||||
if len(cmdArgs) < 1 {
|
||||
logger.Error("Please provide a valid URL as the first argument to curl.")
|
||||
return nil, errors.New("not a valid url")
|
||||
}
|
||||
|
||||
u, err := processURL(cmdArgs[0])
|
||||
if err != nil {
|
||||
logger.Error("Please provide a valid URL as the first argument to curl.")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return u, err
|
||||
}
|
||||
|
||||
// parseAllowRequest will parse cmdArgs and return a copy of the args and result
|
||||
// of the allow request was present
|
||||
func parseAllowRequest(cmdArgs []string) ([]string, bool) {
|
||||
if len(cmdArgs) > 1 {
|
||||
if cmdArgs[0] == "--allow-request" || cmdArgs[0] == "-ar" {
|
||||
return cmdArgs[1:], true
|
||||
}
|
||||
}
|
||||
|
||||
return cmdArgs, false
|
||||
}
|
||||
|
||||
// processURL will preprocess the string (parse to a url, convert to punycode, etc).
|
||||
@@ -197,6 +231,11 @@ func processURL(s string) (*url.URL, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if u.Host == "" {
|
||||
return nil, errors.New("not a valid host")
|
||||
}
|
||||
|
||||
host, err := idna.ToASCII(u.Hostname())
|
||||
if err != nil { // we fail to convert to punycode, just return the url we parsed.
|
||||
return u, nil
|
||||
@@ -210,33 +249,22 @@ func processURL(s string) (*url.URL, error) {
|
||||
return u, nil
|
||||
}
|
||||
|
||||
// buildCurlCmdArgs will build the curl cmd args
|
||||
func buildCurlCmdArgs(cmdArgs []string) ([]string, *url.URL, bool, error) {
|
||||
allowRequest, iAllowRequest := false, 0
|
||||
var appURL *url.URL
|
||||
for i, arg := range cmdArgs {
|
||||
if arg == "-allow-request" || arg == "-ar" {
|
||||
iAllowRequest = i
|
||||
allowRequest = true
|
||||
}
|
||||
|
||||
u, err := processURL(arg)
|
||||
if err == nil {
|
||||
appURL = u
|
||||
cmdArgs[i] = appURL.String()
|
||||
// cloudflaredPath pulls the full path of cloudflared on disk
|
||||
func cloudflaredPath() string {
|
||||
for _, p := range strings.Split(os.Getenv("PATH"), ":") {
|
||||
path := fmt.Sprintf("%s/%s", p, "cloudflared")
|
||||
if isFileThere(path) {
|
||||
return path
|
||||
}
|
||||
}
|
||||
|
||||
if appURL == nil {
|
||||
logger.Error("Please provide a valid URL.")
|
||||
return cmdArgs, appURL, allowRequest, errors.New("invalid url")
|
||||
}
|
||||
|
||||
if allowRequest {
|
||||
// remove from cmdArgs
|
||||
cmdArgs[iAllowRequest] = cmdArgs[len(cmdArgs)-1]
|
||||
cmdArgs = cmdArgs[:len(cmdArgs)-1]
|
||||
}
|
||||
|
||||
return cmdArgs, appURL, allowRequest, nil
|
||||
return "cloudflared"
|
||||
}
|
||||
|
||||
// isFileThere will check for the presence of candidate path
|
||||
func isFileThere(candidate string) bool {
|
||||
fi, err := os.Stat(candidate)
|
||||
if err != nil || fi.IsDir() || !fi.Mode().IsRegular() {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -84,7 +84,8 @@ WantedBy=timers.target
|
||||
var sysvTemplate = ServiceTemplate{
|
||||
Path: "/etc/init.d/cloudflared",
|
||||
FileMode: 0755,
|
||||
Content: `# For RedHat and cousins:
|
||||
Content: `#!/bin/sh
|
||||
# For RedHat and cousins:
|
||||
# chkconfig: 2345 99 01
|
||||
# description: Argo Tunnel agent
|
||||
# processname: {{.Path}}
|
||||
|
||||
@@ -300,11 +300,7 @@ func StartServer(c *cli.Context, version string, shutdownC, graceShutdownC chan
|
||||
c.Set("url", "https://"+helloListener.Addr().String())
|
||||
}
|
||||
|
||||
if uri, err := url.Parse(c.String("url")); err == nil && uri.Scheme == "ssh" {
|
||||
host := uri.Host
|
||||
if uri.Port() == "" { // default to 22
|
||||
host = uri.Hostname() + ":22"
|
||||
}
|
||||
if host := hostnameFromURI(c.String("url")); host != "" {
|
||||
listener, err := net.Listen("tcp", "127.0.0.1:")
|
||||
if err != nil {
|
||||
logger.WithError(err).Error("Cannot start Websocket Proxy Server")
|
||||
@@ -393,6 +389,27 @@ func writePidFile(waitForSignal chan struct{}, pidFile string) {
|
||||
fmt.Fprintf(file, "%d", os.Getpid())
|
||||
}
|
||||
|
||||
func hostnameFromURI(uri string) string {
|
||||
u, err := url.Parse(uri)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
switch u.Scheme {
|
||||
case "ssh":
|
||||
return addPortIfMissing(u, 22)
|
||||
case "rdp":
|
||||
return addPortIfMissing(u, 3389)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func addPortIfMissing(uri *url.URL, port int) string {
|
||||
if uri.Port() != "" {
|
||||
return uri.Host
|
||||
}
|
||||
return fmt.Sprintf("%s:%d", uri.Hostname(), port)
|
||||
}
|
||||
|
||||
func tunnelFlags(shouldHide bool) []cli.Flag {
|
||||
return []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package tunnel
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TesthostnameFromURI(t *testing.T) {
|
||||
assert.Equal(t, "ssh://awesome.warptunnels.horse:22", hostnameFromURI("ssh://awesome.warptunnels.horse:22"))
|
||||
assert.Equal(t, "ssh://awesome.warptunnels.horse:22", hostnameFromURI("ssh://awesome.warptunnels.horse"))
|
||||
assert.Equal(t, "rdp://localhost:3389", hostnameFromURI("rdp://localhost"))
|
||||
assert.Equal(t, "", hostnameFromURI("trash"))
|
||||
assert.Equal(t, "", hostnameFromURI("https://awesomesauce.com"))
|
||||
}
|
||||
+13
-11
@@ -5,6 +5,8 @@ import (
|
||||
"fmt"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -49,9 +51,9 @@ func NewSupervisor(config *TunnelConfig) *Supervisor {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Supervisor) Run(ctx context.Context, connectedSignal chan struct{}) error {
|
||||
func (s *Supervisor) Run(ctx context.Context, connectedSignal chan struct{}, u uuid.UUID) error {
|
||||
logger := s.config.Logger
|
||||
if err := s.initialize(ctx, connectedSignal); err != nil {
|
||||
if err := s.initialize(ctx, connectedSignal, u); err != nil {
|
||||
return err
|
||||
}
|
||||
var tunnelsWaiting []int
|
||||
@@ -94,7 +96,7 @@ func (s *Supervisor) Run(ctx context.Context, connectedSignal chan struct{}) err
|
||||
case <-backoffTimer:
|
||||
backoffTimer = nil
|
||||
for _, index := range tunnelsWaiting {
|
||||
go s.startTunnel(ctx, index, s.newConnectedTunnelSignal(index))
|
||||
go s.startTunnel(ctx, index, s.newConnectedTunnelSignal(index), u)
|
||||
}
|
||||
tunnelsActive += len(tunnelsWaiting)
|
||||
tunnelsWaiting = nil
|
||||
@@ -118,7 +120,7 @@ func (s *Supervisor) Run(ctx context.Context, connectedSignal chan struct{}) err
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Supervisor) initialize(ctx context.Context, connectedSignal chan struct{}) error {
|
||||
func (s *Supervisor) initialize(ctx context.Context, connectedSignal chan struct{}, u uuid.UUID) error {
|
||||
logger := s.config.Logger
|
||||
edgeIPs, err := ResolveEdgeIPs(s.config.EdgeAddrs)
|
||||
if err != nil {
|
||||
@@ -133,7 +135,7 @@ func (s *Supervisor) initialize(ctx context.Context, connectedSignal chan struct
|
||||
s.lastResolve = time.Now()
|
||||
// check entitlement and version too old error before attempting to register more tunnels
|
||||
s.nextUnusedEdgeIP = s.config.HAConnections
|
||||
go s.startFirstTunnel(ctx, connectedSignal)
|
||||
go s.startFirstTunnel(ctx, connectedSignal, u)
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
<-s.tunnelErrors
|
||||
@@ -145,7 +147,7 @@ func (s *Supervisor) initialize(ctx context.Context, connectedSignal chan struct
|
||||
}
|
||||
// At least one successful connection, so start the rest
|
||||
for i := 1; i < s.config.HAConnections; i++ {
|
||||
go s.startTunnel(ctx, i, make(chan struct{}))
|
||||
go s.startTunnel(ctx, i, make(chan struct{}), u)
|
||||
time.Sleep(registrationInterval)
|
||||
}
|
||||
return nil
|
||||
@@ -153,8 +155,8 @@ func (s *Supervisor) initialize(ctx context.Context, connectedSignal chan struct
|
||||
|
||||
// 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 chan struct{}) {
|
||||
err := ServeTunnelLoop(ctx, s.config, s.getEdgeIP(0), 0, connectedSignal)
|
||||
func (s *Supervisor) startFirstTunnel(ctx context.Context, connectedSignal chan struct{}, u uuid.UUID) {
|
||||
err := ServeTunnelLoop(ctx, s.config, s.getEdgeIP(0), 0, connectedSignal, u)
|
||||
defer func() {
|
||||
s.tunnelErrors <- tunnelError{index: 0, err: err}
|
||||
}()
|
||||
@@ -175,14 +177,14 @@ func (s *Supervisor) startFirstTunnel(ctx context.Context, connectedSignal chan
|
||||
default:
|
||||
return
|
||||
}
|
||||
err = ServeTunnelLoop(ctx, s.config, s.getEdgeIP(0), 0, connectedSignal)
|
||||
err = ServeTunnelLoop(ctx, s.config, s.getEdgeIP(0), 0, connectedSignal, u)
|
||||
}
|
||||
}
|
||||
|
||||
// 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 chan struct{}) {
|
||||
err := ServeTunnelLoop(ctx, s.config, s.getEdgeIP(index), uint8(index), connectedSignal)
|
||||
func (s *Supervisor) startTunnel(ctx context.Context, index int, connectedSignal chan struct{}, u uuid.UUID) {
|
||||
err := ServeTunnelLoop(ctx, s.config, s.getEdgeIP(index), uint8(index), connectedSignal, u)
|
||||
s.tunnelErrors <- tunnelError{index: index, err: err}
|
||||
}
|
||||
|
||||
|
||||
+13
-8
@@ -132,15 +132,21 @@ func StartTunnelDaemon(config *TunnelConfig, shutdownC <-chan struct{}, connecte
|
||||
<-shutdownC
|
||||
cancel()
|
||||
}()
|
||||
|
||||
u, err := uuid.NewRandom()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// If a user specified negative HAConnections, we will treat it as requesting 1 connection
|
||||
if config.HAConnections > 1 {
|
||||
return NewSupervisor(config).Run(ctx, connectedSignal)
|
||||
return NewSupervisor(config).Run(ctx, connectedSignal, u)
|
||||
} else {
|
||||
addrs, err := ResolveEdgeIPs(config.EdgeAddrs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return ServeTunnelLoop(ctx, config, addrs[0], 0, connectedSignal)
|
||||
return ServeTunnelLoop(ctx, config, addrs[0], 0, connectedSignal, u)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,6 +155,7 @@ func ServeTunnelLoop(ctx context.Context,
|
||||
addr *net.TCPAddr,
|
||||
connectionID uint8,
|
||||
connectedSignal chan struct{},
|
||||
u uuid.UUID,
|
||||
) error {
|
||||
logger := config.Logger
|
||||
config.Metrics.incrementHaConnections()
|
||||
@@ -164,7 +171,7 @@ func ServeTunnelLoop(ctx context.Context,
|
||||
// Ensure the above goroutine will terminate if we return without connecting
|
||||
defer connectedFuse.Fuse(false)
|
||||
for {
|
||||
err, recoverable := ServeTunnel(ctx, config, addr, connectionID, connectedFuse, &backoff)
|
||||
err, recoverable := ServeTunnel(ctx, config, addr, connectionID, connectedFuse, &backoff, u)
|
||||
if recoverable {
|
||||
if duration, ok := backoff.GetBackoffDuration(ctx); ok {
|
||||
logger.Infof("Retrying in %s seconds", duration)
|
||||
@@ -183,6 +190,7 @@ func ServeTunnel(
|
||||
connectionID uint8,
|
||||
connectedFuse *h2mux.BooleanFuse,
|
||||
backoff *BackoffHandler,
|
||||
u uuid.UUID,
|
||||
) (err error, recoverable bool) {
|
||||
// Treat panics as recoverable errors
|
||||
defer func() {
|
||||
@@ -222,7 +230,7 @@ func ServeTunnel(
|
||||
errGroup, serveCtx := errgroup.WithContext(ctx)
|
||||
|
||||
errGroup.Go(func() error {
|
||||
err := RegisterTunnel(serveCtx, handler.muxer, config, connectionID, originLocalIP)
|
||||
err := RegisterTunnel(serveCtx, handler.muxer, config, connectionID, originLocalIP, u)
|
||||
if err == nil {
|
||||
connectedFuse.Fuse(true)
|
||||
backoff.SetGracePeriod()
|
||||
@@ -302,6 +310,7 @@ func RegisterTunnel(
|
||||
config *TunnelConfig,
|
||||
connectionID uint8,
|
||||
originLocalIP string,
|
||||
uuid uuid.UUID,
|
||||
) error {
|
||||
config.TransportLogger.Debug("initiating RPC stream to register")
|
||||
stream, err := muxer.OpenStream([]h2mux.Header{
|
||||
@@ -328,10 +337,6 @@ func RegisterTunnel(
|
||||
serverInfoPromise := tsClient.GetServerInfo(ctx, func(tunnelrpc.TunnelServer_getServerInfo_Params) error {
|
||||
return nil
|
||||
})
|
||||
uuid, err := uuid.NewRandom()
|
||||
if err != nil {
|
||||
return clientRegisterTunnelError{cause: err}
|
||||
}
|
||||
registration, err := ts.RegisterTunnel(
|
||||
ctx,
|
||||
config.OriginCert,
|
||||
|
||||
Reference in New Issue
Block a user