TUN-1081: cloudflared now generates UUIDs

This commit is contained in:
Adam Chalmers 2018-10-05 12:12:13 -05:00
parent f7b1f7cb22
commit af2f2910b6
4 changed files with 123 additions and 92 deletions

View File

@ -4,6 +4,7 @@ import (
"bufio" "bufio"
"crypto/tls" "crypto/tls"
"fmt" "fmt"
"github.com/google/uuid"
"io" "io"
"net" "net"
"net/http" "net/http"
@ -103,7 +104,7 @@ func (e clientRegisterTunnelError) Error() string {
return e.cause.Error() 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 policy := tunnelrpc.ExistingTunnelPolicy_balance
if c.HAConnections <= 1 && c.LBPool == "" { if c.HAConnections <= 1 && c.LBPool == "" {
policy = tunnelrpc.ExistingTunnelPolicy_disconnect policy = tunnelrpc.ExistingTunnelPolicy_disconnect
@ -120,6 +121,7 @@ func (c *TunnelConfig) RegistrationOptions(connectionID uint8, OriginLocalIP str
IsAutoupdated: c.IsAutoupdated, IsAutoupdated: c.IsAutoupdated,
RunFromTerminal: c.RunFromTerminal, RunFromTerminal: c.RunFromTerminal,
CompressionQuality: c.CompressionQuality, 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 { serverInfoPromise := tsClient.GetServerInfo(ctx, func(tunnelrpc.TunnelServer_getServerInfo_Params) error {
return nil return nil
}) })
uuid, err := uuid.NewRandom()
if err != nil {
return clientRegisterTunnelError{cause: err}
}
registration, err := ts.RegisterTunnel( registration, err := ts.RegisterTunnel(
ctx, ctx,
config.OriginCert, config.OriginCert,
config.Hostname, config.Hostname,
config.RegistrationOptions(connectionID, originLocalIP), config.RegistrationOptions(connectionID, originLocalIP, uuid),
) )
LogServerInfo(serverInfoPromise.Result(), connectionID, config.Metrics, config.Logger) LogServerInfo(serverInfoPromise.Result(), connectionID, config.Metrics, config.Logger)
if err != nil { if err != nil {

View File

@ -1,9 +1,11 @@
package pogs package pogs
import ( import (
"context"
"github.com/cloudflare/cloudflared/tunnelrpc" "github.com/cloudflare/cloudflared/tunnelrpc"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"golang.org/x/net/context"
"zombiezen.com/go/capnproto2" "zombiezen.com/go/capnproto2"
"zombiezen.com/go/capnproto2/pogs" "zombiezen.com/go/capnproto2/pogs"
"zombiezen.com/go/capnproto2/rpc" "zombiezen.com/go/capnproto2/rpc"
@ -56,6 +58,7 @@ type RegistrationOptions struct {
IsAutoupdated bool `capnp:"isAutoupdated"` IsAutoupdated bool `capnp:"isAutoupdated"`
RunFromTerminal bool `capnp:"runFromTerminal"` RunFromTerminal bool `capnp:"runFromTerminal"`
CompressionQuality uint64 `capnp:"compressionQuality"` CompressionQuality uint64 `capnp:"compressionQuality"`
UUID string `capnp:"uuid"`
} }
func MarshalRegistrationOptions(s tunnelrpc.RegistrationOptions, p *RegistrationOptions) error { func MarshalRegistrationOptions(s tunnelrpc.RegistrationOptions, p *RegistrationOptions) error {

View File

@ -43,6 +43,7 @@ struct RegistrationOptions {
runFromTerminal @9 :Bool; runFromTerminal @9 :Bool;
# cross stream compression setting, 0 - off, 3 - high # cross stream compression setting, 0 - off, 3 - high
compressionQuality @10 :UInt64; compressionQuality @10 :UInt64;
uuid @11 :Text;
} }
struct Tag { struct Tag {

View File

@ -269,12 +269,12 @@ type RegistrationOptions struct{ capnp.Struct }
const RegistrationOptions_TypeID = 0xc793e50592935b4a const RegistrationOptions_TypeID = 0xc793e50592935b4a
func NewRegistrationOptions(s *capnp.Segment) (RegistrationOptions, error) { 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 return RegistrationOptions{st}, err
} }
func NewRootRegistrationOptions(s *capnp.Segment) (RegistrationOptions, error) { 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 return RegistrationOptions{st}, err
} }
@ -448,12 +448,31 @@ func (s RegistrationOptions) SetCompressionQuality(v uint64) {
s.Struct.SetUint64(8, v) 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. // RegistrationOptions_List is a list of RegistrationOptions.
type RegistrationOptions_List struct{ capnp.List } type RegistrationOptions_List struct{ capnp.List }
// NewRegistrationOptions creates a new list of RegistrationOptions. // NewRegistrationOptions creates a new list of RegistrationOptions.
func NewRegistrationOptions_List(s *capnp.Segment, sz int32) (RegistrationOptions_List, error) { 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 return RegistrationOptions_List{l}, err
} }
@ -1308,92 +1327,94 @@ func (p TunnelServer_unregisterTunnel_Results_Promise) Struct() (TunnelServer_un
return TunnelServer_unregisterTunnel_Results{s}, err return TunnelServer_unregisterTunnel_Results{s}, err
} }
const schema_db8274f9144abc7e = "x\xda\x9cV]\x8c\x14\xd5\x12\xae\xef\x9c\x99\xedY\xb2" + const schema_db8274f9144abc7e = "x\xda\x9cV_\x8c\x13U\x17?\xbf{\xdb\x9d\x16v" +
"\xcbl\xa7\x87\\\x98\\2\x09Y\xc2OX.\\\xe0" + "\xe9N\xa6$\xd0|\xa4\xf9\x08||\x10A\x101\xb0" +
"f\xd9{\xaf\xfb\xe3\x82\x99uY\xa6\x190\x08\x98\xd0" + "\xfe\xd9?.h\xd7e\xe9\xd0\xd5\x10\xc0\x84\xa1\xbd\x94" +
"\xcc\x1c\x86^{\xba'\xdd=\x08D~$\x18\x95(" + "Y\xdb\x99ff\x8a,\xe1\x7f\xd6\x88D\x09\x08<\x88" +
"Q\x91\x071\x18$1Qc\xfc\x89&\x06\x83\x09\xbe" + "`\x90\x84\x08\x86\xa8\x89&&\x06\x13|P\x1ex " +
"H\x0c1\xbc\xa8\x91Hb\x94\xec\x03DC\xdc\xe8\x83" + "&b4\x92\x18%<H$\xc4\x8d<hb\xc6\xdc" +
"&\xa6\xcd\xe9\xd9\x9ei\x16\x05\xf4\xed\xccw\xeaT}" + "\xe9N[v\x15\xd0\xb7\xdb\xdf=\xf7\x9c\xdf9s\xce" +
"U]\xf5\xd5,\xfb\x07\x1f`\xcb\x93\xdf$\x89\xf4\xe1" + "\xeft\xe1\xffx\x17[\x14\xfd>J\xa4\xf7F[\xfc" +
"d[\xf0\xbf\xea\xa53\xff9q\xf1\x08\xa9Y\x16\x1c" + "\xc7\xca\x97O=r\xf4\xd2\x08\xa9)\xe6\xef<\xdf\x97" +
"87\x92\xf9\xc5?\xfc5\x11V|\xc1\xf6A\xbb\xc6" + "\xfc\xcd\xdb\xfb\x1d\x11\x16_a\xdb\xa0\xfd\xc4\x14\"\xed" +
"\x14\"m\x82\xad'\x04\x97\x96\x9c\xfb\xf0\xd9\xf7\x9ex" + ":[E\xf0/?p\xfe\x93\x83\x1f\xbe\xfc&\xe9s" +
"\x89\xf4\x05\x00QB!Z\xf1\x1b\xfb\x15\x04M\xe5\xfd" + "\x00\xa2\x88B\xb4\xf8\x0f\xf6;\x08\x9a\xca;\x09\xfe\x91" +
"\x84\xe0\x85\xaf>\x1a\xab>w\xf2\x0c\xa9\x0b\xa2\xfb\xd5" + "o>\x1d(\x1f:v\x8a\xd49\xe1\xfd2\xce\x18E" +
"\x9c1J\x04\xb3\xf2\xb8r~y\xe2\x83\xc6M\x92\xcb" + "\xfc\xa9\x19\\\xbd\xb0(\xf2q\xed&\xca\xe5\xd5|~" +
"\xab\x1e~]>\x1d\xe4o\x13\x82\xb9?\x0cu\xda7" + "C>\xed\xe6\xef\x13\xfc\x197{\xda\xac[{/\x90" +
"\x0e\x9f'5\x8b\x16\x8b\x86\xe1\xb7|\x04\xda\xcf\xf2\xa8" + "\x9aB\x83E\xcd\xf0\x07\xde\x07\xed\xb6<j\xbf\x04\xc6" +
"\xfd\x18\x1a\x8fl=\xfe|r\xe2\xf8\x05\xd2\xb3\x88q" + "}\xeb\x0e\xbf\x1e\xbd~\xf8\"\xe9)4q\x8e*\xd2" +
"N\xb6I\xebg\x12.\xb4W\xc2\xe0\xa7\x12\x0e#\x04" + "\xfa\xb5\x88\x03\xed\xed \xf8\x89\xc8;\x8c\xe0\xa7>x" +
"\xd9w\xfe\xfb\xd6P\xf9\xf2\xc5i\xbe\xc3\xcc\xd6)\x93" + "\xf4\xbd\x9e\xc2\xb7\x97\xc6\xf9\x0e2{E\x19\xd5\x8e\xca" +
"\xda\x83\x8a<mR\x1e!\x04l\xc2\x98s\xe8\xcb{" + "w\xda!\xe5E\x82\xcf\xae\x1b\xd3w\x7f\xfd\xc4\xd5\xa6" +
"\xae\xc4RxW\xf9\x0e\x94\x08\xc6\x1e\xd8:\xde\xbe\xff" + "\x14n*?\x82\"\xfe\xc0s\xeb\x86\xe2;\xae]\x1b" +
"\xea\xd5\xa9\x14 \xaf^U\xc2\x14\xce*2\xfbU\xdb" + "K\x01\x013%H\xe1\xb6\"\xb3_\xb2\xa1[\xac_" +
"\x07\xc5\xb6\xde\xcd\xd7I\xcd\xf2\x9b\x0ayY\xe9\x83v" + "\xba\xe6\x06\xa9)~G!\xa7\xc6:\xa0\xcd\x8e\xc9 " +
"-\x0c2\xa1\\\xd0\xaa)\x85(8v`x\xfd\xea" + "\xff\x8d]\xd4\xce\xca\x93\x7f`g\xef\xaae3?\x1b" +
"y\x1fO\xc6\xddmJMJwfJ\xba\xdb\xd9\xfb" + "mvw(6*\xdd\x9d\x8eIw\x9b\x96\xfe\xfc\xd4" +
"\xfd}\xf3\x8f}29\x8duh\xf8Tj1\xb4\x17" + "\xec\x03_\x8c\x8ec\x1d\x18~\x1e\x9b\x07\xedJ\xe0\xf1" +
"\xa5\x1f\xed\x844\xbe\xb1\xf6\xe5\xcf\xb3\xe9\xecOz\x16" + "Ki|k\xc5[_\xa5\x12\xa9_\xf5\x14\x9am\x03" +
"q\xdb\x90\xfe\xd9\xd48\xb4\xcf\xa4\xed\x8aOS9P" + "\xfa\xb7cC\xd0\xe2qy\x8c\xc6\xd3\xa0\xf9\xbeW\xb5" +
"O\xe0\xd7m[Xn-Q\xfaWt,--\x19" + ",Qr*\x91\xfc\x83\xe11\xbf oT\xacJ\xc7" +
"5\xbb\xd6\xb7f\x8f\xe9\xf9\xa6]\xd9\x18\xe2\xfd\x05\xc7" + "\xf2\xad\xa6\xeb\x99Vq0\xc0;\xb3v\xc9\xcc\x0fg" +
"2K{\x0b\x80\xde\x01F\xa4\xce\xed#\x02\xd4Y[" + "\x01\xbd\x15\x8cH\x9d\xd1A\x04\xa8S\xd7\x12\x81\xa9j" +
"\x88\xc0Tu\x88\xa8\xdf\xac\xd8\x8e+\x82\xb2\xe9\x95\x1c" + "\x0fQ\xa7Y\xb4lG\xf8\x05\xd3\xcd\xdb\x96%\x88\xe7" +
"\xdb\x16\xc4K\xfe\xc1\x1d\x86e\xd8%\xd1\x0c\xd4vk" + "\xbd]\x1b\x8d\x92a\xe5E=P\xcb\xc4@\xb5\x009" +
"\xa0F\x80\xa2pw\x0bwi\xddvE\xc5\xf4|\xe1" + "\xe1l\x11\xce\x82\xaa\xe5\x88\xa2\xe9z\xc2\xa9\xc1\xb3:" +
"6\xe0\xee\xfe\x82\xe1\x1aUOO\xf0\x04Q\x02Dj" + "\xb3\x86c\x94]=\xc2#D\x11\x10\xa9m\xc7\x88\xf4" +
"\xe7I\"\xbd\x8bC\xff'CPq\x8d\x92(\x08\x17" + "v\x0e\xfd?\x0c~\xd11\xf2\"+\x1c\x98va\xc0" +
"\xa6S\x1e3l\xa7\xc8E\x09IbH\x12\x9aAg" + "\xb0\xec\x1c\x17yD\x89!J\xa8\x07\x9d\xf2O\x83\xae" +
"\xfe\xd5\xa0\x1b\x84W\xb7|\x8f\x9a\xafn\xff~\xda\xeb" + "\x16n\xb5\xe4\xb9T\x7fu\xf7\xf7\xe3^g\x8dD@" +
"\x82\x91\x0e)w4)\xaf\xd9\"'\x8cC/0\xa8" + "\xb9\xb5Ny\xf9Z9a\x1cz\x96A\x05\x92rf" +
"@F\xce\x8c\xban\x84H\x1f\xe5\xd073\xa8\x8ce" + "\xd4\x95}Dz?\x87\xbe\x86Ae,\x19\x94\xf5\xd9" +
"\xc2\xb2n\x1a\"\xd2\x0b\x1c\xfa6\x86\xc0q\xcd\x8ai" + "\x1e\"=\xcb\xa1\xafg\xf0m\xc7,\x9a\xd6\x93\x82\xb8" +
"\xdf+\x88\xbb>:\x89\xa1\x93\x10\xecr<\xdf6\xaa" + "\xe3\xa1\x8d\x18\xda\x08\xfef\xdb\xf5,\xa3,\x88\x08\xad" +
"\x82\x88\xd0A\x0c\x1d\x84\x83N\xcd7\x1d\xdbCWk" + "\xc4\xd0J\xd8eW<\xd3\xb6\\\xb47\xe6\x81\x80\xf6" +
"\x1e\x08\xe8\x8a\x95\xe0\x0f>\xf0`\xdd\xdf%l\xdf," + "\xa6\x12\xfc\xc5\x07\xee\xaez\x9b\x85\xe5\x99yC>&" +
"\x19\xf21Q\xf8m[\x94\xe7\x11\xe9\x03\x1c\xfah\x8c" + "\x0a\xbem\x83\xf2L\"\xbd\x8bC\xefo\xa2\x9cy\xa8" +
"r\xfe\xdf\xb1<\"\xca\xebv\xb4\xf2P\x1e\x16{#" + ")\x8f\x90\xf2\xca\x8d\x8d<\x94\x17\xc4p\xc8*-\xca" +
"V9Q5L+\xfa\x15%3H\xca\xfd-\x9b\xdb" + "\x86Y\x0a\x7f\x85\xc9t\x93\xf2L\xc3\xe6n\xfcV\x07" +
"\xf1\xdb\x10V\xd5\x0d\xd9\xad\xaf\xe5\xc2\x0c%\xc7%\x11" + "Uu\x02v\xab*\xe9 C\xc9qa\xc8Q\xebF" +
"Gm>F\x88\x8a\xdd\xe0(.C\x8b\xa6\xd6\x83!" + "\x1fQ\xae\x0b\x1c\xb9~4hj\x19\xf4\x10\xe5z%" +
"\xa2\xe2B\x89\xafD\x8b\xa9\xb6\x1cY\xa2\xe2\x12\x89\xf7" + "\x9eE\x83\xa9\xb6\x12)\xa2\xdc\xd3\x12\x1f\x04\x03x\x12" +
"\x82\x01<\x03N\xa4\xad\xc2\x1bD\xc5^\x09\x0fK\xf3" + "\x9cH\xd3\xf1.QnP\xc2\x1b\xa4y\x84'\x11!" +
"\x04\xcf A\xa4\x0d\x86\xee\x07$>*\xf1d\"\x83" + "\xd2\x9e\x0f\xdc\xaf\x97\xf8f\x89G#ID\x894\x81" +
"$\x91\x96\xc7b\xa2\xe2\xb0\xc4\xb7K\xbc\x8de\xd0F" + "yD\xb9\x0d\x12\xdf.\xf1\x16\x96D\x0b\x916\x8c!" +
"\xa4=\x84q\xa2\xe26\x89\xef\x92\xb8\x92\xcc\xc8\x11\xd5" + "\xa2\xdcV\x89\x8fH\\\x89&\xe5\x88j{\xe0\x10\xe5" +
"\x04\\\xa2bY\xe25\x89\xa7fg\x90\"\xd2\xaa!" + "vK\xfcU\x89\xc7\xa6%\x11\x93\x82\x13\xe0\xfb$~" +
"nI|\x8f\xc4\xdb\xe7d\xd0N\xa4\xd5q\x98\xa8\xe8" + "D\xe2\xf1\xe9I\xc4\xa5\xfc`/Q\xee\xa0\xc4\x8fK" +
"K\xfc\x90\xc4g \x83\x19D\xda~\x9c$*\x1e\x92" + "|\x12\x92\x98D\xa4\xbd\x81cD\xb9\xe3\x12?#\xf1" +
"\xf8\xd3`\x08J\x96)l?_\x8ew\xc2n\xe1z" + "\xc9-IL&\xd2N\x07|NJ\xfc\x1c\x18\xfc|" +
"\xa6cG\xbf\xb9\xe35K-\xa6\x06\x1a\x8d6-8" + "\xc9\x14\x96\x97)4w\xc8\x16\xe1\xb8\xa6m\x85\xbf\xb9" +
"i9\xd1H\xb7d\x9f\x804!\xa89\x8e5vs" + "\xed\xd6?\x81\x18\x1bt\xd4\xda7k'\xe4\xa4#\xd1" +
"\x87\xa5}\xa3\xe2a&\xa1\xc0\x81\xae\x96\x8c\x12$\x18" + "X\x07\x04$\x08~\xc5\xb6K\x03wv^\xc23\x8a" +
"\x84\xf3^\xf2MJ;v\xbe\x8c6bhk~\xf2" + ".\xa6\x10\xb2\x1cho\xc8+A\x82~\xa0\x03y\xcf" +
"Q\x87r%\xc3\xca\xd7\x9aLLo\xb0\xee;\xf5\x1a" + "\xa4\x84me\x0ah!\x86\x96z+\xf4\xdb\x94\xce\x1b" +
"\xe5\xca\x86/\xca\x001\x80\x10\xb8u{\xad\xebT7" + "\xa5L\xa5\xce\xc4t\xbb\xab\x9e]\xadP\xba`x\xa2" +
"B\xb8U\xd36,j\xde\x94\x9cj\xcd\x15\x9e\x07\xd3" + "\x00\x10\x03\x08\xbeS\xb5V8vy\x10\xc2)\x9b\x96" +
"\xb1\xf5\xbaa\x99\xdc\xdf\x8bvbh\x8f\xf5\x10\x9b\xde" + "Q\xa2\xfaM\xde.W\x1c\xe1\xba0mK\xaf\x1a%" +
"C\xb9Z\xdfF\xa3\"{&\xd5\xec\xebE\x8b\x89\xf4" + "\x93{\xc3\x88\x13C\x9c\x90\xa8V\xcd\xc2\x84Fc\xe3" +
"n\x0e}Y\xac\xaf{d_/\xe4\xd0W2\xa4\xe5" + "\x1b-]\xe9\x184\x8a\xb2\xb1b\xf5\xe6\x9f;\x8fH" +
"p5{x\xb7a\xd5\xc5-\xddz'\x15\xab\x08\xbf" + "\x9f\xc5\xa1/lj\xfe\xf9\xb2\xf9\xff\xcf\xa1?\xcc\x90" +
"q\xca\xdb;\x9d\xee\x82\xe1*F\xd5\xfb\x9b\xaf7\x08" + "\x90\x13Xo\xf4-F\xa9*&D\xba\x97\xd4\x15\x85" +
"/-\xc5(\xae\x80}Dz\x8aC\xcf0\xf4\xbb\xa1" + "W;e\xacM\xf6\xac\xac\xe1(F\xd9\xfd\x97\xafW" +
"V\xa1\xab\xb5%\xa6\x8d>\xff\xb3p\xfd\x8d(\x8d\xb9" + "\x0b7!\x15\xabY&;\x88\xf4\x18\x87\x9ed\xe8t" +
"O\x125W3\xa2\x8d\xa4\xea\xfb\x88\xa9y\x05\xadm" + "\x02AC{c\x95\x8c\xd3\x07\xfew\xe1:kQj" +
"\x88h\xf9\xa9\xffw\x89\xa9\xab\x14\xb0\xe6\xbf\x01D[" + "\xe2\x10%\xaa\xefo\x84kK\xd5\xb7\x11S3\x0a\x1a" +
"_]t\x94\x98:_\x09\"e\xa4\xfeF\xc8\x01\x04" + "+\x13\xe1\x86T\x1fw\x88\xa9K\x14\xb0\xfa_\x06\x84" +
"Qv\x94\x0b\xf3\x1b@\x10\xc9/\"\x05%\x1a@\x01" + "\x7f\x0d\xd4\xb9\xfb\x89\xa9\xb3\x15?\x94O\xea\xac\x85\xec" +
"w_\xee[\xd4;\xe7\xddM\xc5\xa2Uy\xe7z5" + "\x82\x1ffG\xe9 \xbf.\xf8\xa1F#\x94Y\xa2." +
"\xe2\xa4%_Y\xad\x98\xdfq\"\xbd\x83C\x9f\xcd\x10" + "dq\xff\xe5\x9e \xf1i\xf7~*\x16\xee\xd3{\xd7" +
"X\xce\x94\x94\xa6\xc7b-t;\x89k\x10\x8e\x84." + "\xab\x16'!\xf9\xcaj5\xf9\x1d\"\xd2[9\xf4i" +
"-\x1fK\xff\x99\xa6\xff\xfdR\x85\xf7p\xe8Gb\xdd" + "\x0c~\xc9\x1e\xd3\xdb\xc4@S\x0b\xddM\x07k\x84C" +
"\xfa\x98\x04\x1f\xe5\xd0\x9f\x8c\xa9\xf0\xe3r\x9b\x1c\xe1\xd0" + "5L\xc8\xc7\xd2\x7f\xb2\xee\x7f\x87\x94\xea\xad\x1c\xfaH" +
"O7\x85M=u\x94H?\xcd\xa1\xbf\xd9R5\xf5" + "S\xb7\xee\x91\xe0v\x0e}_\x93T\xbf$W\xce\x08" +
"ui\xf8\x1a\x87\xfe>\x83\"\\7\xe2\xa9\xd4\xdd\x96" + "\x87~\xb2\xae~\xea\x89\xfdD\xfaI\x0e\xfd\\C\xfa" +
"X[Ne\xd4\xb4\x85'%`j\xea\xe5\x95\x9c\xf5" + "\xd4\xb3\xd2\xf0\x0c\x87\xfe\x11\x83\"\x1c'\xe4\xa9T\x9d" +
"\x9ap\xab\x86-l\xf8k\x0d\xd3\xaa\xbb\x82Zc\xda" + "\x86\xa2\x97\xecb\xbfi\x09W\xea\xc1\x98\x04\xc8+9" +
"\xc8/?\x1cS\x8e\xdf\x03\x00\x00\xff\xff#\xa3\xb8\x8f" "\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() { func init() {
schemas.Register(schema_db8274f9144abc7e, schemas.Register(schema_db8274f9144abc7e,