mirror of
https://github.com/cloudflare/cloudflared.git
synced 2026-08-07 15:24:46 +00:00
Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2fc2f3c927 | |||
| 5cd4fab9dd | |||
| 71b113cad3 | |||
| af2f2910b6 | |||
| f7b1f7cb22 | |||
| 2f5ac3b556 | |||
| 920fa9d23e | |||
| 06471132ef | |||
| 65d232efda | |||
| 0b78db185b | |||
| fc2c7c9718 | |||
| 3079f27205 | |||
| 4c464e1adf | |||
| 1a5e82bc04 | |||
| 8364e409a4 | |||
| 170f0acf4f | |||
| 674eb33edc | |||
| c10852a5e3 | |||
| 653f000294 | |||
| dd2b5e4f3e | |||
| 0e6492342b | |||
| f0126d1af2 | |||
| e2194f9417 | |||
| d0bc4d0d96 | |||
| 4f04f35bd1 |
Generated
+1
-1
@@ -461,6 +461,6 @@
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
inputs-digest = "0907565b36c43c6a1c461648f1e69d0367864b61f112e01948f7b008e44598e5"
|
||||
inputs-digest = "ee681bef3527e49801c841e313f98b40116eafe8b60be21273956eeb96487486"
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
[[constraint]]
|
||||
name = "zombiezen.com/go/capnproto2"
|
||||
source = "https://github.com/zombiezen/go-capnproto2"
|
||||
version = "2.17.1"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/gorilla/websocket"
|
||||
|
||||
@@ -55,3 +55,7 @@ release: bin/equinox
|
||||
bin/equinox:
|
||||
mkdir -p bin
|
||||
curl -s https://bin.equinox.io/c/75JtLRTsJ3n/release-tool-beta-$(EQUINOX_PLATFORM).tgz | tar xz -C bin/
|
||||
|
||||
.PHONY: tunnel-deps
|
||||
tunnel-deps:
|
||||
capnp compile -ogo -I ./tunnelrpc tunnelrpc/tunnelrpc.capnp
|
||||
|
||||
+14
-7
@@ -1,10 +1,10 @@
|
||||
2018.9.0
|
||||
- 2018-07-30 TUN-801: Rapid SQL Proxy
|
||||
- 2018-08-20 Fixed name bug
|
||||
- 2018-08-21 Added interactive password & refactored naming
|
||||
- 2018-07-30 TUN-801: Fixed SQL Gateway Dependencies
|
||||
- 2018-08-21 Ascii art for Cloudflared
|
||||
- 2018-08-27 TUN-833: Don't log system root certificate loading failure on Windows
|
||||
2018.10.1
|
||||
- 2018-10-03 TUN-1012: Normalize config filename for Linux services
|
||||
- 2018-10-05 TUN-1081: cloudflared now generates UUIDs
|
||||
- 2018-10-05 TUN-1083: fixed incorrect help menu
|
||||
- 2018-10-05 TUN-1086: fixed config option
|
||||
|
||||
2018.10.0
|
||||
- 2018-08-15 AUTH-910, AUTH-1049, AUTH-1068, AUTH-1056: Generate and store Access tokens with E2EE option, curl/cmd wrapper
|
||||
- 2018-09-11 TUN-890: To support free tunnels, hostname can now be ""
|
||||
- 2018-09-12 TUN-810: Cloudflared should open dash/argotunnel not dash/warp
|
||||
@@ -17,6 +17,13 @@
|
||||
- 2018-09-18 AUTH-1136: addressing beta feedback
|
||||
- 2018-09-26 AUTH-1165: hide access command
|
||||
- 2018-09-26 TUN-1046: Document that delta compression is a beta feature
|
||||
- 2018-09-28 TUN-1056: Lint error broke build
|
||||
- 2018-09-27 TUN-1052: Origintunneld can send back an Origincert to Cloudflared
|
||||
- 2018-09-28 TUN-1052: Changing type of OriginCert to :Data
|
||||
- 2018-10-01 TUN-1062: Makefile target for regenerating Capn Proto definitions
|
||||
- 2018-10-02 TUN-1064: Revert OriginCert capnp changes in Cloudflared. Reverts commits a1ee2342e97 and 8c756c45785.
|
||||
- 2018-10-03 TUN-1076: Pin capnproto2 to version 2.17.1
|
||||
- 2018-10-03 AUTH-1199: unhide access command, added beta label
|
||||
|
||||
2018.8.0
|
||||
- 2018-05-01 Initial commit
|
||||
|
||||
@@ -26,13 +26,13 @@ func Commands() []*cli.Command {
|
||||
return []*cli.Command{
|
||||
{
|
||||
Name: "access",
|
||||
Category: "Access",
|
||||
Category: "Access (BETA)",
|
||||
Usage: "access <subcommand>",
|
||||
Description: `Cloudflare Access protects internal resources by securing, authenticating and monitoring access
|
||||
Description: `(BETA) Cloudflare Access protects internal resources by securing, authenticating and monitoring access
|
||||
per-user and by application. With Cloudflare Access, only authenticated users with the required permissions are
|
||||
able to reach sensitive resources. The commands provided here allow you to interact with Access protected
|
||||
applications from the command line.`,
|
||||
Hidden: true, // This is hidden until we official launch access cli auth
|
||||
applications from the command line. This feature is considered beta. Your feedback is greatly appreciated!
|
||||
https://cfl.re/CLIAuthBeta`,
|
||||
Subcommands: []*cli.Command{
|
||||
{
|
||||
Name: "login",
|
||||
|
||||
@@ -10,13 +10,16 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
defaultConfigFiles = []string{"config.yml", "config.yaml"}
|
||||
// File names from which we attempt to read configuration.
|
||||
DefaultConfigFiles = []string{"config.yml", "config.yaml"}
|
||||
|
||||
// Launchd doesn't set root env variables, so there is default
|
||||
// Windows default config dir was ~/cloudflare-warp in documentation; let's keep it compatible
|
||||
DefaultConfigDirs = []string{"~/.cloudflared", "~/.cloudflare-warp", "~/cloudflare-warp", "/usr/local/etc/cloudflared", "/etc/cloudflared"}
|
||||
)
|
||||
|
||||
const DefaultCredentialFile = "cert.pem"
|
||||
|
||||
// FileExists checks to see if a file exist at the provided path.
|
||||
func FileExists(path string) (bool, error) {
|
||||
f, err := os.Open(path)
|
||||
@@ -40,11 +43,11 @@ func FindInputSourceContext(context *cli.Context) (altsrc.InputSourceContext, er
|
||||
}
|
||||
|
||||
// FindDefaultConfigPath returns the first path that contains a config file.
|
||||
// If none of the combination of defaultConfigDirs (differs by OS for legacy reasons)
|
||||
// and defaultConfigFiles contains a config file, return empty string.
|
||||
// If none of the combination of DefaultConfigDirs and DefaultConfigFiles
|
||||
// contains a config file, return empty string.
|
||||
func FindDefaultConfigPath() string {
|
||||
for _, configDir := range DefaultConfigDirs {
|
||||
for _, configFile := range defaultConfigFiles {
|
||||
for _, configFile := range DefaultConfigFiles {
|
||||
dirPath, err := homedir.Expand(configDir)
|
||||
if err != nil {
|
||||
continue
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/cloudflare/cloudflared/cmd/cloudflared/config"
|
||||
cli "gopkg.in/urfave/cli.v2"
|
||||
)
|
||||
|
||||
@@ -30,12 +31,14 @@ func runApp(app *cli.App, shutdownC, graceShutdownC chan struct{}) {
|
||||
app.Run(os.Args)
|
||||
}
|
||||
|
||||
// The directory and files that are used by the service.
|
||||
// These are hard-coded in the templates below.
|
||||
const (
|
||||
serviceConfigDir = "/etc/cloudflared"
|
||||
defaultCredentialFile = "cert.pem"
|
||||
serviceConfigFile = "config.yml"
|
||||
serviceCredentialFile = "cert.pem"
|
||||
)
|
||||
|
||||
var defaultConfigFiles = []string{"config.yml", "config.yaml"}
|
||||
var systemdTemplates = []ServiceTemplate{
|
||||
{
|
||||
Path: "/etc/systemd/system/cloudflared.service",
|
||||
@@ -178,6 +181,23 @@ func isSystemd() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func copyUserConfiguration(userConfigDir, userConfigFile, userCredentialFile string) error {
|
||||
if err := ensureConfigDirExists(serviceConfigDir); err != nil {
|
||||
return err
|
||||
}
|
||||
srcCredentialPath := filepath.Join(userConfigDir, userCredentialFile)
|
||||
destCredentialPath := filepath.Join(serviceConfigDir, serviceCredentialFile)
|
||||
if err := copyCredential(srcCredentialPath, destCredentialPath); err != nil {
|
||||
return err
|
||||
}
|
||||
srcConfigPath := filepath.Join(userConfigDir, userConfigFile)
|
||||
destConfigPath := filepath.Join(serviceConfigDir, serviceConfigFile)
|
||||
if err := copyConfig(srcConfigPath, destConfigPath); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func installLinuxService(c *cli.Context) error {
|
||||
etPath, err := os.Executable()
|
||||
if err != nil {
|
||||
@@ -185,11 +205,12 @@ func installLinuxService(c *cli.Context) error {
|
||||
}
|
||||
templateArgs := ServiceTemplateArgs{Path: etPath}
|
||||
|
||||
defaultConfigDir := filepath.Dir(c.String("config"))
|
||||
defaultConfigFile := filepath.Base(c.String("config"))
|
||||
if err = copyCredentials(serviceConfigDir, defaultConfigDir, defaultConfigFile, defaultCredentialFile); err != nil {
|
||||
userConfigDir := filepath.Dir(c.String("config"))
|
||||
userConfigFile := filepath.Base(c.String("config"))
|
||||
userCredentialFile := config.DefaultCredentialFile
|
||||
if err = copyUserConfiguration(userConfigDir, userConfigFile, userCredentialFile); err != nil {
|
||||
logger.WithError(err).Infof("Failed to copy user configuration. Before running the service, ensure that %s contains two files, %s and %s",
|
||||
serviceConfigDir, defaultCredentialFile, defaultConfigFiles[0])
|
||||
serviceConfigDir, serviceCredentialFile, serviceConfigFile)
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
+3
-21
@@ -8,7 +8,6 @@ import (
|
||||
"golang.org/x/crypto/ssh/terminal"
|
||||
|
||||
"github.com/cloudflare/cloudflared/cmd/cloudflared/access"
|
||||
"github.com/cloudflare/cloudflared/cmd/cloudflared/config"
|
||||
"github.com/cloudflare/cloudflared/cmd/cloudflared/tunnel"
|
||||
"github.com/cloudflare/cloudflared/cmd/cloudflared/updater"
|
||||
"github.com/cloudflare/cloudflared/log"
|
||||
@@ -17,7 +16,6 @@ import (
|
||||
"github.com/getsentry/raven-go"
|
||||
"github.com/mitchellh/go-homedir"
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
"gopkg.in/urfave/cli.v2/altsrc"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
@@ -46,6 +44,8 @@ func main() {
|
||||
|
||||
app := &cli.App{}
|
||||
app.Name = "cloudflared"
|
||||
app.Usage = "Cloudflare's command-line tool and agent"
|
||||
app.ArgsUsage = "origin-url"
|
||||
app.Copyright = fmt.Sprintf(`(c) %d Cloudflare Inc.
|
||||
Use is subject to the license agreement at %s`, time.Now().Year(), licenseUrl)
|
||||
app.Version = fmt.Sprintf("%s (built %s)", Version, BuildTime)
|
||||
@@ -54,7 +54,7 @@ func main() {
|
||||
and configure access control.`
|
||||
app.Flags = flags()
|
||||
app.Action = action(Version, shutdownC, graceShutdownC)
|
||||
app.Before = before(app.Flags)
|
||||
app.Before = tunnel.Before
|
||||
app.Commands = commands()
|
||||
|
||||
tunnel.Init(Version, shutdownC, graceShutdownC) // we need this to support the tunnel sub command...
|
||||
@@ -103,24 +103,6 @@ func action(version string, shutdownC, graceShutdownC chan struct{}) cli.ActionF
|
||||
}
|
||||
}
|
||||
|
||||
func before(flags []cli.Flag) cli.BeforeFunc {
|
||||
return func(context *cli.Context) error {
|
||||
inputSource, err := config.FindInputSourceContext(context)
|
||||
if err != nil {
|
||||
logger.WithError(err).Infof("Cannot load configuration from %s", context.String("config"))
|
||||
return err
|
||||
} else if inputSource != nil {
|
||||
err := altsrc.ApplyInputSourceValues(context, inputSource, flags)
|
||||
if err != nil {
|
||||
logger.WithError(err).Infof("Cannot apply configuration from %s", context.String("config"))
|
||||
return err
|
||||
}
|
||||
logger.Infof("Applied configuration from %s", context.String("config"))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func userHomeDir() (string, error) {
|
||||
// This returns the home dir of the executing user using OS-specific method
|
||||
// for discovering the home dir. It's not recommended to call this function
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"text/template"
|
||||
|
||||
"github.com/cloudflare/cloudflared/cmd/cloudflared/config"
|
||||
@@ -120,8 +119,7 @@ func openFile(path string, create bool) (file *os.File, exists bool, err error)
|
||||
return file, false, err
|
||||
}
|
||||
|
||||
func copyCertificate(srcConfigDir, destConfigDir, credentialFile string) error {
|
||||
destCredentialPath := filepath.Join(destConfigDir, credentialFile)
|
||||
func copyCredential(srcCredentialPath, destCredentialPath string) error {
|
||||
destFile, exists, err := openFile(destCredentialPath, true)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -131,7 +129,6 @@ func copyCertificate(srcConfigDir, destConfigDir, credentialFile string) error {
|
||||
}
|
||||
defer destFile.Close()
|
||||
|
||||
srcCredentialPath := filepath.Join(srcConfigDir, credentialFile)
|
||||
srcFile, _, err := openFile(srcCredentialPath, false)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -147,17 +144,8 @@ func copyCertificate(srcConfigDir, destConfigDir, credentialFile string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func copyCredentials(serviceConfigDir, defaultConfigDir, defaultConfigFile, defaultCredentialFile string) error {
|
||||
if err := ensureConfigDirExists(serviceConfigDir); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := copyCertificate(defaultConfigDir, serviceConfigDir, defaultCredentialFile); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
func copyConfig(srcConfigPath, destConfigPath string) error {
|
||||
// Copy or create config
|
||||
destConfigPath := filepath.Join(serviceConfigDir, defaultConfigFile)
|
||||
destFile, exists, err := openFile(destConfigPath, true)
|
||||
if err != nil {
|
||||
logger.WithError(err).Infof("cannot open %s", destConfigPath)
|
||||
@@ -168,7 +156,6 @@ func copyCredentials(serviceConfigDir, defaultConfigDir, defaultConfigFile, defa
|
||||
}
|
||||
defer destFile.Close()
|
||||
|
||||
srcConfigPath := filepath.Join(defaultConfigDir, defaultConfigFile)
|
||||
srcFile, _, err := openFile(srcConfigPath, false)
|
||||
if err != nil {
|
||||
fmt.Println("Your service needs a config file that at least specifies the hostname option.")
|
||||
|
||||
@@ -121,25 +121,8 @@ func Commands() []*cli.Command {
|
||||
}
|
||||
return err
|
||||
},
|
||||
Before: func(c *cli.Context) error {
|
||||
if c.String("config") == "" {
|
||||
logger.Warnf("Cannot determine default configuration path. No file %v in %v", defaultConfigFiles, config.DefaultConfigDirs)
|
||||
}
|
||||
inputSource, err := config.FindInputSourceContext(c)
|
||||
if err != nil {
|
||||
logger.WithError(err).Infof("Cannot load configuration from %s", c.String("config"))
|
||||
return err
|
||||
} else if inputSource != nil {
|
||||
err := altsrc.ApplyInputSourceValues(c, inputSource, c.App.Flags)
|
||||
if err != nil {
|
||||
logger.WithError(err).Infof("Cannot apply configuration from %s", c.String("config"))
|
||||
return err
|
||||
}
|
||||
logger.Infof("Applied configuration from %s", c.String("config"))
|
||||
}
|
||||
return nil
|
||||
},
|
||||
Usage: "SQL Gateway is an SQL over HTTP reverse proxy",
|
||||
Before: Before,
|
||||
Usage: "SQL Gateway is an SQL over HTTP reverse proxy",
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
Name: "db",
|
||||
@@ -166,6 +149,7 @@ func Commands() []*cli.Command {
|
||||
cmds = append(cmds, &cli.Command{
|
||||
Name: "tunnel",
|
||||
Action: tunnel,
|
||||
Before: Before,
|
||||
Category: "Tunnel",
|
||||
Usage: "Make a locally-running web service accessible over the internet using Argo Tunnel.",
|
||||
ArgsUsage: "[origin-url]",
|
||||
@@ -211,7 +195,7 @@ func StartServer(c *cli.Context, version string, shutdownC, graceShutdownC chan
|
||||
dnsReadySignal := make(chan struct{})
|
||||
|
||||
if c.String("config") == "" {
|
||||
logger.Warnf("Cannot determine default configuration path. No file %v in %v", defaultConfigFiles, config.DefaultConfigDirs)
|
||||
logger.Warnf("Cannot determine default configuration path. No file %v in %v", config.DefaultConfigFiles, config.DefaultConfigDirs)
|
||||
}
|
||||
|
||||
if err := configMainLogger(c); err != nil {
|
||||
@@ -231,7 +215,7 @@ func StartServer(c *cli.Context, version string, shutdownC, graceShutdownC chan
|
||||
|
||||
defer func() {
|
||||
if err := tmpTraceFile.Close(); err != nil {
|
||||
logger.WithError(err).Error("Failed to close trace output file %s", tmpTraceFile.Name())
|
||||
logger.WithError(err).Errorf("Failed to close trace output file %s", tmpTraceFile.Name())
|
||||
}
|
||||
if err := os.Rename(tmpTraceFile.Name(), c.String("trace-output")); err != nil {
|
||||
logger.WithError(err).Errorf("Failed to rename temporary trace output file %s to %s", tmpTraceFile.Name(), c.String("trace-output"))
|
||||
@@ -338,6 +322,25 @@ func StartServer(c *cli.Context, version string, shutdownC, graceShutdownC chan
|
||||
return waitToShutdown(&wg, errC, shutdownC, graceShutdownC, c.Duration("grace-period"))
|
||||
}
|
||||
|
||||
func Before(c *cli.Context) error {
|
||||
if c.String("config") == "" {
|
||||
logger.Warnf("Cannot determine default configuration path. No file %v in %v", config.DefaultConfigFiles, config.DefaultConfigDirs)
|
||||
}
|
||||
inputSource, err := config.FindInputSourceContext(c)
|
||||
if err != nil {
|
||||
logger.WithError(err).Infof("Cannot load configuration from %s", c.String("config"))
|
||||
return err
|
||||
} else if inputSource != nil {
|
||||
err := altsrc.ApplyInputSourceValues(c, inputSource, c.App.Flags)
|
||||
if err != nil {
|
||||
logger.WithError(err).Infof("Cannot apply configuration from %s", c.String("config"))
|
||||
return err
|
||||
}
|
||||
logger.Infof("Applied configuration from %s", c.String("config"))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func waitToShutdown(wg *sync.WaitGroup,
|
||||
errC chan error,
|
||||
shutdownC, graceShutdownC chan struct{},
|
||||
|
||||
@@ -30,20 +30,17 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
defaultConfigFiles = []string{"config.yml", "config.yaml"}
|
||||
developerPortal = "https://developers.cloudflare.com/argo-tunnel"
|
||||
quickStartUrl = developerPortal + "/quickstart/quickstart/"
|
||||
serviceUrl = developerPortal + "/reference/service/"
|
||||
argumentsUrl = developerPortal + "/reference/arguments/"
|
||||
developerPortal = "https://developers.cloudflare.com/argo-tunnel"
|
||||
quickStartUrl = developerPortal + "/quickstart/quickstart/"
|
||||
serviceUrl = developerPortal + "/reference/service/"
|
||||
argumentsUrl = developerPortal + "/reference/arguments/"
|
||||
)
|
||||
|
||||
const defaultCredentialFile = "cert.pem"
|
||||
|
||||
// returns the first path that contains a cert.pem file. If none of the defaultConfigDirs
|
||||
// (differs by OS for legacy reasons) contains a cert.pem file, return empty string
|
||||
// returns the first path that contains a cert.pem file. If none of the DefaultConfigDirs
|
||||
// contains a cert.pem file, return empty string
|
||||
func findDefaultOriginCertPath() string {
|
||||
for _, defaultConfigDir := range config.DefaultConfigDirs {
|
||||
originCertPath, _ := homedir.Expand(filepath.Join(defaultConfigDir, defaultCredentialFile))
|
||||
originCertPath, _ := homedir.Expand(filepath.Join(defaultConfigDir, config.DefaultCredentialFile))
|
||||
if ok, _ := config.FileExists(originCertPath); ok {
|
||||
return originCertPath
|
||||
}
|
||||
@@ -111,7 +108,7 @@ func dnsProxyStandAlone(c *cli.Context) bool {
|
||||
|
||||
func getOriginCert(c *cli.Context) ([]byte, error) {
|
||||
if c.String("origincert") == "" {
|
||||
logger.Warnf("Cannot determine default origin certificate path. No file %s in %v", defaultCredentialFile, config.DefaultConfigDirs)
|
||||
logger.Warnf("Cannot determine default origin certificate path. No file %s in %v", config.DefaultCredentialFile, config.DefaultConfigDirs)
|
||||
if isRunningFromTerminal() {
|
||||
logger.Errorf("You need to specify the origin certificate path with --origincert option, or set TUNNEL_ORIGIN_CERT environment variable. See %s for more information.", argumentsUrl)
|
||||
return nil, fmt.Errorf("Client didn't specify origincert path when running from terminal")
|
||||
|
||||
@@ -56,7 +56,7 @@ func checkForExistingCert() (string, bool, error) {
|
||||
if err != nil {
|
||||
return "", false, err
|
||||
}
|
||||
path := filepath.Join(configPath, defaultCredentialFile)
|
||||
path := filepath.Join(configPath, config.DefaultCredentialFile)
|
||||
fileInfo, err := os.Stat(path)
|
||||
if err == nil && fileInfo.Size() > 0 {
|
||||
return path, true, nil
|
||||
|
||||
+8
-2
@@ -4,6 +4,7 @@ import (
|
||||
"bufio"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"github.com/google/uuid"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
@@ -103,7 +104,7 @@ func (e clientRegisterTunnelError) Error() string {
|
||||
return e.cause.Error()
|
||||
}
|
||||
|
||||
func (c *TunnelConfig) RegistrationOptions(connectionID uint8, OriginLocalIP string) *tunnelpogs.RegistrationOptions {
|
||||
func (c *TunnelConfig) RegistrationOptions(connectionID uint8, OriginLocalIP string, uuid uuid.UUID) *tunnelpogs.RegistrationOptions {
|
||||
policy := tunnelrpc.ExistingTunnelPolicy_balance
|
||||
if c.HAConnections <= 1 && c.LBPool == "" {
|
||||
policy = tunnelrpc.ExistingTunnelPolicy_disconnect
|
||||
@@ -120,6 +121,7 @@ func (c *TunnelConfig) RegistrationOptions(connectionID uint8, OriginLocalIP str
|
||||
IsAutoupdated: c.IsAutoupdated,
|
||||
RunFromTerminal: c.RunFromTerminal,
|
||||
CompressionQuality: c.CompressionQuality,
|
||||
UUID: uuid.String(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -316,11 +318,15 @@ func RegisterTunnel(ctx context.Context, muxer *h2mux.Muxer, config *TunnelConfi
|
||||
serverInfoPromise := tsClient.GetServerInfo(ctx, func(tunnelrpc.TunnelServer_getServerInfo_Params) error {
|
||||
return nil
|
||||
})
|
||||
uuid, err := uuid.NewRandom()
|
||||
if err != nil {
|
||||
return clientRegisterTunnelError{cause: err}
|
||||
}
|
||||
registration, err := ts.RegisterTunnel(
|
||||
ctx,
|
||||
config.OriginCert,
|
||||
config.Hostname,
|
||||
config.RegistrationOptions(connectionID, originLocalIP),
|
||||
config.RegistrationOptions(connectionID, originLocalIP, uuid),
|
||||
)
|
||||
LogServerInfo(serverInfoPromise.Result(), connectionID, config.Metrics, config.Logger)
|
||||
if err != nil {
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package pogs
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/cloudflare/cloudflared/tunnelrpc"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"golang.org/x/net/context"
|
||||
"zombiezen.com/go/capnproto2"
|
||||
"zombiezen.com/go/capnproto2/pogs"
|
||||
"zombiezen.com/go/capnproto2/rpc"
|
||||
@@ -56,6 +58,7 @@ type RegistrationOptions struct {
|
||||
IsAutoupdated bool `capnp:"isAutoupdated"`
|
||||
RunFromTerminal bool `capnp:"runFromTerminal"`
|
||||
CompressionQuality uint64 `capnp:"compressionQuality"`
|
||||
UUID string `capnp:"uuid"`
|
||||
}
|
||||
|
||||
func MarshalRegistrationOptions(s tunnelrpc.RegistrationOptions, p *RegistrationOptions) error {
|
||||
|
||||
@@ -43,6 +43,7 @@ struct RegistrationOptions {
|
||||
runFromTerminal @9 :Bool;
|
||||
# cross stream compression setting, 0 - off, 3 - high
|
||||
compressionQuality @10 :UInt64;
|
||||
uuid @11 :Text;
|
||||
}
|
||||
|
||||
struct Tag {
|
||||
|
||||
+165
-89
@@ -105,6 +105,11 @@ func (s Authentication_List) At(i int) Authentication { return Authentication{s.
|
||||
|
||||
func (s Authentication_List) Set(i int, v Authentication) error { return s.List.SetStruct(i, v.Struct) }
|
||||
|
||||
func (s Authentication_List) String() string {
|
||||
str, _ := text.MarshalList(0xc082ef6e0d42ed1d, s.List)
|
||||
return str
|
||||
}
|
||||
|
||||
// Authentication_Promise is a wrapper for a Authentication promised by a client call.
|
||||
type Authentication_Promise struct{ *capnp.Pipeline }
|
||||
|
||||
@@ -245,6 +250,11 @@ func (s TunnelRegistration_List) Set(i int, v TunnelRegistration) error {
|
||||
return s.List.SetStruct(i, v.Struct)
|
||||
}
|
||||
|
||||
func (s TunnelRegistration_List) String() string {
|
||||
str, _ := text.MarshalList(0xf41a0f001ad49e46, s.List)
|
||||
return str
|
||||
}
|
||||
|
||||
// TunnelRegistration_Promise is a wrapper for a TunnelRegistration promised by a client call.
|
||||
type TunnelRegistration_Promise struct{ *capnp.Pipeline }
|
||||
|
||||
@@ -259,12 +269,12 @@ type RegistrationOptions struct{ capnp.Struct }
|
||||
const RegistrationOptions_TypeID = 0xc793e50592935b4a
|
||||
|
||||
func NewRegistrationOptions(s *capnp.Segment) (RegistrationOptions, error) {
|
||||
st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 16, PointerCount: 6})
|
||||
st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 16, PointerCount: 7})
|
||||
return RegistrationOptions{st}, err
|
||||
}
|
||||
|
||||
func NewRootRegistrationOptions(s *capnp.Segment) (RegistrationOptions, error) {
|
||||
st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 16, PointerCount: 6})
|
||||
st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 16, PointerCount: 7})
|
||||
return RegistrationOptions{st}, err
|
||||
}
|
||||
|
||||
@@ -438,12 +448,31 @@ func (s RegistrationOptions) SetCompressionQuality(v uint64) {
|
||||
s.Struct.SetUint64(8, v)
|
||||
}
|
||||
|
||||
func (s RegistrationOptions) Uuid() (string, error) {
|
||||
p, err := s.Struct.Ptr(6)
|
||||
return p.Text(), err
|
||||
}
|
||||
|
||||
func (s RegistrationOptions) HasUuid() bool {
|
||||
p, err := s.Struct.Ptr(6)
|
||||
return p.IsValid() || err != nil
|
||||
}
|
||||
|
||||
func (s RegistrationOptions) UuidBytes() ([]byte, error) {
|
||||
p, err := s.Struct.Ptr(6)
|
||||
return p.TextBytes(), err
|
||||
}
|
||||
|
||||
func (s RegistrationOptions) SetUuid(v string) error {
|
||||
return s.Struct.SetText(6, v)
|
||||
}
|
||||
|
||||
// RegistrationOptions_List is a list of RegistrationOptions.
|
||||
type RegistrationOptions_List struct{ capnp.List }
|
||||
|
||||
// NewRegistrationOptions creates a new list of RegistrationOptions.
|
||||
func NewRegistrationOptions_List(s *capnp.Segment, sz int32) (RegistrationOptions_List, error) {
|
||||
l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 16, PointerCount: 6}, sz)
|
||||
l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 16, PointerCount: 7}, sz)
|
||||
return RegistrationOptions_List{l}, err
|
||||
}
|
||||
|
||||
@@ -455,6 +484,11 @@ func (s RegistrationOptions_List) Set(i int, v RegistrationOptions) error {
|
||||
return s.List.SetStruct(i, v.Struct)
|
||||
}
|
||||
|
||||
func (s RegistrationOptions_List) String() string {
|
||||
str, _ := text.MarshalList(0xc793e50592935b4a, s.List)
|
||||
return str
|
||||
}
|
||||
|
||||
// RegistrationOptions_Promise is a wrapper for a RegistrationOptions promised by a client call.
|
||||
type RegistrationOptions_Promise struct{ *capnp.Pipeline }
|
||||
|
||||
@@ -539,6 +573,11 @@ func (s Tag_List) At(i int) Tag { return Tag{s.List.Struct(i)} }
|
||||
|
||||
func (s Tag_List) Set(i int, v Tag) error { return s.List.SetStruct(i, v.Struct) }
|
||||
|
||||
func (s Tag_List) String() string {
|
||||
str, _ := text.MarshalList(0xcbd96442ae3bb01a, s.List)
|
||||
return str
|
||||
}
|
||||
|
||||
// Tag_Promise is a wrapper for a Tag promised by a client call.
|
||||
type Tag_Promise struct{ *capnp.Pipeline }
|
||||
|
||||
@@ -664,6 +703,11 @@ func (s ServerInfo_List) At(i int) ServerInfo { return ServerInfo{s.List.Struct(
|
||||
|
||||
func (s ServerInfo_List) Set(i int, v ServerInfo) error { return s.List.SetStruct(i, v.Struct) }
|
||||
|
||||
func (s ServerInfo_List) String() string {
|
||||
str, _ := text.MarshalList(0xf2c68e2547ec3866, s.List)
|
||||
return str
|
||||
}
|
||||
|
||||
// ServerInfo_Promise is a wrapper for a ServerInfo promised by a client call.
|
||||
type ServerInfo_Promise struct{ *capnp.Pipeline }
|
||||
|
||||
@@ -925,6 +969,11 @@ func (s TunnelServer_registerTunnel_Params_List) Set(i int, v TunnelServer_regis
|
||||
return s.List.SetStruct(i, v.Struct)
|
||||
}
|
||||
|
||||
func (s TunnelServer_registerTunnel_Params_List) String() string {
|
||||
str, _ := text.MarshalList(0xb70431c0dc014915, s.List)
|
||||
return str
|
||||
}
|
||||
|
||||
// TunnelServer_registerTunnel_Params_Promise is a wrapper for a TunnelServer_registerTunnel_Params promised by a client call.
|
||||
type TunnelServer_registerTunnel_Params_Promise struct{ *capnp.Pipeline }
|
||||
|
||||
@@ -1004,6 +1053,11 @@ func (s TunnelServer_registerTunnel_Results_List) Set(i int, v TunnelServer_regi
|
||||
return s.List.SetStruct(i, v.Struct)
|
||||
}
|
||||
|
||||
func (s TunnelServer_registerTunnel_Results_List) String() string {
|
||||
str, _ := text.MarshalList(0xf2c122394f447e8e, s.List)
|
||||
return str
|
||||
}
|
||||
|
||||
// TunnelServer_registerTunnel_Results_Promise is a wrapper for a TunnelServer_registerTunnel_Results promised by a client call.
|
||||
type TunnelServer_registerTunnel_Results_Promise struct{ *capnp.Pipeline }
|
||||
|
||||
@@ -1058,6 +1112,11 @@ func (s TunnelServer_getServerInfo_Params_List) Set(i int, v TunnelServer_getSer
|
||||
return s.List.SetStruct(i, v.Struct)
|
||||
}
|
||||
|
||||
func (s TunnelServer_getServerInfo_Params_List) String() string {
|
||||
str, _ := text.MarshalList(0xdc3ed6801961e502, s.List)
|
||||
return str
|
||||
}
|
||||
|
||||
// TunnelServer_getServerInfo_Params_Promise is a wrapper for a TunnelServer_getServerInfo_Params promised by a client call.
|
||||
type TunnelServer_getServerInfo_Params_Promise struct{ *capnp.Pipeline }
|
||||
|
||||
@@ -1133,6 +1192,11 @@ func (s TunnelServer_getServerInfo_Results_List) Set(i int, v TunnelServer_getSe
|
||||
return s.List.SetStruct(i, v.Struct)
|
||||
}
|
||||
|
||||
func (s TunnelServer_getServerInfo_Results_List) String() string {
|
||||
str, _ := text.MarshalList(0xe3e37d096a5b564e, s.List)
|
||||
return str
|
||||
}
|
||||
|
||||
// TunnelServer_getServerInfo_Results_Promise is a wrapper for a TunnelServer_getServerInfo_Results promised by a client call.
|
||||
type TunnelServer_getServerInfo_Results_Promise struct{ *capnp.Pipeline }
|
||||
|
||||
@@ -1195,6 +1259,11 @@ func (s TunnelServer_unregisterTunnel_Params_List) Set(i int, v TunnelServer_unr
|
||||
return s.List.SetStruct(i, v.Struct)
|
||||
}
|
||||
|
||||
func (s TunnelServer_unregisterTunnel_Params_List) String() string {
|
||||
str, _ := text.MarshalList(0x9b87b390babc2ccf, s.List)
|
||||
return str
|
||||
}
|
||||
|
||||
// TunnelServer_unregisterTunnel_Params_Promise is a wrapper for a TunnelServer_unregisterTunnel_Params promised by a client call.
|
||||
type TunnelServer_unregisterTunnel_Params_Promise struct{ *capnp.Pipeline }
|
||||
|
||||
@@ -1245,6 +1314,11 @@ func (s TunnelServer_unregisterTunnel_Results_List) Set(i int, v TunnelServer_un
|
||||
return s.List.SetStruct(i, v.Struct)
|
||||
}
|
||||
|
||||
func (s TunnelServer_unregisterTunnel_Results_List) String() string {
|
||||
str, _ := text.MarshalList(0xa29a916d4ebdd894, s.List)
|
||||
return str
|
||||
}
|
||||
|
||||
// TunnelServer_unregisterTunnel_Results_Promise is a wrapper for a TunnelServer_unregisterTunnel_Results promised by a client call.
|
||||
type TunnelServer_unregisterTunnel_Results_Promise struct{ *capnp.Pipeline }
|
||||
|
||||
@@ -1253,92 +1327,94 @@ func (p TunnelServer_unregisterTunnel_Results_Promise) Struct() (TunnelServer_un
|
||||
return TunnelServer_unregisterTunnel_Results{s}, err
|
||||
}
|
||||
|
||||
const schema_db8274f9144abc7e = "x\xda\x9cV]\x8c\x14\xd5\x12\xae\xef\x9c\x99\xedY\xb2" +
|
||||
"\xcbl\xa7\x87\\\x98\\2\x09Y\xc2OX.\\\xe0" +
|
||||
"f\xd9{\xaf\xfb\xe3\x82\x99uY\xa6\x190\x08\x98\xd0" +
|
||||
"\xcc\x1c\x86^{\xba'\xdd=\x08D~$\x18\x95(" +
|
||||
"Q\x91\x071\x18$1Qc\xfc\x89&\x06\x83\x09\xbe" +
|
||||
"H\x0c1\xbc\xa8\x91Hb\x94\xec\x03DC\xdc\xe8\x83" +
|
||||
"&\xa6\xcd\xe9\xd9\x9ei\x16\x05\xf4\xed\xccw\xeaT}" +
|
||||
"U]\xf5\xd5,\xfb\x07\x1f`\xcb\x93\xdf$\x89\xf4\xe1" +
|
||||
"d[\xf0\xbf\xea\xa53\xff9q\xf1\x08\xa9Y\x16\x1c" +
|
||||
"87\x92\xf9\xc5?\xfc5\x11V|\xc1\xf6A\xbb\xc6" +
|
||||
"\x14\"m\x82\xad'\x04\x97\x96\x9c\xfb\xf0\xd9\xf7\x9ex" +
|
||||
"\x89\xf4\x05\x00QB!Z\xf1\x1b\xfb\x15\x04M\xe5\xfd" +
|
||||
"\x84\xe0\x85\xaf>\x1a\xab>w\xf2\x0c\xa9\x0b\xa2\xfb\xd5" +
|
||||
"\x9c1J\x04\xb3\xf2\xb8r~y\xe2\x83\xc6M\x92\xcb" +
|
||||
"\xab\x1e~]>\x1d\xe4o\x13\x82\xb9?\x0cu\xda7" +
|
||||
"\x0e\x9f'5\x8b\x16\x8b\x86\xe1\xb7|\x04\xda\xcf\xf2\xa8" +
|
||||
"\xfd\x18\x1a\x8fl=\xfe|r\xe2\xf8\x05\xd2\xb3\x88q" +
|
||||
"N\xb6I\xebg\x12.\xb4W\xc2\xe0\xa7\x12\x0e#\x04" +
|
||||
"\xd9w\xfe\xfb\xd6P\xf9\xf2\xc5i\xbe\xc3\xcc\xd6)\x93" +
|
||||
"\xda\x83\x8a<mR\x1e!\x04l\xc2\x98s\xe8\xcb{" +
|
||||
"\xae\xc4RxW\xf9\x0e\x94\x08\xc6\x1e\xd8:\xde\xbe\xff" +
|
||||
"\xea\xd5\xa9\x14 \xaf^U\xc2\x14\xce*2\xfbU\xdb" +
|
||||
"\x07\xc5\xb6\xde\xcd\xd7I\xcd\xf2\x9b\x0ayY\xe9\x83v" +
|
||||
"-\x0c2\xa1\\\xd0\xaa)\x85(8v`x\xfd\xea" +
|
||||
"y\x1fO\xc6\xddmJMJwfJ\xba\xdb\xd9\xfb" +
|
||||
"\xfd}\xf3\x8f}29\x8duh\xf8Tj1\xb4\x17" +
|
||||
"\xa5\x1f\xed\x844\xbe\xb1\xf6\xe5\xcf\xb3\xe9\xecOz\x16" +
|
||||
"q\xdb\x90\xfe\xd9\xd48\xb4\xcf\xa4\xed\x8aOS9P" +
|
||||
"O\xe0\xd7m[Xn-Q\xfaWt,--\x19" +
|
||||
"5\xbb\xd6\xb7f\x8f\xe9\xf9\xa6]\xd9\x18\xe2\xfd\x05\xc7" +
|
||||
"2K{\x0b\x80\xde\x01F\xa4\xce\xed#\x02\xd4Y[" +
|
||||
"\x88\xc0Tu\x88\xa8\xdf\xac\xd8\x8e+\x82\xb2\xe9\x95\x1c" +
|
||||
"\xdb\x16\xc4K\xfe\xc1\x1d\x86e\xd8%\xd1\x0c\xd4vk" +
|
||||
"\xa0F\x80\xa2pw\x0bwi\xddvE\xc5\xf4|\xe1" +
|
||||
"6\xe0\xee\xfe\x82\xe1\x1aUOO\xf0\x04Q\x02Dj" +
|
||||
"\xe7I\"\xbd\x8bC\xff'CPq\x8d\x92(\x08\x17" +
|
||||
"\xa6S\x1e3l\xa7\xc8E\x09IbH\x12\x9aAg" +
|
||||
"\xfe\xd5\xa0\x1b\x84W\xb7|\x8f\x9a\xafn\xff~\xda\xeb" +
|
||||
"\x82\x91\x0e)w4)\xaf\xd9\"'\x8cC/0\xa8" +
|
||||
"@F\xce\x8c\xban\x84H\x1f\xe5\xd073\xa8\x8ce" +
|
||||
"\xc2\xb2n\x1a\"\xd2\x0b\x1c\xfa6\x86\xc0q\xcd\x8ai" +
|
||||
"\xdf+\x88\xbb>:\x89\xa1\x93\x10\xecr<\xdf6\xaa" +
|
||||
"\x82\x88\xd0A\x0c\x1d\x84\x83N\xcd7\x1d\xdbCWk" +
|
||||
"\x1e\x08\xe8\x8a\x95\xe0\x0f>\xf0`\xdd\xdf%l\xdf," +
|
||||
"\x19\xf21Q\xf8m[\x94\xe7\x11\xe9\x03\x1c\xfah\x8c" +
|
||||
"r\xfe\xdf\xb1<\"\xca\xebv\xb4\xf2P\x1e\x16{#" +
|
||||
"V9Q5L+\xfa\x15%3H\xca\xfd-\x9b\xdb" +
|
||||
"\xf1\xdb\x10V\xd5\x0d\xd9\xad\xaf\xe5\xc2\x0c%\xc7%\x11" +
|
||||
"Gm>F\x88\x8a\xdd\xe0(.C\x8b\xa6\xd6\x83!" +
|
||||
"\xa2\xe2B\x89\xafD\x8b\xa9\xb6\x1cY\xa2\xe2\x12\x89\xf7" +
|
||||
"\x82\x01<\x03N\xa4\xad\xc2\x1bD\xc5^\x09\x0fK\xf3" +
|
||||
"\x04\xcf A\xa4\x0d\x86\xee\x07$>*\xf1d\"\x83" +
|
||||
"$\x91\x96\xc7b\xa2\xe2\xb0\xc4\xb7K\xbc\x8de\xd0F" +
|
||||
"\xa4=\x84q\xa2\xe26\x89\xef\x92\xb8\x92\xcc\xc8\x11\xd5" +
|
||||
"\x04\\\xa2bY\xe25\x89\xa7fg\x90\"\xd2\xaa!" +
|
||||
"nI|\x8f\xc4\xdb\xe7d\xd0N\xa4\xd5q\x98\xa8\xe8" +
|
||||
"K\xfc\x90\xc4g \x83\x19D\xda~\x9c$*\x1e\x92" +
|
||||
"\xf8\xd3`\x08J\x96)l?_\x8ew\xc2n\xe1z" +
|
||||
"\xa6cG\xbf\xb9\xe35K-\xa6\x06\x1a\x8d6-8" +
|
||||
"i9\xd1H\xb7d\x9f\x804!\xa89\x8e5vs" +
|
||||
"\x87\xa5}\xa3\xe2a&\xa1\xc0\x81\xae\x96\x8c\x12$\x18" +
|
||||
"\x84\xf3^\xf2MJ;v\xbe\x8c6bhk~\xf2" +
|
||||
"Q\x87r%\xc3\xca\xd7\x9aLLo\xb0\xee;\xf5\x1a" +
|
||||
"\xe5\xca\x86/\xca\x001\x80\x10\xb8u{\xad\xebT7" +
|
||||
"B\xb8U\xd36,j\xde\x94\x9cj\xcd\x15\x9e\x07\xd3" +
|
||||
"\xb1\xf5\xbaa\x99\xdc\xdf\x8bvbh\x8f\xf5\x10\x9b\xde" +
|
||||
"C\xb9Z\xdfF\xa3\"{&\xd5\xec\xebE\x8b\x89\xf4" +
|
||||
"n\x0e}Y\xac\xaf{d_/\xe4\xd0W2\xa4\xe5" +
|
||||
"p5{x\xb7a\xd5\xc5-\xddz'\x15\xab\x08\xbf" +
|
||||
"q\xca\xdb;\x9d\xee\x82\xe1*F\xd5\xfb\x9b\xaf7\x08" +
|
||||
"/-\xc5(\xae\x80}Dz\x8aC\xcf0\xf4\xbb\xa1" +
|
||||
"V\xa1\xab\xb5%\xa6\x8d>\xff\xb3p\xfd\x8d(\x8d\xb9" +
|
||||
"O\x125W3\xa2\x8d\xa4\xea\xfb\x88\xa9y\x05\xadm" +
|
||||
"\x88h\xf9\xa9\xffw\x89\xa9\xab\x14\xb0\xe6\xbf\x01D[" +
|
||||
"_]t\x94\x98:_\x09\"e\xa4\xfeF\xc8\x01\x04" +
|
||||
"Qv\x94\x0b\xf3\x1b@\x10\xc9/\"\x05%\x1a@\x01" +
|
||||
"w_\xee[\xd4;\xe7\xddM\xc5\xa2Uy\xe7z5" +
|
||||
"\xe2\xa4%_Y\xad\x98\xdfq\"\xbd\x83C\x9f\xcd\x10" +
|
||||
"X\xce\x94\x94\xa6\xc7b-t;\x89k\x10\x8e\x84." +
|
||||
"-\x1fK\xff\x99\xa6\xff\xfdR\x85\xf7p\xe8Gb\xdd" +
|
||||
"\xfa\x98\x04\x1f\xe5\xd0\x9f\x8c\xa9\xf0\xe3r\x9b\x1c\xe1\xd0" +
|
||||
"O7\x85M=u\x94H?\xcd\xa1\xbf\xd9R5\xf5" +
|
||||
"ui\xf8\x1a\x87\xfe>\x83\"\\7\xe2\xa9\xd4\xdd\x96" +
|
||||
"X[Ne\xd4\xb4\x85'%`j\xea\xe5\x95\x9c\xf5" +
|
||||
"\x9ap\xab\x86-l\xf8k\x0d\xd3\xaa\xbb\x82Zc\xda" +
|
||||
"\xc8/?\x1cS\x8e\xdf\x03\x00\x00\xff\xff#\xa3\xb8\x8f"
|
||||
const schema_db8274f9144abc7e = "x\xda\x9cV_\x8c\x13U\x17?\xbf{\xdb\x9d\x16v" +
|
||||
"\xe9N\xa6$\xd0|\xa4\xf9\x08||\x10A\x101\xb0" +
|
||||
"\xfe\xd9?.h\xd7e\xe9\xd0\xd5\x10\xc0\x84\xa1\xbd\x94" +
|
||||
"Y\xdb\x99ff\x8a,\xe1\x7f\xd6\x88D\x09\x08<\x88" +
|
||||
"`\x90\x84\x08\x86\xa8\x89&&\x06\x13|P\x1ex " +
|
||||
"&b4\x92\x18%<H$\xc4\x8d<hb\xc6\xdc" +
|
||||
"\xe9N[v\x15\xd0\xb7\xdb\xdf=\xf7\x9c\xdf9s\xce" +
|
||||
"\xeft\xe1\xffx\x17[\x14\xfd>J\xa4\xf7F[\xfc" +
|
||||
"\xc7\xca\x97O=r\xf4\xd2\x08\xa9)\xe6\xef<\xdf\x97" +
|
||||
"\xfc\xcd\xdb\xfb\x1d\x11\x16_a\xdb\xa0\xfd\xc4\x14\"\xed" +
|
||||
":[E\xf0/?p\xfe\x93\x83\x1f\xbe\xfc&\xe9s" +
|
||||
"\x00\xa2\x88B\xb4\xf8\x0f\xf6;\x08\x9a\xca;\x09\xfe\x91" +
|
||||
"o>\x1d(\x1f:v\x8a\xd49\xe1\xfd2\xce\x18E" +
|
||||
"\xfc\xa9\x19\\\xbd\xb0(\xf2q\xed&\xca\xe5\xd5|~" +
|
||||
"C>\xed\xe6\xef\x13\xfc\x197{\xda\xac[{/\x90" +
|
||||
"\x9aB\x83E\xcd\xf0\x07\xde\x07\xed\xb6<j\xbf\x04\xc6" +
|
||||
"}\xeb\x0e\xbf\x1e\xbd~\xf8\"\xe9)4q\x8e*\xd2" +
|
||||
"\xfa\xb5\x88\x03\xed\xed \xf8\x89\xc8;\x8c\xe0\xa7>x" +
|
||||
"\xf4\xbd\x9e\xc2\xb7\x97\xc6\xf9\x0e2{E\x19\xd5\x8e\xca" +
|
||||
"w\xda!\xe5E\x82\xcf\xae\x1b\xd3w\x7f\xfd\xc4\xd5\xa6" +
|
||||
"\x14n*?\x82\"\xfe\xc0s\xeb\x86\xe2;\xae]\x1b" +
|
||||
"K\x01\x013%H\xe1\xb6\"\xb3_\xb2\xa1[\xac_" +
|
||||
"\xba\xe6\x06\xa9)~G!\xa7\xc6:\xa0\xcd\x8e\xc9 " +
|
||||
"\xff\x8d]\xd4\xce\xca\x93\x7f`g\xef\xaae3?\x1b" +
|
||||
"mvw(6*\xdd\x9d\x8eIw\x9b\x96\xfe\xfc\xd4" +
|
||||
"\xec\x03_\x8c\x8ec\x1d\x18~\x1e\x9b\x07\xedJ\xe0\xf1" +
|
||||
"Ki|k\xc5[_\xa5\x12\xa9_\xf5\x14\x9am\x03" +
|
||||
"\xfa\xb7cC\xd0\xe2qy\x8c\xc6\xd3\xa0\xf9\xbeW\xb5" +
|
||||
",Qr*\x91\xfc\x83\xe11\xbf oT\xacJ\xc7" +
|
||||
"\xf2\xad\xa6\xeb\x99Vq0\xc0;\xb3v\xc9\xcc\x0fg" +
|
||||
"\x01\xbd\x15\x8cH\x9d\xd1A\x04\xa8S\xd7\x12\x81\xa9j" +
|
||||
"\x0fQ\xa7Y\xb4lG\xf8\x05\xd3\xcd\xdb\x96%\x88\xe7" +
|
||||
"\xbd]\x1b\x8d\x92a\xe5E=P\xcb\xc4@\xb5\x009" +
|
||||
"\xe1l\x11\xce\x82\xaa\xe5\x88\xa2\xe9z\xc2\xa9\xc1\xb3:" +
|
||||
"\xb3\x86c\x94]=\xc2#D\x11\x10\xa9m\xc7\x88\xf4" +
|
||||
"v\x0e\xfd?\x0c~\xd11\xf2\"+\x1c\x98va\xc0" +
|
||||
"\xb0\xec\x1c\x17yD\x89!J\xa8\x07\x9d\xf2O\x83\xae" +
|
||||
"\x16n\xb5\xe4\xb9T\x7fu\xf7\xf7\xe3^g\x8dD@" +
|
||||
"\xb9\xb5Ny\xf9Z9a\x1cz\x96A\x05\x92rf" +
|
||||
"\xd4\x95}Dz?\x87\xbe\x86Ae,\x19\x94\xf5\xd9" +
|
||||
"\x1e\"=\xcb\xa1\xafg\xf0m\xc7,\x9a\xd6\x93\x82\xb8" +
|
||||
"\xe3\xa1\x8d\x18\xda\x08\xfef\xdb\xf5,\xa3,\x88\x08\xad" +
|
||||
"\xc4\xd0J\xd8eW<\xd3\xb6\\\xb47\xe6\x81\x80\xf6" +
|
||||
"\xa6\x12\xfc\xc5\x07\xee\xaez\x9b\x85\xe5\x99yC>&" +
|
||||
"\x0a\xbem\x83\xf2L\"\xbd\x8bC\xefo\xa2\x9cy\xa8" +
|
||||
")\x8f\x90\xf2\xca\x8d\x8d<\x94\x17\xc4p\xc8*-\xca" +
|
||||
"\x86Y\x0a\x7f\x85\xc9t\x93\xf2L\xc3\xe6n\xfcV\x07" +
|
||||
"Uu\x02v\xab*\xe9 C\xc9qa\xc8Q\xebF" +
|
||||
"\x1fQ\xae\x0b\x1c\xb9~4hj\x19\xf4\x10\xe5z%" +
|
||||
"\x9eE\x83\xa9\xb6\x12)\xa2\xdc\xd3\x12\x1f\x04\x03x\x12" +
|
||||
"\x9cH\xd3\xf1.QnP\xc2\x1b\xa4y\x84'\x11!" +
|
||||
"\xd2\x9e\x0f\xdc\xaf\x97\xf8f\x89G#ID\x894\x81" +
|
||||
"yD\xb9\x0d\x12\xdf.\xf1\x16\x96D\x0b\x916\x8c!" +
|
||||
"\xa2\xdcV\x89\x8fH\\\x89&\xe5\x88j{\xe0\x10\xe5" +
|
||||
"vK\xfcU\x89\xc7\xa6%\x11\x93\x82\x13\xe0\xfb$~" +
|
||||
"D\xe2\xf1\xe9I\xc4\xa5\xfc`/Q\xee\xa0\xc4\x8fK" +
|
||||
"|\x12\x92\x98D\xa4\xbd\x81cD\xb9\xe3\x12?#\xf1" +
|
||||
"\xc9-IL&\xd2N\x07|NJ\xfc\x1c\x18\xfc|" +
|
||||
"\xc9\x14\x96\x97)4w\xc8\x16\xe1\xb8\xa6m\x85\xbf\xb9" +
|
||||
"\xed\xd6?\x81\x18\x1bt\xd4\xda7k'\xe4\xa4#\xd1" +
|
||||
"X\x07\x04$\x08~\xc5\xb6K\x03wv^\xc23\x8a" +
|
||||
".\xa6\x10\xb2\x1cho\xc8+A\x82~\xa0\x03y\xcf" +
|
||||
"\xa4\x84me\x0ah!\x86\x96z+\xf4\xdb\x94\xce\x1b" +
|
||||
"\xa5L\xa5\xce\xc4t\xbb\xab\x9e]\xadP\xba`x\xa2" +
|
||||
"\x00\x10\x03\x08\xbeS\xb5V8vy\x10\xc2)\x9b\x96" +
|
||||
"Q\xa2\xfaM\xde.W\x1c\xe1\xba0mK\xaf\x1a%" +
|
||||
"\x93{\xc3\x88\x13C\x9c\x90\xa8V\xcd\xc2\x84Fc\xe3" +
|
||||
"\x1b-]\xe9\x184\x8a\xb2\xb1b\xf5\xe6\x9f;\x8fH" +
|
||||
"\x9f\xc5\xa1/lj\xfe\xf9\xb2\xf9\xff\xcf\xa1?\xcc\x90" +
|
||||
"\x90\x13Xo\xf4-F\xa9*&D\xba\x97\xd4\x15\x85" +
|
||||
"W;e\xacM\xf6\xac\xac\xe1(F\xd9\xfd\x97\xafW" +
|
||||
"\x0b7!\x15\xabY&;\x88\xf4\x18\x87\x9ed\xe8t" +
|
||||
"\x02AC{c\x95\x8c\xd3\x07\xfew\xe1:kQj" +
|
||||
"\xe2\x10%\xaa\xefo\x84kK\xd5\xb7\x11S3\x0a\x1a" +
|
||||
"+\x13\xe1\x86T\x1fw\x88\xa9K\x14\xb0\xfa_\x06\x84" +
|
||||
"\x7f\x0d\xd4\xb9\xfb\x89\xa9\xb3\x15?\x94O\xea\xac\x85\xec" +
|
||||
"\x82\x1ffG\xe9 \xbf.\xf8\xa1F#\x94Y\xa2." +
|
||||
"dq\xff\xe5\x9e \xf1i\xf7~*\x16\xee\xd3{\xd7" +
|
||||
"\xab\x16'!\xf9\xcaj5\xf9\x1d\"\xd2[9\xf4i" +
|
||||
"\x0c~\xc9\x1e\xd3\xdb\xc4@S\x0b\xddM\x07k\x84C" +
|
||||
"5L\xc8\xc7\xd2\x7f\xb2\xee\x7f\x87\x94\xea\xad\x1c\xfaH" +
|
||||
"S\xb7\xee\x91\xe0v\x0e}_\x93T\xbf$W\xce\x08" +
|
||||
"\x87~\xb2\xae~\xea\x89\xfdD\xfaI\x0e\xfd\\C\xfa" +
|
||||
"\xd4\xb3\xd2\xf0\x0c\x87\xfe\x11\x83\"\x1c'\xe4\xa9T\x9d" +
|
||||
"\x86\xa2\x97\xecb\xbfi\x09W\xea\xc1\x98\x04\xc8+9" +
|
||||
"\xf8\x15\xe1\x94\x0dKX\xf0V\x18f\xa9\xea\x08j\xcc" +
|
||||
"l-\xbfLo\x93\x8c\xfc\x19\x00\x00\xff\xff@V\xc0" +
|
||||
"\xb7"
|
||||
|
||||
func init() {
|
||||
schemas.Register(schema_db8274f9144abc7e,
|
||||
|
||||
Reference in New Issue
Block a user