TUN-1828: Update declarative tunnel config struct

This commit is contained in:
Nick Vollmar 2019-05-17 09:23:05 -05:00
parent 4bff1ef9df
commit 1485ca0fc7
5 changed files with 664 additions and 412 deletions

View File

@ -70,7 +70,7 @@ tunnel-deps: tunnelrpc/tunnelrpc.capnp.go
tunnelrpc/tunnelrpc.capnp.go: tunnelrpc/tunnelrpc.capnp tunnelrpc/tunnelrpc.capnp.go: tunnelrpc/tunnelrpc.capnp
which capnp # https://capnproto.org/install.html which capnp # https://capnproto.org/install.html
which capnpc-go # go get zombiezen.com/go/capnproto2/capnpc-go which capnpc-go # go get zombiezen.com/go/capnproto2/capnpc-go
capnp compile -ogo -I ./tunnelrpc tunnelrpc/tunnelrpc.capnp capnp compile -ogo tunnelrpc/tunnelrpc.capnp
.PHONY: vet .PHONY: vet
vet: vet:

View File

@ -15,8 +15,8 @@ import (
/// Structs /// Structs
/// ///
type CloudflaredConfig struct { type ClientConfig struct {
Timestamp time.Time Version uint64
AutoUpdateFrequency time.Duration AutoUpdateFrequency time.Duration
MetricsUpdateFrequency time.Duration MetricsUpdateFrequency time.Duration
HeartbeatInterval time.Duration HeartbeatInterval time.Duration
@ -24,6 +24,7 @@ type CloudflaredConfig struct {
GracePeriod time.Duration GracePeriod time.Duration
DoHProxyConfigs []*DoHProxyConfig DoHProxyConfigs []*DoHProxyConfig
ReverseProxyConfigs []*ReverseProxyConfig ReverseProxyConfigs []*ReverseProxyConfig
NumHAConnections uint8
} }
type UseConfigurationResult struct { type UseConfigurationResult struct {
@ -38,7 +39,7 @@ type DoHProxyConfig struct {
} }
type ReverseProxyConfig struct { type ReverseProxyConfig struct {
TunnelID string TunnelHostname string
Origin OriginConfig Origin OriginConfig
Retries uint64 Retries uint64
ConnectionTimeout time.Duration ConnectionTimeout time.Duration
@ -46,6 +47,27 @@ type ReverseProxyConfig struct {
CompressionQuality uint64 CompressionQuality uint64
} }
func NewReverseProxyConfig(
tunnelHostname string,
originConfig OriginConfig,
retries uint64,
connectionTimeout time.Duration,
chunkedEncoding bool,
compressionQuality uint64,
) (*ReverseProxyConfig, error) {
if originConfig == nil {
return nil, fmt.Errorf("NewReverseProxyConfig: originConfig was null")
}
return &ReverseProxyConfig{
TunnelHostname: tunnelHostname,
Origin: originConfig,
Retries: retries,
ConnectionTimeout: connectionTimeout,
ChunkedEncoding: chunkedEncoding,
CompressionQuality: compressionQuality,
}, nil
}
//go-sumtype:decl OriginConfig //go-sumtype:decl OriginConfig
type OriginConfig interface { type OriginConfig interface {
isOriginConfig() isOriginConfig()
@ -81,29 +103,31 @@ type HelloWorldOriginConfig struct{}
func (_ *HelloWorldOriginConfig) isOriginConfig() {} func (_ *HelloWorldOriginConfig) isOriginConfig() {}
/// /*
/// Boilerplate to convert between these structs and the primitive structs generated by capnp-go * Boilerplate to convert between these structs and the primitive structs
/// * generated by capnp-go.
* Mnemonics for variable names in this section:
* - `p` is for POGS (plain old Go struct)
* - `s` (and `ss`) is for "capnp.Struct", which is the fundamental type
* underlying the capnp-go data structures.
*/
func MarshalCloudflaredConfig(s tunnelrpc.CloudflaredConfig, p *CloudflaredConfig) error { func MarshalClientConfig(s tunnelrpc.ClientConfig, p *ClientConfig) error {
s.SetTimestamp(p.Timestamp.UnixNano()) s.SetVersion(p.Version)
s.SetAutoUpdateFrequency(p.AutoUpdateFrequency.Nanoseconds()) s.SetAutoUpdateFrequency(p.AutoUpdateFrequency.Nanoseconds())
s.SetMetricsUpdateFrequency(p.MetricsUpdateFrequency.Nanoseconds()) s.SetMetricsUpdateFrequency(p.MetricsUpdateFrequency.Nanoseconds())
s.SetHeartbeatInterval(p.HeartbeatInterval.Nanoseconds()) s.SetHeartbeatInterval(p.HeartbeatInterval.Nanoseconds())
s.SetMaxFailedHeartbeats(p.MaxFailedHeartbeats) s.SetMaxFailedHeartbeats(p.MaxFailedHeartbeats)
s.SetGracePeriod(p.GracePeriod.Nanoseconds()) s.SetGracePeriod(p.GracePeriod.Nanoseconds())
s.SetNumHAConnections(p.NumHAConnections)
err := marshalDoHProxyConfigs(s, p.DoHProxyConfigs) err := marshalDoHProxyConfigs(s, p.DoHProxyConfigs)
if err != nil { if err != nil {
return err return err
} }
err = marshalReverseProxyConfigs(s, p.ReverseProxyConfigs) return marshalReverseProxyConfigs(s, p.ReverseProxyConfigs)
if err != nil {
return err
}
return nil
} }
func marshalDoHProxyConfigs(s tunnelrpc.CloudflaredConfig, dohProxyConfigs []*DoHProxyConfig) error { func marshalDoHProxyConfigs(s tunnelrpc.ClientConfig, dohProxyConfigs []*DoHProxyConfig) error {
capnpList, err := s.NewDohProxyConfigs(int32(len(dohProxyConfigs))) capnpList, err := s.NewDohProxyConfigs(int32(len(dohProxyConfigs)))
if err != nil { if err != nil {
return err return err
@ -117,7 +141,7 @@ func marshalDoHProxyConfigs(s tunnelrpc.CloudflaredConfig, dohProxyConfigs []*Do
return nil return nil
} }
func marshalReverseProxyConfigs(s tunnelrpc.CloudflaredConfig, reverseProxyConfigs []*ReverseProxyConfig) error { func marshalReverseProxyConfigs(s tunnelrpc.ClientConfig, reverseProxyConfigs []*ReverseProxyConfig) error {
capnpList, err := s.NewReverseProxyConfigs(int32(len(reverseProxyConfigs))) capnpList, err := s.NewReverseProxyConfigs(int32(len(reverseProxyConfigs)))
if err != nil { if err != nil {
return err return err
@ -131,14 +155,15 @@ func marshalReverseProxyConfigs(s tunnelrpc.CloudflaredConfig, reverseProxyConfi
return nil return nil
} }
func UnmarshalCloudflaredConfig(s tunnelrpc.CloudflaredConfig) (*CloudflaredConfig, error) { func UnmarshalClientConfig(s tunnelrpc.ClientConfig) (*ClientConfig, error) {
p := new(CloudflaredConfig) p := new(ClientConfig)
p.Timestamp = time.Unix(0, s.Timestamp()).UTC() p.Version = s.Version()
p.AutoUpdateFrequency = time.Duration(s.AutoUpdateFrequency()) p.AutoUpdateFrequency = time.Duration(s.AutoUpdateFrequency())
p.MetricsUpdateFrequency = time.Duration(s.MetricsUpdateFrequency()) p.MetricsUpdateFrequency = time.Duration(s.MetricsUpdateFrequency())
p.HeartbeatInterval = time.Duration(s.HeartbeatInterval()) p.HeartbeatInterval = time.Duration(s.HeartbeatInterval())
p.MaxFailedHeartbeats = s.MaxFailedHeartbeats() p.MaxFailedHeartbeats = s.MaxFailedHeartbeats()
p.GracePeriod = time.Duration(s.GracePeriod()) p.GracePeriod = time.Duration(s.GracePeriod())
p.NumHAConnections = s.NumHAConnections()
dohProxyConfigs, err := unmarshalDoHProxyConfigs(s) dohProxyConfigs, err := unmarshalDoHProxyConfigs(s)
if err != nil { if err != nil {
return nil, err return nil, err
@ -152,7 +177,7 @@ func UnmarshalCloudflaredConfig(s tunnelrpc.CloudflaredConfig) (*CloudflaredConf
return p, err return p, err
} }
func unmarshalDoHProxyConfigs(s tunnelrpc.CloudflaredConfig) ([]*DoHProxyConfig, error) { func unmarshalDoHProxyConfigs(s tunnelrpc.ClientConfig) ([]*DoHProxyConfig, error) {
var result []*DoHProxyConfig var result []*DoHProxyConfig
marshalledDoHProxyConfigs, err := s.DohProxyConfigs() marshalledDoHProxyConfigs, err := s.DohProxyConfigs()
if err != nil { if err != nil {
@ -169,7 +194,7 @@ func unmarshalDoHProxyConfigs(s tunnelrpc.CloudflaredConfig) ([]*DoHProxyConfig,
return result, nil return result, nil
} }
func unmarshalReverseProxyConfigs(s tunnelrpc.CloudflaredConfig) ([]*ReverseProxyConfig, error) { func unmarshalReverseProxyConfigs(s tunnelrpc.ClientConfig) ([]*ReverseProxyConfig, error) {
var result []*ReverseProxyConfig var result []*ReverseProxyConfig
marshalledReverseProxyConfigs, err := s.ReverseProxyConfigs() marshalledReverseProxyConfigs, err := s.ReverseProxyConfigs()
if err != nil { if err != nil {
@ -207,7 +232,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.SetTunnelID(p.TunnelID) s.SetTunnelHostname(p.TunnelHostname)
switch config := p.Origin.(type) { switch config := p.Origin.(type) {
case *HTTPOriginConfig: case *HTTPOriginConfig:
ss, err := s.Origin().NewHttp() ss, err := s.Origin().NewHttp()
@ -245,11 +270,11 @@ func MarshalReverseProxyConfig(s tunnelrpc.ReverseProxyConfig, p *ReverseProxyCo
func UnmarshalReverseProxyConfig(s tunnelrpc.ReverseProxyConfig) (*ReverseProxyConfig, error) { func UnmarshalReverseProxyConfig(s tunnelrpc.ReverseProxyConfig) (*ReverseProxyConfig, error) {
p := new(ReverseProxyConfig) p := new(ReverseProxyConfig)
tunnelID, err := s.TunnelID() tunnelHostname, err := s.TunnelHostname()
if err != nil { if err != nil {
return nil, err return nil, err
} }
p.TunnelID = tunnelID p.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()
@ -339,31 +364,30 @@ func UnmarshalHelloWorldOriginConfig(s tunnelrpc.HelloWorldOriginConfig) (*Hello
return p, err return p, err
} }
type CloudflaredServer interface { type ClientService interface {
UseConfiguration(ctx context.Context, config *CloudflaredConfig) (*CloudflaredConfig, error) UseConfiguration(ctx context.Context, config *ClientConfig) (*ClientConfig, error)
GetConfiguration(ctx context.Context) (*CloudflaredConfig, error)
} }
type CloudflaredServer_PogsClient struct { type ClientService_PogsClient struct {
Client capnp.Client Client capnp.Client
Conn *rpc.Conn Conn *rpc.Conn
} }
func (c *CloudflaredServer_PogsClient) Close() error { func (c *ClientService_PogsClient) Close() error {
return c.Conn.Close() return c.Conn.Close()
} }
func (c *CloudflaredServer_PogsClient) UseConfiguration( func (c *ClientService_PogsClient) UseConfiguration(
ctx context.Context, ctx context.Context,
config *CloudflaredConfig, config *ClientConfig,
) (*UseConfigurationResult, error) { ) (*UseConfigurationResult, error) {
client := tunnelrpc.CloudflaredServer{Client: c.Client} client := tunnelrpc.ClientService{Client: c.Client}
promise := client.UseConfiguration(ctx, func(p tunnelrpc.CloudflaredServer_useConfiguration_Params) error { promise := client.UseConfiguration(ctx, func(p tunnelrpc.ClientService_useConfiguration_Params) error {
cloudflaredConfig, err := p.NewCloudflaredConfig() clientServiceConfig, err := p.NewClientConfig()
if err != nil { if err != nil {
return err return err
} }
return MarshalCloudflaredConfig(cloudflaredConfig, config) return MarshalClientConfig(clientServiceConfig, config)
}) })
retval, err := promise.Result().Struct() retval, err := promise.Result().Struct()
if err != nil { if err != nil {

View File

@ -1,6 +1,8 @@
package pogs package pogs
import ( import (
"fmt"
"reflect"
"testing" "testing"
"time" "time"
@ -10,15 +12,18 @@ import (
capnp "zombiezen.com/go/capnproto2" capnp "zombiezen.com/go/capnproto2"
) )
func TestCloudflaredConfig(t *testing.T) { func TestClientConfig(t *testing.T) {
addDoHProxyConfigs := func(c *CloudflaredConfig) { addDoHProxyConfigs := func(c *ClientConfig) {
c.DoHProxyConfigs = []*DoHProxyConfig{ c.DoHProxyConfigs = []*DoHProxyConfig{
sampleDoHProxyConfig(), sampleDoHProxyConfig(),
} }
} }
addReverseProxyConfigs := func(c *CloudflaredConfig) { addReverseProxyConfigs := func(c *ClientConfig) {
c.ReverseProxyConfigs = []*ReverseProxyConfig{ c.ReverseProxyConfigs = []*ReverseProxyConfig{
sampleReverseProxyConfig(), sampleReverseProxyConfig(),
sampleReverseProxyConfig(func(c *ReverseProxyConfig) {
c.ChunkedEncoding = false
}),
sampleReverseProxyConfig(func(c *ReverseProxyConfig) { sampleReverseProxyConfig(func(c *ReverseProxyConfig) {
c.Origin = sampleHTTPOriginConfig() c.Origin = sampleHTTPOriginConfig()
}), }),
@ -31,23 +36,23 @@ func TestCloudflaredConfig(t *testing.T) {
} }
} }
testCases := []*CloudflaredConfig{ testCases := []*ClientConfig{
sampleCloudflaredConfig(), sampleClientConfig(),
sampleCloudflaredConfig(addDoHProxyConfigs), sampleClientConfig(addDoHProxyConfigs),
sampleCloudflaredConfig(addReverseProxyConfigs), sampleClientConfig(addReverseProxyConfigs),
sampleCloudflaredConfig(addDoHProxyConfigs, addReverseProxyConfigs), sampleClientConfig(addDoHProxyConfigs, addReverseProxyConfigs),
} }
for i, testCase := range testCases { for i, testCase := range testCases {
_, seg, err := capnp.NewMessage(capnp.SingleSegment(nil)) _, seg, err := capnp.NewMessage(capnp.SingleSegment(nil))
capnpEntity, err := tunnelrpc.NewCloudflaredConfig(seg) capnpEntity, err := tunnelrpc.NewClientConfig(seg)
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.Fatal("Couldn't initialize a new message") t.Fatal("Couldn't initialize a new message")
} }
err = MarshalCloudflaredConfig(capnpEntity, testCase) err = MarshalClientConfig(capnpEntity, testCase)
if !assert.NoError(t, err, "testCase index %v failed to marshal", i) { if !assert.NoError(t, err, "testCase index %v failed to marshal", i) {
continue continue
} }
result, err := UnmarshalCloudflaredConfig(capnpEntity) result, err := UnmarshalClientConfig(capnpEntity)
if !assert.NoError(t, err, "testCase index %v failed to unmarshal", i) { if !assert.NoError(t, err, "testCase index %v failed to unmarshal", i) {
continue continue
} }
@ -208,18 +213,17 @@ func TestWebSocketOriginConfig(t *testing.T) {
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// Functions to generate sample data for ease of testing // Functions to generate sample data for ease of testing
func sampleCloudflaredConfig(overrides ...func(*CloudflaredConfig)) *CloudflaredConfig { func sampleClientConfig(overrides ...func(*ClientConfig)) *ClientConfig {
// strip the location and monotonic clock reading so that assert.Equals() sample := &ClientConfig{
// will work correctly Version: uint64(1337),
now := time.Now().UTC().Round(0)
sample := &CloudflaredConfig{
Timestamp: now,
AutoUpdateFrequency: 21 * time.Hour, AutoUpdateFrequency: 21 * time.Hour,
MetricsUpdateFrequency: 11 * time.Minute, MetricsUpdateFrequency: 11 * time.Minute,
HeartbeatInterval: 5 * time.Second, HeartbeatInterval: 5 * time.Second,
MaxFailedHeartbeats: 9001, MaxFailedHeartbeats: 9001,
GracePeriod: 31 * time.Second, GracePeriod: 31 * time.Second,
NumHAConnections: 49,
} }
sample.ensureNoZeroFields()
for _, f := range overrides { for _, f := range overrides {
f(sample) f(sample)
} }
@ -232,6 +236,7 @@ func sampleDoHProxyConfig(overrides ...func(*DoHProxyConfig)) *DoHProxyConfig {
ListenPort: 53, ListenPort: 53,
Upstreams: []string{"https://1.example.com", "https://2.example.com"}, Upstreams: []string{"https://1.example.com", "https://2.example.com"},
} }
sample.ensureNoZeroFields()
for _, f := range overrides { for _, f := range overrides {
f(sample) f(sample)
} }
@ -240,13 +245,14 @@ func sampleDoHProxyConfig(overrides ...func(*DoHProxyConfig)) *DoHProxyConfig {
func sampleReverseProxyConfig(overrides ...func(*ReverseProxyConfig)) *ReverseProxyConfig { func sampleReverseProxyConfig(overrides ...func(*ReverseProxyConfig)) *ReverseProxyConfig {
sample := &ReverseProxyConfig{ sample := &ReverseProxyConfig{
TunnelID: "hijk", TunnelHostname: "hijk.example.com",
Origin: &HelloWorldOriginConfig{}, Origin: &HelloWorldOriginConfig{},
Retries: 18, Retries: 18,
ConnectionTimeout: 5 * time.Second, ConnectionTimeout: 5 * time.Second,
ChunkedEncoding: false, ChunkedEncoding: true,
CompressionQuality: 4, CompressionQuality: 4,
} }
sample.ensureNoZeroFields()
for _, f := range overrides { for _, f := range overrides {
f(sample) f(sample)
} }
@ -265,6 +271,7 @@ func sampleHTTPOriginConfig(overrides ...func(*HTTPOriginConfig)) *HTTPOriginCon
MaxIdleConnections: 19, MaxIdleConnections: 19,
IdleConnectionTimeout: 17 * time.Second, IdleConnectionTimeout: 17 * time.Second,
} }
sample.ensureNoZeroFields()
for _, f := range overrides { for _, f := range overrides {
f(sample) f(sample)
} }
@ -275,6 +282,7 @@ func sampleUnixSocketOriginConfig(overrides ...func(*UnixSocketOriginConfig)) *U
sample := &UnixSocketOriginConfig{ sample := &UnixSocketOriginConfig{
Path: "/var/lib/file.sock", Path: "/var/lib/file.sock",
} }
sample.ensureNoZeroFields()
for _, f := range overrides { for _, f := range overrides {
f(sample) f(sample)
} }
@ -285,8 +293,71 @@ func sampleWebSocketOriginConfig(overrides ...func(*WebSocketOriginConfig)) *Web
sample := &WebSocketOriginConfig{ sample := &WebSocketOriginConfig{
URL: "ssh://example.com", URL: "ssh://example.com",
} }
sample.ensureNoZeroFields()
for _, f := range overrides { for _, f := range overrides {
f(sample) f(sample)
} }
return sample return sample
} }
func (c *ClientConfig) ensureNoZeroFields() {
ensureNoZeroFieldsInSample(reflect.ValueOf(c), []string{"DoHProxyConfigs", "ReverseProxyConfigs"})
}
func (c *DoHProxyConfig) ensureNoZeroFields() {
ensureNoZeroFieldsInSample(reflect.ValueOf(c), []string{})
}
func (c *ReverseProxyConfig) ensureNoZeroFields() {
ensureNoZeroFieldsInSample(reflect.ValueOf(c), []string{})
}
func (c *HTTPOriginConfig) ensureNoZeroFields() {
ensureNoZeroFieldsInSample(reflect.ValueOf(c), []string{})
}
func (c *UnixSocketOriginConfig) ensureNoZeroFields() {
ensureNoZeroFieldsInSample(reflect.ValueOf(c), []string{})
}
func (c *WebSocketOriginConfig) ensureNoZeroFields() {
ensureNoZeroFieldsInSample(reflect.ValueOf(c), []string{})
}
// ensureNoZeroFieldsInSample checks that all fields in the sample struct,
// except those listed in `allowedZeroFieldNames`, are initialized to nonzero
// values. Note that the value has to be a pointer for reflection to work
// correctly:
// e := &ExampleStruct{ ... }
// ensureNoZeroFieldsInSample(reflect.ValueOf(e), []string{})
//
// Context:
// Our tests work by taking a sample struct and marshalling/unmarshalling it.
// This makes them easy to write, but introduces some risk: if we don't
// include a field in the sample value, it won't be covered under tests.
// This check reduces that risk by requiring fields to be either initialized
// or explicitly uninitialized.
// https://bitbucket.cfdata.org/projects/TUN/repos/cloudflared/pull-requests/151/overview?commentId=348012
func ensureNoZeroFieldsInSample(ptrToSampleValue reflect.Value, allowedZeroFieldNames []string) {
sampleValue := ptrToSampleValue.Elem()
structType := ptrToSampleValue.Type().Elem()
allowedZeroFieldSet := make(map[string]bool)
for _, name := range allowedZeroFieldNames {
if _, ok := structType.FieldByName(name); !ok {
panic(fmt.Sprintf("struct %v has no field %v", structType.Name(), name))
}
allowedZeroFieldSet[name] = true
}
for i := 0; i < structType.NumField(); i++ {
if allowedZeroFieldSet[structType.Field(i).Name] {
continue
}
zeroValue := reflect.Zero(structType.Field(i).Type)
if reflect.DeepEqual(zeroValue.Interface(), sampleValue.Field(i).Interface()) {
panic(fmt.Sprintf("In the sample value for struct %v, field %v was not initialized", structType.Name(), structType.Field(i).Name))
}
}
}

View File

@ -72,10 +72,11 @@ struct ConnectError {
shouldRetry @2 :Bool; shouldRetry @2 :Bool;
} }
struct CloudflaredConfig { struct ClientConfig {
# Timestamp (in ns) of this configuration. Any configuration supplied to # Version of this configuration. This value is opaque, but is guaranteed
# useConfiguration() with an older timestamp should be ignored. # to monotonically increase in value. Any configuration supplied to
timestamp @0 :Int64; # useConfiguration() with a smaller `version` should be ignored.
version @0 :UInt64;
# 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`
@ -101,10 +102,14 @@ struct CloudflaredConfig {
dohProxyConfigs @6 :List(DoHProxyConfig); dohProxyConfigs @6 :List(DoHProxyConfig);
# Configuration for cloudflared to run as an HTTP reverse proxy. # Configuration for cloudflared to run as an HTTP reverse proxy.
reverseProxyConfigs @7 :List(ReverseProxyConfig); reverseProxyConfigs @7 :List(ReverseProxyConfig);
# Number of persistent connections to keep open between cloudflared and
# the edge.
# cloudflared CLI option: `ha-connections`
numHAConnections @8 :UInt8;
} }
struct ReverseProxyConfig { struct ReverseProxyConfig {
tunnelID @0 :Text; tunnelHostname @0 :Text;
origin :union { origin :union {
http @1 :HTTPOriginConfig; http @1 :HTTPOriginConfig;
socket @2 :UnixSocketOriginConfig; socket @2 :UnixSocketOriginConfig;
@ -230,6 +235,6 @@ interface TunnelServer {
connect @3 (parameters :CapnpConnectParameters) -> (result :ConnectResult); connect @3 (parameters :CapnpConnectParameters) -> (result :ConnectResult);
} }
interface CloudflaredServer { interface ClientService {
useConfiguration @0 (cloudflaredConfig :CloudflaredConfig) -> (result :UseConfigurationResult); useConfiguration @0 (clientServiceConfig :ClientConfig) -> (result :UseConfigurationResult);
} }

File diff suppressed because it is too large Load Diff