TUN-1952: Group ClientConfig fields by the component that uses the config, and return the part of the config that failed to be applied
This commit is contained in:
parent
25a04e0c69
commit
ca619a97bc
|
@ -77,6 +77,16 @@ type MuxedStream struct {
|
||||||
dictionaries h2Dictionaries
|
dictionaries h2Dictionaries
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TunnelHostname string
|
||||||
|
|
||||||
|
func (th TunnelHostname) String() string {
|
||||||
|
return string(th)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (th TunnelHostname) IsSet() bool {
|
||||||
|
return th != ""
|
||||||
|
}
|
||||||
|
|
||||||
func (s *MuxedStream) Read(p []byte) (n int, err error) {
|
func (s *MuxedStream) Read(p []byte) (n int, err error) {
|
||||||
var readBuffer ReadWriteClosedCloser
|
var readBuffer ReadWriteClosedCloser
|
||||||
if s.dictionaries.read != nil {
|
if s.dictionaries.read != nil {
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"net/url"
|
"net/url"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/cloudflare/cloudflared/h2mux"
|
||||||
"github.com/cloudflare/cloudflared/originservice"
|
"github.com/cloudflare/cloudflared/originservice"
|
||||||
"github.com/cloudflare/cloudflared/tlsconfig"
|
"github.com/cloudflare/cloudflared/tlsconfig"
|
||||||
"github.com/cloudflare/cloudflared/tunnelrpc"
|
"github.com/cloudflare/cloudflared/tunnelrpc"
|
||||||
|
@ -17,37 +18,82 @@ import (
|
||||||
capnp "zombiezen.com/go/capnproto2"
|
capnp "zombiezen.com/go/capnproto2"
|
||||||
"zombiezen.com/go/capnproto2/pogs"
|
"zombiezen.com/go/capnproto2/pogs"
|
||||||
"zombiezen.com/go/capnproto2/rpc"
|
"zombiezen.com/go/capnproto2/rpc"
|
||||||
|
"zombiezen.com/go/capnproto2/server"
|
||||||
)
|
)
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Structs
|
/// Structs
|
||||||
///
|
///
|
||||||
|
|
||||||
|
// ClientConfig is a collection of FallibleConfig that determines how cloudflared should function
|
||||||
type ClientConfig struct {
|
type ClientConfig struct {
|
||||||
Version uint64
|
Version Version
|
||||||
AutoUpdateFrequency time.Duration
|
SupervisorConfig *SupervisorConfig
|
||||||
MetricsUpdateFrequency time.Duration
|
EdgeConnectionConfig *EdgeConnectionConfig
|
||||||
HeartbeatInterval time.Duration
|
|
||||||
MaxFailedHeartbeats uint64
|
|
||||||
GracePeriod time.Duration
|
|
||||||
DoHProxyConfigs []*DoHProxyConfig
|
DoHProxyConfigs []*DoHProxyConfig
|
||||||
ReverseProxyConfigs []*ReverseProxyConfig
|
ReverseProxyConfigs []*ReverseProxyConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
// Version type models the version of a ClientConfig
|
||||||
|
type Version uint64
|
||||||
|
|
||||||
|
func InitVersion() Version {
|
||||||
|
return Version(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v Version) IsNewerOrEqual(comparedVersion Version) bool {
|
||||||
|
return v >= comparedVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v Version) String() string {
|
||||||
|
return fmt.Sprintf("Version: %d", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FallibleConfig is an interface implemented by configs that cloudflared might not be able to apply
|
||||||
|
type FallibleConfig interface {
|
||||||
|
FailReason(err error) string
|
||||||
|
}
|
||||||
|
|
||||||
|
// SupervisorConfig specifies config of components managed by Supervisor other than ConnectionManager
|
||||||
|
type SupervisorConfig struct {
|
||||||
|
AutoUpdateFrequency time.Duration
|
||||||
|
MetricsUpdateFrequency time.Duration
|
||||||
|
GracePeriod time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
|
// FailReason impelents FallibleConfig interface for SupervisorConfig
|
||||||
|
func (sc *SupervisorConfig) FailReason(err error) string {
|
||||||
|
return fmt.Sprintf("Cannot apply SupervisorConfig, err: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// EdgeConnectionConfig specifies what parameters and how may connections should ConnectionManager establish with edge
|
||||||
|
type EdgeConnectionConfig struct {
|
||||||
NumHAConnections uint8
|
NumHAConnections uint8
|
||||||
|
HeartbeatInterval time.Duration
|
||||||
|
Timeout time.Duration
|
||||||
|
MaxFailedHeartbeats uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
type UseConfigurationResult struct {
|
// FailReason impelents FallibleConfig interface for EdgeConnectionConfig
|
||||||
Success bool
|
func (cmc *EdgeConnectionConfig) FailReason(err error) string {
|
||||||
ErrorMessage string
|
return fmt.Sprintf("Cannot apply EdgeConnectionConfig, err: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DoHProxyConfig is configuration for DNS over HTTPS service
|
||||||
type DoHProxyConfig struct {
|
type DoHProxyConfig struct {
|
||||||
ListenHost string
|
ListenHost string
|
||||||
ListenPort uint16
|
ListenPort uint16
|
||||||
Upstreams []string
|
Upstreams []string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FailReason impelents FallibleConfig interface for DoHProxyConfig
|
||||||
|
func (dpc *DoHProxyConfig) FailReason(err error) string {
|
||||||
|
return fmt.Sprintf("Cannot apply DoHProxyConfig, err: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReverseProxyConfig how and for what hostnames can this cloudflared proxy
|
||||||
type ReverseProxyConfig struct {
|
type ReverseProxyConfig struct {
|
||||||
TunnelHostname string
|
TunnelHostname h2mux.TunnelHostname
|
||||||
Origin OriginConfig
|
Origin OriginConfig
|
||||||
Retries uint64
|
Retries uint64
|
||||||
ConnectionTimeout time.Duration
|
ConnectionTimeout time.Duration
|
||||||
|
@ -65,7 +111,7 @@ func NewReverseProxyConfig(
|
||||||
return nil, fmt.Errorf("NewReverseProxyConfig: originConfig was null")
|
return nil, fmt.Errorf("NewReverseProxyConfig: originConfig was null")
|
||||||
}
|
}
|
||||||
return &ReverseProxyConfig{
|
return &ReverseProxyConfig{
|
||||||
TunnelHostname: tunnelHostname,
|
TunnelHostname: h2mux.TunnelHostname(tunnelHostname),
|
||||||
Origin: originConfig,
|
Origin: originConfig,
|
||||||
Retries: retries,
|
Retries: retries,
|
||||||
ConnectionTimeout: connectionTimeout,
|
ConnectionTimeout: connectionTimeout,
|
||||||
|
@ -73,6 +119,11 @@ func NewReverseProxyConfig(
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FailReason impelents FallibleConfig interface for ReverseProxyConfig
|
||||||
|
func (rpc *ReverseProxyConfig) FailReason(err error) string {
|
||||||
|
return fmt.Sprintf("Cannot apply ReverseProxyConfig, err: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
//go-sumtype:decl OriginConfig
|
//go-sumtype:decl OriginConfig
|
||||||
type OriginConfig interface {
|
type OriginConfig interface {
|
||||||
// Service returns a OriginService used to proxy to the origin
|
// Service returns a OriginService used to proxy to the origin
|
||||||
|
@ -221,18 +272,45 @@ func (_ *HelloWorldOriginConfig) isOriginConfig() {}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
func MarshalClientConfig(s tunnelrpc.ClientConfig, p *ClientConfig) error {
|
func MarshalClientConfig(s tunnelrpc.ClientConfig, p *ClientConfig) error {
|
||||||
s.SetVersion(p.Version)
|
s.SetVersion(uint64(p.Version))
|
||||||
s.SetAutoUpdateFrequency(p.AutoUpdateFrequency.Nanoseconds())
|
|
||||||
s.SetMetricsUpdateFrequency(p.MetricsUpdateFrequency.Nanoseconds())
|
supervisorConfig, err := s.NewSupervisorConfig()
|
||||||
s.SetHeartbeatInterval(p.HeartbeatInterval.Nanoseconds())
|
|
||||||
s.SetMaxFailedHeartbeats(p.MaxFailedHeartbeats)
|
|
||||||
s.SetGracePeriod(p.GracePeriod.Nanoseconds())
|
|
||||||
s.SetNumHAConnections(p.NumHAConnections)
|
|
||||||
err := marshalDoHProxyConfigs(s, p.DoHProxyConfigs)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return errors.Wrap(err, "failed to get SupervisorConfig")
|
||||||
}
|
}
|
||||||
return marshalReverseProxyConfigs(s, p.ReverseProxyConfigs)
|
if err = MarshalSupervisorConfig(supervisorConfig, p.SupervisorConfig); err != nil {
|
||||||
|
return errors.Wrap(err, "MarshalSupervisorConfig error")
|
||||||
|
}
|
||||||
|
|
||||||
|
edgeConnectionConfig, err := s.NewEdgeConnectionConfig()
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "failed to get EdgeConnectionConfig")
|
||||||
|
}
|
||||||
|
if err := MarshalEdgeConnectionConfig(edgeConnectionConfig, p.EdgeConnectionConfig); err != nil {
|
||||||
|
return errors.Wrap(err, "MarshalEdgeConnectionConfig error")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := marshalDoHProxyConfigs(s, p.DoHProxyConfigs); err != nil {
|
||||||
|
return errors.Wrap(err, "marshalDoHProxyConfigs error")
|
||||||
|
}
|
||||||
|
if err := marshalReverseProxyConfigs(s, p.ReverseProxyConfigs); err != nil {
|
||||||
|
return errors.Wrap(err, "marshalReverseProxyConfigs error")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func MarshalSupervisorConfig(s tunnelrpc.SupervisorConfig, p *SupervisorConfig) error {
|
||||||
|
if err := pogs.Insert(tunnelrpc.SupervisorConfig_TypeID, s.Struct, p); err != nil {
|
||||||
|
return errors.Wrap(err, "failed to insert SupervisorConfig")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func MarshalEdgeConnectionConfig(s tunnelrpc.EdgeConnectionConfig, p *EdgeConnectionConfig) error {
|
||||||
|
if err := pogs.Insert(tunnelrpc.EdgeConnectionConfig_TypeID, s.Struct, p); err != nil {
|
||||||
|
return errors.Wrap(err, "failed to insert EdgeConnectionConfig")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func marshalDoHProxyConfigs(s tunnelrpc.ClientConfig, dohProxyConfigs []*DoHProxyConfig) error {
|
func marshalDoHProxyConfigs(s tunnelrpc.ClientConfig, dohProxyConfigs []*DoHProxyConfig) error {
|
||||||
|
@ -265,23 +343,48 @@ func marshalReverseProxyConfigs(s tunnelrpc.ClientConfig, reverseProxyConfigs []
|
||||||
|
|
||||||
func UnmarshalClientConfig(s tunnelrpc.ClientConfig) (*ClientConfig, error) {
|
func UnmarshalClientConfig(s tunnelrpc.ClientConfig) (*ClientConfig, error) {
|
||||||
p := new(ClientConfig)
|
p := new(ClientConfig)
|
||||||
p.Version = s.Version()
|
p.Version = Version(s.Version())
|
||||||
p.AutoUpdateFrequency = time.Duration(s.AutoUpdateFrequency())
|
|
||||||
p.MetricsUpdateFrequency = time.Duration(s.MetricsUpdateFrequency())
|
supervisorConfig, err := s.SupervisorConfig()
|
||||||
p.HeartbeatInterval = time.Duration(s.HeartbeatInterval())
|
|
||||||
p.MaxFailedHeartbeats = s.MaxFailedHeartbeats()
|
|
||||||
p.GracePeriod = time.Duration(s.GracePeriod())
|
|
||||||
p.NumHAConnections = s.NumHAConnections()
|
|
||||||
dohProxyConfigs, err := unmarshalDoHProxyConfigs(s)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "failed to get SupervisorConfig")
|
||||||
}
|
}
|
||||||
p.DoHProxyConfigs = dohProxyConfigs
|
p.SupervisorConfig, err = UnmarshalSupervisorConfig(supervisorConfig)
|
||||||
reverseProxyConfigs, err := unmarshalReverseProxyConfigs(s)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "UnmarshalSupervisorConfig error")
|
||||||
}
|
}
|
||||||
p.ReverseProxyConfigs = reverseProxyConfigs
|
|
||||||
|
edgeConnectionConfig, err := s.EdgeConnectionConfig()
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "failed to get ConnectionManagerConfig")
|
||||||
|
}
|
||||||
|
p.EdgeConnectionConfig, err = UnmarshalEdgeConnectionConfig(edgeConnectionConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "UnmarshalConnectionManagerConfig error")
|
||||||
|
}
|
||||||
|
|
||||||
|
p.DoHProxyConfigs, err = unmarshalDoHProxyConfigs(s)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "unmarshalDoHProxyConfigs error")
|
||||||
|
}
|
||||||
|
|
||||||
|
p.ReverseProxyConfigs, err = unmarshalReverseProxyConfigs(s)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "unmarshalReverseProxyConfigs error")
|
||||||
|
}
|
||||||
|
|
||||||
|
return p, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func UnmarshalSupervisorConfig(s tunnelrpc.SupervisorConfig) (*SupervisorConfig, error) {
|
||||||
|
p := new(SupervisorConfig)
|
||||||
|
err := pogs.Extract(p, tunnelrpc.SupervisorConfig_TypeID, s.Struct)
|
||||||
|
return p, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func UnmarshalEdgeConnectionConfig(s tunnelrpc.EdgeConnectionConfig) (*EdgeConnectionConfig, error) {
|
||||||
|
p := new(EdgeConnectionConfig)
|
||||||
|
err := pogs.Extract(p, tunnelrpc.EdgeConnectionConfig_TypeID, s.Struct)
|
||||||
return p, err
|
return p, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,13 +423,38 @@ func unmarshalReverseProxyConfigs(s tunnelrpc.ClientConfig) ([]*ReverseProxyConf
|
||||||
}
|
}
|
||||||
|
|
||||||
func MarshalUseConfigurationResult(s tunnelrpc.UseConfigurationResult, p *UseConfigurationResult) error {
|
func MarshalUseConfigurationResult(s tunnelrpc.UseConfigurationResult, p *UseConfigurationResult) error {
|
||||||
return pogs.Insert(tunnelrpc.UseConfigurationResult_TypeID, s.Struct, p)
|
capnpList, err := s.NewFailedConfigs(int32(len(p.FailedConfigs)))
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "Cannot create new FailedConfigs")
|
||||||
|
}
|
||||||
|
for i, unmarshalledFailedConfig := range p.FailedConfigs {
|
||||||
|
err := MarshalFailedConfig(capnpList.At(i), unmarshalledFailedConfig)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "Cannot MarshalFailedConfig at index %d", i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.SetSuccess(p.Success)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func UnmarshalUseConfigurationResult(s tunnelrpc.UseConfigurationResult) (*UseConfigurationResult, error) {
|
func UnmarshalUseConfigurationResult(s tunnelrpc.UseConfigurationResult) (*UseConfigurationResult, error) {
|
||||||
p := new(UseConfigurationResult)
|
p := new(UseConfigurationResult)
|
||||||
err := pogs.Extract(p, tunnelrpc.UseConfigurationResult_TypeID, s.Struct)
|
var failedConfigs []*FailedConfig
|
||||||
return p, err
|
marshalledFailedConfigs, err := s.FailedConfigs()
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "Cannot get FailedConfigs")
|
||||||
|
}
|
||||||
|
for i := 0; i < marshalledFailedConfigs.Len(); i++ {
|
||||||
|
ss := marshalledFailedConfigs.At(i)
|
||||||
|
failedConfig, err := UnmarshalFailedConfig(ss)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "Cannot UnmarshalFailedConfig at index %d", i)
|
||||||
|
}
|
||||||
|
failedConfigs = append(failedConfigs, failedConfig)
|
||||||
|
}
|
||||||
|
p.FailedConfigs = failedConfigs
|
||||||
|
p.Success = s.Success()
|
||||||
|
return p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func MarshalDoHProxyConfig(s tunnelrpc.DoHProxyConfig, p *DoHProxyConfig) error {
|
func MarshalDoHProxyConfig(s tunnelrpc.DoHProxyConfig, p *DoHProxyConfig) error {
|
||||||
|
@ -340,7 +468,7 @@ func UnmarshalDoHProxyConfig(s tunnelrpc.DoHProxyConfig) (*DoHProxyConfig, error
|
||||||
}
|
}
|
||||||
|
|
||||||
func MarshalReverseProxyConfig(s tunnelrpc.ReverseProxyConfig, p *ReverseProxyConfig) error {
|
func MarshalReverseProxyConfig(s tunnelrpc.ReverseProxyConfig, p *ReverseProxyConfig) error {
|
||||||
s.SetTunnelHostname(p.TunnelHostname)
|
s.SetTunnelHostname(p.TunnelHostname.String())
|
||||||
switch config := p.Origin.(type) {
|
switch config := p.Origin.(type) {
|
||||||
case *HTTPOriginConfig:
|
case *HTTPOriginConfig:
|
||||||
ss, err := s.Origin().NewHttp()
|
ss, err := s.Origin().NewHttp()
|
||||||
|
@ -381,7 +509,7 @@ func UnmarshalReverseProxyConfig(s tunnelrpc.ReverseProxyConfig) (*ReverseProxyC
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
p.TunnelHostname = tunnelHostname
|
p.TunnelHostname = h2mux.TunnelHostname(tunnelHostname)
|
||||||
switch s.Origin().Which() {
|
switch s.Origin().Which() {
|
||||||
case tunnelrpc.ReverseProxyConfig_origin_Which_http:
|
case tunnelrpc.ReverseProxyConfig_origin_Which_http:
|
||||||
ss, err := s.Origin().Http()
|
ss, err := s.Origin().Http()
|
||||||
|
@ -584,3 +712,141 @@ func (c *ClientService_PogsClient) UseConfiguration(
|
||||||
}
|
}
|
||||||
return UnmarshalUseConfigurationResult(retval)
|
return UnmarshalUseConfigurationResult(retval)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ClientService_ServerToClient(s ClientService) tunnelrpc.ClientService {
|
||||||
|
return tunnelrpc.ClientService_ServerToClient(ClientService_PogsImpl{s})
|
||||||
|
}
|
||||||
|
|
||||||
|
type ClientService_PogsImpl struct {
|
||||||
|
impl ClientService
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i ClientService_PogsImpl) UseConfiguration(p tunnelrpc.ClientService_useConfiguration) error {
|
||||||
|
config, err := p.Params.ClientServiceConfig()
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "Cannot get CloudflaredConfig parameter")
|
||||||
|
}
|
||||||
|
pogsConfig, err := UnmarshalClientConfig(config)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "Cannot unmarshal tunnelrpc.CloudflaredConfig to *CloudflaredConfig")
|
||||||
|
}
|
||||||
|
server.Ack(p.Options)
|
||||||
|
userConfigResult, err := i.impl.UseConfiguration(p.Ctx, pogsConfig)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
result, err := p.Results.NewResult()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return MarshalUseConfigurationResult(result, userConfigResult)
|
||||||
|
}
|
||||||
|
|
||||||
|
type UseConfigurationResult struct {
|
||||||
|
Success bool
|
||||||
|
FailedConfigs []*FailedConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
type FailedConfig struct {
|
||||||
|
Config FallibleConfig
|
||||||
|
Reason string
|
||||||
|
}
|
||||||
|
|
||||||
|
func MarshalFailedConfig(s tunnelrpc.FailedConfig, p *FailedConfig) error {
|
||||||
|
switch config := p.Config.(type) {
|
||||||
|
case *SupervisorConfig:
|
||||||
|
ss, err := s.Config().NewSupervisor()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = MarshalSupervisorConfig(ss, config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case *EdgeConnectionConfig:
|
||||||
|
ss, err := s.Config().EdgeConnection()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = MarshalEdgeConnectionConfig(ss, config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case *DoHProxyConfig:
|
||||||
|
ss, err := s.Config().NewDoh()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = MarshalDoHProxyConfig(ss, config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case *ReverseProxyConfig:
|
||||||
|
ss, err := s.Config().NewReverseProxy()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = MarshalReverseProxyConfig(ss, config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("Unknown type for Config: %T", config)
|
||||||
|
}
|
||||||
|
s.SetReason(p.Reason)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func UnmarshalFailedConfig(s tunnelrpc.FailedConfig) (*FailedConfig, error) {
|
||||||
|
p := new(FailedConfig)
|
||||||
|
switch s.Config().Which() {
|
||||||
|
case tunnelrpc.FailedConfig_config_Which_supervisor:
|
||||||
|
ss, err := s.Config().Supervisor()
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "Cannot get SupervisorConfig from Config")
|
||||||
|
}
|
||||||
|
config, err := UnmarshalSupervisorConfig(ss)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "Cannot UnmarshalSupervisorConfig")
|
||||||
|
}
|
||||||
|
p.Config = config
|
||||||
|
case tunnelrpc.FailedConfig_config_Which_edgeConnection:
|
||||||
|
ss, err := s.Config().EdgeConnection()
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "Cannot get ConnectionManager from Config")
|
||||||
|
}
|
||||||
|
config, err := UnmarshalEdgeConnectionConfig(ss)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "Cannot UnmarshalConnectionManagerConfig")
|
||||||
|
}
|
||||||
|
p.Config = config
|
||||||
|
case tunnelrpc.FailedConfig_config_Which_doh:
|
||||||
|
ss, err := s.Config().Doh()
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "Cannot get Doh from Config")
|
||||||
|
}
|
||||||
|
config, err := UnmarshalDoHProxyConfig(ss)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "Cannot UnmarshalDoHProxyConfig")
|
||||||
|
}
|
||||||
|
p.Config = config
|
||||||
|
case tunnelrpc.FailedConfig_config_Which_reverseProxy:
|
||||||
|
ss, err := s.Config().ReverseProxy()
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "Cannot get ReverseProxy from Config")
|
||||||
|
}
|
||||||
|
config, err := UnmarshalReverseProxyConfig(ss)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "Cannot UnmarshalReverseProxyConfig")
|
||||||
|
}
|
||||||
|
p.Config = config
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("Unknown type for FailedConfig: %v", s.Config().Which())
|
||||||
|
}
|
||||||
|
reason, err := s.Reason()
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "Cannot get Reason")
|
||||||
|
}
|
||||||
|
p.Reason = reason
|
||||||
|
return p, nil
|
||||||
|
}
|
||||||
|
|
|
@ -13,6 +13,14 @@ import (
|
||||||
capnp "zombiezen.com/go/capnproto2"
|
capnp "zombiezen.com/go/capnproto2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestVersion(t *testing.T) {
|
||||||
|
firstVersion := InitVersion()
|
||||||
|
secondVersion := Version(1)
|
||||||
|
assert.False(t, firstVersion.IsNewerOrEqual(secondVersion))
|
||||||
|
assert.True(t, secondVersion.IsNewerOrEqual(firstVersion))
|
||||||
|
assert.True(t, secondVersion.IsNewerOrEqual(secondVersion))
|
||||||
|
}
|
||||||
|
|
||||||
func TestClientConfig(t *testing.T) {
|
func TestClientConfig(t *testing.T) {
|
||||||
addDoHProxyConfigs := func(c *ClientConfig) {
|
addDoHProxyConfigs := func(c *ClientConfig) {
|
||||||
c.DoHProxyConfigs = []*DoHProxyConfig{
|
c.DoHProxyConfigs = []*DoHProxyConfig{
|
||||||
|
@ -67,7 +75,16 @@ func TestUseConfigurationResult(t *testing.T) {
|
||||||
},
|
},
|
||||||
&UseConfigurationResult{
|
&UseConfigurationResult{
|
||||||
Success: false,
|
Success: false,
|
||||||
ErrorMessage: "the quick brown fox jumped over the lazy dogs",
|
FailedConfigs: []*FailedConfig{
|
||||||
|
{
|
||||||
|
Config: sampleReverseProxyConfig(),
|
||||||
|
Reason: "Invalid certificate",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Config: sampleDoHProxyConfig(),
|
||||||
|
Reason: "Cannot listen on port 53",
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
|
@ -193,13 +210,18 @@ func TestWebSocketOriginConfig(t *testing.T) {
|
||||||
|
|
||||||
func sampleClientConfig(overrides ...func(*ClientConfig)) *ClientConfig {
|
func sampleClientConfig(overrides ...func(*ClientConfig)) *ClientConfig {
|
||||||
sample := &ClientConfig{
|
sample := &ClientConfig{
|
||||||
Version: uint64(1337),
|
Version: Version(1337),
|
||||||
|
SupervisorConfig: &SupervisorConfig{
|
||||||
AutoUpdateFrequency: 21 * time.Hour,
|
AutoUpdateFrequency: 21 * time.Hour,
|
||||||
MetricsUpdateFrequency: 11 * time.Minute,
|
MetricsUpdateFrequency: 11 * time.Minute,
|
||||||
|
GracePeriod: 31 * time.Second,
|
||||||
|
},
|
||||||
|
EdgeConnectionConfig: &EdgeConnectionConfig{
|
||||||
|
NumHAConnections: 49,
|
||||||
|
Timeout: 9 * time.Second,
|
||||||
HeartbeatInterval: 5 * time.Second,
|
HeartbeatInterval: 5 * time.Second,
|
||||||
MaxFailedHeartbeats: 9001,
|
MaxFailedHeartbeats: 9001,
|
||||||
GracePeriod: 31 * time.Second,
|
},
|
||||||
NumHAConnections: 49,
|
|
||||||
}
|
}
|
||||||
sample.ensureNoZeroFields()
|
sample.ensureNoZeroFields()
|
||||||
for _, f := range overrides {
|
for _, f := range overrides {
|
||||||
|
|
|
@ -77,35 +77,46 @@ struct ClientConfig {
|
||||||
# to monotonically increase in value. Any configuration supplied to
|
# to monotonically increase in value. Any configuration supplied to
|
||||||
# useConfiguration() with a smaller `version` should be ignored.
|
# useConfiguration() with a smaller `version` should be ignored.
|
||||||
version @0 :UInt64;
|
version @0 :UInt64;
|
||||||
|
# supervisorConfig is configuration for supervisor, the component that manages connection manager,
|
||||||
|
# autoupdater and metrics server
|
||||||
|
supervisorConfig @1 :SupervisorConfig;
|
||||||
|
# edgeConnectionConfig is configuration for connection manager, the componenet that manages connections with the edge
|
||||||
|
edgeConnectionConfig @2 :EdgeConnectionConfig;
|
||||||
|
# Configuration for cloudflared to run as a DNS-over-HTTPS proxy.
|
||||||
|
# cloudflared CLI option: `proxy-dns`
|
||||||
|
dohProxyConfigs @3 :List(DoHProxyConfig);
|
||||||
|
# Configuration for cloudflared to run as an HTTP reverse proxy.
|
||||||
|
reverseProxyConfigs @4 :List(ReverseProxyConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SupervisorConfig {
|
||||||
# Frequency (in ns) to check Equinox for updates.
|
# Frequency (in ns) to check Equinox for updates.
|
||||||
# Zero means auto-update is disabled.
|
# Zero means auto-update is disabled.
|
||||||
# cloudflared CLI option: `autoupdate-freq`
|
# cloudflared CLI option: `autoupdate-freq`
|
||||||
autoUpdateFrequency @1 :Int64;
|
autoUpdateFrequency @0 :Int64;
|
||||||
# Frequency (in ns) to update connection-based metrics.
|
# Frequency (in ns) to update connection-based metrics.
|
||||||
# cloudflared CLI option: `metrics-update-freq`
|
# cloudflared CLI option: `metrics-update-freq`
|
||||||
metricsUpdateFrequency @2 :Int64;
|
metricsUpdateFrequency @1 :Int64;
|
||||||
# interval (in ns) between heartbeats with the Cloudflare edge
|
|
||||||
# cloudflared CLI option: `heartbeat-interval`
|
|
||||||
heartbeatInterval @3 :Int64;
|
|
||||||
# Minimum number of unacked heartbeats for cloudflared to send before
|
|
||||||
# closing the connection to the edge.
|
|
||||||
# cloudflared CLI option: `heartbeat-count`
|
|
||||||
maxFailedHeartbeats @4 :UInt64;
|
|
||||||
# Time (in ns) to continue serving requests after cloudflared receives its
|
# Time (in ns) to continue serving requests after cloudflared receives its
|
||||||
# first SIGINT/SIGTERM. A second SIGINT/SIGTERM will force cloudflared to
|
# first SIGINT/SIGTERM. A second SIGINT/SIGTERM will force cloudflared to
|
||||||
# shutdown immediately. For example, this field can be used to gracefully
|
# shutdown immediately. For example, this field can be used to gracefully
|
||||||
# transition traffic to another cloudflared instance.
|
# transition traffic to another cloudflared instance.
|
||||||
# cloudflared CLI option: `grace-period`
|
# cloudflared CLI option: `grace-period`
|
||||||
gracePeriod @5 :Int64;
|
gracePeriod @2 :Int64;
|
||||||
# Configuration for cloudflared to run as a DNS-over-HTTPS proxy.
|
}
|
||||||
# cloudflared CLI option: `proxy-dns`
|
|
||||||
dohProxyConfigs @6 :List(DoHProxyConfig);
|
struct EdgeConnectionConfig {
|
||||||
# Configuration for cloudflared to run as an HTTP reverse proxy.
|
|
||||||
reverseProxyConfigs @7 :List(ReverseProxyConfig);
|
|
||||||
# Number of persistent connections to keep open between cloudflared and
|
|
||||||
# the edge.
|
|
||||||
# cloudflared CLI option: `ha-connections`
|
# cloudflared CLI option: `ha-connections`
|
||||||
numHAConnections @8 :UInt8;
|
numHAConnections @0 :UInt8;
|
||||||
|
# Interval (in ns) between heartbeats with the Cloudflare edge
|
||||||
|
# cloudflared CLI option: `heartbeat-interval`
|
||||||
|
heartbeatInterval @1 :Int64;
|
||||||
|
# Maximum wait time to connect with the edge.
|
||||||
|
timeout @2 :Int64;
|
||||||
|
# Number of unacked heartbeats for cloudflared to send before
|
||||||
|
# closing the connection to the edge.
|
||||||
|
# cloudflared CLI option: `heartbeat-count`
|
||||||
|
maxFailedHeartbeats @3 :UInt64;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ReverseProxyConfig {
|
struct ReverseProxyConfig {
|
||||||
|
@ -251,7 +262,17 @@ struct ServerInfo {
|
||||||
|
|
||||||
struct UseConfigurationResult {
|
struct UseConfigurationResult {
|
||||||
success @0 :Bool;
|
success @0 :Bool;
|
||||||
errorMessage @1 :Text;
|
failedConfigs @1 :List(FailedConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct FailedConfig {
|
||||||
|
config :union {
|
||||||
|
supervisor @0 :SupervisorConfig;
|
||||||
|
edgeConnection @1 :EdgeConnectionConfig;
|
||||||
|
doh @2 :DoHProxyConfig;
|
||||||
|
reverseProxy @3 :ReverseProxyConfig;
|
||||||
|
}
|
||||||
|
reason @4 :Text;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface TunnelServer {
|
interface TunnelServer {
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue