TUN-1606: Define CloudflaredConfig RPC structure, interface for cloudflared's RPC server
This commit is contained in:
parent
9a43a92b1c
commit
13d25a52a9
18
Makefile
18
Makefile
|
@ -28,11 +28,11 @@ clean:
|
||||||
go clean
|
go clean
|
||||||
|
|
||||||
.PHONY: cloudflared
|
.PHONY: cloudflared
|
||||||
cloudflared:
|
cloudflared: tunnel-deps
|
||||||
go build -v $(VERSION_FLAGS) $(IMPORT_PATH)/cmd/cloudflared
|
go build -v $(VERSION_FLAGS) $(IMPORT_PATH)/cmd/cloudflared
|
||||||
|
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
test:
|
test: vet
|
||||||
go test -v -race $(VERSION_FLAGS) ./...
|
go test -v -race $(VERSION_FLAGS) ./...
|
||||||
|
|
||||||
.PHONY: cloudflared-deb
|
.PHONY: cloudflared-deb
|
||||||
|
@ -65,5 +65,15 @@ bin/equinox:
|
||||||
curl -s https://bin.equinox.io/c/75JtLRTsJ3n/release-tool-beta-$(EQUINOX_PLATFORM).tgz | tar xz -C bin/
|
curl -s https://bin.equinox.io/c/75JtLRTsJ3n/release-tool-beta-$(EQUINOX_PLATFORM).tgz | tar xz -C bin/
|
||||||
|
|
||||||
.PHONY: tunnel-deps
|
.PHONY: tunnel-deps
|
||||||
tunnel-deps:
|
tunnel-deps: tunnelrpc/tunnelrpc.capnp.go
|
||||||
capnp compile -ogo -I ./tunnelrpc tunnelrpc/tunnelrpc.capnp
|
|
||||||
|
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:tunnelrpc -I ./tunnelrpc tunnelrpc/tunnelrpc.capnp
|
||||||
|
|
||||||
|
.PHONY: vet
|
||||||
|
vet:
|
||||||
|
go vet -tests=false ./...
|
||||||
|
which go-sumtype # go get github.com/BurntSushi/go-sumtype
|
||||||
|
go-sumtype $$(go list ./...)
|
||||||
|
|
22
cfsetup.yaml
22
cfsetup.yaml
|
@ -1,5 +1,6 @@
|
||||||
pinned_go: &pinned_go go=1.11.5-1
|
pinned_go: &pinned_go go=1.11.5-1
|
||||||
build_dir: &build_dir /cfsetup_build/src/github.com/cloudflare/cloudflared/
|
build_dir: &build_dir /cfsetup_build/src/github.com/cloudflare/cloudflared/
|
||||||
|
default-flavor: stretch
|
||||||
stretch: &stretch
|
stretch: &stretch
|
||||||
build:
|
build:
|
||||||
build_dir: *build_dir
|
build_dir: *build_dir
|
||||||
|
@ -46,15 +47,15 @@ stretch: &stretch
|
||||||
- export CC=arm-linux-gnueabihf-gcc
|
- export CC=arm-linux-gnueabihf-gcc
|
||||||
- make release
|
- make release
|
||||||
release-linux-386:
|
release-linux-386:
|
||||||
build_dir: *build_dir
|
build_dir: *build_dir
|
||||||
builddeps:
|
builddeps:
|
||||||
- *pinned_go
|
- *pinned_go
|
||||||
- gcc-multilib
|
- gcc-multilib
|
||||||
post-cache:
|
post-cache:
|
||||||
- export GOPATH=/cfsetup_build/
|
- export GOPATH=/cfsetup_build/
|
||||||
- export GOOS=linux
|
- export GOOS=linux
|
||||||
- export GOARCH=386
|
- export GOARCH=386
|
||||||
- make release
|
- make release
|
||||||
release-windows-amd64:
|
release-windows-amd64:
|
||||||
build_dir: *build_dir
|
build_dir: *build_dir
|
||||||
builddeps:
|
builddeps:
|
||||||
|
@ -86,6 +87,9 @@ stretch: &stretch
|
||||||
- export GOPATH=/cfsetup_build/
|
- export GOPATH=/cfsetup_build/
|
||||||
- export GOOS=linux
|
- export GOOS=linux
|
||||||
- export GOARCH=amd64
|
- export GOARCH=amd64
|
||||||
|
- sudo chown -R $(whoami) /cfsetup_build/
|
||||||
|
- go get github.com/BurntSushi/go-sumtype
|
||||||
|
- export PATH="$GOPATH/bin:$PATH"
|
||||||
- make test
|
- make test
|
||||||
|
|
||||||
jessie: *stretch
|
jessie: *stretch
|
||||||
|
|
|
@ -0,0 +1,373 @@
|
||||||
|
package pogs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/cloudflare/cloudflared/tunnelrpc"
|
||||||
|
capnp "zombiezen.com/go/capnproto2"
|
||||||
|
"zombiezen.com/go/capnproto2/pogs"
|
||||||
|
"zombiezen.com/go/capnproto2/rpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Structs
|
||||||
|
///
|
||||||
|
|
||||||
|
type CloudflaredConfig struct {
|
||||||
|
Timestamp time.Time
|
||||||
|
AutoUpdateFrequency time.Duration
|
||||||
|
MetricsUpdateFrequency time.Duration
|
||||||
|
HeartbeatInterval time.Duration
|
||||||
|
MaxFailedHeartbeats uint64
|
||||||
|
GracePeriod time.Duration
|
||||||
|
DoHProxyConfigs []*DoHProxyConfig
|
||||||
|
ReverseProxyConfigs []*ReverseProxyConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
type UseConfigurationResult struct {
|
||||||
|
Success bool
|
||||||
|
ErrorMessage string
|
||||||
|
}
|
||||||
|
|
||||||
|
type DoHProxyConfig struct {
|
||||||
|
ListenHost string
|
||||||
|
ListenPort uint16
|
||||||
|
Upstreams []string
|
||||||
|
}
|
||||||
|
|
||||||
|
type ReverseProxyConfig struct {
|
||||||
|
TunnelID string
|
||||||
|
Origin OriginConfig
|
||||||
|
Retries uint64
|
||||||
|
ConnectionTimeout time.Duration
|
||||||
|
ChunkedEncoding bool
|
||||||
|
CompressionQuality uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
//go-sumtype:decl OriginConfig
|
||||||
|
type OriginConfig interface {
|
||||||
|
isOriginConfig()
|
||||||
|
}
|
||||||
|
|
||||||
|
type HTTPOriginConfig struct {
|
||||||
|
URL string `capnp:"url"`
|
||||||
|
TCPKeepAlive time.Duration `capnp:"tcpKeepAlive"`
|
||||||
|
DialDualStack bool
|
||||||
|
TLSHandshakeTimeout time.Duration `capnp:"tlsHandshakeTimeout"`
|
||||||
|
TLSVerify bool `capnp:"tlsVerify"`
|
||||||
|
OriginCAPool string
|
||||||
|
OriginServerName string
|
||||||
|
MaxIdleConnections uint64
|
||||||
|
IdleConnectionTimeout time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ *HTTPOriginConfig) isOriginConfig() {}
|
||||||
|
|
||||||
|
type UnixSocketOriginConfig struct {
|
||||||
|
Path string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ *UnixSocketOriginConfig) isOriginConfig() {}
|
||||||
|
|
||||||
|
type WebSocketOriginConfig struct {
|
||||||
|
URL string `capnp:"url"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ *WebSocketOriginConfig) isOriginConfig() {}
|
||||||
|
|
||||||
|
type HelloWorldOriginConfig struct{}
|
||||||
|
|
||||||
|
func (_ *HelloWorldOriginConfig) isOriginConfig() {}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Boilerplate to convert between these structs and the primitive structs generated by capnp-go
|
||||||
|
///
|
||||||
|
|
||||||
|
func MarshalCloudflaredConfig(s tunnelrpc.CloudflaredConfig, p *CloudflaredConfig) error {
|
||||||
|
s.SetTimestamp(p.Timestamp.UnixNano())
|
||||||
|
s.SetAutoUpdateFrequency(p.AutoUpdateFrequency.Nanoseconds())
|
||||||
|
s.SetMetricsUpdateFrequency(p.MetricsUpdateFrequency.Nanoseconds())
|
||||||
|
s.SetHeartbeatInterval(p.HeartbeatInterval.Nanoseconds())
|
||||||
|
s.SetMaxFailedHeartbeats(p.MaxFailedHeartbeats)
|
||||||
|
s.SetGracePeriod(p.GracePeriod.Nanoseconds())
|
||||||
|
err := marshalDoHProxyConfigs(s, p.DoHProxyConfigs)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = marshalReverseProxyConfigs(s, p.ReverseProxyConfigs)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func marshalDoHProxyConfigs(s tunnelrpc.CloudflaredConfig, dohProxyConfigs []*DoHProxyConfig) error {
|
||||||
|
capnpList, err := s.NewDohProxyConfigs(int32(len(dohProxyConfigs)))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for i, unmarshalledConfig := range dohProxyConfigs {
|
||||||
|
err := MarshalDoHProxyConfig(capnpList.At(i), unmarshalledConfig)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func marshalReverseProxyConfigs(s tunnelrpc.CloudflaredConfig, reverseProxyConfigs []*ReverseProxyConfig) error {
|
||||||
|
capnpList, err := s.NewReverseProxyConfigs(int32(len(reverseProxyConfigs)))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for i, unmarshalledConfig := range reverseProxyConfigs {
|
||||||
|
err := MarshalReverseProxyConfig(capnpList.At(i), unmarshalledConfig)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func UnmarshalCloudflaredConfig(s tunnelrpc.CloudflaredConfig) (*CloudflaredConfig, error) {
|
||||||
|
p := new(CloudflaredConfig)
|
||||||
|
p.Timestamp = time.Unix(0, s.Timestamp()).UTC()
|
||||||
|
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())
|
||||||
|
dohProxyConfigs, err := unmarshalDoHProxyConfigs(s)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
p.DoHProxyConfigs = dohProxyConfigs
|
||||||
|
reverseProxyConfigs, err := unmarshalReverseProxyConfigs(s)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
p.ReverseProxyConfigs = reverseProxyConfigs
|
||||||
|
return p, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func unmarshalDoHProxyConfigs(s tunnelrpc.CloudflaredConfig) ([]*DoHProxyConfig, error) {
|
||||||
|
var result []*DoHProxyConfig
|
||||||
|
marshalledDoHProxyConfigs, err := s.DohProxyConfigs()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for i := 0; i < marshalledDoHProxyConfigs.Len(); i++ {
|
||||||
|
ss := marshalledDoHProxyConfigs.At(i)
|
||||||
|
dohProxyConfig, err := UnmarshalDoHProxyConfig(ss)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
result = append(result, dohProxyConfig)
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func unmarshalReverseProxyConfigs(s tunnelrpc.CloudflaredConfig) ([]*ReverseProxyConfig, error) {
|
||||||
|
var result []*ReverseProxyConfig
|
||||||
|
marshalledReverseProxyConfigs, err := s.ReverseProxyConfigs()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for i := 0; i < marshalledReverseProxyConfigs.Len(); i++ {
|
||||||
|
ss := marshalledReverseProxyConfigs.At(i)
|
||||||
|
reverseProxyConfig, err := UnmarshalReverseProxyConfig(ss)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
result = append(result, reverseProxyConfig)
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func MarshalUseConfigurationResult(s tunnelrpc.UseConfigurationResult, p *UseConfigurationResult) error {
|
||||||
|
return pogs.Insert(tunnelrpc.UseConfigurationResult_TypeID, s.Struct, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func UnmarshalUseConfigurationResult(s tunnelrpc.UseConfigurationResult) (*UseConfigurationResult, error) {
|
||||||
|
p := new(UseConfigurationResult)
|
||||||
|
err := pogs.Extract(p, tunnelrpc.UseConfigurationResult_TypeID, s.Struct)
|
||||||
|
return p, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func MarshalDoHProxyConfig(s tunnelrpc.DoHProxyConfig, p *DoHProxyConfig) error {
|
||||||
|
return pogs.Insert(tunnelrpc.DoHProxyConfig_TypeID, s.Struct, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func UnmarshalDoHProxyConfig(s tunnelrpc.DoHProxyConfig) (*DoHProxyConfig, error) {
|
||||||
|
p := new(DoHProxyConfig)
|
||||||
|
err := pogs.Extract(p, tunnelrpc.DoHProxyConfig_TypeID, s.Struct)
|
||||||
|
return p, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func MarshalReverseProxyConfig(s tunnelrpc.ReverseProxyConfig, p *ReverseProxyConfig) error {
|
||||||
|
s.SetTunnelID(p.TunnelID)
|
||||||
|
switch config := p.Origin.(type) {
|
||||||
|
case *HTTPOriginConfig:
|
||||||
|
ss, err := s.Origin().NewHttp()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
MarshalHTTPOriginConfig(ss, config)
|
||||||
|
case *UnixSocketOriginConfig:
|
||||||
|
ss, err := s.Origin().NewSocket()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
MarshalUnixSocketOriginConfig(ss, config)
|
||||||
|
case *WebSocketOriginConfig:
|
||||||
|
ss, err := s.Origin().NewWebsocket()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
MarshalWebSocketOriginConfig(ss, config)
|
||||||
|
case *HelloWorldOriginConfig:
|
||||||
|
ss, err := s.Origin().NewHelloWorld()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
MarshalHelloWorldOriginConfig(ss, config)
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("Unknown type for config: %T", config)
|
||||||
|
}
|
||||||
|
s.SetRetries(p.Retries)
|
||||||
|
s.SetConnectionTimeout(p.ConnectionTimeout.Nanoseconds())
|
||||||
|
s.SetChunkedEncoding(p.ChunkedEncoding)
|
||||||
|
s.SetCompressionQuality(p.CompressionQuality)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func UnmarshalReverseProxyConfig(s tunnelrpc.ReverseProxyConfig) (*ReverseProxyConfig, error) {
|
||||||
|
p := new(ReverseProxyConfig)
|
||||||
|
tunnelID, err := s.TunnelID()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
p.TunnelID = tunnelID
|
||||||
|
switch s.Origin().Which() {
|
||||||
|
case tunnelrpc.ReverseProxyConfig_origin_Which_http:
|
||||||
|
ss, err := s.Origin().Http()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
config, err := UnmarshalHTTPOriginConfig(ss)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
p.Origin = config
|
||||||
|
case tunnelrpc.ReverseProxyConfig_origin_Which_socket:
|
||||||
|
ss, err := s.Origin().Socket()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
config, err := UnmarshalUnixSocketOriginConfig(ss)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
p.Origin = config
|
||||||
|
case tunnelrpc.ReverseProxyConfig_origin_Which_websocket:
|
||||||
|
ss, err := s.Origin().Websocket()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
config, err := UnmarshalWebSocketOriginConfig(ss)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
p.Origin = config
|
||||||
|
case tunnelrpc.ReverseProxyConfig_origin_Which_helloWorld:
|
||||||
|
ss, err := s.Origin().HelloWorld()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
config, err := UnmarshalHelloWorldOriginConfig(ss)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
p.Origin = config
|
||||||
|
}
|
||||||
|
p.Retries = s.Retries()
|
||||||
|
p.ConnectionTimeout = time.Duration(s.ConnectionTimeout())
|
||||||
|
p.ChunkedEncoding = s.ChunkedEncoding()
|
||||||
|
p.CompressionQuality = s.CompressionQuality()
|
||||||
|
return p, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func MarshalHTTPOriginConfig(s tunnelrpc.HTTPOriginConfig, p *HTTPOriginConfig) error {
|
||||||
|
return pogs.Insert(tunnelrpc.HTTPOriginConfig_TypeID, s.Struct, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func UnmarshalHTTPOriginConfig(s tunnelrpc.HTTPOriginConfig) (*HTTPOriginConfig, error) {
|
||||||
|
p := new(HTTPOriginConfig)
|
||||||
|
err := pogs.Extract(p, tunnelrpc.HTTPOriginConfig_TypeID, s.Struct)
|
||||||
|
return p, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func MarshalUnixSocketOriginConfig(s tunnelrpc.UnixSocketOriginConfig, p *UnixSocketOriginConfig) error {
|
||||||
|
return pogs.Insert(tunnelrpc.UnixSocketOriginConfig_TypeID, s.Struct, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func UnmarshalUnixSocketOriginConfig(s tunnelrpc.UnixSocketOriginConfig) (*UnixSocketOriginConfig, error) {
|
||||||
|
p := new(UnixSocketOriginConfig)
|
||||||
|
err := pogs.Extract(p, tunnelrpc.UnixSocketOriginConfig_TypeID, s.Struct)
|
||||||
|
return p, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func MarshalWebSocketOriginConfig(s tunnelrpc.WebSocketOriginConfig, p *WebSocketOriginConfig) error {
|
||||||
|
return pogs.Insert(tunnelrpc.WebSocketOriginConfig_TypeID, s.Struct, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func UnmarshalWebSocketOriginConfig(s tunnelrpc.WebSocketOriginConfig) (*WebSocketOriginConfig, error) {
|
||||||
|
p := new(WebSocketOriginConfig)
|
||||||
|
err := pogs.Extract(p, tunnelrpc.WebSocketOriginConfig_TypeID, s.Struct)
|
||||||
|
return p, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func MarshalHelloWorldOriginConfig(s tunnelrpc.HelloWorldOriginConfig, p *HelloWorldOriginConfig) error {
|
||||||
|
return pogs.Insert(tunnelrpc.HelloWorldOriginConfig_TypeID, s.Struct, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func UnmarshalHelloWorldOriginConfig(s tunnelrpc.HelloWorldOriginConfig) (*HelloWorldOriginConfig, error) {
|
||||||
|
p := new(HelloWorldOriginConfig)
|
||||||
|
err := pogs.Extract(p, tunnelrpc.HelloWorldOriginConfig_TypeID, s.Struct)
|
||||||
|
return p, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type CloudflaredServer interface {
|
||||||
|
UseConfiguration(ctx context.Context, config *CloudflaredConfig) (*CloudflaredConfig, error)
|
||||||
|
GetConfiguration(ctx context.Context) (*CloudflaredConfig, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type CloudflaredServer_PogsClient struct {
|
||||||
|
Client capnp.Client
|
||||||
|
Conn *rpc.Conn
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CloudflaredServer_PogsClient) Close() error {
|
||||||
|
return c.Conn.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CloudflaredServer_PogsClient) UseConfiguration(
|
||||||
|
ctx context.Context,
|
||||||
|
config *CloudflaredConfig,
|
||||||
|
) (*UseConfigurationResult, error) {
|
||||||
|
client := tunnelrpc.CloudflaredServer{Client: c.Client}
|
||||||
|
promise := client.UseConfiguration(ctx, func(p tunnelrpc.CloudflaredServer_useConfiguration_Params) error {
|
||||||
|
cloudflaredConfig, err := p.NewCloudflaredConfig()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return MarshalCloudflaredConfig(cloudflaredConfig, config)
|
||||||
|
})
|
||||||
|
retval, err := promise.Result().Struct()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return UnmarshalUseConfigurationResult(retval)
|
||||||
|
}
|
|
@ -0,0 +1,292 @@
|
||||||
|
package pogs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
"github.com/cloudflare/cloudflared/tunnelrpc"
|
||||||
|
capnp "zombiezen.com/go/capnproto2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCloudflaredConfig(t *testing.T) {
|
||||||
|
addDoHProxyConfigs := func(c *CloudflaredConfig) {
|
||||||
|
c.DoHProxyConfigs = []*DoHProxyConfig{
|
||||||
|
sampleDoHProxyConfig(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addReverseProxyConfigs := func(c *CloudflaredConfig) {
|
||||||
|
c.ReverseProxyConfigs = []*ReverseProxyConfig{
|
||||||
|
sampleReverseProxyConfig(),
|
||||||
|
sampleReverseProxyConfig(func(c *ReverseProxyConfig) {
|
||||||
|
c.Origin = sampleHTTPOriginConfig()
|
||||||
|
}),
|
||||||
|
sampleReverseProxyConfig(func(c *ReverseProxyConfig) {
|
||||||
|
c.Origin = sampleUnixSocketOriginConfig()
|
||||||
|
}),
|
||||||
|
sampleReverseProxyConfig(func(c *ReverseProxyConfig) {
|
||||||
|
c.Origin = sampleWebSocketOriginConfig()
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
testCases := []*CloudflaredConfig{
|
||||||
|
sampleCloudflaredConfig(),
|
||||||
|
sampleCloudflaredConfig(addDoHProxyConfigs),
|
||||||
|
sampleCloudflaredConfig(addReverseProxyConfigs),
|
||||||
|
sampleCloudflaredConfig(addDoHProxyConfigs, addReverseProxyConfigs),
|
||||||
|
}
|
||||||
|
for i, testCase := range testCases {
|
||||||
|
_, seg, err := capnp.NewMessage(capnp.SingleSegment(nil))
|
||||||
|
capnpEntity, err := tunnelrpc.NewCloudflaredConfig(seg)
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
t.Fatal("Couldn't initialize a new message")
|
||||||
|
}
|
||||||
|
err = MarshalCloudflaredConfig(capnpEntity, testCase)
|
||||||
|
if !assert.NoError(t, err, "testCase index %v failed to marshal", i) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
result, err := UnmarshalCloudflaredConfig(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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUseConfigurationResult(t *testing.T) {
|
||||||
|
testCases := []*UseConfigurationResult{
|
||||||
|
&UseConfigurationResult{
|
||||||
|
Success: true,
|
||||||
|
},
|
||||||
|
&UseConfigurationResult{
|
||||||
|
Success: false,
|
||||||
|
ErrorMessage: "the quick brown fox jumped over the lazy dogs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for i, testCase := range testCases {
|
||||||
|
_, seg, err := capnp.NewMessage(capnp.SingleSegment(nil))
|
||||||
|
capnpEntity, err := tunnelrpc.NewUseConfigurationResult(seg)
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
t.Fatal("Couldn't initialize a new message")
|
||||||
|
}
|
||||||
|
err = MarshalUseConfigurationResult(capnpEntity, testCase)
|
||||||
|
if !assert.NoError(t, err, "testCase index %v failed to marshal", i) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
result, err := UnmarshalUseConfigurationResult(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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDoHProxyConfig(t *testing.T) {
|
||||||
|
testCases := []*DoHProxyConfig{
|
||||||
|
sampleDoHProxyConfig(),
|
||||||
|
sampleDoHProxyConfig(func(c *DoHProxyConfig) {
|
||||||
|
c.Upstreams = nil
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
for i, testCase := range testCases {
|
||||||
|
_, seg, err := capnp.NewMessage(capnp.SingleSegment(nil))
|
||||||
|
capnpEntity, err := tunnelrpc.NewDoHProxyConfig(seg)
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
t.Fatal("Couldn't initialize a new message")
|
||||||
|
}
|
||||||
|
err = MarshalDoHProxyConfig(capnpEntity, testCase)
|
||||||
|
if !assert.NoError(t, err, "testCase index %v failed to marshal", i) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
result, err := UnmarshalDoHProxyConfig(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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReverseProxyConfig(t *testing.T) {
|
||||||
|
testCases := []*ReverseProxyConfig{
|
||||||
|
sampleReverseProxyConfig(),
|
||||||
|
sampleReverseProxyConfig(func(c *ReverseProxyConfig) {
|
||||||
|
c.Origin = sampleHTTPOriginConfig()
|
||||||
|
}),
|
||||||
|
sampleReverseProxyConfig(func(c *ReverseProxyConfig) {
|
||||||
|
c.Origin = sampleUnixSocketOriginConfig()
|
||||||
|
}),
|
||||||
|
sampleReverseProxyConfig(func(c *ReverseProxyConfig) {
|
||||||
|
c.Origin = sampleWebSocketOriginConfig()
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
for i, testCase := range testCases {
|
||||||
|
_, seg, err := capnp.NewMessage(capnp.SingleSegment(nil))
|
||||||
|
capnpEntity, err := tunnelrpc.NewReverseProxyConfig(seg)
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
t.Fatal("Couldn't initialize a new message")
|
||||||
|
}
|
||||||
|
err = MarshalReverseProxyConfig(capnpEntity, testCase)
|
||||||
|
if !assert.NoError(t, err, "testCase index %v failed to marshal", i) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
result, err := UnmarshalReverseProxyConfig(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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHTTPOriginConfig(t *testing.T) {
|
||||||
|
testCases := []*HTTPOriginConfig{
|
||||||
|
sampleHTTPOriginConfig(),
|
||||||
|
}
|
||||||
|
for i, testCase := range testCases {
|
||||||
|
_, seg, err := capnp.NewMessage(capnp.SingleSegment(nil))
|
||||||
|
capnpEntity, err := tunnelrpc.NewHTTPOriginConfig(seg)
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
t.Fatal("Couldn't initialize a new message")
|
||||||
|
}
|
||||||
|
err = MarshalHTTPOriginConfig(capnpEntity, testCase)
|
||||||
|
if !assert.NoError(t, err, "testCase index %v failed to marshal", i) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
result, err := UnmarshalHTTPOriginConfig(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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnixSocketOriginConfig(t *testing.T) {
|
||||||
|
testCases := []*UnixSocketOriginConfig{
|
||||||
|
sampleUnixSocketOriginConfig(),
|
||||||
|
}
|
||||||
|
for i, testCase := range testCases {
|
||||||
|
_, seg, err := capnp.NewMessage(capnp.SingleSegment(nil))
|
||||||
|
capnpEntity, err := tunnelrpc.NewUnixSocketOriginConfig(seg)
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
t.Fatal("Couldn't initialize a new message")
|
||||||
|
}
|
||||||
|
err = MarshalUnixSocketOriginConfig(capnpEntity, testCase)
|
||||||
|
if !assert.NoError(t, err, "testCase index %v failed to marshal", i) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
result, err := UnmarshalUnixSocketOriginConfig(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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWebSocketOriginConfig(t *testing.T) {
|
||||||
|
testCases := []*WebSocketOriginConfig{
|
||||||
|
sampleWebSocketOriginConfig(),
|
||||||
|
}
|
||||||
|
for i, testCase := range testCases {
|
||||||
|
_, seg, err := capnp.NewMessage(capnp.SingleSegment(nil))
|
||||||
|
capnpEntity, err := tunnelrpc.NewWebSocketOriginConfig(seg)
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
t.Fatal("Couldn't initialize a new message")
|
||||||
|
}
|
||||||
|
err = MarshalWebSocketOriginConfig(capnpEntity, testCase)
|
||||||
|
if !assert.NoError(t, err, "testCase index %v failed to marshal", i) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
result, err := UnmarshalWebSocketOriginConfig(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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// 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,
|
||||||
|
AutoUpdateFrequency: 21 * time.Hour,
|
||||||
|
MetricsUpdateFrequency: 11 * time.Minute,
|
||||||
|
HeartbeatInterval: 5 * time.Second,
|
||||||
|
MaxFailedHeartbeats: 9001,
|
||||||
|
GracePeriod: 31 * time.Second,
|
||||||
|
}
|
||||||
|
for _, f := range overrides {
|
||||||
|
f(sample)
|
||||||
|
}
|
||||||
|
return sample
|
||||||
|
}
|
||||||
|
|
||||||
|
func sampleDoHProxyConfig(overrides ...func(*DoHProxyConfig)) *DoHProxyConfig {
|
||||||
|
sample := &DoHProxyConfig{
|
||||||
|
ListenHost: "127.0.0.1",
|
||||||
|
ListenPort: 53,
|
||||||
|
Upstreams: []string{"https://1.example.com", "https://2.example.com"},
|
||||||
|
}
|
||||||
|
for _, f := range overrides {
|
||||||
|
f(sample)
|
||||||
|
}
|
||||||
|
return sample
|
||||||
|
}
|
||||||
|
|
||||||
|
func sampleReverseProxyConfig(overrides ...func(*ReverseProxyConfig)) *ReverseProxyConfig {
|
||||||
|
sample := &ReverseProxyConfig{
|
||||||
|
TunnelID: "hijk",
|
||||||
|
Origin: &HelloWorldOriginConfig{},
|
||||||
|
Retries: 18,
|
||||||
|
ConnectionTimeout: 5 * time.Second,
|
||||||
|
ChunkedEncoding: false,
|
||||||
|
CompressionQuality: 4,
|
||||||
|
}
|
||||||
|
for _, f := range overrides {
|
||||||
|
f(sample)
|
||||||
|
}
|
||||||
|
return sample
|
||||||
|
}
|
||||||
|
|
||||||
|
func sampleHTTPOriginConfig(overrides ...func(*HTTPOriginConfig)) *HTTPOriginConfig {
|
||||||
|
sample := &HTTPOriginConfig{
|
||||||
|
URL: "https://example.com",
|
||||||
|
TCPKeepAlive: 7 * time.Second,
|
||||||
|
DialDualStack: true,
|
||||||
|
TLSHandshakeTimeout: 11 * time.Second,
|
||||||
|
TLSVerify: true,
|
||||||
|
OriginCAPool: "/etc/cert.pem",
|
||||||
|
OriginServerName: "secure.example.com",
|
||||||
|
MaxIdleConnections: 19,
|
||||||
|
IdleConnectionTimeout: 17 * time.Second,
|
||||||
|
}
|
||||||
|
for _, f := range overrides {
|
||||||
|
f(sample)
|
||||||
|
}
|
||||||
|
return sample
|
||||||
|
}
|
||||||
|
|
||||||
|
func sampleUnixSocketOriginConfig(overrides ...func(*UnixSocketOriginConfig)) *UnixSocketOriginConfig {
|
||||||
|
sample := &UnixSocketOriginConfig{
|
||||||
|
Path: "/var/lib/file.sock",
|
||||||
|
}
|
||||||
|
for _, f := range overrides {
|
||||||
|
f(sample)
|
||||||
|
}
|
||||||
|
return sample
|
||||||
|
}
|
||||||
|
|
||||||
|
func sampleWebSocketOriginConfig(overrides ...func(*WebSocketOriginConfig)) *WebSocketOriginConfig {
|
||||||
|
sample := &WebSocketOriginConfig{
|
||||||
|
URL: "ssh://example.com",
|
||||||
|
}
|
||||||
|
for _, f := range overrides {
|
||||||
|
f(sample)
|
||||||
|
}
|
||||||
|
return sample
|
||||||
|
}
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"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"
|
"zombiezen.com/go/capnproto2/server"
|
||||||
|
|
|
@ -70,6 +70,137 @@ struct ConnectError {
|
||||||
shouldRetry @2 :Bool;
|
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;
|
||||||
|
# Frequency (in ns) to check Equinox for updates.
|
||||||
|
# Zero means auto-update is disabled.
|
||||||
|
# cloudflared CLI option: `autoupdate-freq`
|
||||||
|
autoUpdateFrequency @1 :Int64;
|
||||||
|
# Frequency (in ns) to update connection-based metrics.
|
||||||
|
# cloudflared CLI option: `metrics-update-freq`
|
||||||
|
metricsUpdateFrequency @2 :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
|
||||||
|
# first SIGINT/SIGTERM. A second SIGINT/SIGTERM will force cloudflared to
|
||||||
|
# shutdown immediately. For example, this field can be used to gracefully
|
||||||
|
# transition traffic to another cloudflared instance.
|
||||||
|
# cloudflared CLI option: `grace-period`
|
||||||
|
gracePeriod @5 :Int64;
|
||||||
|
# Configuration for cloudflared to run as a DNS-over-HTTPS proxy.
|
||||||
|
# cloudflared CLI option: `proxy-dns`
|
||||||
|
dohProxyConfigs @6 :List(DoHProxyConfig);
|
||||||
|
# Configuration for cloudflared to run as an HTTP reverse proxy.
|
||||||
|
reverseProxyConfigs @7 :List(ReverseProxyConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ReverseProxyConfig {
|
||||||
|
tunnelID @0 :Text;
|
||||||
|
origin :union {
|
||||||
|
http @1 :HTTPOriginConfig;
|
||||||
|
socket @2 :UnixSocketOriginConfig;
|
||||||
|
websocket @3 :WebSocketOriginConfig;
|
||||||
|
helloWorld @4 :HelloWorldOriginConfig;
|
||||||
|
}
|
||||||
|
# Maximum number of retries for connection/protocol errors.
|
||||||
|
# cloudflared CLI option: `retries`
|
||||||
|
retries @5 :UInt64;
|
||||||
|
# maximum time (in ns) for cloudflared to wait to establish a connection
|
||||||
|
# to the origin. Zero means no timeout.
|
||||||
|
# cloudflared CLI option: `proxy-connect-timeout`
|
||||||
|
connectionTimeout @6 :Int64;
|
||||||
|
# Whether cloudflared should allow chunked transfer encoding to the
|
||||||
|
# origin. (This should be disabled for WSGI origins, for example.)
|
||||||
|
# negation of cloudflared CLI option: `no-chunked-encoding`
|
||||||
|
chunkedEncoding @7 :Bool;
|
||||||
|
# (beta) Use cross-stream compression instead of HTTP compression.
|
||||||
|
# 0=off, 1=low, 2=medium, 3=high.
|
||||||
|
# For more context see the mapping here: https://github.com/cloudflare/cloudflared/blob/2019.3.2/h2mux/h2_dictionaries.go#L62
|
||||||
|
# cloudflared CLI option: `compression-quality`
|
||||||
|
compressionQuality @8 :UInt64;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct UnixSocketOriginConfig {
|
||||||
|
# path to the socket file.
|
||||||
|
# cloudflared will send data to this socket via a Unix socket connection.
|
||||||
|
# cloudflared CLI option: `unix-socket`
|
||||||
|
path @0 :Text;
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
struct WebSocketOriginConfig {
|
||||||
|
# URI of the origin service.
|
||||||
|
# cloudflared will start a websocket server that forwards data to this URI
|
||||||
|
# cloudflared CLI option: `url`
|
||||||
|
# cloudflared logic: https://github.com/cloudflare/cloudflared/blob/2019.3.2/cmd/cloudflared/tunnel/cmd.go#L304
|
||||||
|
url @0 :Text;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct HTTPOriginConfig {
|
||||||
|
# HTTP(S) URL of the origin service.
|
||||||
|
# cloudflared CLI option: `url`
|
||||||
|
url @0 :Text;
|
||||||
|
# the TCP keep-alive period (in ns) for an active network connection.
|
||||||
|
# Zero means keep-alives are not enabled.
|
||||||
|
# cloudflared CLI option: `proxy-tcp-keepalive`
|
||||||
|
tcpKeepAlive @1 :Int64;
|
||||||
|
# whether cloudflared should use a "happy eyeballs"-compliant procedure
|
||||||
|
# to connect to origins that resolve to both IPv4 and IPv6 addresses
|
||||||
|
# negation of cloudflared CLI option: `proxy-no-happy-eyeballs`
|
||||||
|
dialDualStack @2 :Bool;
|
||||||
|
# maximum time (in ns) for cloudflared to wait for a TLS handshake
|
||||||
|
# with the origin. Zero means no timeout.
|
||||||
|
# cloudflared CLI option: `proxy-tls-timeout`
|
||||||
|
tlsHandshakeTimeout @3 :Int64;
|
||||||
|
# Whether cloudflared should verify TLS connections to the origin.
|
||||||
|
# negation of cloudflared CLI option: `no-tls-verify`
|
||||||
|
tlsVerify @4 :Bool;
|
||||||
|
# originCAPool specifies the root CA that cloudflared should use when
|
||||||
|
# verifying TLS connections to the origin.
|
||||||
|
# - if tlsVerify is false, originCAPool will be ignored.
|
||||||
|
# - if tlsVerify is true and originCAPool is empty, the system CA pool
|
||||||
|
# will be loaded if possible.
|
||||||
|
# - if tlsVerify is true and originCAPool is non-empty, cloudflared will
|
||||||
|
# treat it as the filepath to the root CA.
|
||||||
|
# cloudflared CLI option: `origin-ca-pool`
|
||||||
|
originCAPool @5 :Text;
|
||||||
|
# Hostname to use when verifying TLS connections to the origin.
|
||||||
|
# cloudflared CLI option: `origin-server-name`
|
||||||
|
originServerName @6 :Text;
|
||||||
|
# maximum number of idle (keep-alive) connections for cloudflared to
|
||||||
|
# keep open with the origin. Zero means no limit.
|
||||||
|
# cloudflared CLI option: `proxy-keepalive-connections`
|
||||||
|
maxIdleConnections @7 :UInt64;
|
||||||
|
# maximum time (in ns) for an idle (keep-alive) connection to remain
|
||||||
|
# idle before closing itself. Zero means no timeout.
|
||||||
|
# cloudflared CLI option: `proxy-keepalive-timeout`
|
||||||
|
idleConnectionTimeout @8 :Int64;
|
||||||
|
}
|
||||||
|
|
||||||
|
# configuration for cloudflared to provide a DNS over HTTPS proxy server
|
||||||
|
struct DoHProxyConfig {
|
||||||
|
# The hostname for the DoH proxy server to listen on.
|
||||||
|
# cloudflared CLI option: `proxy-dns-address`
|
||||||
|
listenHost @0 :Text;
|
||||||
|
# The port for the DoH proxy server to listen on.
|
||||||
|
# cloudflared CLI option: `proxy-dns-port`
|
||||||
|
listenPort @1 :UInt16;
|
||||||
|
# Upstream endpoint URLs for the DoH proxy server.
|
||||||
|
# cloudflared CLI option: `proxy-dns-upstream`
|
||||||
|
upstreams @2 :List(Text);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct HelloWorldOriginConfig {
|
||||||
|
# nothing to configure
|
||||||
|
}
|
||||||
|
|
||||||
struct Tag {
|
struct Tag {
|
||||||
name @0 :Text;
|
name @0 :Text;
|
||||||
value @1 :Text;
|
value @1 :Text;
|
||||||
|
@ -85,9 +216,18 @@ struct ServerInfo {
|
||||||
locationName @0 :Text;
|
locationName @0 :Text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct UseConfigurationResult {
|
||||||
|
success @0 :Bool;
|
||||||
|
errorMessage @1 :Text;
|
||||||
|
}
|
||||||
|
|
||||||
interface TunnelServer {
|
interface TunnelServer {
|
||||||
registerTunnel @0 (originCert :Data, hostname :Text, options :RegistrationOptions) -> (result :TunnelRegistration);
|
registerTunnel @0 (originCert :Data, hostname :Text, options :RegistrationOptions) -> (result :TunnelRegistration);
|
||||||
getServerInfo @1 () -> (result :ServerInfo);
|
getServerInfo @1 () -> (result :ServerInfo);
|
||||||
unregisterTunnel @2 (gracePeriodNanoSec :Int64) -> ();
|
unregisterTunnel @2 (gracePeriodNanoSec :Int64) -> ();
|
||||||
connect @3 (parameters :CapnpConnectParameters) -> (result :ConnectResult);
|
connect @3 (parameters :CapnpConnectParameters) -> (result :ConnectResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface CloudflaredServer {
|
||||||
|
useConfiguration @0 (cloudflaredConfig :CloudflaredConfig) -> (result :UseConfigurationResult);
|
||||||
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue