Skip to content

Commit 654a326

Browse files
committed
TUN-8424: Refactor capnp registration server
Move RegistrationServer and RegistrationClient into tunnelrpc module to properly abstract out the capnp aspects internal to the module only.
1 parent 43446bc commit 654a326

File tree

13 files changed

+198
-168
lines changed

13 files changed

+198
-168
lines changed

cmd/cloudflared/tunnel/cmd.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ func routeFromFlag(c *cli.Context) (route cfapi.HostnameRoute, ok bool) {
287287
func StartServer(
288288
c *cli.Context,
289289
info *cliutil.BuildInfo,
290-
namedTunnel *connection.NamedTunnelProperties,
290+
namedTunnel *connection.TunnelProperties,
291291
log *zerolog.Logger,
292292
) error {
293293
err := sentry.Init(sentry.ClientOptions{

cmd/cloudflared/tunnel/configuration.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ func isSecretEnvVar(key string) bool {
108108
return false
109109
}
110110

111-
func dnsProxyStandAlone(c *cli.Context, namedTunnel *connection.NamedTunnelProperties) bool {
111+
func dnsProxyStandAlone(c *cli.Context, namedTunnel *connection.TunnelProperties) bool {
112112
return c.IsSet("proxy-dns") &&
113113
!(c.IsSet("name") || // adhoc-named tunnel
114114
c.IsSet(ingress.HelloWorldFlag) || // quick or named tunnel
@@ -121,7 +121,7 @@ func prepareTunnelConfig(
121121
info *cliutil.BuildInfo,
122122
log, logTransport *zerolog.Logger,
123123
observer *connection.Observer,
124-
namedTunnel *connection.NamedTunnelProperties,
124+
namedTunnel *connection.TunnelProperties,
125125
) (*supervisor.TunnelConfig, *orchestration.Config, error) {
126126
clientID, err := uuid.NewRandom()
127127
if err != nil {

cmd/cloudflared/tunnel/quick_tunnel.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ func RunQuickTunnel(sc *subcommandContext) error {
7979
return StartServer(
8080
sc.c,
8181
buildInfo,
82-
&connection.NamedTunnelProperties{Credentials: credentials, QuickTunnelUrl: data.Result.Hostname},
82+
&connection.TunnelProperties{Credentials: credentials, QuickTunnelUrl: data.Result.Hostname},
8383
sc.log,
8484
)
8585
}

cmd/cloudflared/tunnel/subcommand_context.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ func (sc *subcommandContext) runWithCredentials(credentials connection.Credentia
261261
return StartServer(
262262
sc.c,
263263
buildInfo,
264-
&connection.NamedTunnelProperties{Credentials: credentials},
264+
&connection.TunnelProperties{Credentials: credentials},
265265
sc.log,
266266
)
267267
}

connection/connection.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ type Orchestrator interface {
4242
GetOriginProxy() (OriginProxy, error)
4343
}
4444

45-
type NamedTunnelProperties struct {
45+
type TunnelProperties struct {
4646
Credentials Credentials
4747
Client pogs.ClientInfo
4848
QuickTunnelUrl string

connection/control.go

Lines changed: 49 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,25 @@ import (
66
"net"
77
"time"
88

9-
"github.com/rs/zerolog"
10-
119
"github.com/cloudflare/cloudflared/management"
10+
"github.com/cloudflare/cloudflared/tunnelrpc"
1211
tunnelpogs "github.com/cloudflare/cloudflared/tunnelrpc/pogs"
1312
)
1413

15-
// RPCClientFunc derives a named tunnel rpc client that can then be used to register and unregister connections.
16-
type RPCClientFunc func(context.Context, io.ReadWriteCloser, *zerolog.Logger) NamedTunnelRPCClient
14+
// registerClient derives a named tunnel rpc client that can then be used to register and unregister connections.
15+
type registerClientFunc func(context.Context, io.ReadWriteCloser, time.Duration) tunnelrpc.RegistrationClient
1716

1817
type controlStream struct {
1918
observer *Observer
2019

21-
connectedFuse ConnectedFuse
22-
namedTunnelProperties *NamedTunnelProperties
23-
connIndex uint8
24-
edgeAddress net.IP
25-
protocol Protocol
20+
connectedFuse ConnectedFuse
21+
tunnelProperties *TunnelProperties
22+
connIndex uint8
23+
edgeAddress net.IP
24+
protocol Protocol
2625

27-
newRPCClientFunc RPCClientFunc
26+
registerClientFunc registerClientFunc
27+
registerTimeout time.Duration
2828

2929
gracefulShutdownC <-chan struct{}
3030
gracePeriod time.Duration
@@ -47,27 +47,29 @@ type TunnelConfigJSONGetter interface {
4747
func NewControlStream(
4848
observer *Observer,
4949
connectedFuse ConnectedFuse,
50-
namedTunnelConfig *NamedTunnelProperties,
50+
tunnelProperties *TunnelProperties,
5151
connIndex uint8,
5252
edgeAddress net.IP,
53-
newRPCClientFunc RPCClientFunc,
53+
registerClientFunc registerClientFunc,
54+
registerTimeout time.Duration,
5455
gracefulShutdownC <-chan struct{},
5556
gracePeriod time.Duration,
5657
protocol Protocol,
5758
) ControlStreamHandler {
58-
if newRPCClientFunc == nil {
59-
newRPCClientFunc = newRegistrationRPCClient
59+
if registerClientFunc == nil {
60+
registerClientFunc = tunnelrpc.NewRegistrationClient
6061
}
6162
return &controlStream{
62-
observer: observer,
63-
connectedFuse: connectedFuse,
64-
namedTunnelProperties: namedTunnelConfig,
65-
newRPCClientFunc: newRPCClientFunc,
66-
connIndex: connIndex,
67-
edgeAddress: edgeAddress,
68-
gracefulShutdownC: gracefulShutdownC,
69-
gracePeriod: gracePeriod,
70-
protocol: protocol,
63+
observer: observer,
64+
connectedFuse: connectedFuse,
65+
tunnelProperties: tunnelProperties,
66+
registerClientFunc: registerClientFunc,
67+
registerTimeout: registerTimeout,
68+
connIndex: connIndex,
69+
edgeAddress: edgeAddress,
70+
gracefulShutdownC: gracefulShutdownC,
71+
gracePeriod: gracePeriod,
72+
protocol: protocol,
7173
}
7274
}
7375

@@ -77,13 +79,25 @@ func (c *controlStream) ServeControlStream(
7779
connOptions *tunnelpogs.ConnectionOptions,
7880
tunnelConfigGetter TunnelConfigJSONGetter,
7981
) error {
80-
rpcClient := c.newRPCClientFunc(ctx, rw, c.observer.log)
81-
82-
registrationDetails, err := rpcClient.RegisterConnection(ctx, c.namedTunnelProperties, connOptions, c.connIndex, c.edgeAddress, c.observer)
82+
registrationClient := c.registerClientFunc(ctx, rw, c.registerTimeout)
83+
84+
registrationDetails, err := registrationClient.RegisterConnection(
85+
ctx,
86+
c.tunnelProperties.Credentials.Auth(),
87+
c.tunnelProperties.Credentials.TunnelID,
88+
connOptions,
89+
c.connIndex,
90+
c.edgeAddress)
8391
if err != nil {
84-
rpcClient.Close()
85-
return err
92+
defer registrationClient.Close()
93+
if err.Error() == DuplicateConnectionError {
94+
c.observer.metrics.regFail.WithLabelValues("dup_edge_conn", "registerConnection").Inc()
95+
return errDuplicationConnection
96+
}
97+
c.observer.metrics.regFail.WithLabelValues("server_error", "registerConnection").Inc()
98+
return serverRegistrationErrorFromRPC(err)
8699
}
100+
c.observer.metrics.regSuccess.WithLabelValues("registerConnection").Inc()
87101

88102
c.observer.logConnected(registrationDetails.UUID, c.connIndex, registrationDetails.Location, c.edgeAddress, c.protocol)
89103
c.observer.sendConnectedEvent(c.connIndex, c.protocol, registrationDetails.Location)
@@ -92,21 +106,23 @@ func (c *controlStream) ServeControlStream(
92106
// if conn index is 0 and tunnel is not remotely managed, then send local ingress rules configuration
93107
if c.connIndex == 0 && !registrationDetails.TunnelIsRemotelyManaged {
94108
if tunnelConfig, err := tunnelConfigGetter.GetConfigJSON(); err == nil {
95-
if err := rpcClient.SendLocalConfiguration(ctx, tunnelConfig, c.observer); err != nil {
109+
if err := registrationClient.SendLocalConfiguration(ctx, tunnelConfig); err != nil {
110+
c.observer.metrics.localConfigMetrics.pushesErrors.Inc()
96111
c.observer.log.Err(err).Msg("unable to send local configuration")
97112
}
113+
c.observer.metrics.localConfigMetrics.pushes.Inc()
98114
} else {
99115
c.observer.log.Err(err).Msg("failed to obtain current configuration")
100116
}
101117
}
102118

103-
c.waitForUnregister(ctx, rpcClient)
119+
c.waitForUnregister(ctx, registrationClient)
104120
return nil
105121
}
106122

107-
func (c *controlStream) waitForUnregister(ctx context.Context, rpcClient NamedTunnelRPCClient) {
123+
func (c *controlStream) waitForUnregister(ctx context.Context, registrationClient tunnelrpc.RegistrationClient) {
108124
// wait for connection termination or start of graceful shutdown
109-
defer rpcClient.Close()
125+
defer registrationClient.Close()
110126
select {
111127
case <-ctx.Done():
112128
break
@@ -115,7 +131,7 @@ func (c *controlStream) waitForUnregister(ctx context.Context, rpcClient NamedTu
115131
}
116132

117133
c.observer.sendUnregisteringEvent(c.connIndex)
118-
rpcClient.GracefulShutdown(ctx, c.gracePeriod)
134+
registrationClient.GracefulShutdown(ctx, c.gracePeriod)
119135
c.observer.log.Info().
120136
Int(management.EventTypeKey, int(management.Cloudflared)).
121137
Uint8(LogFieldConnIndex, c.connIndex).

connection/http2.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@ type HTTP2Connection struct {
4040
connOptions *tunnelpogs.ConnectionOptions
4141
observer *Observer
4242
connIndex uint8
43-
// newRPCClientFunc allows us to mock RPCs during testing
44-
newRPCClientFunc func(context.Context, io.ReadWriteCloser, *zerolog.Logger) NamedTunnelRPCClient
4543

4644
log *zerolog.Logger
4745
activeRequestsWG sync.WaitGroup
@@ -69,7 +67,6 @@ func NewHTTP2Connection(
6967
connOptions: connOptions,
7068
observer: observer,
7169
connIndex: connIndex,
72-
newRPCClientFunc: newRegistrationRPCClient,
7370
controlStreamHandler: controlStreamHandler,
7471
log: log,
7572
}

connection/http2_test.go

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ import (
2020
"github.com/stretchr/testify/require"
2121
"golang.org/x/net/http2"
2222

23+
"github.com/cloudflare/cloudflared/tunnelrpc"
2324
"github.com/cloudflare/cloudflared/tunnelrpc/pogs"
24-
tunnelpogs "github.com/cloudflare/cloudflared/tunnelrpc/pogs"
2525
)
2626

2727
var (
@@ -36,10 +36,11 @@ func newTestHTTP2Connection() (*HTTP2Connection, net.Conn) {
3636
controlStream := NewControlStream(
3737
obs,
3838
mockConnectedFuse{},
39-
&NamedTunnelProperties{},
39+
&TunnelProperties{},
4040
connIndex,
4141
nil,
4242
nil,
43+
1*time.Second,
4344
nil,
4445
1*time.Second,
4546
HTTP2,
@@ -168,23 +169,23 @@ type mockNamedTunnelRPCClient struct {
168169
unregistered chan struct{}
169170
}
170171

171-
func (mc mockNamedTunnelRPCClient) SendLocalConfiguration(c context.Context, config []byte, observer *Observer) error {
172+
func (mc mockNamedTunnelRPCClient) SendLocalConfiguration(c context.Context, config []byte) error {
172173
return nil
173174
}
174175

175176
func (mc mockNamedTunnelRPCClient) RegisterConnection(
176-
c context.Context,
177-
properties *NamedTunnelProperties,
178-
options *tunnelpogs.ConnectionOptions,
177+
ctx context.Context,
178+
auth pogs.TunnelAuth,
179+
tunnelID uuid.UUID,
180+
options *pogs.ConnectionOptions,
179181
connIndex uint8,
180182
edgeAddress net.IP,
181-
observer *Observer,
182-
) (*tunnelpogs.ConnectionDetails, error) {
183+
) (*pogs.ConnectionDetails, error) {
183184
if mc.shouldFail != nil {
184185
return nil, mc.shouldFail
185186
}
186187
close(mc.registered)
187-
return &tunnelpogs.ConnectionDetails{
188+
return &pogs.ConnectionDetails{
188189
Location: "LIS",
189190
UUID: uuid.New(),
190191
TunnelIsRemotelyManaged: false,
@@ -203,8 +204,8 @@ type mockRPCClientFactory struct {
203204
unregistered chan struct{}
204205
}
205206

206-
func (mf *mockRPCClientFactory) newMockRPCClient(context.Context, io.ReadWriteCloser, *zerolog.Logger) NamedTunnelRPCClient {
207-
return mockNamedTunnelRPCClient{
207+
func (mf *mockRPCClientFactory) newMockRPCClient(context.Context, io.ReadWriteCloser, time.Duration) tunnelrpc.RegistrationClient {
208+
return &mockNamedTunnelRPCClient{
208209
shouldFail: mf.shouldFail,
209210
registered: mf.registered,
210211
unregistered: mf.unregistered,
@@ -360,10 +361,11 @@ func TestServeControlStream(t *testing.T) {
360361
controlStream := NewControlStream(
361362
obs,
362363
mockConnectedFuse{},
363-
&NamedTunnelProperties{},
364+
&TunnelProperties{},
364365
1,
365366
nil,
366367
rpcClientFactory.newMockRPCClient,
368+
1*time.Second,
367369
nil,
368370
1*time.Second,
369371
HTTP2,
@@ -412,10 +414,11 @@ func TestFailRegistration(t *testing.T) {
412414
controlStream := NewControlStream(
413415
obs,
414416
mockConnectedFuse{},
415-
&NamedTunnelProperties{},
417+
&TunnelProperties{},
416418
http2Conn.connIndex,
417419
nil,
418420
rpcClientFactory.newMockRPCClient,
421+
1*time.Second,
419422
nil,
420423
1*time.Second,
421424
HTTP2,
@@ -460,10 +463,11 @@ func TestGracefulShutdownHTTP2(t *testing.T) {
460463
controlStream := NewControlStream(
461464
obs,
462465
mockConnectedFuse{},
463-
&NamedTunnelProperties{},
466+
&TunnelProperties{},
464467
http2Conn.connIndex,
465468
nil,
466469
rpcClientFactory.newMockRPCClient,
470+
1*time.Second,
467471
shutdownC,
468472
1*time.Second,
469473
HTTP2,

0 commit comments

Comments
 (0)