TUN-8423: Deprecate older legacy tunnel capnp interfaces
Since legacy tunnels have been removed for a while now, we can remove many of the capnp rpc interfaces that are no longer leveraged by the legacy tunnel registration and authentication mechanisms.
This commit is contained in:
parent
e9f010111d
commit
43446bc692
|
@ -663,9 +663,9 @@ func tunnelFlags(shouldHide bool) []cli.Flag {
|
||||||
}),
|
}),
|
||||||
altsrc.NewStringSliceFlag(&cli.StringSliceFlag{
|
altsrc.NewStringSliceFlag(&cli.StringSliceFlag{
|
||||||
Name: "tag",
|
Name: "tag",
|
||||||
Usage: "Custom tags used to identify this tunnel, in format `KEY=VALUE`. Multiple tags may be specified",
|
Usage: "Custom tags used to identify this tunnel via added HTTP request headers to the origin, in format `KEY=VALUE`. Multiple tags may be specified.",
|
||||||
EnvVars: []string{"TUNNEL_TAG"},
|
EnvVars: []string{"TUNNEL_TAG"},
|
||||||
Hidden: shouldHide,
|
Hidden: true,
|
||||||
}),
|
}),
|
||||||
altsrc.NewDurationFlag(&cli.DurationFlag{
|
altsrc.NewDurationFlag(&cli.DurationFlag{
|
||||||
Name: "heartbeat-interval",
|
Name: "heartbeat-interval",
|
||||||
|
|
|
@ -27,7 +27,7 @@ import (
|
||||||
"github.com/cloudflare/cloudflared/orchestration"
|
"github.com/cloudflare/cloudflared/orchestration"
|
||||||
"github.com/cloudflare/cloudflared/supervisor"
|
"github.com/cloudflare/cloudflared/supervisor"
|
||||||
"github.com/cloudflare/cloudflared/tlsconfig"
|
"github.com/cloudflare/cloudflared/tlsconfig"
|
||||||
tunnelpogs "github.com/cloudflare/cloudflared/tunnelrpc/pogs"
|
"github.com/cloudflare/cloudflared/tunnelrpc/pogs"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -133,7 +133,7 @@ func prepareTunnelConfig(
|
||||||
log.Err(err).Msg("Tag parse failure")
|
log.Err(err).Msg("Tag parse failure")
|
||||||
return nil, nil, errors.Wrap(err, "Tag parse failure")
|
return nil, nil, errors.Wrap(err, "Tag parse failure")
|
||||||
}
|
}
|
||||||
tags = append(tags, tunnelpogs.Tag{Name: "ID", Value: clientID.String()})
|
tags = append(tags, pogs.Tag{Name: "ID", Value: clientID.String()})
|
||||||
|
|
||||||
transportProtocol := c.String("protocol")
|
transportProtocol := c.String("protocol")
|
||||||
|
|
||||||
|
@ -166,7 +166,7 @@ func prepareTunnelConfig(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
namedTunnel.Client = tunnelpogs.ClientInfo{
|
namedTunnel.Client = pogs.ClientInfo{
|
||||||
ClientID: clientID[:],
|
ClientID: clientID[:],
|
||||||
Features: clientFeatures,
|
Features: clientFeatures,
|
||||||
Version: info.Version(),
|
Version: info.Version(),
|
||||||
|
|
|
@ -4,23 +4,23 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
|
||||||
tunnelpogs "github.com/cloudflare/cloudflared/tunnelrpc/pogs"
|
"github.com/cloudflare/cloudflared/tunnelrpc/pogs"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Restrict key names to characters allowed in an HTTP header name.
|
// Restrict key names to characters allowed in an HTTP header name.
|
||||||
// Restrict key values to printable characters (what is recognised as data in an HTTP header value).
|
// Restrict key values to printable characters (what is recognised as data in an HTTP header value).
|
||||||
var tagRegexp = regexp.MustCompile("^([a-zA-Z0-9!#$%&'*+\\-.^_`|~]+)=([[:print:]]+)$")
|
var tagRegexp = regexp.MustCompile("^([a-zA-Z0-9!#$%&'*+\\-.^_`|~]+)=([[:print:]]+)$")
|
||||||
|
|
||||||
func NewTagFromCLI(compoundTag string) (tunnelpogs.Tag, bool) {
|
func NewTagFromCLI(compoundTag string) (pogs.Tag, bool) {
|
||||||
matches := tagRegexp.FindStringSubmatch(compoundTag)
|
matches := tagRegexp.FindStringSubmatch(compoundTag)
|
||||||
if len(matches) == 0 {
|
if len(matches) == 0 {
|
||||||
return tunnelpogs.Tag{}, false
|
return pogs.Tag{}, false
|
||||||
}
|
}
|
||||||
return tunnelpogs.Tag{Name: matches[1], Value: matches[2]}, true
|
return pogs.Tag{Name: matches[1], Value: matches[2]}, true
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTagSliceFromCLI(tags []string) ([]tunnelpogs.Tag, error) {
|
func NewTagSliceFromCLI(tags []string) ([]pogs.Tag, error) {
|
||||||
var tagSlice []tunnelpogs.Tag
|
var tagSlice []pogs.Tag
|
||||||
for _, compoundTag := range tags {
|
for _, compoundTag := range tags {
|
||||||
if tag, ok := NewTagFromCLI(compoundTag); ok {
|
if tag, ok := NewTagFromCLI(compoundTag); ok {
|
||||||
tagSlice = append(tagSlice, tag)
|
tagSlice = append(tagSlice, tag)
|
||||||
|
|
|
@ -3,7 +3,7 @@ package tunnel
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
tunnelpogs "github.com/cloudflare/cloudflared/tunnelrpc/pogs"
|
"github.com/cloudflare/cloudflared/tunnelrpc/pogs"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
@ -11,12 +11,12 @@ import (
|
||||||
func TestSingleTag(t *testing.T) {
|
func TestSingleTag(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
Input string
|
Input string
|
||||||
Output tunnelpogs.Tag
|
Output pogs.Tag
|
||||||
Fail bool
|
Fail bool
|
||||||
}{
|
}{
|
||||||
{Input: "x=y", Output: tunnelpogs.Tag{Name: "x", Value: "y"}},
|
{Input: "x=y", Output: pogs.Tag{Name: "x", Value: "y"}},
|
||||||
{Input: "More-Complex=Tag Values", Output: tunnelpogs.Tag{Name: "More-Complex", Value: "Tag Values"}},
|
{Input: "More-Complex=Tag Values", Output: pogs.Tag{Name: "More-Complex", Value: "Tag Values"}},
|
||||||
{Input: "First=Equals=Wins", Output: tunnelpogs.Tag{Name: "First", Value: "Equals=Wins"}},
|
{Input: "First=Equals=Wins", Output: pogs.Tag{Name: "First", Value: "Equals=Wins"}},
|
||||||
{Input: "x=", Fail: true},
|
{Input: "x=", Fail: true},
|
||||||
{Input: "=y", Fail: true},
|
{Input: "=y", Fail: true},
|
||||||
{Input: "=", Fail: true},
|
{Input: "=", Fail: true},
|
||||||
|
|
|
@ -12,41 +12,6 @@ import (
|
||||||
tunnelpogs "github.com/cloudflare/cloudflared/tunnelrpc/pogs"
|
tunnelpogs "github.com/cloudflare/cloudflared/tunnelrpc/pogs"
|
||||||
)
|
)
|
||||||
|
|
||||||
type tunnelServerClient struct {
|
|
||||||
client tunnelpogs.TunnelServer_PogsClient
|
|
||||||
transport rpc.Transport
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewTunnelRPCClient creates and returns a new RPC client, which will communicate using a stream on the given muxer.
|
|
||||||
// This method is exported for supervisor to call Authenticate RPC
|
|
||||||
func NewTunnelServerClient(
|
|
||||||
ctx context.Context,
|
|
||||||
stream io.ReadWriteCloser,
|
|
||||||
log *zerolog.Logger,
|
|
||||||
) *tunnelServerClient {
|
|
||||||
transport := rpc.StreamTransport(stream)
|
|
||||||
conn := rpc.NewConn(transport)
|
|
||||||
registrationClient := tunnelpogs.RegistrationServer_PogsClient{Client: conn.Bootstrap(ctx), Conn: conn}
|
|
||||||
return &tunnelServerClient{
|
|
||||||
client: tunnelpogs.TunnelServer_PogsClient{RegistrationServer_PogsClient: registrationClient, Client: conn.Bootstrap(ctx), Conn: conn},
|
|
||||||
transport: transport,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tsc *tunnelServerClient) Authenticate(ctx context.Context, classicTunnel *ClassicTunnelProperties, registrationOptions *tunnelpogs.RegistrationOptions) (tunnelpogs.AuthOutcome, error) {
|
|
||||||
authResp, err := tsc.client.Authenticate(ctx, classicTunnel.OriginCert, classicTunnel.Hostname, registrationOptions)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return authResp.Outcome(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tsc *tunnelServerClient) Close() {
|
|
||||||
// Closing the client will also close the connection
|
|
||||||
_ = tsc.client.Close()
|
|
||||||
_ = tsc.transport.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
type NamedTunnelRPCClient interface {
|
type NamedTunnelRPCClient interface {
|
||||||
RegisterConnection(
|
RegisterConnection(
|
||||||
c context.Context,
|
c context.Context,
|
||||||
|
|
|
@ -14,7 +14,7 @@ import (
|
||||||
"github.com/cloudflare/cloudflared/connection"
|
"github.com/cloudflare/cloudflared/connection"
|
||||||
"github.com/cloudflare/cloudflared/ingress"
|
"github.com/cloudflare/cloudflared/ingress"
|
||||||
"github.com/cloudflare/cloudflared/proxy"
|
"github.com/cloudflare/cloudflared/proxy"
|
||||||
tunnelpogs "github.com/cloudflare/cloudflared/tunnelrpc/pogs"
|
"github.com/cloudflare/cloudflared/tunnelrpc/pogs"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Orchestrator manages configurations, so they can be updatable during runtime
|
// Orchestrator manages configurations, so they can be updatable during runtime
|
||||||
|
@ -32,7 +32,7 @@ type Orchestrator struct {
|
||||||
internalRules []ingress.Rule
|
internalRules []ingress.Rule
|
||||||
// cloudflared Configuration
|
// cloudflared Configuration
|
||||||
config *Config
|
config *Config
|
||||||
tags []tunnelpogs.Tag
|
tags []pogs.Tag
|
||||||
log *zerolog.Logger
|
log *zerolog.Logger
|
||||||
|
|
||||||
// orchestrator must not handle any more updates after shutdownC is closed
|
// orchestrator must not handle any more updates after shutdownC is closed
|
||||||
|
@ -43,7 +43,7 @@ type Orchestrator struct {
|
||||||
|
|
||||||
func NewOrchestrator(ctx context.Context,
|
func NewOrchestrator(ctx context.Context,
|
||||||
config *Config,
|
config *Config,
|
||||||
tags []tunnelpogs.Tag,
|
tags []pogs.Tag,
|
||||||
internalRules []ingress.Rule,
|
internalRules []ingress.Rule,
|
||||||
log *zerolog.Logger) (*Orchestrator, error) {
|
log *zerolog.Logger) (*Orchestrator, error) {
|
||||||
o := &Orchestrator{
|
o := &Orchestrator{
|
||||||
|
@ -65,7 +65,7 @@ func NewOrchestrator(ctx context.Context,
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateConfig creates a new proxy with the new ingress rules
|
// UpdateConfig creates a new proxy with the new ingress rules
|
||||||
func (o *Orchestrator) UpdateConfig(version int32, config []byte) *tunnelpogs.UpdateConfigurationResponse {
|
func (o *Orchestrator) UpdateConfig(version int32, config []byte) *pogs.UpdateConfigurationResponse {
|
||||||
o.lock.Lock()
|
o.lock.Lock()
|
||||||
defer o.lock.Unlock()
|
defer o.lock.Unlock()
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ func (o *Orchestrator) UpdateConfig(version int32, config []byte) *tunnelpogs.Up
|
||||||
Int32("current_version", o.currentVersion).
|
Int32("current_version", o.currentVersion).
|
||||||
Int32("received_version", version).
|
Int32("received_version", version).
|
||||||
Msg("Current version is equal or newer than received version")
|
Msg("Current version is equal or newer than received version")
|
||||||
return &tunnelpogs.UpdateConfigurationResponse{
|
return &pogs.UpdateConfigurationResponse{
|
||||||
LastAppliedVersion: o.currentVersion,
|
LastAppliedVersion: o.currentVersion,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,7 @@ func (o *Orchestrator) UpdateConfig(version int32, config []byte) *tunnelpogs.Up
|
||||||
Int32("version", version).
|
Int32("version", version).
|
||||||
Str("config", string(config)).
|
Str("config", string(config)).
|
||||||
Msgf("Failed to deserialize new configuration")
|
Msgf("Failed to deserialize new configuration")
|
||||||
return &tunnelpogs.UpdateConfigurationResponse{
|
return &pogs.UpdateConfigurationResponse{
|
||||||
LastAppliedVersion: o.currentVersion,
|
LastAppliedVersion: o.currentVersion,
|
||||||
Err: err,
|
Err: err,
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,7 @@ func (o *Orchestrator) UpdateConfig(version int32, config []byte) *tunnelpogs.Up
|
||||||
Int32("version", version).
|
Int32("version", version).
|
||||||
Str("config", string(config)).
|
Str("config", string(config)).
|
||||||
Msgf("Failed to update ingress")
|
Msgf("Failed to update ingress")
|
||||||
return &tunnelpogs.UpdateConfigurationResponse{
|
return &pogs.UpdateConfigurationResponse{
|
||||||
LastAppliedVersion: o.currentVersion,
|
LastAppliedVersion: o.currentVersion,
|
||||||
Err: err,
|
Err: err,
|
||||||
}
|
}
|
||||||
|
@ -107,7 +107,7 @@ func (o *Orchestrator) UpdateConfig(version int32, config []byte) *tunnelpogs.Up
|
||||||
Str("config", string(config)).
|
Str("config", string(config)).
|
||||||
Msg("Updated to new configuration")
|
Msg("Updated to new configuration")
|
||||||
configVersion.Set(float64(version))
|
configVersion.Set(float64(version))
|
||||||
return &tunnelpogs.UpdateConfigurationResponse{
|
return &pogs.UpdateConfigurationResponse{
|
||||||
LastAppliedVersion: o.currentVersion,
|
LastAppliedVersion: o.currentVersion,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,12 +23,12 @@ import (
|
||||||
"github.com/cloudflare/cloudflared/ingress"
|
"github.com/cloudflare/cloudflared/ingress"
|
||||||
"github.com/cloudflare/cloudflared/management"
|
"github.com/cloudflare/cloudflared/management"
|
||||||
"github.com/cloudflare/cloudflared/tracing"
|
"github.com/cloudflare/cloudflared/tracing"
|
||||||
tunnelpogs "github.com/cloudflare/cloudflared/tunnelrpc/pogs"
|
"github.com/cloudflare/cloudflared/tunnelrpc/pogs"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
testLogger = zerolog.Nop()
|
testLogger = zerolog.Nop()
|
||||||
testTags = []tunnelpogs.Tag{
|
testTags = []pogs.Tag{
|
||||||
{
|
{
|
||||||
Name: "package",
|
Name: "package",
|
||||||
Value: "orchestration",
|
Value: "orchestration",
|
||||||
|
|
|
@ -19,7 +19,7 @@ import (
|
||||||
"github.com/cloudflare/cloudflared/ingress"
|
"github.com/cloudflare/cloudflared/ingress"
|
||||||
"github.com/cloudflare/cloudflared/stream"
|
"github.com/cloudflare/cloudflared/stream"
|
||||||
"github.com/cloudflare/cloudflared/tracing"
|
"github.com/cloudflare/cloudflared/tracing"
|
||||||
tunnelpogs "github.com/cloudflare/cloudflared/tunnelrpc/pogs"
|
"github.com/cloudflare/cloudflared/tunnelrpc/pogs"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -33,7 +33,7 @@ type Proxy struct {
|
||||||
ingressRules ingress.Ingress
|
ingressRules ingress.Ingress
|
||||||
warpRouting *ingress.WarpRoutingService
|
warpRouting *ingress.WarpRoutingService
|
||||||
management *ingress.ManagementService
|
management *ingress.ManagementService
|
||||||
tags []tunnelpogs.Tag
|
tags []pogs.Tag
|
||||||
log *zerolog.Logger
|
log *zerolog.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ type Proxy struct {
|
||||||
func NewOriginProxy(
|
func NewOriginProxy(
|
||||||
ingressRules ingress.Ingress,
|
ingressRules ingress.Ingress,
|
||||||
warpRouting ingress.WarpRoutingConfig,
|
warpRouting ingress.WarpRoutingConfig,
|
||||||
tags []tunnelpogs.Tag,
|
tags []pogs.Tag,
|
||||||
writeTimeout time.Duration,
|
writeTimeout time.Duration,
|
||||||
log *zerolog.Logger,
|
log *zerolog.Logger,
|
||||||
) *Proxy {
|
) *Proxy {
|
||||||
|
|
|
@ -30,11 +30,11 @@ import (
|
||||||
"github.com/cloudflare/cloudflared/ingress"
|
"github.com/cloudflare/cloudflared/ingress"
|
||||||
"github.com/cloudflare/cloudflared/logger"
|
"github.com/cloudflare/cloudflared/logger"
|
||||||
"github.com/cloudflare/cloudflared/tracing"
|
"github.com/cloudflare/cloudflared/tracing"
|
||||||
tunnelpogs "github.com/cloudflare/cloudflared/tunnelrpc/pogs"
|
"github.com/cloudflare/cloudflared/tunnelrpc/pogs"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
testTags = []tunnelpogs.Tag{{Name: "Name", Value: "value"}}
|
testTags = []pogs.Tag{{Name: "Name", Value: "value"}}
|
||||||
noWarpRouting = ingress.WarpRoutingConfig{}
|
noWarpRouting = ingress.WarpRoutingConfig{}
|
||||||
testWarpRouting = ingress.WarpRoutingConfig{
|
testWarpRouting = ingress.WarpRoutingConfig{
|
||||||
ConnectTimeout: config.CustomDuration{Duration: time.Second},
|
ConnectTimeout: config.CustomDuration{Duration: time.Second},
|
||||||
|
|
|
@ -10,7 +10,6 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/quic-go/quic-go"
|
"github.com/quic-go/quic-go"
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
|
@ -27,8 +26,7 @@ import (
|
||||||
quicpogs "github.com/cloudflare/cloudflared/quic"
|
quicpogs "github.com/cloudflare/cloudflared/quic"
|
||||||
"github.com/cloudflare/cloudflared/retry"
|
"github.com/cloudflare/cloudflared/retry"
|
||||||
"github.com/cloudflare/cloudflared/signal"
|
"github.com/cloudflare/cloudflared/signal"
|
||||||
tunnelpogs "github.com/cloudflare/cloudflared/tunnelrpc/pogs"
|
"github.com/cloudflare/cloudflared/tunnelrpc/pogs"
|
||||||
"github.com/cloudflare/cloudflared/tunnelrpc/proto"
|
|
||||||
"github.com/cloudflare/cloudflared/tunnelstate"
|
"github.com/cloudflare/cloudflared/tunnelstate"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -49,7 +47,7 @@ type TunnelConfig struct {
|
||||||
HAConnections int
|
HAConnections int
|
||||||
IsAutoupdated bool
|
IsAutoupdated bool
|
||||||
LBPool string
|
LBPool string
|
||||||
Tags []tunnelpogs.Tag
|
Tags []pogs.Tag
|
||||||
Log *zerolog.Logger
|
Log *zerolog.Logger
|
||||||
LogTransport *zerolog.Logger
|
LogTransport *zerolog.Logger
|
||||||
Observer *connection.Observer
|
Observer *connection.Observer
|
||||||
|
@ -73,34 +71,12 @@ type TunnelConfig struct {
|
||||||
FeatureSelector *features.FeatureSelector
|
FeatureSelector *features.FeatureSelector
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *TunnelConfig) registrationOptions(connectionID uint8, OriginLocalIP string, uuid uuid.UUID) *tunnelpogs.RegistrationOptions {
|
func (c *TunnelConfig) connectionOptions(originLocalAddr string, numPreviousAttempts uint8) *pogs.ConnectionOptions {
|
||||||
policy := proto.ExistingTunnelPolicy_balance
|
|
||||||
if c.HAConnections <= 1 && c.LBPool == "" {
|
|
||||||
policy = proto.ExistingTunnelPolicy_disconnect
|
|
||||||
}
|
|
||||||
return &tunnelpogs.RegistrationOptions{
|
|
||||||
ClientID: c.ClientID,
|
|
||||||
Version: c.ReportedVersion,
|
|
||||||
OS: c.OSArch,
|
|
||||||
ExistingTunnelPolicy: policy,
|
|
||||||
PoolName: c.LBPool,
|
|
||||||
Tags: c.Tags,
|
|
||||||
ConnectionID: connectionID,
|
|
||||||
OriginLocalIP: OriginLocalIP,
|
|
||||||
IsAutoupdated: c.IsAutoupdated,
|
|
||||||
RunFromTerminal: c.RunFromTerminal,
|
|
||||||
CompressionQuality: 0,
|
|
||||||
UUID: uuid.String(),
|
|
||||||
Features: c.SupportedFeatures(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *TunnelConfig) connectionOptions(originLocalAddr string, numPreviousAttempts uint8) *tunnelpogs.ConnectionOptions {
|
|
||||||
// attempt to parse out origin IP, but don't fail since it's informational field
|
// attempt to parse out origin IP, but don't fail since it's informational field
|
||||||
host, _, _ := net.SplitHostPort(originLocalAddr)
|
host, _, _ := net.SplitHostPort(originLocalAddr)
|
||||||
originIP := net.ParseIP(host)
|
originIP := net.ParseIP(host)
|
||||||
|
|
||||||
return &tunnelpogs.ConnectionOptions{
|
return &pogs.ConnectionOptions{
|
||||||
Client: c.NamedTunnel.Client,
|
Client: c.NamedTunnel.Client,
|
||||||
OriginLocalIP: originIP,
|
OriginLocalIP: originIP,
|
||||||
ReplaceExisting: c.ReplaceExisting,
|
ReplaceExisting: c.ReplaceExisting,
|
||||||
|
@ -530,7 +506,7 @@ func (e *EdgeTunnelServer) serveHTTP2(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
connLog *ConnAwareLogger,
|
connLog *ConnAwareLogger,
|
||||||
tlsServerConn net.Conn,
|
tlsServerConn net.Conn,
|
||||||
connOptions *tunnelpogs.ConnectionOptions,
|
connOptions *pogs.ConnectionOptions,
|
||||||
controlStreamHandler connection.ControlStreamHandler,
|
controlStreamHandler connection.ControlStreamHandler,
|
||||||
connIndex uint8,
|
connIndex uint8,
|
||||||
) error {
|
) error {
|
||||||
|
@ -572,7 +548,7 @@ func (e *EdgeTunnelServer) serveQUIC(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
edgeAddr *net.UDPAddr,
|
edgeAddr *net.UDPAddr,
|
||||||
connLogger *ConnAwareLogger,
|
connLogger *ConnAwareLogger,
|
||||||
connOptions *tunnelpogs.ConnectionOptions,
|
connOptions *pogs.ConnectionOptions,
|
||||||
controlStreamHandler connection.ControlStreamHandler,
|
controlStreamHandler connection.ControlStreamHandler,
|
||||||
connIndex uint8,
|
connIndex uint8,
|
||||||
) (err error, recoverable bool) {
|
) (err error, recoverable bool) {
|
||||||
|
|
|
@ -1,131 +0,0 @@
|
||||||
package pogs
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// AuthenticateResponse is the serialized response from the Authenticate RPC.
|
|
||||||
// It's a 1:1 representation of the capnp message, so it's not very useful for programmers.
|
|
||||||
// Instead, you should call the `Outcome()` method to get a programmer-friendly sum type, with one
|
|
||||||
// case for each possible outcome.
|
|
||||||
type AuthenticateResponse struct {
|
|
||||||
PermanentErr string
|
|
||||||
RetryableErr string
|
|
||||||
Jwt []byte
|
|
||||||
HoursUntilRefresh uint8
|
|
||||||
}
|
|
||||||
|
|
||||||
// Outcome turns the deserialized response of Authenticate into a programmer-friendly sum type.
|
|
||||||
func (ar AuthenticateResponse) Outcome() AuthOutcome {
|
|
||||||
// If the user's authentication was unsuccessful, the server will return an error explaining why.
|
|
||||||
// cloudflared should fatal with this error.
|
|
||||||
if ar.PermanentErr != "" {
|
|
||||||
return NewAuthFail(errors.New(ar.PermanentErr))
|
|
||||||
}
|
|
||||||
|
|
||||||
// If there was a network error, then cloudflared should retry later,
|
|
||||||
// because origintunneld couldn't prove whether auth was correct or not.
|
|
||||||
if ar.RetryableErr != "" {
|
|
||||||
return NewAuthUnknown(errors.New(ar.RetryableErr), ar.HoursUntilRefresh)
|
|
||||||
}
|
|
||||||
|
|
||||||
// If auth succeeded, return the token and refresh it when instructed.
|
|
||||||
if len(ar.Jwt) > 0 {
|
|
||||||
return NewAuthSuccess(ar.Jwt, ar.HoursUntilRefresh)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise the state got messed up.
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// AuthOutcome is a programmer-friendly sum type denoting the possible outcomes of Authenticate.
|
|
||||||
type AuthOutcome interface {
|
|
||||||
isAuthOutcome()
|
|
||||||
// Serialize into an AuthenticateResponse which can be sent via Capnp
|
|
||||||
Serialize() AuthenticateResponse
|
|
||||||
}
|
|
||||||
|
|
||||||
// AuthSuccess means the backend successfully authenticated this cloudflared.
|
|
||||||
type AuthSuccess struct {
|
|
||||||
jwt []byte
|
|
||||||
hoursUntilRefresh uint8
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewAuthSuccess(jwt []byte, hoursUntilRefresh uint8) AuthSuccess {
|
|
||||||
return AuthSuccess{jwt: jwt, hoursUntilRefresh: hoursUntilRefresh}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ao AuthSuccess) JWT() []byte {
|
|
||||||
return ao.jwt
|
|
||||||
}
|
|
||||||
|
|
||||||
// RefreshAfter is how long cloudflared should wait before rerunning Authenticate.
|
|
||||||
func (ao AuthSuccess) RefreshAfter() time.Duration {
|
|
||||||
return hoursToTime(ao.hoursUntilRefresh)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Serialize into an AuthenticateResponse which can be sent via Capnp
|
|
||||||
func (ao AuthSuccess) Serialize() AuthenticateResponse {
|
|
||||||
return AuthenticateResponse{
|
|
||||||
Jwt: ao.jwt,
|
|
||||||
HoursUntilRefresh: ao.hoursUntilRefresh,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ao AuthSuccess) isAuthOutcome() {}
|
|
||||||
|
|
||||||
// AuthFail means this cloudflared has the wrong auth and should exit.
|
|
||||||
type AuthFail struct {
|
|
||||||
err error
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewAuthFail(err error) AuthFail {
|
|
||||||
return AuthFail{err: err}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ao AuthFail) Error() string {
|
|
||||||
return ao.err.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Serialize into an AuthenticateResponse which can be sent via Capnp
|
|
||||||
func (ao AuthFail) Serialize() AuthenticateResponse {
|
|
||||||
return AuthenticateResponse{
|
|
||||||
PermanentErr: ao.err.Error(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ao AuthFail) isAuthOutcome() {}
|
|
||||||
|
|
||||||
// AuthUnknown means the backend couldn't finish checking authentication. Try again later.
|
|
||||||
type AuthUnknown struct {
|
|
||||||
err error
|
|
||||||
hoursUntilRefresh uint8
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewAuthUnknown(err error, hoursUntilRefresh uint8) AuthUnknown {
|
|
||||||
return AuthUnknown{err: err, hoursUntilRefresh: hoursUntilRefresh}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ao AuthUnknown) Error() string {
|
|
||||||
return ao.err.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
// RefreshAfter is how long cloudflared should wait before rerunning Authenticate.
|
|
||||||
func (ao AuthUnknown) RefreshAfter() time.Duration {
|
|
||||||
return hoursToTime(ao.hoursUntilRefresh)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Serialize into an AuthenticateResponse which can be sent via Capnp
|
|
||||||
func (ao AuthUnknown) Serialize() AuthenticateResponse {
|
|
||||||
return AuthenticateResponse{
|
|
||||||
RetryableErr: ao.err.Error(),
|
|
||||||
HoursUntilRefresh: ao.hoursUntilRefresh,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ao AuthUnknown) isAuthOutcome() {}
|
|
||||||
|
|
||||||
func hoursToTime(hours uint8) time.Duration {
|
|
||||||
return time.Duration(hours) * time.Hour
|
|
||||||
}
|
|
|
@ -1,78 +0,0 @@
|
||||||
package pogs
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"zombiezen.com/go/capnproto2/pogs"
|
|
||||||
"zombiezen.com/go/capnproto2/server"
|
|
||||||
|
|
||||||
"github.com/cloudflare/cloudflared/tunnelrpc/proto"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (i TunnelServer_PogsImpl) Authenticate(p proto.TunnelServer_authenticate) error {
|
|
||||||
originCert, err := p.Params.OriginCert()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
hostname, err := p.Params.Hostname()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
options, err := p.Params.Options()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
pogsOptions, err := UnmarshalRegistrationOptions(options)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
server.Ack(p.Options)
|
|
||||||
resp, err := i.impl.Authenticate(p.Ctx, originCert, hostname, pogsOptions)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
result, err := p.Results.NewResult()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return MarshalAuthenticateResponse(result, resp)
|
|
||||||
}
|
|
||||||
|
|
||||||
func MarshalAuthenticateResponse(s proto.AuthenticateResponse, p *AuthenticateResponse) error {
|
|
||||||
return pogs.Insert(proto.AuthenticateResponse_TypeID, s.Struct, p)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c TunnelServer_PogsClient) Authenticate(ctx context.Context, originCert []byte, hostname string, options *RegistrationOptions) (*AuthenticateResponse, error) {
|
|
||||||
client := proto.TunnelServer{Client: c.Client}
|
|
||||||
promise := client.Authenticate(ctx, func(p proto.TunnelServer_authenticate_Params) error {
|
|
||||||
err := p.SetOriginCert(originCert)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = p.SetHostname(hostname)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
registrationOptions, err := p.NewOptions()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = MarshalRegistrationOptions(registrationOptions, options)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
retval, err := promise.Result().Struct()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return UnmarshalAuthenticateResponse(retval)
|
|
||||||
}
|
|
||||||
|
|
||||||
func UnmarshalAuthenticateResponse(s proto.AuthenticateResponse) (*AuthenticateResponse, error) {
|
|
||||||
p := new(AuthenticateResponse)
|
|
||||||
err := pogs.Extract(p, proto.AuthenticateResponse_TypeID, s.Struct)
|
|
||||||
return p, err
|
|
||||||
}
|
|
|
@ -1,136 +0,0 @@
|
||||||
package pogs
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"reflect"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
capnp "zombiezen.com/go/capnproto2"
|
|
||||||
|
|
||||||
"github.com/cloudflare/cloudflared/tunnelrpc/proto"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Ensure the AuthOutcome sum is correct
|
|
||||||
var _ AuthOutcome = &AuthSuccess{}
|
|
||||||
var _ AuthOutcome = &AuthFail{}
|
|
||||||
var _ AuthOutcome = &AuthUnknown{}
|
|
||||||
|
|
||||||
// Unit tests for AuthenticateResponse.Outcome()
|
|
||||||
func TestAuthenticateResponseOutcome(t *testing.T) {
|
|
||||||
type fields struct {
|
|
||||||
PermanentErr string
|
|
||||||
RetryableErr string
|
|
||||||
Jwt []byte
|
|
||||||
HoursUntilRefresh uint8
|
|
||||||
}
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
fields fields
|
|
||||||
want AuthOutcome
|
|
||||||
}{
|
|
||||||
{"success",
|
|
||||||
fields{Jwt: []byte("asdf"), HoursUntilRefresh: 6},
|
|
||||||
AuthSuccess{jwt: []byte("asdf"), hoursUntilRefresh: 6},
|
|
||||||
},
|
|
||||||
{"fail",
|
|
||||||
fields{PermanentErr: "bad creds"},
|
|
||||||
AuthFail{err: fmt.Errorf("bad creds")},
|
|
||||||
},
|
|
||||||
{"error",
|
|
||||||
fields{RetryableErr: "bad conn", HoursUntilRefresh: 6},
|
|
||||||
AuthUnknown{err: fmt.Errorf("bad conn"), hoursUntilRefresh: 6},
|
|
||||||
},
|
|
||||||
{"nil (no fields are set)",
|
|
||||||
fields{},
|
|
||||||
nil,
|
|
||||||
},
|
|
||||||
{"nil (too few fields are set)",
|
|
||||||
fields{HoursUntilRefresh: 6},
|
|
||||||
nil,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
ar := AuthenticateResponse{
|
|
||||||
PermanentErr: tt.fields.PermanentErr,
|
|
||||||
RetryableErr: tt.fields.RetryableErr,
|
|
||||||
Jwt: tt.fields.Jwt,
|
|
||||||
HoursUntilRefresh: tt.fields.HoursUntilRefresh,
|
|
||||||
}
|
|
||||||
got := ar.Outcome()
|
|
||||||
if !reflect.DeepEqual(got, tt.want) {
|
|
||||||
t.Errorf("AuthenticateResponse.Outcome() = %T, want %v", got, tt.want)
|
|
||||||
}
|
|
||||||
if got != nil && !reflect.DeepEqual(got.Serialize(), ar) {
|
|
||||||
t.Errorf(".Outcome() and .Serialize() should be inverses but weren't. Expected %v, got %v", ar, got.Serialize())
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAuthSuccess(t *testing.T) {
|
|
||||||
input := NewAuthSuccess([]byte("asdf"), 6)
|
|
||||||
output, ok := input.Serialize().Outcome().(AuthSuccess)
|
|
||||||
assert.True(t, ok)
|
|
||||||
assert.Equal(t, input, output)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAuthUnknown(t *testing.T) {
|
|
||||||
input := NewAuthUnknown(fmt.Errorf("pdx unreachable"), 6)
|
|
||||||
output, ok := input.Serialize().Outcome().(AuthUnknown)
|
|
||||||
assert.True(t, ok)
|
|
||||||
assert.Equal(t, input, output)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAuthFail(t *testing.T) {
|
|
||||||
input := NewAuthFail(fmt.Errorf("wrong creds"))
|
|
||||||
output, ok := input.Serialize().Outcome().(AuthFail)
|
|
||||||
assert.True(t, ok)
|
|
||||||
assert.Equal(t, input, output)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestWhenToRefresh(t *testing.T) {
|
|
||||||
expected := 4 * time.Hour
|
|
||||||
actual := hoursToTime(4)
|
|
||||||
if expected != actual {
|
|
||||||
t.Fatalf("expected %v hours, got %v", expected, actual)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test that serializing and deserializing AuthenticationResponse undo each other.
|
|
||||||
func TestSerializeAuthenticationResponse(t *testing.T) {
|
|
||||||
|
|
||||||
tests := []*AuthenticateResponse{
|
|
||||||
{
|
|
||||||
Jwt: []byte("\xbd\xb2\x3d\xbc\x20\xe2\x8c\x98"),
|
|
||||||
HoursUntilRefresh: 24,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
PermanentErr: "bad auth",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
RetryableErr: "bad connection",
|
|
||||||
HoursUntilRefresh: 24,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, testCase := range tests {
|
|
||||||
_, seg, err := capnp.NewMessage(capnp.SingleSegment(nil))
|
|
||||||
assert.NoError(t, err)
|
|
||||||
capnpEntity, err := proto.NewAuthenticateResponse(seg)
|
|
||||||
if !assert.NoError(t, err) {
|
|
||||||
t.Fatal("Couldn't initialize a new message")
|
|
||||||
}
|
|
||||||
err = MarshalAuthenticateResponse(capnpEntity, testCase)
|
|
||||||
if !assert.NoError(t, err, "testCase index %v failed to marshal", i) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
result, err := UnmarshalAuthenticateResponse(capnpEntity)
|
|
||||||
if !assert.NoError(t, err, "testCase index %v failed to unmarshal", i) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
assert.Equal(t, testCase, result, "testCase index %v didn't preserve struct through marshalling and unmarshalling", i)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,93 +0,0 @@
|
||||||
package pogs
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"zombiezen.com/go/capnproto2/server"
|
|
||||||
|
|
||||||
"github.com/cloudflare/cloudflared/tunnelrpc/proto"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (i TunnelServer_PogsImpl) ReconnectTunnel(p proto.TunnelServer_reconnectTunnel) error {
|
|
||||||
jwt, err := p.Params.Jwt()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
eventDigest, err := p.Params.EventDigest()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
connDigest, err := p.Params.ConnDigest()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
hostname, err := p.Params.Hostname()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
options, err := p.Params.Options()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
pogsOptions, err := UnmarshalRegistrationOptions(options)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
server.Ack(p.Options)
|
|
||||||
registration, err := i.impl.ReconnectTunnel(p.Ctx, jwt, eventDigest, connDigest, hostname, pogsOptions)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
result, err := p.Results.NewResult()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return MarshalTunnelRegistration(result, registration)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c TunnelServer_PogsClient) ReconnectTunnel(
|
|
||||||
ctx context.Context,
|
|
||||||
jwt,
|
|
||||||
eventDigest []byte,
|
|
||||||
connDigest []byte,
|
|
||||||
hostname string,
|
|
||||||
options *RegistrationOptions,
|
|
||||||
) *TunnelRegistration {
|
|
||||||
client := proto.TunnelServer{Client: c.Client}
|
|
||||||
promise := client.ReconnectTunnel(ctx, func(p proto.TunnelServer_reconnectTunnel_Params) error {
|
|
||||||
err := p.SetJwt(jwt)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = p.SetEventDigest(eventDigest)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = p.SetConnDigest(connDigest)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = p.SetHostname(hostname)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
registrationOptions, err := p.NewOptions()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = MarshalRegistrationOptions(registrationOptions, options)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
retval, err := promise.Result().Struct()
|
|
||||||
if err != nil {
|
|
||||||
return NewRetryableRegistrationError(err, defaultRetryAfterSeconds).Serialize()
|
|
||||||
}
|
|
||||||
registration, err := UnmarshalTunnelRegistration(retval)
|
|
||||||
if err != nil {
|
|
||||||
return NewRetryableRegistrationError(err, defaultRetryAfterSeconds).Serialize()
|
|
||||||
}
|
|
||||||
return registration
|
|
||||||
}
|
|
|
@ -54,18 +54,14 @@ func TestConnectionRegistrationRPC(t *testing.T) {
|
||||||
|
|
||||||
// Server-side
|
// Server-side
|
||||||
testImpl := testConnectionRegistrationServer{}
|
testImpl := testConnectionRegistrationServer{}
|
||||||
srv := TunnelServer_ServerToClient(&testImpl)
|
srv := RegistrationServer_ServerToClient(&testImpl)
|
||||||
serverConn := rpc.NewConn(t1, rpc.MainInterface(srv.Client))
|
serverConn := rpc.NewConn(t1, rpc.MainInterface(srv.Client))
|
||||||
defer serverConn.Wait()
|
defer serverConn.Wait()
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
clientConn := rpc.NewConn(t2)
|
clientConn := rpc.NewConn(t2)
|
||||||
defer clientConn.Close()
|
defer clientConn.Close()
|
||||||
client := TunnelServer_PogsClient{
|
client := RegistrationServer_PogsClient{
|
||||||
RegistrationServer_PogsClient: RegistrationServer_PogsClient{
|
|
||||||
Client: clientConn.Bootstrap(ctx),
|
|
||||||
Conn: clientConn,
|
|
||||||
},
|
|
||||||
Client: clientConn.Bootstrap(ctx),
|
Client: clientConn.Bootstrap(ctx),
|
||||||
Conn: clientConn,
|
Conn: clientConn,
|
||||||
}
|
}
|
||||||
|
@ -123,8 +119,6 @@ func TestConnectionRegistrationRPC(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type testConnectionRegistrationServer struct {
|
type testConnectionRegistrationServer struct {
|
||||||
mockTunnelServerBase
|
|
||||||
|
|
||||||
details *ConnectionDetails
|
details *ConnectionDetails
|
||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
|
@ -147,3 +141,7 @@ func (t *testConnectionRegistrationServer) RegisterConnection(ctx context.Contex
|
||||||
|
|
||||||
panic("either details or err mush be set")
|
panic("either details or err mush be set")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *testConnectionRegistrationServer) UnregisterConnection(ctx context.Context) {
|
||||||
|
panic("unimplemented: UnregisterConnection")
|
||||||
|
}
|
|
@ -1,40 +0,0 @@
|
||||||
package pogs
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/google/uuid"
|
|
||||||
)
|
|
||||||
|
|
||||||
// mockTunnelServerBase provides a placeholder implementation
|
|
||||||
// for TunnelServer interface that can be used to build
|
|
||||||
// mocks for specific unit tests without having to implement every method
|
|
||||||
type mockTunnelServerBase struct{}
|
|
||||||
|
|
||||||
func (mockTunnelServerBase) RegisterConnection(ctx context.Context, auth TunnelAuth, tunnelID uuid.UUID, connIndex byte, options *ConnectionOptions) (*ConnectionDetails, error) {
|
|
||||||
panic("unexpected call to RegisterConnection")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mockTunnelServerBase) UnregisterConnection(ctx context.Context) {
|
|
||||||
panic("unexpected call to UnregisterConnection")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mockTunnelServerBase) RegisterTunnel(ctx context.Context, originCert []byte, hostname string, options *RegistrationOptions) *TunnelRegistration {
|
|
||||||
panic("unexpected call to RegisterTunnel")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mockTunnelServerBase) GetServerInfo(ctx context.Context) (*ServerInfo, error) {
|
|
||||||
panic("unexpected call to GetServerInfo")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mockTunnelServerBase) UnregisterTunnel(ctx context.Context, gracePeriodNanoSec int64) error {
|
|
||||||
panic("unexpected call to UnregisterTunnel")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mockTunnelServerBase) Authenticate(ctx context.Context, originCert []byte, hostname string, options *RegistrationOptions) (*AuthenticateResponse, error) {
|
|
||||||
panic("unexpected call to Authenticate")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mockTunnelServerBase) ReconnectTunnel(ctx context.Context, jwt, eventDigest, connDigest []byte, hostname string, options *RegistrationOptions) (*TunnelRegistration, error) {
|
|
||||||
panic("unexpected call to ReconnectTunnel")
|
|
||||||
}
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
package pogs
|
||||||
|
|
||||||
|
// Tag previously was a legacy tunnel capnp struct but was deprecated. To help reduce the amount of changes imposed
|
||||||
|
// by removing this simple struct, it was copied out of the capnp and provided here instead.
|
||||||
|
type Tag struct {
|
||||||
|
Name string
|
||||||
|
Value string
|
||||||
|
}
|
|
@ -1,334 +0,0 @@
|
||||||
package pogs
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
capnp "zombiezen.com/go/capnproto2"
|
|
||||||
"zombiezen.com/go/capnproto2/pogs"
|
|
||||||
"zombiezen.com/go/capnproto2/rpc"
|
|
||||||
"zombiezen.com/go/capnproto2/server"
|
|
||||||
|
|
||||||
"github.com/cloudflare/cloudflared/tunnelrpc/proto"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
defaultRetryAfterSeconds = 15
|
|
||||||
)
|
|
||||||
|
|
||||||
type Authentication struct {
|
|
||||||
Key string
|
|
||||||
Email string
|
|
||||||
OriginCAKey string
|
|
||||||
}
|
|
||||||
|
|
||||||
func MarshalAuthentication(s proto.Authentication, p *Authentication) error {
|
|
||||||
return pogs.Insert(proto.Authentication_TypeID, s.Struct, p)
|
|
||||||
}
|
|
||||||
|
|
||||||
func UnmarshalAuthentication(s proto.Authentication) (*Authentication, error) {
|
|
||||||
p := new(Authentication)
|
|
||||||
err := pogs.Extract(p, proto.Authentication_TypeID, s.Struct)
|
|
||||||
return p, err
|
|
||||||
}
|
|
||||||
|
|
||||||
type TunnelRegistration struct {
|
|
||||||
SuccessfulTunnelRegistration
|
|
||||||
Err string
|
|
||||||
PermanentFailure bool
|
|
||||||
RetryAfterSeconds uint16
|
|
||||||
}
|
|
||||||
|
|
||||||
type SuccessfulTunnelRegistration struct {
|
|
||||||
Url string
|
|
||||||
LogLines []string
|
|
||||||
TunnelID string `capnp:"tunnelID"`
|
|
||||||
EventDigest []byte
|
|
||||||
ConnDigest []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewSuccessfulTunnelRegistration(
|
|
||||||
url string,
|
|
||||||
logLines []string,
|
|
||||||
tunnelID string,
|
|
||||||
eventDigest []byte,
|
|
||||||
connDigest []byte,
|
|
||||||
) *TunnelRegistration {
|
|
||||||
// Marshal nil will result in an error
|
|
||||||
if logLines == nil {
|
|
||||||
logLines = []string{}
|
|
||||||
}
|
|
||||||
return &TunnelRegistration{
|
|
||||||
SuccessfulTunnelRegistration: SuccessfulTunnelRegistration{
|
|
||||||
Url: url,
|
|
||||||
LogLines: logLines,
|
|
||||||
TunnelID: tunnelID,
|
|
||||||
EventDigest: eventDigest,
|
|
||||||
ConnDigest: connDigest,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Not calling this function Error() to avoid confusion with implementing error interface
|
|
||||||
func (tr TunnelRegistration) DeserializeError() TunnelRegistrationError {
|
|
||||||
if tr.Err != "" {
|
|
||||||
err := fmt.Errorf(tr.Err)
|
|
||||||
if tr.PermanentFailure {
|
|
||||||
return NewPermanentRegistrationError(err)
|
|
||||||
}
|
|
||||||
retryAfterSeconds := tr.RetryAfterSeconds
|
|
||||||
if retryAfterSeconds < defaultRetryAfterSeconds {
|
|
||||||
retryAfterSeconds = defaultRetryAfterSeconds
|
|
||||||
}
|
|
||||||
return NewRetryableRegistrationError(err, retryAfterSeconds)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type TunnelRegistrationError interface {
|
|
||||||
error
|
|
||||||
Serialize() *TunnelRegistration
|
|
||||||
IsPermanent() bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type PermanentRegistrationError struct {
|
|
||||||
err string
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewPermanentRegistrationError(err error) TunnelRegistrationError {
|
|
||||||
return &PermanentRegistrationError{
|
|
||||||
err: err.Error(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pre *PermanentRegistrationError) Error() string {
|
|
||||||
return pre.err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pre *PermanentRegistrationError) Serialize() *TunnelRegistration {
|
|
||||||
return &TunnelRegistration{
|
|
||||||
Err: pre.err,
|
|
||||||
PermanentFailure: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*PermanentRegistrationError) IsPermanent() bool {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
type RetryableRegistrationError struct {
|
|
||||||
err string
|
|
||||||
retryAfterSeconds uint16
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewRetryableRegistrationError(err error, retryAfterSeconds uint16) TunnelRegistrationError {
|
|
||||||
return &RetryableRegistrationError{
|
|
||||||
err: err.Error(),
|
|
||||||
retryAfterSeconds: retryAfterSeconds,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (rre *RetryableRegistrationError) Error() string {
|
|
||||||
return rre.err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (rre *RetryableRegistrationError) Serialize() *TunnelRegistration {
|
|
||||||
return &TunnelRegistration{
|
|
||||||
Err: rre.err,
|
|
||||||
PermanentFailure: false,
|
|
||||||
RetryAfterSeconds: rre.retryAfterSeconds,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*RetryableRegistrationError) IsPermanent() bool {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func MarshalTunnelRegistration(s proto.TunnelRegistration, p *TunnelRegistration) error {
|
|
||||||
return pogs.Insert(proto.TunnelRegistration_TypeID, s.Struct, p)
|
|
||||||
}
|
|
||||||
|
|
||||||
func UnmarshalTunnelRegistration(s proto.TunnelRegistration) (*TunnelRegistration, error) {
|
|
||||||
p := new(TunnelRegistration)
|
|
||||||
err := pogs.Extract(p, proto.TunnelRegistration_TypeID, s.Struct)
|
|
||||||
return p, err
|
|
||||||
}
|
|
||||||
|
|
||||||
type RegistrationOptions struct {
|
|
||||||
ClientID string `capnp:"clientId"`
|
|
||||||
Version string
|
|
||||||
OS string `capnp:"os"`
|
|
||||||
ExistingTunnelPolicy proto.ExistingTunnelPolicy
|
|
||||||
PoolName string `capnp:"poolName"`
|
|
||||||
Tags []Tag
|
|
||||||
ConnectionID uint8 `capnp:"connectionId"`
|
|
||||||
OriginLocalIP string `capnp:"originLocalIp"`
|
|
||||||
IsAutoupdated bool `capnp:"isAutoupdated"`
|
|
||||||
RunFromTerminal bool `capnp:"runFromTerminal"`
|
|
||||||
CompressionQuality uint64 `capnp:"compressionQuality"`
|
|
||||||
UUID string `capnp:"uuid"`
|
|
||||||
NumPreviousAttempts uint8
|
|
||||||
Features []string
|
|
||||||
}
|
|
||||||
|
|
||||||
func MarshalRegistrationOptions(s proto.RegistrationOptions, p *RegistrationOptions) error {
|
|
||||||
return pogs.Insert(proto.RegistrationOptions_TypeID, s.Struct, p)
|
|
||||||
}
|
|
||||||
|
|
||||||
func UnmarshalRegistrationOptions(s proto.RegistrationOptions) (*RegistrationOptions, error) {
|
|
||||||
p := new(RegistrationOptions)
|
|
||||||
err := pogs.Extract(p, proto.RegistrationOptions_TypeID, s.Struct)
|
|
||||||
return p, err
|
|
||||||
}
|
|
||||||
|
|
||||||
type Tag struct {
|
|
||||||
Name string `json:"name"`
|
|
||||||
Value string `json:"value"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ServerInfo struct {
|
|
||||||
LocationName string
|
|
||||||
}
|
|
||||||
|
|
||||||
func MarshalServerInfo(s proto.ServerInfo, p *ServerInfo) error {
|
|
||||||
return pogs.Insert(proto.ServerInfo_TypeID, s.Struct, p)
|
|
||||||
}
|
|
||||||
|
|
||||||
func UnmarshalServerInfo(s proto.ServerInfo) (*ServerInfo, error) {
|
|
||||||
p := new(ServerInfo)
|
|
||||||
err := pogs.Extract(p, proto.ServerInfo_TypeID, s.Struct)
|
|
||||||
return p, err
|
|
||||||
}
|
|
||||||
|
|
||||||
type TunnelServer interface {
|
|
||||||
RegistrationServer
|
|
||||||
RegisterTunnel(ctx context.Context, originCert []byte, hostname string, options *RegistrationOptions) *TunnelRegistration
|
|
||||||
GetServerInfo(ctx context.Context) (*ServerInfo, error)
|
|
||||||
UnregisterTunnel(ctx context.Context, gracePeriodNanoSec int64) error
|
|
||||||
Authenticate(ctx context.Context, originCert []byte, hostname string, options *RegistrationOptions) (*AuthenticateResponse, error)
|
|
||||||
ReconnectTunnel(ctx context.Context, jwt, eventDigest, connDigest []byte, hostname string, options *RegistrationOptions) (*TunnelRegistration, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TunnelServer_ServerToClient(s TunnelServer) proto.TunnelServer {
|
|
||||||
return proto.TunnelServer_ServerToClient(TunnelServer_PogsImpl{RegistrationServer_PogsImpl{s}, s})
|
|
||||||
}
|
|
||||||
|
|
||||||
type TunnelServer_PogsImpl struct {
|
|
||||||
RegistrationServer_PogsImpl
|
|
||||||
impl TunnelServer
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i TunnelServer_PogsImpl) RegisterTunnel(p proto.TunnelServer_registerTunnel) error {
|
|
||||||
originCert, err := p.Params.OriginCert()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
hostname, err := p.Params.Hostname()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
options, err := p.Params.Options()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
pogsOptions, err := UnmarshalRegistrationOptions(options)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
server.Ack(p.Options)
|
|
||||||
registration := i.impl.RegisterTunnel(p.Ctx, originCert, hostname, pogsOptions)
|
|
||||||
|
|
||||||
result, err := p.Results.NewResult()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return MarshalTunnelRegistration(result, registration)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i TunnelServer_PogsImpl) GetServerInfo(p proto.TunnelServer_getServerInfo) error {
|
|
||||||
server.Ack(p.Options)
|
|
||||||
serverInfo, err := i.impl.GetServerInfo(p.Ctx)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
result, err := p.Results.NewResult()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return MarshalServerInfo(result, serverInfo)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i TunnelServer_PogsImpl) UnregisterTunnel(p proto.TunnelServer_unregisterTunnel) error {
|
|
||||||
gracePeriodNanoSec := p.Params.GracePeriodNanoSec()
|
|
||||||
server.Ack(p.Options)
|
|
||||||
return i.impl.UnregisterTunnel(p.Ctx, gracePeriodNanoSec)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i TunnelServer_PogsImpl) ObsoleteDeclarativeTunnelConnect(p proto.TunnelServer_obsoleteDeclarativeTunnelConnect) error {
|
|
||||||
return fmt.Errorf("RPC to create declarative tunnel connection has been deprecated")
|
|
||||||
}
|
|
||||||
|
|
||||||
type TunnelServer_PogsClient struct {
|
|
||||||
RegistrationServer_PogsClient
|
|
||||||
Client capnp.Client
|
|
||||||
Conn *rpc.Conn
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c TunnelServer_PogsClient) Close() error {
|
|
||||||
c.Client.Close()
|
|
||||||
return c.Conn.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c TunnelServer_PogsClient) RegisterTunnel(ctx context.Context, originCert []byte, hostname string, options *RegistrationOptions) *TunnelRegistration {
|
|
||||||
client := proto.TunnelServer{Client: c.Client}
|
|
||||||
promise := client.RegisterTunnel(ctx, func(p proto.TunnelServer_registerTunnel_Params) error {
|
|
||||||
err := p.SetOriginCert(originCert)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = p.SetHostname(hostname)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
registrationOptions, err := p.NewOptions()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = MarshalRegistrationOptions(registrationOptions, options)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
retval, err := promise.Result().Struct()
|
|
||||||
if err != nil {
|
|
||||||
return NewRetryableRegistrationError(err, defaultRetryAfterSeconds).Serialize()
|
|
||||||
}
|
|
||||||
registration, err := UnmarshalTunnelRegistration(retval)
|
|
||||||
if err != nil {
|
|
||||||
return NewRetryableRegistrationError(err, defaultRetryAfterSeconds).Serialize()
|
|
||||||
}
|
|
||||||
return registration
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c TunnelServer_PogsClient) GetServerInfo(ctx context.Context) (*ServerInfo, error) {
|
|
||||||
client := proto.TunnelServer{Client: c.Client}
|
|
||||||
promise := client.GetServerInfo(ctx, func(p proto.TunnelServer_getServerInfo_Params) error {
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
retval, err := promise.Result().Struct()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return UnmarshalServerInfo(retval)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c TunnelServer_PogsClient) UnregisterTunnel(ctx context.Context, gracePeriodNanoSec int64) error {
|
|
||||||
client := proto.TunnelServer{Client: c.Client}
|
|
||||||
promise := client.UnregisterTunnel(ctx, func(p proto.TunnelServer_unregisterTunnel_Params) error {
|
|
||||||
p.SetGracePeriodNanoSec(gracePeriodNanoSec)
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
_, err := promise.Struct()
|
|
||||||
return err
|
|
||||||
}
|
|
|
@ -1,57 +0,0 @@
|
||||||
package pogs
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
capnp "zombiezen.com/go/capnproto2"
|
|
||||||
|
|
||||||
"github.com/cloudflare/cloudflared/tunnelrpc/proto"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
testURL = "tunnel.example.com"
|
|
||||||
testTunnelID = "asdfghjkl;"
|
|
||||||
testRetryAfterSeconds = 19
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
testErr = fmt.Errorf("Invalid credential")
|
|
||||||
testLogLines = []string{"all", "working"}
|
|
||||||
testEventDigest = []byte("asdf")
|
|
||||||
testConnDigest = []byte("lkjh")
|
|
||||||
)
|
|
||||||
|
|
||||||
// *PermanentRegistrationError implements TunnelRegistrationError
|
|
||||||
var _ TunnelRegistrationError = (*PermanentRegistrationError)(nil)
|
|
||||||
|
|
||||||
// *RetryableRegistrationError implements TunnelRegistrationError
|
|
||||||
var _ TunnelRegistrationError = (*RetryableRegistrationError)(nil)
|
|
||||||
|
|
||||||
func TestTunnelRegistration(t *testing.T) {
|
|
||||||
testCases := []*TunnelRegistration{
|
|
||||||
NewSuccessfulTunnelRegistration(testURL, testLogLines, testTunnelID, testEventDigest, testConnDigest),
|
|
||||||
NewSuccessfulTunnelRegistration(testURL, nil, testTunnelID, testEventDigest, testConnDigest),
|
|
||||||
NewPermanentRegistrationError(testErr).Serialize(),
|
|
||||||
NewRetryableRegistrationError(testErr, testRetryAfterSeconds).Serialize(),
|
|
||||||
}
|
|
||||||
for i, testCase := range testCases {
|
|
||||||
_, seg, err := capnp.NewMessage(capnp.SingleSegment(nil))
|
|
||||||
assert.NoError(t, err)
|
|
||||||
capnpEntity, err := proto.NewTunnelRegistration(seg)
|
|
||||||
if !assert.NoError(t, err) {
|
|
||||||
t.Fatal("Couldn't initialize a new message")
|
|
||||||
}
|
|
||||||
err = MarshalTunnelRegistration(capnpEntity, testCase)
|
|
||||||
if !assert.NoError(t, err, "testCase #%v failed to marshal", i) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
result, err := UnmarshalTunnelRegistration(capnpEntity)
|
|
||||||
if !assert.NoError(t, err, "testCase #%v failed to unmarshal", i) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
assert.Equal(t, testCase, result, "testCase index %v didn't preserve struct through marshalling and unmarshalling", i)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -3,13 +3,21 @@ using Go = import "go.capnp";
|
||||||
$Go.package("proto");
|
$Go.package("proto");
|
||||||
$Go.import("github.com/cloudflare/cloudflared/tunnelrpc");
|
$Go.import("github.com/cloudflare/cloudflared/tunnelrpc");
|
||||||
|
|
||||||
|
# === DEPRECATED Legacy Tunnel Authentication and Registration methods/servers ===
|
||||||
|
#
|
||||||
|
# These structs and interfaces are no longer used but it is important to keep
|
||||||
|
# them around to make sure backwards compatibility within the rpc protocol is
|
||||||
|
# maintained.
|
||||||
|
|
||||||
struct Authentication @0xc082ef6e0d42ed1d {
|
struct Authentication @0xc082ef6e0d42ed1d {
|
||||||
|
# DEPRECATED: Legacy tunnel authentication mechanism
|
||||||
key @0 :Text;
|
key @0 :Text;
|
||||||
email @1 :Text;
|
email @1 :Text;
|
||||||
originCAKey @2 :Text;
|
originCAKey @2 :Text;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TunnelRegistration @0xf41a0f001ad49e46 {
|
struct TunnelRegistration @0xf41a0f001ad49e46 {
|
||||||
|
# DEPRECATED: Legacy tunnel authentication mechanism
|
||||||
err @0 :Text;
|
err @0 :Text;
|
||||||
# the url to access the tunnel
|
# the url to access the tunnel
|
||||||
url @1 :Text;
|
url @1 :Text;
|
||||||
|
@ -28,6 +36,8 @@ struct TunnelRegistration @0xf41a0f001ad49e46 {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RegistrationOptions @0xc793e50592935b4a {
|
struct RegistrationOptions @0xc793e50592935b4a {
|
||||||
|
# DEPRECATED: Legacy tunnel authentication mechanism
|
||||||
|
|
||||||
# The tunnel client's unique identifier, used to verify a reconnection.
|
# The tunnel client's unique identifier, used to verify a reconnection.
|
||||||
clientId @0 :Text;
|
clientId @0 :Text;
|
||||||
# Information about the running binary.
|
# Information about the running binary.
|
||||||
|
@ -56,28 +66,50 @@ struct RegistrationOptions @0xc793e50592935b4a {
|
||||||
features @13 :List(Text);
|
features @13 :List(Text);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Tag @0xcbd96442ae3bb01a {
|
|
||||||
name @0 :Text;
|
|
||||||
value @1 :Text;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum ExistingTunnelPolicy @0x84cb9536a2cf6d3c {
|
enum ExistingTunnelPolicy @0x84cb9536a2cf6d3c {
|
||||||
|
# DEPRECATED: Legacy tunnel registration mechanism
|
||||||
|
|
||||||
ignore @0;
|
ignore @0;
|
||||||
disconnect @1;
|
disconnect @1;
|
||||||
balance @2;
|
balance @2;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ServerInfo @0xf2c68e2547ec3866 {
|
struct ServerInfo @0xf2c68e2547ec3866 {
|
||||||
|
# DEPRECATED: Legacy tunnel registration mechanism
|
||||||
|
|
||||||
locationName @0 :Text;
|
locationName @0 :Text;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct AuthenticateResponse @0x82c325a07ad22a65 {
|
struct AuthenticateResponse @0x82c325a07ad22a65 {
|
||||||
|
# DEPRECATED: Legacy tunnel registration mechanism
|
||||||
|
|
||||||
permanentErr @0 :Text;
|
permanentErr @0 :Text;
|
||||||
retryableErr @1 :Text;
|
retryableErr @1 :Text;
|
||||||
jwt @2 :Data;
|
jwt @2 :Data;
|
||||||
hoursUntilRefresh @3 :UInt8;
|
hoursUntilRefresh @3 :UInt8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface TunnelServer @0xea58385c65416035 extends (RegistrationServer) {
|
||||||
|
# DEPRECATED: Legacy tunnel authentication server
|
||||||
|
|
||||||
|
registerTunnel @0 (originCert :Data, hostname :Text, options :RegistrationOptions) -> (result :TunnelRegistration);
|
||||||
|
getServerInfo @1 () -> (result :ServerInfo);
|
||||||
|
unregisterTunnel @2 (gracePeriodNanoSec :Int64) -> ();
|
||||||
|
# obsoleteDeclarativeTunnelConnect RPC deprecated in TUN-3019
|
||||||
|
obsoleteDeclarativeTunnelConnect @3 () -> ();
|
||||||
|
authenticate @4 (originCert :Data, hostname :Text, options :RegistrationOptions) -> (result :AuthenticateResponse);
|
||||||
|
reconnectTunnel @5 (jwt :Data, eventDigest :Data, connDigest :Data, hostname :Text, options :RegistrationOptions) -> (result :TunnelRegistration);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Tag @0xcbd96442ae3bb01a {
|
||||||
|
# DEPRECATED: Legacy tunnel additional HTTP header mechanism
|
||||||
|
|
||||||
|
name @0 :Text;
|
||||||
|
value @1 :Text;
|
||||||
|
}
|
||||||
|
|
||||||
|
# === End DEPRECATED Objects ===
|
||||||
|
|
||||||
struct ClientInfo @0x83ced0145b2f114b {
|
struct ClientInfo @0x83ced0145b2f114b {
|
||||||
# The tunnel client's unique identifier, used to verify a reconnection.
|
# The tunnel client's unique identifier, used to verify a reconnection.
|
||||||
clientId @0 :Data;
|
clientId @0 :Data;
|
||||||
|
@ -136,16 +168,6 @@ interface RegistrationServer @0xf71695ec7fe85497 {
|
||||||
updateLocalConfiguration @2 (config :Data) -> ();
|
updateLocalConfiguration @2 (config :Data) -> ();
|
||||||
}
|
}
|
||||||
|
|
||||||
interface TunnelServer @0xea58385c65416035 extends (RegistrationServer) {
|
|
||||||
registerTunnel @0 (originCert :Data, hostname :Text, options :RegistrationOptions) -> (result :TunnelRegistration);
|
|
||||||
getServerInfo @1 () -> (result :ServerInfo);
|
|
||||||
unregisterTunnel @2 (gracePeriodNanoSec :Int64) -> ();
|
|
||||||
# obsoleteDeclarativeTunnelConnect RPC deprecated in TUN-3019
|
|
||||||
obsoleteDeclarativeTunnelConnect @3 () -> ();
|
|
||||||
authenticate @4 (originCert :Data, hostname :Text, options :RegistrationOptions) -> (result :AuthenticateResponse);
|
|
||||||
reconnectTunnel @5 (jwt :Data, eventDigest :Data, connDigest :Data, hostname :Text, options :RegistrationOptions) -> (result :TunnelRegistration);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct RegisterUdpSessionResponse @0xab6d5210c1f26687 {
|
struct RegisterUdpSessionResponse @0xab6d5210c1f26687 {
|
||||||
err @0 :Text;
|
err @0 :Text;
|
||||||
spans @1 :Data;
|
spans @1 :Data;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue