TUN-1828: Update declarative tunnel config struct
This commit is contained in:
parent
4bff1ef9df
commit
1485ca0fc7
2
Makefile
2
Makefile
|
@ -70,7 +70,7 @@ tunnel-deps: tunnelrpc/tunnelrpc.capnp.go
|
|||
tunnelrpc/tunnelrpc.capnp.go: tunnelrpc/tunnelrpc.capnp
|
||||
which capnp # https://capnproto.org/install.html
|
||||
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
|
||||
vet:
|
||||
|
|
|
@ -15,8 +15,8 @@ import (
|
|||
/// Structs
|
||||
///
|
||||
|
||||
type CloudflaredConfig struct {
|
||||
Timestamp time.Time
|
||||
type ClientConfig struct {
|
||||
Version uint64
|
||||
AutoUpdateFrequency time.Duration
|
||||
MetricsUpdateFrequency time.Duration
|
||||
HeartbeatInterval time.Duration
|
||||
|
@ -24,6 +24,7 @@ type CloudflaredConfig struct {
|
|||
GracePeriod time.Duration
|
||||
DoHProxyConfigs []*DoHProxyConfig
|
||||
ReverseProxyConfigs []*ReverseProxyConfig
|
||||
NumHAConnections uint8
|
||||
}
|
||||
|
||||
type UseConfigurationResult struct {
|
||||
|
@ -38,7 +39,7 @@ type DoHProxyConfig struct {
|
|||
}
|
||||
|
||||
type ReverseProxyConfig struct {
|
||||
TunnelID string
|
||||
TunnelHostname string
|
||||
Origin OriginConfig
|
||||
Retries uint64
|
||||
ConnectionTimeout time.Duration
|
||||
|
@ -46,6 +47,27 @@ type ReverseProxyConfig struct {
|
|||
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
|
||||
type OriginConfig interface {
|
||||
isOriginConfig()
|
||||
|
@ -81,29 +103,31 @@ type HelloWorldOriginConfig struct{}
|
|||
|
||||
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 {
|
||||
s.SetTimestamp(p.Timestamp.UnixNano())
|
||||
func MarshalClientConfig(s tunnelrpc.ClientConfig, p *ClientConfig) error {
|
||||
s.SetVersion(p.Version)
|
||||
s.SetAutoUpdateFrequency(p.AutoUpdateFrequency.Nanoseconds())
|
||||
s.SetMetricsUpdateFrequency(p.MetricsUpdateFrequency.Nanoseconds())
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
err = marshalReverseProxyConfigs(s, p.ReverseProxyConfigs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return marshalReverseProxyConfigs(s, p.ReverseProxyConfigs)
|
||||
}
|
||||
|
||||
func marshalDoHProxyConfigs(s tunnelrpc.CloudflaredConfig, dohProxyConfigs []*DoHProxyConfig) error {
|
||||
func marshalDoHProxyConfigs(s tunnelrpc.ClientConfig, dohProxyConfigs []*DoHProxyConfig) error {
|
||||
capnpList, err := s.NewDohProxyConfigs(int32(len(dohProxyConfigs)))
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -117,7 +141,7 @@ func marshalDoHProxyConfigs(s tunnelrpc.CloudflaredConfig, dohProxyConfigs []*Do
|
|||
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)))
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -131,14 +155,15 @@ func marshalReverseProxyConfigs(s tunnelrpc.CloudflaredConfig, reverseProxyConfi
|
|||
return nil
|
||||
}
|
||||
|
||||
func UnmarshalCloudflaredConfig(s tunnelrpc.CloudflaredConfig) (*CloudflaredConfig, error) {
|
||||
p := new(CloudflaredConfig)
|
||||
p.Timestamp = time.Unix(0, s.Timestamp()).UTC()
|
||||
func UnmarshalClientConfig(s tunnelrpc.ClientConfig) (*ClientConfig, error) {
|
||||
p := new(ClientConfig)
|
||||
p.Version = s.Version()
|
||||
p.AutoUpdateFrequency = time.Duration(s.AutoUpdateFrequency())
|
||||
p.MetricsUpdateFrequency = time.Duration(s.MetricsUpdateFrequency())
|
||||
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 {
|
||||
return nil, err
|
||||
|
@ -152,7 +177,7 @@ func UnmarshalCloudflaredConfig(s tunnelrpc.CloudflaredConfig) (*CloudflaredConf
|
|||
return p, err
|
||||
}
|
||||
|
||||
func unmarshalDoHProxyConfigs(s tunnelrpc.CloudflaredConfig) ([]*DoHProxyConfig, error) {
|
||||
func unmarshalDoHProxyConfigs(s tunnelrpc.ClientConfig) ([]*DoHProxyConfig, error) {
|
||||
var result []*DoHProxyConfig
|
||||
marshalledDoHProxyConfigs, err := s.DohProxyConfigs()
|
||||
if err != nil {
|
||||
|
@ -169,7 +194,7 @@ func unmarshalDoHProxyConfigs(s tunnelrpc.CloudflaredConfig) ([]*DoHProxyConfig,
|
|||
return result, nil
|
||||
}
|
||||
|
||||
func unmarshalReverseProxyConfigs(s tunnelrpc.CloudflaredConfig) ([]*ReverseProxyConfig, error) {
|
||||
func unmarshalReverseProxyConfigs(s tunnelrpc.ClientConfig) ([]*ReverseProxyConfig, error) {
|
||||
var result []*ReverseProxyConfig
|
||||
marshalledReverseProxyConfigs, err := s.ReverseProxyConfigs()
|
||||
if err != nil {
|
||||
|
@ -207,7 +232,7 @@ func UnmarshalDoHProxyConfig(s tunnelrpc.DoHProxyConfig) (*DoHProxyConfig, error
|
|||
}
|
||||
|
||||
func MarshalReverseProxyConfig(s tunnelrpc.ReverseProxyConfig, p *ReverseProxyConfig) error {
|
||||
s.SetTunnelID(p.TunnelID)
|
||||
s.SetTunnelHostname(p.TunnelHostname)
|
||||
switch config := p.Origin.(type) {
|
||||
case *HTTPOriginConfig:
|
||||
ss, err := s.Origin().NewHttp()
|
||||
|
@ -245,11 +270,11 @@ func MarshalReverseProxyConfig(s tunnelrpc.ReverseProxyConfig, p *ReverseProxyCo
|
|||
|
||||
func UnmarshalReverseProxyConfig(s tunnelrpc.ReverseProxyConfig) (*ReverseProxyConfig, error) {
|
||||
p := new(ReverseProxyConfig)
|
||||
tunnelID, err := s.TunnelID()
|
||||
tunnelHostname, err := s.TunnelHostname()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.TunnelID = tunnelID
|
||||
p.TunnelHostname = tunnelHostname
|
||||
switch s.Origin().Which() {
|
||||
case tunnelrpc.ReverseProxyConfig_origin_Which_http:
|
||||
ss, err := s.Origin().Http()
|
||||
|
@ -339,31 +364,30 @@ func UnmarshalHelloWorldOriginConfig(s tunnelrpc.HelloWorldOriginConfig) (*Hello
|
|||
return p, err
|
||||
}
|
||||
|
||||
type CloudflaredServer interface {
|
||||
UseConfiguration(ctx context.Context, config *CloudflaredConfig) (*CloudflaredConfig, error)
|
||||
GetConfiguration(ctx context.Context) (*CloudflaredConfig, error)
|
||||
type ClientService interface {
|
||||
UseConfiguration(ctx context.Context, config *ClientConfig) (*ClientConfig, error)
|
||||
}
|
||||
|
||||
type CloudflaredServer_PogsClient struct {
|
||||
type ClientService_PogsClient struct {
|
||||
Client capnp.Client
|
||||
Conn *rpc.Conn
|
||||
}
|
||||
|
||||
func (c *CloudflaredServer_PogsClient) Close() error {
|
||||
func (c *ClientService_PogsClient) Close() error {
|
||||
return c.Conn.Close()
|
||||
}
|
||||
|
||||
func (c *CloudflaredServer_PogsClient) UseConfiguration(
|
||||
func (c *ClientService_PogsClient) UseConfiguration(
|
||||
ctx context.Context,
|
||||
config *CloudflaredConfig,
|
||||
config *ClientConfig,
|
||||
) (*UseConfigurationResult, error) {
|
||||
client := tunnelrpc.CloudflaredServer{Client: c.Client}
|
||||
promise := client.UseConfiguration(ctx, func(p tunnelrpc.CloudflaredServer_useConfiguration_Params) error {
|
||||
cloudflaredConfig, err := p.NewCloudflaredConfig()
|
||||
client := tunnelrpc.ClientService{Client: c.Client}
|
||||
promise := client.UseConfiguration(ctx, func(p tunnelrpc.ClientService_useConfiguration_Params) error {
|
||||
clientServiceConfig, err := p.NewClientConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return MarshalCloudflaredConfig(cloudflaredConfig, config)
|
||||
return MarshalClientConfig(clientServiceConfig, config)
|
||||
})
|
||||
retval, err := promise.Result().Struct()
|
||||
if err != nil {
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package pogs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
@ -10,15 +12,18 @@ import (
|
|||
capnp "zombiezen.com/go/capnproto2"
|
||||
)
|
||||
|
||||
func TestCloudflaredConfig(t *testing.T) {
|
||||
addDoHProxyConfigs := func(c *CloudflaredConfig) {
|
||||
func TestClientConfig(t *testing.T) {
|
||||
addDoHProxyConfigs := func(c *ClientConfig) {
|
||||
c.DoHProxyConfigs = []*DoHProxyConfig{
|
||||
sampleDoHProxyConfig(),
|
||||
}
|
||||
}
|
||||
addReverseProxyConfigs := func(c *CloudflaredConfig) {
|
||||
addReverseProxyConfigs := func(c *ClientConfig) {
|
||||
c.ReverseProxyConfigs = []*ReverseProxyConfig{
|
||||
sampleReverseProxyConfig(),
|
||||
sampleReverseProxyConfig(func(c *ReverseProxyConfig) {
|
||||
c.ChunkedEncoding = false
|
||||
}),
|
||||
sampleReverseProxyConfig(func(c *ReverseProxyConfig) {
|
||||
c.Origin = sampleHTTPOriginConfig()
|
||||
}),
|
||||
|
@ -31,23 +36,23 @@ func TestCloudflaredConfig(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
testCases := []*CloudflaredConfig{
|
||||
sampleCloudflaredConfig(),
|
||||
sampleCloudflaredConfig(addDoHProxyConfigs),
|
||||
sampleCloudflaredConfig(addReverseProxyConfigs),
|
||||
sampleCloudflaredConfig(addDoHProxyConfigs, addReverseProxyConfigs),
|
||||
testCases := []*ClientConfig{
|
||||
sampleClientConfig(),
|
||||
sampleClientConfig(addDoHProxyConfigs),
|
||||
sampleClientConfig(addReverseProxyConfigs),
|
||||
sampleClientConfig(addDoHProxyConfigs, addReverseProxyConfigs),
|
||||
}
|
||||
for i, testCase := range testCases {
|
||||
_, seg, err := capnp.NewMessage(capnp.SingleSegment(nil))
|
||||
capnpEntity, err := tunnelrpc.NewCloudflaredConfig(seg)
|
||||
capnpEntity, err := tunnelrpc.NewClientConfig(seg)
|
||||
if !assert.NoError(t, err) {
|
||||
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) {
|
||||
continue
|
||||
}
|
||||
result, err := UnmarshalCloudflaredConfig(capnpEntity)
|
||||
result, err := UnmarshalClientConfig(capnpEntity)
|
||||
if !assert.NoError(t, err, "testCase index %v failed to unmarshal", i) {
|
||||
continue
|
||||
}
|
||||
|
@ -208,18 +213,17 @@ func TestWebSocketOriginConfig(t *testing.T) {
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Functions to generate sample data for ease of testing
|
||||
|
||||
func sampleCloudflaredConfig(overrides ...func(*CloudflaredConfig)) *CloudflaredConfig {
|
||||
// strip the location and monotonic clock reading so that assert.Equals()
|
||||
// will work correctly
|
||||
now := time.Now().UTC().Round(0)
|
||||
sample := &CloudflaredConfig{
|
||||
Timestamp: now,
|
||||
func sampleClientConfig(overrides ...func(*ClientConfig)) *ClientConfig {
|
||||
sample := &ClientConfig{
|
||||
Version: uint64(1337),
|
||||
AutoUpdateFrequency: 21 * time.Hour,
|
||||
MetricsUpdateFrequency: 11 * time.Minute,
|
||||
HeartbeatInterval: 5 * time.Second,
|
||||
MaxFailedHeartbeats: 9001,
|
||||
GracePeriod: 31 * time.Second,
|
||||
NumHAConnections: 49,
|
||||
}
|
||||
sample.ensureNoZeroFields()
|
||||
for _, f := range overrides {
|
||||
f(sample)
|
||||
}
|
||||
|
@ -232,6 +236,7 @@ func sampleDoHProxyConfig(overrides ...func(*DoHProxyConfig)) *DoHProxyConfig {
|
|||
ListenPort: 53,
|
||||
Upstreams: []string{"https://1.example.com", "https://2.example.com"},
|
||||
}
|
||||
sample.ensureNoZeroFields()
|
||||
for _, f := range overrides {
|
||||
f(sample)
|
||||
}
|
||||
|
@ -240,13 +245,14 @@ func sampleDoHProxyConfig(overrides ...func(*DoHProxyConfig)) *DoHProxyConfig {
|
|||
|
||||
func sampleReverseProxyConfig(overrides ...func(*ReverseProxyConfig)) *ReverseProxyConfig {
|
||||
sample := &ReverseProxyConfig{
|
||||
TunnelID: "hijk",
|
||||
TunnelHostname: "hijk.example.com",
|
||||
Origin: &HelloWorldOriginConfig{},
|
||||
Retries: 18,
|
||||
ConnectionTimeout: 5 * time.Second,
|
||||
ChunkedEncoding: false,
|
||||
ChunkedEncoding: true,
|
||||
CompressionQuality: 4,
|
||||
}
|
||||
sample.ensureNoZeroFields()
|
||||
for _, f := range overrides {
|
||||
f(sample)
|
||||
}
|
||||
|
@ -265,6 +271,7 @@ func sampleHTTPOriginConfig(overrides ...func(*HTTPOriginConfig)) *HTTPOriginCon
|
|||
MaxIdleConnections: 19,
|
||||
IdleConnectionTimeout: 17 * time.Second,
|
||||
}
|
||||
sample.ensureNoZeroFields()
|
||||
for _, f := range overrides {
|
||||
f(sample)
|
||||
}
|
||||
|
@ -275,6 +282,7 @@ func sampleUnixSocketOriginConfig(overrides ...func(*UnixSocketOriginConfig)) *U
|
|||
sample := &UnixSocketOriginConfig{
|
||||
Path: "/var/lib/file.sock",
|
||||
}
|
||||
sample.ensureNoZeroFields()
|
||||
for _, f := range overrides {
|
||||
f(sample)
|
||||
}
|
||||
|
@ -285,8 +293,71 @@ func sampleWebSocketOriginConfig(overrides ...func(*WebSocketOriginConfig)) *Web
|
|||
sample := &WebSocketOriginConfig{
|
||||
URL: "ssh://example.com",
|
||||
}
|
||||
sample.ensureNoZeroFields()
|
||||
for _, f := range overrides {
|
||||
f(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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,10 +72,11 @@ struct ConnectError {
|
|||
shouldRetry @2 :Bool;
|
||||
}
|
||||
|
||||
struct CloudflaredConfig {
|
||||
# Timestamp (in ns) of this configuration. Any configuration supplied to
|
||||
# useConfiguration() with an older timestamp should be ignored.
|
||||
timestamp @0 :Int64;
|
||||
struct ClientConfig {
|
||||
# Version of this configuration. This value is opaque, but is guaranteed
|
||||
# to monotonically increase in value. Any configuration supplied to
|
||||
# useConfiguration() with a smaller `version` should be ignored.
|
||||
version @0 :UInt64;
|
||||
# Frequency (in ns) to check Equinox for updates.
|
||||
# Zero means auto-update is disabled.
|
||||
# cloudflared CLI option: `autoupdate-freq`
|
||||
|
@ -101,10 +102,14 @@ struct CloudflaredConfig {
|
|||
dohProxyConfigs @6 :List(DoHProxyConfig);
|
||||
# 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`
|
||||
numHAConnections @8 :UInt8;
|
||||
}
|
||||
|
||||
struct ReverseProxyConfig {
|
||||
tunnelID @0 :Text;
|
||||
tunnelHostname @0 :Text;
|
||||
origin :union {
|
||||
http @1 :HTTPOriginConfig;
|
||||
socket @2 :UnixSocketOriginConfig;
|
||||
|
@ -230,6 +235,6 @@ interface TunnelServer {
|
|||
connect @3 (parameters :CapnpConnectParameters) -> (result :ConnectResult);
|
||||
}
|
||||
|
||||
interface CloudflaredServer {
|
||||
useConfiguration @0 (cloudflaredConfig :CloudflaredConfig) -> (result :UseConfigurationResult);
|
||||
interface ClientService {
|
||||
useConfiguration @0 (clientServiceConfig :ClientConfig) -> (result :UseConfigurationResult);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue